一.硬件资源
- STM32F407VET6 flash:512K
- SIMCOM7600CE模块(MQTT)
二.软件情况
工程代码分两个来做,一个是BootLoader工程代码,一个是APP应用工程代码。
注意对flash进行分区,这里我分4个区域,bootloader区、APP1区(运行的程序)、APP2区(存储待更新的程序)、FLAG区(标志位+待更新程序字节数)数据。但是注意这4部分数据必须在不同的扇区,不能有两部分数据处于同一扇区,因为写地址如果非 0XFF,那么会先擦除整个扇区且不保存扇区数据。建议使用1024K flash,操作空间更大一点。
基础知识就不多说了,只提一下思路和关键点:
思路:设备上电复位,运行BootLoader代码,BootLoader代码主要是根据FLAG区判断是否需要远程更新,如果不需要,则跳转至APP1区,运行应用程序代码;如果需要,则读取flash中APP2区域的数据,写进APP1区,然后清空FLAG区,跳转APP1区运行。主程序主要就是接收服务器的更新代码,写进APP2区,置位FLAG,然后重启。
关键点:
1.BootLoader工程代码需要在MDK中设置程序地址,程序是从0X08000000开始运行的,占用了128K,所以设置如下图所示:
2.APP的设置。
APP起始运行地址0X08020000 以及flash大小128K
这里要注意,中断向量表的问题。在主程序初始化的时候,对中断向量表进行偏移:
//中断向量表偏移
SCB->VTOR = FLASH_BASE | 0x20000;
3.这里我们远程烧写的是bin文件而不是hex文件,所以还需要设置MDK,生产bin文件。(具体路径根据你的MDK安装路径来写)
还有很多需要优化的地方,比如远程升级的时候传输中断怎么办,如何重回上一个版本,就不多说了。
补充:
1.烧写程序的时候,记得不要点击全部擦除。
2.原子哥的例程是根据串口来做的,里面有很多判断不适合4G升级,需要作出改动
3.BootLoader跳转前,一定要在最后的跳转函数前,DeInit之前初始化的外设以及关掉中断()。如下图:
4.由于我是使用了ucosII操作系统,发现程序跳转过来之后,会在操作系统启动的时候卡住,目前还在找原因,有待补充。(原因已经找到:接收服务器更新包的数组太大,导致HardFault_Handler,数组调小后正常,可以考虑分包接收数据)
5.经过测试,已经成功完成了服务器远程升级功能。