来自QQ群 Linux && 技术分享 311078264

打开链接加入QQ群:https://jq.qq.com/?_wv=1027&k=5Gr3bAx

此文档由elikang整理,为了文章简单直接,许多细节未能在文章中体现,如有疑问请进群讨论。

 

STM32在线升级 (IAP)

不需要拆机就能够对产品进行升级,通过Bootloader就可以完成这项工作。

1、先了解一下IAP

1.1、ISP和IAP的区别:
      ISP(In-System Programming)在系统可编程,指电路板上的空白器件可以编程写入最终用户代码, 而不需要从电路板上取下器件,已经编程的器件也可以用ISP方式擦除或再编程。
      IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。

      ISP和IAP技术是未来仪器仪表的发展方向。

      ISP技术的优势是不需要编程器就可以进行单片机的实验和开发,单片机芯片可以直接焊接到电路板上,调试结束即成成品,免去了调试时由于频繁地插入取出芯片对芯片和电路板带来的不便。
      IAP技术是从结构上将Flash存储器映射为两个存储体,当运行一个存储体上的用户程序时,可对另一个存储体重新编程,之后将程序从一个存储体转向另一个。

1.2、IAP的编写流程
      由Bootloader负责检测SD卡中是否有固件更新所需的BIN文件,或者通过SPI、CAN、以太网等方式获取BIN文件。
      如果获取到所需要的BIN文件,则开始复制文件更新固件,更新结束后跳转到指定的地址开始执行最新的程序。  

2、STM32内置Flash

       STM32内部FLASH的起始地址为0X08000000,Bootloader程序文件就从此地址开始写入,存放APP程序的首地址设置在紧跟Bootloader之后。当程序开始执行时,首先运行的是Bootloader程序,然后Bootloader收到BIN文件并将其复制到APP区域使固件得以更新,固件更新结束后还需要跳转到APP程序开始执行新的程序,完成这最后这一步要了解Cortex-M3的中断向量表。

       程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,当复位中断程序运行完成后才跳转到main函数。由此可见,在最后一步的设计中需要根据存放APP程序的起始地址以及中断向量表来设置栈顶地址,并获取复位中断地址跳转到复位中断程序。

      内置Flash的分配情况大致如下:

     

       在只有一个程序的情况下应该是如下所示:

     

 

       STM32Fx有一个中断向量表,这个中断向量表存放代码开始部分的后4个字节处(即0x08000004),代码开始的4个字节存放的是栈顶地址。   

       当发生中断后程序通过查找该表得到相应的中断服务程序入口,然后跳到相应的中断服务程序中执行。

      上电后从0x08000004处取出复位中断向量的地址,然后跳转到复位中断程序入口(标号1所示),执行结束后跳转到main函数。

      在执行main函数的过程中发生中断,则STM32强制将PC指针指回中断向量表处(标号3所示),从中断向量表中找到相应的中断函数入口地址,跳转到相应的中断服务函数,执行完中断服务函数后再返回到main函数中来。

   

       在内置的Flash里面添加一个BootLoader程序,BootLoader程序和user application各有一个中断向量表,      

       假设BootLoader程序占用的空间为N+M字节,则程序的走向应该如下图所示(借用网友的原图并做改动,其中虚线部分为原图步骤④⑤的走向,本人改为指向灰色部分)。

     

      上电初始程序依然从0x08000004处取出复位中断向量地址,执行复位中断函数后跳转到IAP的main(标号①所示),
在IAP的main函数执行完成后强制跳转到0x08000004+N+M处(标号②所示),最后跳转到新的main函数中来(标号③所示),
当发生中断请求后,程序跳转到新的中断向量表中取出新的中断函数入口地址,再跳转到新的中断服务函数中执行(标号④⑤所示),执行完中断函数后再返回到main函数中来(标号⑥所示)。

      对于步骤④⑤我认为的是,在main函数的执行过程中,如果CPU得到一个中断请求,PC指针本来应该跳转到0x08000004处的中断向量表,由于我们设置了中断向量表偏移量为N+M,因此PC指针被强制跳转到0x08000004+N+M处的中断向量表中得到相应的中断函数地址,再跳转到相应新的中断服务函数,执行结束后返回到main函数中来。

3、Bootloader、APP程序设计 (STM32有内置的BootLoader,这里是自己实现的)

      要实现IAP方案升级程序,需要设计两部分内容:Bootloader + 用户程序App。

      Bootloader和App都是完整的STM32工程,区别在于工程所实现的功能和占用Flash的大小。由于Bootloader的功能比较单一,并且为了节约Flash留给用户App,Bootloader一般不带操作系统,所占用的Flash较小。APP是完整的用户程序,按照正常的设计流程进行设计,只需要在工程配置和部分初始化代码处进行修改。

   3.1bootloader程序设计

     1.确定存放APP程序的首地址  
        #define FLASH_APP_ADDR                 0x08003C00 //应用程序起始地址

     2.将接收到的程序镜像写入到Flash中

     3.跳转到新程序运行,具体实现看下面代码:

     

        __disable_irq();    //需要关闭总中断,跳转到App中再打开,避免跳转过程被中断打断

    3.2、用户App设计

     正常的用户工程设计完成后,对用户的工程和部分代码进行修改来实现IAP方案下的用户APP。

     关键点在Flash地址的设置和中断偏移量的设置,这两处设置不正确会导致app无法跳转成功。

     我使用的keil,其它IDE环境可以参考修改。

    1、Flash地址设置(这个地址需要和BootLoader中对应)

    

    这里的地址起点与Bootloader的FLASH_APP_ADDR必须一致,与下面的位移偏移量SCB->VTOR也要一致。

      2、中断向量表偏移,以及使能全局中断(BootLoader在跳转前会关闭全局中断)。

      

       3、App.bin生成

       打开“Options for Target”

      

       在如下图示勾选,并输入如下命令:

      

      基本的命令格式是fromelf --bin !L --output xxx.bin 这里需要注意空格,大小写。
      3、编译链接生成bin文件:
       窗口中有如下的提示信息,表示bin文件生成成功。

      

      在输出文件夹中找到BIN文件,这个文件就是用户App的BIN文件。

 

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐