单片机的程序升级其实本质就是对单片机的片上Flash进行擦写,将新的程序写入到运行的Flash位置。做了2G模块的IAP程序升级和基于串口上位机的IAP程序升级。写下一点自己的浅见。
概况:
-
软件上:
具备远程升级的单片机的程序整体具体包含两个部分,一部分是(APP)应用程序,另一部分是(BOOT)引导程序。
APP程序 就是我们需要进行更新的程序,程序包括的内容:应用相关的程序(业务相关),接受并解析升级数据包的程序,存储数据包的程序。
BOOT程序 就是负责对已经存储好的升级数据包文件写入APP程序所在的Flash;并跳转到APP程序;
这两部分的程序是相互独立的运行的,拥有相互跳转的能力,相互升级对方的能力。上电一般先运行BOOT程序,然后跳转到APP程序执行。BOOT程序一般很小,APP程序比较大。 -
硬件上:
单Flash块的单片机:Flash存储位置上BOOT程序从默认启动Flash地址 0x0000000 开始开始存储 ,APP程序从BOOT 程序后的指定Flash页的基地址开始(Flash擦除写入以页(page)为单位)。
多个Flash块的单片机:单片机有相应的Flash区分(例如LDROM,APROM等),一般将两个程序存储与不同的区块,查看手册配置好,启动flash即可。
如下图所示:
1. BOOT程序结构:
- 单块Flash的BOOT程序结构简单(单片机为新唐的M4系列,使用复位跳转方式。也可以使用非重启方式跳转:重映射向量表之后,栈指针也要修改到APP_ADDR,(APP_ADDR + 4) 复位中断处理函数为程序入口),如下:
//只是示意步骤,并非真正程序,隐去细节
int32_t main(void)
{
SYS_Init(); //系统以及外设初始化
SYS_UnlockReg(); //解锁系统寄存器的写保护
FMC_Open(); //开启Flash擦写
set_IAP_boot_mode(); //进入IAP模式
if(CheckUpdateFlag()) //检查是否需要升级APP程序
{
if(DataCheck()) //检验待写入的APP数据的完整性
{
FMC_ENABLE_AP_UPDATE(); //开启程序区的Falsh写入
load_image_to_flash(); //写入新的APP程序
WriteUpdateFlag(Update_Success); //更新升级标志位至升级完成
FMC_DISABLE_AP_UPDATE(); //关闭程序区的Falsh写入
}
else
{
WriteUpdateFlag(Update_Failed); //更新升级标志位至升级完成
}
}
NVIC->ICER[0] = 0xFFFFFFFF; //关闭所有中断
FMC_SetVectorPageAddr(APP_ADDR); //重定向APP程序执行向量,页对齐
NVIC_SystemReset(); //重启跳转至APP程序,或者使用程序跳转
}
- 多块Flash的情况:只是将跳转的方式的操作有所区别,基本一致。
2. APP程序结构:
APP程序的程序升级流程就把从数据源获取的数据(不管是网络传输过来的数据,还是通过串口传输的数据),按照约定的格式解析出APP的二进制数据包和程序的校验值存储起来,在接收完毕数据之后把升级的标志位置为需要升级,然后执行跳转到BOOT程序,进行升级。新的APP程序,检查升级是否完成的,上报或者回复相应信息。
至此升级流程就全部完成。这里只讲流程,由于传输的方式和传输协议等的差异,具体的实现方式很多。
3. Flash写入相关:
一般升级文件为单片机工程编译生成的BIN文件,传输量最小。Hex文件大小至少是BIN文件的2倍。
例如如上图所示,数据存储于片上Flash的另一区域,那么一般这块数据的第一页都是用来存放数据包的信息,校验值,升级标志位等升级相关的数据。升级文件的Flash写入就是将BIN文件原封不动的从Flash指定地址(例如APP_ADDR)开始写入,不足一页的用0xFF填充剩下的字节写入。
题外话:现在单片机的功能越来越强大,主频也越来越高,像Coretex-M7的已经达到了500MHz。相应的应用也是越来越丰富,互联网思维(敏捷开发)的全行业推进,做一款产品先做一个demo先上线,然后根据实际情况慢慢的完善。这时候程序的升级就变得非常的重要了,你要是联网的的设备远程升级那就更加的方便了。IAP升级也适用于功能出了问题进行紧急维护。