最近用STM32F407做了一个产品,为了方便以后升级固件和修复bug,所以需要考虑实现iap功能。由于产品对外只有USB和UART两个接口,考虑到多用户的通用性,所以选择了UART作为升级入口。这里不详细描述实现过程,只分享一下自己移植过程遇到的一些问题和自己的一些实现思路供大家参考。
因为我们的产品上只有一个USB接口和一个4Pin的串口,没有设计按键,所以这里我换了一个方式来实现切换,就是利用BKP备份寄存器来实现,实现思路是在在APP中,设计一条升级指令,用户通过USB向MCU发送升级指令后,APP中会对BKP寄存器0写入一个特殊的数字(例如0xbeef),然后让MCU重启。
由于BKP寄存器只要不断电,寄存器内的数据就不会改变(虽然我们的产品中没有设计纽扣电池来为BKP寄存器供电,但是MCU在重启中指不会掉电的,所以BKP寄存器数据依然是可用的)。
MCU重启后会进入Bootloader,读取BKP寄存器的寄存器0内的数据是否为0xbeef,如果不是,就跳转至APP,如果是,就进入DFU模式升级固件,升级完成后将寄存器0写为其他值(例如0x0000) 。
STM32F4系列的flash分区是这样的,这里我们使用前三个扇区划分Bootloader,第四扇区以后划分给APP使用,当然,如果你有多个APP也可以给每个APP划分起始地址。
开发到目前为止,遇见以下几个问题:
- Bootloader可以正常跳转到APP程序的main函数中,但是无法进入ucosii创建的任务。
- 在APP程序中使用printf函数重映射导致pwm异常。
目前已经成功解决了第一个问题,就是在BootLoader程序中,原来使用如下方式跳转
发现可以成功跳转到APP程序的main函数,但是无法进入ucosii创建的任务。后面参考了正点原子的论坛上的一个帖子(连接网址如下http://www.openedv.com/forum.php?mod=viewthread&tid=278105)把BootLoader程序中的跳转函数改成如下:
一切正常。我看了上面论坛的人说了,主要是中断向量设置问题。第二个问题现在还没有解决,在测试中。
第二个问题已经有了解决:是使用YModom协议写入flash时包没有清空。