关于STM32的IAP与FLASH
## 开发环境
我用的是STM32F103,正点原子的库函数版本。刚开始用的用的是STM32C8T6,后来发现程序编译完都有28K,FLASH总共64K,考虑的要IAP,换了STM32CBT6,封装都是 LQFP-48的,但是FLASH大一点,价格贵一点,咋们不差钱,免得后面不够用(最后换了国产GD32CBT6)。
编译环境keil5破解版,嘘嘘嘘~
下载器ST-LINK,淘宝45包邮
## IAP
什么是IAP?为啥要IAP?IAP即为In Application Programming(在应用中编程),简单理解就是跟手机OTA一样在线升级。一般单片机出厂都会烧录好程序,但是这个万一测试不足。人有失蹄,马有失手,程序员总会写BUG。到了用户手上,用户使用环境,操作方式都和测试环境不用,一下就出问题了。怎么办?快递回来?重新烧录程序?快递费加人工费,卖产品还赚个球啊。这时候你就需要OTA啊,给用户在线升级到下个版本就好了,解决问题。
单片机怎么实现在线升级?就是IAP功能。一片STM32芯片的flash内一个用户程序,开机复位地址是0x08000000,接着是中断向量表,0X08000004才是用户的main函数入口。
而IAP方案则是将主程序为两部分,两部分区域各存放一个程序,一个叫bootloader(引导加载程序),另一个叫APP(用户应用程序)。bootloader和APP需要在出厂的时候烧录好,每次开机运行bootloader然后再跳转APP运行,每次要更新程序时就跳转到bootloader对APP所在的地址进行重新烧录,完成后重启进去bootloader,然后跳转到新的APP。
128k的flash我这样划分的:
前62k留的bootloader程序代码,出厂的时候我把APP的功能整和到bootloader里面,作为一个出厂程序,万一以后升级新APP出问题,可以再回到bootloader里面运行APP的基础功能,只要boooader程序的升级模块没问题,以后可以再升级到新的无问题APP,给自己留了后路,后来发现真TM有用!
2k留给变量存储,保证掉电不丢失。在韩斌好友的启发下,增加了对电机状态的存储,确保掉电重启后电机恢复到上次运行的状态,真鸡儿天才,我怎么没想到。
最后64k留给APP代码,64k=64*1024=0x10000,地址位置就是0x08010000,跳转APP就是这个地址。
IAP怎么实现?就是出厂先烧录bootloader程序,我把APP功能也整合了,不用在0x08010000地址再烧录APP程序了。直接0x08000000烧录。
在STM32串口收到升级命令后,判断一下在程序现在在bootloader还是APP里面,bootloader里面就回复开始升级,把串口收到的程序包,写入APP的地址flash就是刚刚说的0x08010000,然后重启重新进去bootloader,引导进去新的APP,为啥要重启,不直接跳转APP,因为bootloader里面我集成APP的功能,bootloader中断初始化了,APP里面中断触发会进去bootloader的中断,中断不会跳转到APP的中断中,那我更新毛线程序啊,还是运用bootloader的中断函数。
如果在APP中收到升级命令,很简单,在flash写的标志位,重启进去bootloader里面更新APP程序,更新好了,跟上次一样再重启,写标志位,就进去新的APP程序了。哈哈哈,完美
## FLASH
STM32的flash根据大小有分别
flash小于256k的,每页1024字节,就是1KB
flash大于256k的,每页2048字节,就是2KB
每次写flash必须一页一页写入,这个是最重要的,划重点了。所以写flash,比较麻烦有几个步骤要记录一下:
1.先判断一下,你要写入的地址是否合理?
2.再解锁flash,这时候中断全部会被屏蔽,触发不了。
3.接着读取整页的数据,看看数据是不是都是0xFFFF(默认擦除后就是这样),如果不是就擦除整页内容,然后把刚刚读出来数据和你要写入的数据整合,重新写入flash的这页里面。
4.然后给flash上锁
5.最后等待2个系统时钟,读取flash值,是否跟要写入的变量一样。需要注意:主频24M以下使用0等待,24M-48M使用1等待,48M~72M使用2等待。
没了,我就记着这么多,有点困,先睡了