STM32F103 串口IAP + 升级终端,心得分享

2019-07-21 02:18发布

最近在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。整个升级区域跳转如下 1.png
我们定一个标志位#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升级
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
52条回答
BJTT
1楼-- · 2019-07-26 09:43
1547674987 发表于 2017-10-11 10:04
楼主,问你个问题,当我芯片SRAM空间不够大,一次放不下所有IAP程序 ,你是怎么搞的

我是放在FLASH 里面的,从FLASH启动的,我还没试过从SRAM启动呢
你的SRAM是多大的呀,
BJTT
2楼-- · 2019-07-26 13:29
Alionlu 发表于 2017-10-12 09:32
boot里面和main文件里面分别如图我现在的问题就是,我app1(keil上针对0x8007000写的100ms延时led翻转) ...

你的意思是说你跳转后,还是APP1 的现象是吗?
1.检查一下你的APP2 的bin文件对不对,因为我之前就范过这个错误,APP1和APP2下载了同一个bin文件,导致每次升级的现象都一样
你的APP2的程序应该是COPY APP1的,然后更改部分地方的是不?哪就检查你生成bin文件的那一段代码,看你生成APP2的bin文件的时候是不是load的是APP1 的 .axf文件,如果是这样,那每次实际上你都是下载的APP1的bin文件
1.png
最好是用串口,APP1   APP2 都定时抛不同的东西出来,这样更直观一点
Alionlu
3楼-- · 2019-07-26 19:05
BJTT 发表于 2017-10-12 11:49
你的意思是说你跳转后,还是APP1 的现象是吗?
1.检查一下你的APP2 的bin文件对不对,因为我之前就范过 ...

有可能是这个问题,我再看看
asianeast
4楼-- · 2019-07-27 00:18
楼主   串口相关的操作可否发来看看  
476623721
5楼-- · 2019-07-27 02:33
 精彩回答 2  元偷偷看……
asianeast
6楼-- · 2019-07-27 07:50
楼主  你的CRC校验采用是哪种算法呀   程序里的校验写的感觉有问题
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;
}

另外采用了几种标准的方法都和你上位机发送出来的校验值不一样     

一周热门 更多>