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-21 11:19
asianeast 发表于 2017-12-4 09:09
首先传到网上的上位机确实是460800的波特率
另外如果只有一个串口且已经使用  比如串口是9600的波特率
...

不好意思,我查看了一下代码,是460800的
你的理解是正确的
但是我的上位机,当你点击  连接设备  后,所有的串口选择项都会被冻结,没法更改了的,直到升级完成或者升级失败,才会释放

但是为什么不能统一一下波特率呢?跟我的上位机一样就可以了嘛

一周热门 更多>