【Nations MCU】IAP 的学习

关键字 :串口IAP 升级

1、IAP简介

        IAP 是 In Application Programming 的缩写,即在应用编程。 IAP 是利用自己的程序代码实现升级程序(新的 APP )从外部接口(可以是串口、 I2C 、 SPI 、网口等等)写入到 flash 中,再通过 flash 读写操作,将新的 APP 覆盖原有 APP 程序,在重新从新的APP 入口位置启动我们的应用程序,同时也负责 IAP 代码的修改和迭代。一句话概括就是, IAP 是一个专门用来升级应用程序的程序。

        通常在实现 IAP 功能时,需要在编写固件程序时设计两部分代码:第一个部分不执行产品正常的功能操作,只是通过通讯接口去接收数据,执行对第二部分代码的更新操作(这部分代码后面简称为 Bootload );第二部分代码才是真正的产品功能代码(这部分代码后面简称为 App )。

         这两部分代码都同时存放在 User Flash 的不同区域中(一般从最低地址开始存放Bootload ,后面紧随 App ),当芯片上电之后会首先执行 Bootload , Bootload 作如下操作:

         ① 检查是否需要对 App 进行更新

         ② 如果不需要更新则跳转到步骤④

         ③ 执行更新操作

         ④ 跳转到 App 执行

           Bootload 必须通过其它方式如 JTAG / SWD 或 ISP 烧录,第二部分代码可以使用Bootload IAP 功能烧录,也可以和 Bootload 一起烧录。后面 Bootload 统称为 IAP 程序。

2、ISP & IAP

        ISP :In System Programing ,通过串口USART0进行在线系统编程。       

        IAP :In applicating Programing ,通过通用嵌入片内的固化代码进行的在应用编程。  

        ISP是指可以在板级上进行编程,而不用把芯片拆下来放到烧写器中,即不脱离系统,所以称作“在系统编程”,它是对整个程序的擦除和写入,通过单片机专用的串行编程接口对单片机内部的 Flash 存储器进行编程。即使芯片焊接在电路板上,只要留出和上位机接口的串行口就能进行烧写。

        IAP 同样是在板级上进行编程, MCU 获取新代码并对程序的某部分重新编程,即可用程序来改变程序,修改程序的一部分达到升级、消除 bug 的目的,而不影响系统的其它部分,烧写过程中程序可以继续运行,另外接口程序是自已写的,这样可以进行远程升级而不影响应用。 IAP 的实现更加灵活,通常可利用单片机的串行口接到计算机的 RS232 口,通过专门设计的固件程序来编程内部存储器。

3、IAP 原理

3.1 无 IAP 机制下程序运行流程
   

       N32G43x 的内部闪存( Flash )的起始地址为 0x0800_0000 ,一般情况下程序的可执行文件从该地址开始写入。此外 N32G43x 是基于 Cortex-M4 内核的,内部是通过“中断向量表”来响应中断。

      程序启动后,首先从“中断向量表”中取出复位中断向量,执行复位中断程序来完成启动(如上图中流程①);在复位中断服务程序执行完之后,会跳转到 main 函数(如②) 。“中断向量表”的起始地址是 0x0800_0004,而 main 函数一般是一个死循环。当来中断时,N32G43x 的内部硬件机制会自动将 PC 指针指向“中断向量表”处(如③),并根据中断源取出对应的中断向量来执行中断服务程序(如④),在执行完中断服务函数之后,程序再次返回 main 函数执行(如⑤)。以上即是正常的程序运行流程。

 

3.2 加入 IAP 机制后程序运行流程
     

       N32G43x 复位后,还是从 0x0800_0004 取出复位中断向量的地址并跳转到复位中断服务程序,在运行完复位中断服务程序之后跳转到 IAP 的 main 函数(如上图中流程①),这部分与无 IAP 机制的程序运行一致。

        在执行完 IAP 以后(即将新的 APP 代码写入 User Flash ,即灰底部分),新 APP 的复位中断起始地址为: 0x0800_0004+N+M 。跳转至新 APP 的复位向量表(如②),取出复位中断向量的地址并跳转执行新 APP 的复位中断服务程序,随后再跳转至新 APP 的 main函数(如③)。同样, main 函数是一个死循环,此时可以看到 Flash 中在不同位置上有两个“中断向量表”。

        但在新 APP 的 main 函数执行过程中,如果 CPU 得到一个中断请求, PC 指针还是强制跳转到 0x0800_0004 这个地址的中断向量表处(如④),而不是新 APP 的中断向量表处。程序会再根据我们设置的中断向量表偏移量(这个新的中断偏移量会在新 APP 中设置,APP程序中会有体现),跳转到对应中断源新的中断服务程序中(如⑤)。执行完中断服务程后,程序返回 main 函数继续运行(如⑥)。以上就是加 IAP 机制之后程序的运行流程。

4、IAP 实现

      了解原理之后,正式来实现 IAP 程序和 APP 程序。由上面过程分析,可以得到 IAP程序需要满足两个条件:

      ①新 APP 必须在 IAP 程序之后的某个偏移量为 x 的地址开始;

      ②必须将新 APP 的中断向量表相应地移动,移动偏移量为 x。

      (注:这里的 x 根据 IAP 程序的大小来自定义的)

 

4.1 IAP 功能说明

      在 IAP 程序中实现以下功能:

       1、 等待通过串口接收过来的数据,该数据应该为新 APP 的 bin 文件;

       2、 接收完成之后自动将接收到的新 APP 的 bin 文件写入设定好的 Flash 地址中;



       3、 通过按键 PA0 来进行 IAP 跳转

      注意事项:

       1、 这里串口接收数据为了简单就用了一个 6KB 的数组去一次性接收存储 APP 的 bin文件,这里数组的大小是根据 APP 程序生成的 bin 大小定的。想节省资源可以采用分包的方式接收。

       2、 N32G43x 写 Flash 是按字( Word )操作的,所以写入的时候需要考虑文件大小以及页对齐问题等。

       3、 进行跳转的时候判断一下栈顶指针存在的地址是否合法,避免烧录的 bin 是一个不正常的文件。

4.2 IAP 在 Keil 的配置

     这里用到的 N32G43x Flash 大小为 128Kb , SRAM 大小为 32Kb 。在 KEIL 配置中这两个参数保持默认,不需要改动,如下:
        

编译后各个段的大小如下:

Code为程序代码部分;

    RO-data 表示程序定义的常量const temp;

    RW-data 表示已初始化的全局变量;

    ZI-data 表示未初始化的全局变量;

          可以计算出 IAP 程序的大小大致为 (Code + RO-data + RW-data)/1024 ≈ 5.17Kb ,多给 IAP 程序留点空间, 8Kb 。这 8Kb 的设置体现在 IAP 程序里面的 FLASH_APP1_ADDR宏定义中, FLASH_APP1_ADDR 表示 APP bin 文件存储的起始地址,即从 0x0800_0000 开始往后推 8Kb 字节开始存储。也就是说前 8kb 是留给 IAP 程序烧录用的。

4.3 APP 工程中注意事项

    1、首先是 APP 程序 Flash 和 SRAM 地址范围的设定,如下:
     

其中 SRAM 不变,与 IAP 的一样,起始地址是 0x2000_0000,大小为 32Kb(N32G43x不同型号可能大小有差异,但是起始地址都一样)。

       有区别的部分是 Flash,我们看到 APP 中 Flash 的起始地址不再是 0x0800_0000,而是 0x0800_2000,也就是从 0x0800_0000 开始,向后偏移了 0x2000 。 0x2000 转换成十进制是 8192 ,8192 除以 1024 正好是 8Kb,也就是说这里 8Kb 的偏移量就是之前说的留给 IAP 程序的空间大小。   如果你不是 8Kb,那么修改 IAP 程序中的 FLASH_APP1_ADDR 宏定义地址和 APP 程序中Flash 起始地址的偏移量以及 Flash Size 即可。

2、APP 程序里面中断向量表的重定义

        可以看到 APP 程序中的示例功能也很简单,就是延时 200ms 打印一次数据。但是在此之前我们可以看到进入 main 函数开始时有一个中断向量表的重定义代码: SCB->VTOR= FLASH_BASE|0x2000 ;

中断向量表的映射,如下:

       宏定义 FLASH_BASE 为 0x0800_0000,宏定义 VECT_TAB_OFFSET 为 0x0。也就是说中断向量表映射地址默认是 0x0800_0000 ,即 Flash 的起始地址。

       SCB->VTOR= FLASH_BASE|0x2000 代表中断向量表映射地址偏移了 0x2000 ,因为新 APP程序的起始地址为 0x0800_2000 ,所以这里将 APP 中的中断向量表进行重定义。

        除去上述两点, APP 程序其他地方与 IAP 程序的配置一致。至此,APP 程序就配置了,编译时顺便生成 bin 文件。编译结果如下:

       同理可以算出 APP 程序的大小约等于 3.24Kb ,之前也说了在 IAP 中定义接收数据数组的大小是 6Kb ,足够一次性接收这个 APP bin 文件了。

实验步骤为:

     1、 烧录 IAP 程序,看到串口打印 IAP 信息;

     2、 用串口助手发送 APP bin 文件,发送完成时 IAP 会打印固件更新完毕的信息;

     3、 通过 PA0 来开始执行 Flash 用户代码,随后会循环执行 APP 中的信息打印操作。
       

可以看到程序是跳转到 APP 去执行了,说明实验正常。

                              

5、Reference:

5.1  CSDN_魏波一_原创 https://blog.csdn.net/weibo1230123/article/details/83685004

5.2  N32G43x_L4xx系列芯片串口IAP升级应用笔记_V1.0

技术文档

类型标题档案
操作手册User Manual

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论