前言:
在很多消费电子设备中,都有远程升级的功能,它的优点能给设备增加新功能,以及以新增新功能为理由的修复bug。
框架:
一个有远程升级的设备有两个程序,一个是bootloader,另一个是设备程序。bootloader自然是引导程序,它的作用是启动哪一个程序。
bootloader一般是处于内存的开始的地址,即设备启动就会去运行它。
升级包:
用keil把程序编译为一个bin文件,然后上位机将bin文件处理成多帧(具体看实际传输设备),向设备发送。
bootloader:
bootloader一启动,首先检查一个标志位,这个标志位我管它叫app_flag,如果它为1时则将pc指针跳转至App1的地址,为2时则跳转到2。
if(user_app_flag_addr==APP2_FLAG) //运行第二个应用程序
{
if(((*(vu32*)(APP2_FLASH_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
{
iap_load_app(APP2_FLASH_ADDR);//执行FLASH APP代码
}
}
else //运行第一个应用程序
{
if(((*(vu32*)(APP1_FLASH_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
{
iap_load_app(APP1_FLASH_ADDR);//执行FLASH APP代码
}
}
远程升级框架:
首先涉及两个点:
1.协议制订
比如协议里面规定控制码为0x10为远程升级,数据长度为两个字节,并且最高位如果置为1则为发送结束。
1.1 当主站发送第一帧数据时,要准备一块区域(EEPROM)保存升级程序,保存之前先进行清空,每收到一帧,就把数据保存在该区域。
1.2 协议里应该有校验位,确保每一帧发来的数据是正确的。
1.3 设备接收到每一帧数据都要向主站发送回应,如果网络问题,导致主站没有收到回应数据,那么主站应该要向设备再次发送这一帧数据,虽然设备已经有了这一帧数据,但可以把这一帧视为重复帧,重复帧不做任何处理。因此,在程序中还要有一个记录当前为第几帧。
1.4 当数据到达最后一帧时,数据长度的最高位置1,程序判断为结束。
2.接受完数据的处理
2.1 程序接收到最后一帧数据时,应该提前回复主站,再做处理。
2.2 程序根据自身处理APP1或APP2,把程序放在APP1或APP2。比如当前程序为APP1,接收到的升级包就应该放在APP2地址帧,如果放在APP1地址中,程序一定会奔溃的。
2.3 程序复制好地方后,进行一波软复位,首先就会执行bootloader,引导程序就会判断app_flag,在复制的时候已经把标志位置为新的APP地址处,那么设备就会运行新程序。