本帖最后由 dfgggf 于 2024-1-12 14:23 编辑
MCU:STM32F030CCT6
编程软件:MDK5
使用的ST库:Hal库
在编程的过程中,原本的方案是将bootloader与app结合到一个工程里,然后实现OTA功能。(ACU项目)
该方案的设计流程是
1.将通过蓝牙将新的固件分页发送给MCU。(一页为128个字节,按照1个字节1个字节的传输)
2.MCU将接收到的固件2k的数据后转存到Flash的指定地址(如0x8020000)内。(2K即2048个字节,即16*128即16页)
3.当MCU接收到完整的固件后跳转到新的APP程序内。
出现的问题:
1. 在将固件的数据存入Flash时出现报错,出现无法写入的问题
(使用的函数:uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint64_t* Data ,uint16_t DataLength) )
2. 在写入Flash后,再次写入是报错。
3. 该方案的弊端:bootloader成功跳转到APP后,存在一个问题:下一次更新APP时,无法直接覆盖当前的程序,否则会出现故障。
分析及处理:
1. 存入Flash时报错,是由于写入的数据一定时64bit,或者要将Flash的地址对齐。
此处采用了将写入的数据转成64bit的数据,因为FLASH_If_Write函数的Data 形参定义为64bit的。也是由于我不会地址对齐,网上查了一些,就是看不懂就 采用了这种方式。
2. 第二个问题的出现,最大的原因就是我不懂Flash的读写的原理。经过网上的查找,结果就是Flash在写入已经存过数据的地址,需要先擦除这个地址存在的 Flash页,也就是说写入Flash,最好是一整页一整页的写入。否则擦除Flash页时会别擦除掉。
3. 第三个问题,经过查证,bootloader与APP分开做成两个工程来进行编程。在测试时,可以通过烧录不同的起始地址来进行烧录,且将debug的Erase Sectors选 上即可。
第二个方案:bootloader与APP1分成两个工程
出现的问题:
1. 按照上一个方案的第3点解决方案,将APP1与bootloader分成两个不同的起始地址(APP1烧录到Flash的APP1区域)进行烧录。boot loader工程内不对APP进 行操作,只负责跳转app1。此时bootloader是可以跳转到APP1内的。
此时通过将APP1烧录到新的Flash地址(APP2区域)后,bootloader负责将Flash的APP2区域的数据复制到Flash的APP1区域内,但不擦除Flash的APP2区 域的数据。此时bootloader也能跳转到APP1。
但此时,bootloader一旦对Flash的APP2区域的数据进行擦除,bootloader就无法正常跳转。
2. APP跳转到bootloader时无法让bootloader正常运行,会出现卡死现象。
分析及处理:
1. 通过参考网上资料发现。当我将APP的起始地址如上图设定好之后,那么程序里的Flash地址就确定下来了,无论是烧录在哪个地址,当bootloader跳转到APP 时,MCU都会寻找到当初设定好的起始地址。所以一旦将APP的数据擦除后,就无法寻址,就会报硬件错误 (HardFault_Handler)。
处理办法:通过Keil设定APP的起始地址(如Flash的APP2区域),再通过烧录工具(STM32 ST-LINK Utility)对指定的Flash区域(Flash的APP1区域)进 行烧录。这样,bootloader在检测到Flash的APP1区域内有程序,则会将Flash的APP1区域的数据覆盖到Flash的APP2区域内,由于APP的起始地址就在Flash的 APP2区域内,那么bootloader就可以正常的跳转了。
2. 在boot loader与APP相互跳转之前,需要将程序的中断都关闭了再进行跳转。
增加一下两条程序
//重置RCC
__HAL_RCC_PWR_CLK_DISABLE();
HAL_RCC_DeInit();
总结:在做boot跳转APP时需要注意的点:
1. 需要算好boot的大小,和app的大小。因为在更新程序时,会同时存在3个工程的程序。
2. 在写入Flash前需要对Flash页进行擦除。
3. 设定程序的起始地址是boot需要跳转的地址。而不是存放的地址。在调试时需要测试boot对新程序进行更新,则通过别的方式进行指定地址的烧录。
在这次问题处理上,存在诸多的不足。对Flash原理的不了解,对OTA的实现方式不了解。总以为时擦除Flash导致boot无法跳转。
参考网址:
https://blog.csdn.net/JosephGodVim/article/details/127075018?spm=1035.2023.3001.6557&utm_medium=distribute.pc_relevant_bbs_down_v2.none-task-blog-2~default~ESQUERY~Rate-2-127075018-bbs-392135754.264^v3^pc_relevant_bbs_down_v2_default&depth_1-utm_source=distribute.pc_relevant_bbs_down_v2.none-task-blog-2~default~ESQUERY~Rate-2-127075018-bbs-392135754.264^v3^pc_relevant_bbs_down_v2_default
重点:
20240112
问题更新:由bootloader跳转APP2 改为bootloader跳转APP1时,出现无法进入中断,导致程序无法运行。
问题原因:由于bootloader跳转到APP时,APP中的中断向量表初始化未进行修改,依然才有APP2地址的中断向量表,因此导致无法进入跳转。
问题出处:
修 改:
笔记:
1. 初始化中断向量表步骤
2.memcpy((void*)0x20000000, (void*)APPLICATION_ADDRESS1, 0xB8);中的0xB8为中断向量表的大小(最后一个地址)
|