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
2019-07-24 01:45
chenfujun062 发表于 2017-9-25 11:57
我想问下,你写到Flash里的代码有几个,断电后,不又回到bootload了么?有什么用?

一共三个区,bootloader, APP1 , APP2,其中APP1 和 APP2是交替着来擦写的,
我这个断电后还是会跳到程序执行的哦,因为我有在FLASH里置了flag,断电后flag是不会消失的,所以每次上电会检测flag位,再决定是跳转到APP 还是执行IAP升级

一周热门 更多>