本帖最后由 穿西装的强子 于 2024-4-8 11:45 编辑
#申请原创# 以STM32F407VET6为例,片上FLASH共有1MBytes大小,分为12个扇区,按datasheet图所示,Main memory
升级主要流程
按不同需求分为几个部分
1.bootloader程序
2.APP程序
3.升级缓存
4.备份(可选)
5.数据存储
一、BootLoader程序及流程
流程图如下:
FLASH分区
以标黄的部分作为自定义的FLASH分区
1.bootloader程序区
2.APP程序区
3.升级缓存区
4.备份区(可选)
5.数据存储区
以上五个部分进行分区
a)bootloader一般10~20Kbytes大小,以64K大小为例,使用扇区0~3;
b)APP程序区,根据不同的代码有不同的大小,若需要备份区,则代码根据剩余的大小平均分3份,例如(1024-32)/3 =330.6666666666667,但是从扇区5开始都是128Kbytes的大小,所以我们暂定256Kbytes大小,那么从扇区5~扇区6为APP区;
c)升级缓存区,该区域是将升级的文件接收到之后放置在该区域,所以该区域的大小是与APP程序区的大小一致,因此分配扇区7~扇区8;
d)备份区,该区域作为软件备份使用,将APP程序备份在此区域,若需要恢复出厂设置或者回退版本则需要将此处数据复制到APP区即可,因此分配扇区9~扇区10;
e)数据存储区,该区域作为自定义数据存储和升级数据的存储区域,一般不会太大,使用扇区4或者扇区11~扇区12均可;
不同的芯片不同的FLASH大小均可按此种方式进行分配;
BootLoader升级代码流程
一、检测是否有APP标志或者找到APP地址上是否有数据
void DevUpdate_Handle(void)
{
if( gfirmbuff->gProtocolFirmware.App_flag == TRUE || (*(__IO uint32_t *)FLASH_APP_ADDR) != 0xFFFFFFFF)
{
if( gfirmbuff->gProtocolFirmware.Update_active == Active_reload ) // 如果有回退标记
{
if( gfirmbuff->gProtocolFirmware.Backoff_flag == TRUE) // 如果备份区有数据则回退,否则正常进入系统
{
DevUpdate_Realod();
}
else
gfirmbuff->gProtocolFirmware.Update_active = Active_none;
}
else if( gfirmbuff->gProtocolFirmware.Update_active == Active_update) // 如果有更新标记
{
DevUpdate_Update();
}
else if( gfirmbuff->gProtocolFirmware.Update_active == Active_none) // 无更新,无回退并且有APP则直接进入系统
{
DevUpdate_JumpToApp();
}
}
}
二、更新数据到APP地址
void DevUpdate_Update(void)
{
INT32U i = 0;
INT32U buff[10];
INT32U buff_2;
DrvFlash_ReadWords(FLASH_DATA_ADDR,&buff_2,1);
if( buff_2 != 0xFFFFFFFF)
{
// 将缓存数据复制到FLASH内
for(i = 0; i < APP_ROM_SIZE/40; i++)
{
DrvFlash_ReadWords(FLASH_DATA_ADDR+i*40,buff,10);
DrvFlash_WriteWords(FLASH_APP_ADDR+i*40,buff,10);
}
gfirmbuff->gProtocolFirmware.firmwaresize = 0;
gfirmbuff->gProtocolFirmware.Update_active = Active_none;
DevProtocol_SaveUpdateParameter(); // 记录数据
}
else
gfirmbuff->gProtocolFirmware.Update_active = Active_none;
}
三、跳转到APP
void DevUpdate_JumpToApp(void)
{
DevProtocol_SaveUpdateParameter();
DrvTimer_Disable(Timer2);
DrvUart_Disable(UartPort1);
__disable_irq();
/* Test if user code is programmed starting from address "ApplicationAddress" */
if (((*(__IO uint32_t *)FLASH_APP_ADDR) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t *)(FLASH_APP_ADDR + 4);
Jump_To_Application = (pFunction)JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t *)FLASH_APP_ADDR);
//Jump to APP
Jump_To_Application();
}
}
bin文件通过串口或者其它通信,将bin转换为16进制数据,将数据发送到缓存区内,通过校验后,将缓存区的数据复制到APP区,跳转到APP区的起始地址,再将msp设置到APP区的起始地址,整个流程就算完成;
二、APP程序
APP只需要处/3个地方
1、起始地址和大小的配置
2、生成BIN文件
3、设置FLASH的偏移
这样便完成整个IAP升级的流程。
|
编辑推荐:奖励200家园币!