最近在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
升级
我是放在FLASH 里面的,从FLASH启动的,我还没试过从SRAM启动呢
你的SRAM是多大的呀,
你的意思是说你跳转后,还是APP1 的现象是吗?
1.检查一下你的APP2 的bin文件对不对,因为我之前就范过这个错误,APP1和APP2下载了同一个bin文件,导致每次升级的现象都一样
你的APP2的程序应该是COPY APP1的,然后更改部分地方的是不?哪就检查你生成bin文件的那一段代码,看你生成APP2的bin文件的时候是不是load的是APP1 的 .axf文件,如果是这样,那每次实际上你都是下载的APP1的bin文件
最好是用串口,APP1 APP2 都定时抛不同的东西出来,这样更直观一点
有可能是这个问题,我再看看
u16 DATA_CRC(u8 * data,u16 len)
{
u16 crc=0;
u8 da;
while(len--!=0)
{
da=(unsigned short)crc>>8;
crc<<=8;
//crc^=crc_ta[da^*data];
data++;
}
return crc;
}
另外采用了几种标准的方法都和你上位机发送出来的校验值不一样
一周热门 更多>