当开始升级的时候,上层下发升级请求,上层按照一定的顺序分发子mcu固件,首先会在主mcu上判断是否满足升级条件,如果各项指标都满足,此时向子mcu发送升级请求,此时子mcu的APP程序中应该可以收到升级指令,此时子mcu应重启进入boot
mcu的引导程序有三种启动方式,这个可以通过手册查到
用的比较多的是主flash引导源,将程序直接写道flash中启动
引导装载程序一般是有一个特定的区域·,由芯片自带的boot进行搬运到flash并且启动程序
片上SRAM启动这种可以避免反复擦写flash,直接从sram启动,可以做高速调试
设置两种bootflag,BootFlagNormal(代表正常运行)和BootFlagOta(代表要升级)
定义一个bootflag相关的静态全局变量结构体
例如
struct {
uint32_t BootFlag;
...;//可以定义一些boot相关的的参数
}stBootParam;
void boot_start(uint32_t runmode)
{
stBootParam.BootFlag = runmode;
flash_erase_obj(ROM_BOOTFLAG_BASE);
flash_save_data(eBOOTFLAG);
NVIC_SystemReset();//软件复位函数
while(1)
{
}
}
通过此函数就可以是软件重启,此时进入bootload后,就会读出flag发现不是正常启动,而是需要进行ota,此时就走ota逻辑
子mcu的bootload
int main(){
boot_peripheral_init();//对时钟、gpio、串口、dma、中断等相关配置进行初始化
flash_read_obj(eBOOTFLAG);//读出boot相关参数到定义的结构体中
switch(stBootParam.BootFlag){
case BootFlagNormal:
boot_normal_process();
break;
case BootFlagOta:
boot_ota_process();
break;
default:
//说明有异常了,需要做异常处理
//可以做个检查,比如通过crc等方式检查代码的有效性,如果有效正常启动,重新存储
//无效进行升级
break;
}
return 0;
}
部分函数的解析:
1、初始化函数:boot_peripheral_init
这个就和正常配置mcu一样,需要什么功能就配置什么外设即可,主要就是时钟,串口,dma,因为需要做通信,接受数据,使用dma能够更好的减负
注意:
在配置GPIO的时候需要注意一下,即使不会使用的GPIO最好是也要做一些配置,因为有些GPIO在BOOT里虽然用不到,但是在主程序中,一些器件就会使用到,还需要根据实际情况配置一下
原因是:在实际工作中发现,当boot跳转到APP的时候,例如某个引脚默认是低,但是在主程序中,此引脚连接了某些器件,默认是高的时候才会是关闭,低是运行,此时从boot跳转主程序,引脚就会从默认是低跳变成默认是高,连接的器件有可能会有一瞬间的上电情况
迷糊了。。。。。后面在更😄