STM32 UDS Bootloader开发-下位机篇-App软件

news/2024/11/8 16:39:30/

文章目录

    • 前言
    • 链接文件
    • APP软件
      • 检查预编程条件
      • 停止DTC设置
      • 禁止无关通讯
      • 定义APP_INFO
      • 调试输出
      • hex处理
    • 总结

前言

在之前的文章中,介绍了STM32 UDS Bootloader开发需求和bootloader软件开发的修改点。本文继续介绍APP软件关于UDS的部分。APP主要实现预编程阶段的部分内容。

链接文件


LR_IROM1 0x0800E000 0x00032000  {    ; load region size_regionER_IROM1 0x0800E000 0x00032000  {  ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20000000 0x0000BFF0  {  ; RW data.ANY (+RW +ZI)}RW_IRAM2 0x2000BFF0 UNINIT 0x00000010  {.ANY (+RW +ZI)}
}LR_IROM2 0x0800D800 0x0000800  {    ; load region size_regionER_IROM2 0x0800D800 0x0000800  {  ; load address = execution address*(.APP_INFO)    .ANY (+RO).ANY (+XO)}}

此处按需求定义APP_INFO的flash区域为起始地址0x0800D800,大小0x800。

RW_IRAM2区域定义UNINIT,保证在APP跳boot复位后,对应ram区域的内容不被初始化

APP软件

检查预编程条件

static void RoutineControl(struct UDSServiceInfo *i_pstUDSServiceInfo, tUdsAppMsgInfo *m_pstPDUMsg)
{uint8 Ret = FALSE;uint32 ReceivedCrc = 0u;ASSERT(NULL_PTR == m_pstPDUMsg);ASSERT(NULL_PTR == i_pstUDSServiceInfo);RestartS3Server();if(TRUE == IsCheckPreProgrammingCondition(m_pstPDUMsg)){m_pstPDUMsg->aDataBuf[0u] = i_pstUDSServiceInfo->SerNum + 0x40u;m_pstPDUMsg->xDataLen = 4u;}#ifdef UDS_PROJECT_FOR_BOOTLOADER/* Is erase memory routine control? */else if (TRUE == IsEraseMemoryRoutineControl(m_pstPDUMsg)){/* Request client timeout time */SetNegativeErroCode(i_pstUDSServiceInfo->SerNum, NRC_SERVICE_BUSY, m_pstPDUMsg);m_pstPDUMsg->pfUDSTxMsgServiceCallBack = &DoEraseFlash;}/* Is check sum routine control? */else if (TRUE == IsCheckSumRoutineControl(m_pstPDUMsg)){ReceivedCrc = m_pstPDUMsg->aDataBuf[4u];ReceivedCrc = (ReceivedCrc << 8u) | m_pstPDUMsg->aDataBuf[5u];/* TODO Bootloader: #04 SID_31 Uncomment this 2 lines when CRC32 used */#ifdef EN_CRC32_SOFTWAREReceivedCrc = (ReceivedCrc << 8u) | m_pstPDUMsg->aDataBuf[6u];ReceivedCrc = (ReceivedCrc << 8u) | m_pstPDUMsg->aDataBuf[7u];#endifFlash_SavedReceivedCheckSumCrc(ReceivedCrc);/* Request client timeout time */SetNegativeErroCode(i_pstUDSServiceInfo->SerNum, NRC_SERVICE_BUSY, m_pstPDUMsg);m_pstPDUMsg->pfUDSTxMsgServiceCallBack = &DoCheckSum;}/* Is check programming dependency? */else if (TRUE == IsCheckProgrammingDependency(m_pstPDUMsg)){/* Write application information in flash. */(void)Flash_WriteFlashAppInfo();/* Do check programming dependency */Ret = DoCheckProgrammingDependency();if (TRUE == Ret){m_pstPDUMsg->aDataBuf[0u] = i_pstUDSServiceInfo->SerNum + 0x40u;m_pstPDUMsg->xDataLen = 4u;}else{/* Don't have this routine control ID */SetNegativeErroCode(i_pstUDSServiceInfo->SerNum, NRC_SUBFUNCTION_NOT_SUPPORTED, m_pstPDUMsg);}}#endifelse{/* Don't have this routine control ID */SetNegativeErroCode(i_pstUDSServiceInfo->SerNum, NRC_SUBFUNCTION_NOT_SUPPORTED, m_pstPDUMsg);}
}

此处正常检查预编程条件应该判断车速,蓄电池电压这些,这里直接返回的true.

停止DTC设置

static void ControlDTCSetting(struct UDSServiceInfo *i_pstUDSServiceInfo, tUdsAppMsgInfo *m_pstPDUMsg)
{uint8 RequestSubfunction = 0u;ASSERT(NULL_PTR == m_pstPDUMsg);ASSERT(NULL_PTR == i_pstUDSServiceInfo);RequestSubfunction = m_pstPDUMsg->aDataBuf[1u];switch (RequestSubfunction){case 0x01u :case 0x02u :m_pstPDUMsg->aDataBuf[0u] = i_pstUDSServiceInfo->SerNum + 0x40u;m_pstPDUMsg->aDataBuf[1u] = RequestSubfunction;m_pstPDUMsg->xDataLen = 2u;break;case 0x81u :case 0x82u :m_pstPDUMsg->xDataLen = 0u;break;default :SetNegativeErroCode(i_pstUDSServiceInfo->SerNum, NRC_SUBFUNCTION_NOT_SUPPORTED, m_pstPDUMsg);break;}
}

此处正常应该调用停止DTC诊断的API函数,本APP没有做诊断,所以没有,直接返回的true

禁止无关通讯

static void CommunicationControl(struct UDSServiceInfo *i_pstUDSServiceInfo, tUdsAppMsgInfo *m_pstPDUMsg)
{uint8 RequestSubfunction = 0u;ASSERT(NULL_PTR == m_pstPDUMsg);ASSERT(NULL_PTR == i_pstUDSServiceInfo);RequestSubfunction = m_pstPDUMsg->aDataBuf[1u];switch (RequestSubfunction){case 0x0u :case 0x03u :m_pstPDUMsg->aDataBuf[0u] = i_pstUDSServiceInfo->SerNum + 0x40u;m_pstPDUMsg->aDataBuf[1u] = RequestSubfunction;m_pstPDUMsg->xDataLen = 2u;break;case 0x80u :case 0x83u :/* Don't transmit UDS message. */m_pstPDUMsg->aDataBuf[0u] = 0u;m_pstPDUMsg->xDataLen = 0u;break;default :SetNegativeErroCode(i_pstUDSServiceInfo->SerNum, NRC_SUBFUNCTION_NOT_SUPPORTED, m_pstPDUMsg);break;}
}

此处应该停止发送应用报文和网络管理报文,本APP没有其他报文发送,此处直接返回true

定义APP_INFO

__attribute__((used)) __attribute__((section (".APP_INFO"))) const tAppFlashStatus gs_stAppFlashStatusInfo = 
{.appStartAddr = APP_A_START_ADDR,.isFlashErasedSuccessfull =  0x00,.isFlashProgramSuccessfull = 0x00,.isFlashStructValid = 0x00,
};

定义该flash区域为APP_INFO,配置appStartAddr为0x0800E000.

调试输出

为了确认BOOT和APP跳转是否成功,设置了Bootloader软件中LED1闪烁,APP软件中LED0闪烁

boolean TIMER_HAL_Is100msTickTimeout(void)
{boolean result = FALSE;if (gs_100msCnt >= 1000u){result = TRUE;gs_100msCnt -= 1000u;#ifdef UDS_PROJECT_FOR_APPLED0=!LED0;#endif}timerTickCnt++;return result;
}

hex处理

此处编译出来hex有两块


使用hexview+bat脚本填充间隔

..\..\..\HexTools\hexview.exe /G /s .\STM32_UDS_APP.hex  /S /FA: /AF:0xFF /XI:32  -o STM32_UDS_APP_Fill.hex /e:errorfile 

创建单个区域文件(/FA)

此选项可用于创建单个块文件。在这种情况下,HexView将使用第一个块的起始地址和最后一个块的结束地址,并使用/AFxx参数给定的填充字符填充其间的所有剩余byte。

/AF:0xFF表示填充使用0xFF

/XI:32指定输出行的字节数为32

总结

到此,APP软件开发就完成了。后面有时间会介绍上位机的开发

丐版刷写界面如下:


http://www.ppmy.cn/news/669572.html

相关文章

100vh

100vh 是一个 CSS 单位&#xff0c;表示视口&#xff08;浏览器窗口&#xff09;的高度。具体来说&#xff0c;它表示相对于视口高度的百分比&#xff0c;其中 vh 表示视口高度的1%。 举个例子&#xff0c;如果浏览器窗口的高度为 800 像素&#xff0c;那么 100vh 就等于 800 …

RK3568-SARADC

RK3568-SARADC RK3568有8路SARADC配置设备树 内核常用接口 获取adc值: iio_read_channel_raw() 获取电压: iio_read_channel_processed()ADC常用接口 可以通过用户态接口获取adc值&#xff0c;其中*表示adc第多少通道: cat /sys/bus/iio/devices/iio\:device0/in_voltage*…

rk3399 注册drm 驱动

rk3399 基于component 框架&#xff0c;在probe阶段解析dts中各个设备的信息&#xff0c;加到componet match 列表中&#xff0c;等所有的设备加载完毕后&#xff0c;就会引发master设备的bind。 1.vop probe static int vop_probe(struct platform_device *pdev) {struct de…

MSP430F5529输出PWM

msp430f5529产生4路PWM波&#xff0c;改变占空比从而改变电机(直流减速电机)的速度。驱动电机必然会用到驱动模块&#xff0c;接下来就介绍一下驱动模块——L298N L298N驱动 若要对直流电机进行PWM调速&#xff0c;需设置IN1和IN2,即确定电机的转动方向&#xff1b;然后对使能…

Rk3399 Android9.0 恢复出厂设置流程

Reset 流程 : 1.原生设置中响应 恢复出厂设置 功能,继而发出重置广播(Intent.ACTION_FACTORY_RESET) . 2.frameWork层 接收到此广播,根据广播所携带的参数执行Android层的Reset设定. 3.Android层执行到最后会将Reset配置信息写入 /cache/recovery/command 中,最终进入Recove…

RK3588 配置HDMI支持8K分辨率输出

RK3588 配置HDMI支持8K分辨率输出 RK3588 芯片最高支持的输出分辨率可以到8K&#xff0c;由于Android12 SDK要支持多个显示接口&#xff0c;所以默认最高只配置了4K的分辨率支持&#xff0c;下面以RK3588-EVB1的开发板上配置HDMI输出8K输出为例进行说明如何让RK3588支持8K分辨…

超详细!旗舰SoC RK3588参数介绍-飞凌嵌入式

OK3568-C开发板 RK3588是瑞芯微旗下最新的8K旗舰SoC芯片&#xff0c;采用ARM架构&#xff0c;主要用于PC、边缘计算设备、个人移动互联网设备和其他数字多媒体应用。 RK3588集成了四核Cortex-A76和四核Cortex-A55&#xff0c;以及单独的NEON协处理器&#xff0c;支持8K视频编解…

Python神经网络学习(七)--强化学习--使用神经网络

前言 前面说到了强化学习&#xff0c;但是仅仅是使用了一个表格&#xff0c;这也是属于强化学习的范畴了&#xff0c;毕竟强化学习属于在试错中学习的。 但是现在有一些问题&#xff0c;如果这个表格非常大呢&#xff1f;悬崖徒步仅仅是一个长12宽4&#xff0c;每个位置4个动…