最近在STM32F103VET6的MCU上进行了IAP升级的钻研,写出了IAP的升级程序以及一个桌面的升级终端,现在将一些心得跟过程分享出来
首先,最重要的当然是要对于STM32的FLASH要有一定的理解啦,这个可以去原子哥的开发手册里面参考一下,有对于FLASH 的介绍
大伙儿可以看看从网上搜的,其他高手写的介绍
http://blog.chinaunix.net/uid-20617446-id-3847242.html 或者也可以自己去问度娘,一大堆
好啦,下面进入正题,我使用的STM32F103VET6的FLASH是512K的,所以我将FLASH分为4个区域,分别是IAP , APP1,APP2还有剩下的一部分区域用来存放一些FLAG,如下[mw_shl_code=cpp,true]#define FLASH_Base_ADDR 0x08000000 //IAP APP Addr: 0x08000000 - 0x08019000 (size:100k) //bootloader
#define FLASH_Sector_A_StartAddr 0x08019000 //Sector A Addr: 0x08019000 - 0x0803E800 (size:150k) //APP1
#define FLASH_Sector_B_StartAddr 0x0803E800 //Sector B Addr: 0x0803E800 - 0x08064000 (size:150k) //APP2[/mw_shl_code]
实际上,bootloader区留个20-30K就很足够了,我留了100K简直太多余了。主要实现的是对于从IAP升级到APP1 或者 APP2,如果当前程序工作在APP1区,那么接下来将会升级将会APP2的区域进行,如果当前程序工作在APP2区,那么就擦写APP1区,这么做有一个好处,就是万一升级出现错误,我们还可以退回到原程序。说的通俗一点,就是整个BootLoader是一个跳板,无论是进行升级,还是掉电重新运行APP,都是要通过BootLoader。整个升级区域跳转如下
我们定一个标志位#define FLASH_Running_APP_Flag 0x08065000 //0x08064800 - 0x08065000 (size:2k) 0x1234:run IAP 0x4567:run App1 0x6789:run APP2
当有程序被刷进去后,每次重新上电,程序会读取一个标志位,然后根据读取来的东西,再选择跳转到APP
工作还是进行IAP
升级[mw_shl_code=cpp,true] if(Read_Whole_Word(FLASH_Running_APP_Flag)==0x4567) //Load in sector A
{
#if DEBUG_MODE
printf("go to sector A
");
#endif
Load_From_Sector(FLASH_Sector_A_StartAddr);
}
if(Read_Whole_Word(FLASH_Running_APP_Flag)==0x6789) //Load in sector B
{
#if DEBUG_MODE
printf("go to sector B
");
#endif
Load_From_Sector(FLASH_Sector_B_StartAddr);
}
else //IAP
{
#if DEBUG_MODE
printf("got to IAP
");
#endif
while(1)
{
TIMER_Event_Handler();
}
}[/mw_shl_code]
我们定一个标志位[mw_shl_code=cpp,true]#define FLASH_Running_APP_Flag 0x08065000 //0x08064800 - 0x08065000 (size:2k) 0x1234:run IAP 0x4567:run App1 0x6789:run APP2
[/mw_shl_code]
当有程序被刷进去后,每次重新上电,程序会读取一个标志位,然后根据读取来的东西,再选择跳转到APP
工作还是进行IAP
升级
APP可以拿去用啊,通信协议也给出来了,这不就够了吗
一周热门 更多>