以STM32G484RE举例,固件烧录到FLASH的起始地址进行保存,理论上可烧录的最大文件为512Kb,实际项目中固件一般不会这么大,所以空余的一部分可用作数据的保存。
| 项目 | Value |
|---|---|
| FLASH的起始地址 | 0x8000000 |
| FLASH的容量 | 0x80000 512KB |
FLASH分区如下,
将0x8000000作为运行BootLoader程序,最大为64KB,
将0x80100000作为System数据存储区域,可保存系统配置文件、时间等数据最大为64KB,
将0x80200000-0x80400000作为UserAPP_1程序的保存地址,大小为128KB,
将0x80400000-0x80600000作为UserAPP_2程序的保存地址,大小为128KB,
将0x80600000-0x80800000作为UpdataBin 程序的保存地址,大小为128KB,

STM32 KEIL中各分区对应的代码配置应与分区地址对应
BootLoader:0x8000000

UserApp_1:0x8020000

开机上电运行FLASH起始地址0x8000000 处保存的BootLoader程序,检查FLASH内是否有新的升级文件需要更新,流程具体任务如下所示

UserAPP就是用户项目的主要代码,
1.主函数内,第一行,执行下述语句,设置偏移量
SCB->VTOR = FLASH_BASE | 0x20000;//设置偏移量 对应当前APP程序的分区地址
2.将升级原始文件切片、加密按照传输协议封装打包,通过串口、SPI、以太网、蓝牙、WIFI、IIC等方式进行传输
3.在UserAPP中设计线程,接收UpdataBin更新文件,保存到上面分区的 UpdataBin 0x8060000中,大小不超过128KB
4.接收完成后 ,变更Parpam保存的参数,使能更新状态标志,
5.直接调用系统API函数 进行软件复位 重新启动 代码从BootLoader开始运行
typedef volatile uint32_t vu32; //四字节对齐的数据类型(vu32*)appxaddr //将 appxaddr 地址强制转换为指针
*(vu32*)appxaddr //取 appxaddr 指针指向地址保存的值uint32_t ReadWord(uint32_t faddr)
{return *(vu32*)faddr; //可根据强制转换的类型来更改一次读取的长度 vu32 4字节 vu64 8字节
}
typedef void (*iapfun)(void); //定义一个函数类型的参数.
iapfun jump2app;
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(uint32_t addr)
{MSR MSP, r0 //set Main Stack valueBX r14
}void iap_load_app(uint32_t appxaddr)
{if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.{ jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)jump2app(); //跳转到APP.}
}
上一篇:关于竹子的文章,怎样开头
下一篇:如何制定测试团队度量体系