您的位置 首页 芯片行情

STM32F103实现IAP在线升级应用程序

实现IAP技术的核心是一段预先烧写在单片机内部的IAP程序。这段程序主要负责与外部的上位机软件进行握手同步,然后将通过外设通信接口将来自于上位机软件的程序数据接收后写入单片机内部指定的闪存区域,然后再跳转执行新写入的程序,最终就达到了程序更新的目的。\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

一、环境介绍

MCU: STM32F103ZET6

编程IDE: Keil5.25

二、 IAP介绍

IAP,全称是“In-Application Programming”,中文解释为“在程序中编程”。IAP是一种对通过微控制器的对外接口(如USART,IIC,CANUSB以太网接口甚至是无线射频通道)对正在运行程序的微控制器进行内部程序的更新的技术(注意这完全有别于ICP或者ISP技术)。

ICP(In-Circuit Programming)技术即通过在线仿真器单片机进行程序烧写,而ISP技术则是通过单片机内置的bootloader程序引导的烧写技术。无论是ICP技术还是ISP技术,都需要有机械性的操作如连接下载线,设置跳线帽等。若产品的电路板已经层层密封在外壳中,要对其进行程序更新无疑困难重重,若产品安装于狭窄空间等难以触及的地方,更是一场灾难。但若进引入了IAP技术,则完全可以避免上述尴尬情况,而且若使用远距离或无线的数据传输方案,甚至可以实现远程编程和无线编程。这绝对是ICP或ISP技术无法做到的。某种微控制器支持IAP技术的首要前提是其必须是基于可重复编程闪存的微控制器。STM32微控制器带有可编程的内置闪存,同时STM32拥有在数量上和种类上都非常丰富的外设通信接口,因此在STM32上实现IAP技术是完全可行的。

实现IAP技术的核心是一段预先烧写在单片机内部的IAP程序。这段程序主要负责与外部的上位机软件进行握手同步,然后将通过外设通信接口将来自于上位机软件的程序数据接收后写入单片机内部指定的闪存区域,然后再跳转执行新写入的程序,最终就达到了程序更新的目的。

在STM32微控制器上实现IAP程序之前首先要回顾一下STM32的内部闪存组织架构和其启动过程。STM32的内部闪存地址起始于0x8000000,一般情况下,程序文件就从此地址开始写入。此外STM32是基于Cortex-M3内核的微控制器,其内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动。而这张“中断向量表”的起始地址是0x8000004,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。最后还需要知道关键的一点,通过修改STM32工程的链接脚本可以修改程序文件写入闪存的起始地址。

在STM32微控制器上实现IAP方案,除了常规的串口接收数据以及闪存数据写入等常规操作外,还需注意STM32的启动过程和中断响应方式。

下图显示了STM32常规的运行流程:

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

图解读如下:1、 STM32复位后,会从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序。2、 复位中断服务程序执行的最终结果是跳转至C程序的main函数,而main函数应该是一个死循环,是一个永不返回的函数。3、 在main函数执行的过程中,发生了一个中断请求,此时STM32的硬件机制会将PC指针强制指回中断向量表处。4、 根据中断源进入相应的中断服务程序。5、 中断服务程序执行完毕后,程序再度返回至main函数中执行。

若在STM32中加入了IAP程序:

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

1、 STM32复位后,从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,随后跳转至IAP程序的main函数。

2、 执行完IAP过程后(STM32内部多出了新写入的程序,地址始于0x8000004+N+M)跳转至新写入程序的复位向量表,取出新程序的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数。新程序的main函数应该也具有永不返回的特性。同时应该注意在STM32的内部存储空间在不同的位置上出现了2个中断向量表。

3、 在新程序main函数执行的过程中,一个中断请求来临,PC指针仍会回转至地址为0x8000004中断向量表处,而并不是新程序的中断向量表,注意到这是由STM32的硬件机制决定的。

4、 根据中断源跳转至对应的中断服务,注意此时是跳转至了新程序的中断服务程序中。

5、 中断服务执行完毕后,返回main函数。

二、hex文件与bin文件区别

Intel HEX文件是记录文本行的ASCII文本文件,在Intel HEX文件中,每一行是一个HEX记录,由十六进制数组成的机器码或者数据常量。Intel HEX文件经常被用于将程序或数据传输存储到ROM、EPROM,大多数编程器和模拟器使用Intel HEX文件。 很多编译器的支持生成HEX格式的烧录文件,尤其是Keil c。但是编程器能够下载的往往是BIN格式,因此HEX转BIN是每个编程器都必须支持的功能。HEX格式文件以行为单位,每行由“:”(0x3a)开始,以回车键结束(0x0d,0x0a)。行内的数据都是由两个字符表示一个16进制字节,比如”01”就表示数0x01;”0a”,就表示0x0a。对于16位的地址,则高位在前低位在后,比如地址0x010a,在HEX格式文件中就表示为字符串”010a”。

hex和bin文件格式 Hex文件,这里指的是Intel标准的十六进制文件,也就是机器代码的十六进制形式,并且是用一定文件格式的ASCII码来表示。具体格式介绍如下: Intel hex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。 hex和bin文件格式Hex文件,这里指的是Intel标准的十六进制文件,也就是机器代码的十六进制形式,并且是用一定文件格式的ASCII码来表示。具体格式介绍如下: Intel hex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。

三、使用Keil软件完成hex文件转bin文件http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

选项框里的代码:

C:\\app_setup\\for_KEIL\\ARM\\ARMCC\\bin\\fromelf.exe –bin -o ./OBJECT/STM32_MD.bin ./OBJECT/STM32_MD.axf

解析如下:

C:\\app_setup\\for_KEIL\\ARM\\ARMCC\\bin\\fromelf.exe:是keil软件安装目录下的一个工具,用于生成bin

–bin -o ./OBJECT/STM32_MD.bin :指定生成bin文件的目录和名称

./OBJECT/STM32_MD.axf :指定输入的文件. 生成hex文件需要axf文件

新工程的编译指令:

C:\\Keil_v5\\ARM\\ARMCC\\bin\\fromelf.exe –bin -o ./obj/STM32HD.bin ./obj/STM32HD.axf

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

将该文件下载到STM32内置FLASH,复位开发板,即可启动程序。

四、 使用win hex软件将bin文件搞成数组http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

生成数组之后,可以直接将数组编译到程序里,然后使用STM32内置FLASH编程代码,将该程序烧写到内置FLASH里,再复位开发板即可运行新的程序。

五、 Keil编译程序大小计算

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

Program Size: Code=x RO-data=x RW-data=x ZI-data=x 的含义

Code(代码): 程序所占用的FLASH大小,存储在FLASH.

2. RO-data(只读的数据): Read-only-data,程序定义的常量,如const型,存储在FLASH中。

3. RW-data(有初始值要求的、可读可写的数据):

4. Read-write-data,已经被初始化的变量,存储在FLASH中。初始化时RW-data从flash拷贝到SRAM。

5. ZI-data:Zero-Init-data,未被初始化的可读写变量,存储在SRAM中。ZI-data不会被算做代码里因为不会被初始化。

ROM(Flash) size = Code + RO-data + RW-data;

RAM size = RW-data + ZI-data

简单的说就是在烧写的时候是FLASH中的被占用的空间为:Code+RO Data+RW Data

程序运行的时候,芯片内部RAM使用的空间为: RW Data + ZI Data

六、工程编译信息与堆栈信息查看http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

对于没有OS的程序,堆栈大小是在 startup.s 里设置的: Stack_Size EQU 0x00000800

对于使用用 uCos 的系统,OS自带任务的堆栈,在 os_cfg.h 里定义:

/* ——————— TASK STACK SIZE ———————- */ #define OS_TASK_TMR_STK_SIZE    128    /* Timer      task stack size (# of OS_STK wide entries)        */#define OS_TASK_STAT_STK_SIZE   128    /* Statistics task stack size (# of OS_STK wide entries)        */ #define OS_TASK_IDLE_STK_SIZE   128    /* Idle       task stack size (# of OS_STK wide entries)        */  

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

用户程序的任务堆栈,在 app_cfg.h 里定义:

#define  APP_TASK_MANAGER_STK_SIZE           512 #define  APP_TASK_GSM_STK_SIZE                        512 #define  APP_TASK_OBD_STK_SIZE                         512 #define  OS_PROBE_TASK_STK_SIZE                       128  

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

总结:

1, 合理设置堆栈很重要

2, 多种方法结合,相互核对、校验

3, 尽量避免大数组,如果一定要用,尽量定义为 全局变量,使其不占用堆栈空间, 如果函数有重入可能性,则要注意保护。

七、实现STM32在线升级程序7.1 升级的思路与步骤

1. 首先得完成STM32内置FLASH编程操作

2. 将(升级的程序)新的程序编译生成bin文件(编译之前需要在Keil软件里设置FLASH的起始位置)

3. 创建一个专门用于升级的boot程序(IAP Bootloader)

4. 使用网络、串口、SD卡等方式接收到bin文件,再将bin文件烧写到STM32内置FLASH里

5. 设置主堆栈指针

6. 将用户代码区第二个字(第4个字节)为程序开始地址(强制转为函数指针)

7. 执行函数,进行程序跳转

7.2 待升级的程序FLASH起始设置

Bootloader的程序大小先固定为: 20KB,最好是越小越好,可以预留更加多的空间给APP程序使用。

20KB—–>20480Byte—–> 0x5000

STM32内置FLASH闪存的起始地址是: 0x08000000 ,大小是512KB。

现在将内置FLASH闪存前20KB的空间留给Bootloader程序使用,后面剩下的空间就给APP程序使用。

APP程序的起始位置就可以设置为: 0x08000000+ 0x5000=0x08005000

剩余的大小就是: 512KB-20KB=492KB——>503808Byte——–>0x7B000

设置FLASH的起始位置(APP主程序):

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

中断向量表偏移量设置

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

设置编译bin文件

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

7.3 Bootloader的程序设置

//设置写入的地址,必须偶数,因为数据读写都是按照2个字节进行#define FLASH_APP_ADDR0x08005000  //应用程序存放到FLASH中的起始地址int main(){     printf(\"UART1 OK.....\\n\");printf(\"进入IAP Bootloader程序!\\n\");  while(1)  {  key=KEY_Scanf();      if(key==1)//KEY1按下,写入STM32 FLASH      {        printf(\"正在更新IAP程序...............\\n\");        iap_write_appbin(FLASH_APP_ADDR,(u8*)app_bin_data,sizeof(app_bin_data));//烧写新的程序到内置FLASHprintf(\"程序更新成功....\\n\");        iap_load_app(FLASH_APP_ADDR);//执行FLASH APP代码      }  }}/*函数功能:跳转到应用程序段appxaddr:用户代码起始地址.*/typedef  void (*iap_function)(void);//定义一个函数类型的参数.   void IAP_LoadApp(u32 app_addr){  //给函数指针赋值合法地址  jump2app=(iap_function)*(vu32*)(app_addr+4);//用户代码区第二个字为程序开始地址(复位地址)  __set_MSP(*(vu32*)app_addr);  //设置主堆栈指针  jump2app();     //跳转到APP.}

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

http://news.vvfanli.com/wp-content/uploads/2022/03/20220315060300-62302c1494377.gif

<!–

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。

作者: admin

为您推荐

如何使用GPU编程优化模型/代码

  使用 Python 和 NumPy 库开发的 HIM 模型在 hackathon 开始时没有并行或 GPU 计算。在活动期间, THINKLAB 团队使用 CuPy 为了使他们的代码在 GPU 上并行运行,然后重点将用户定义的 CUDA 内核应用于参数。结果是 672 倍加速,计算时间从 2 周缩短到大约 30 分钟。\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

NVIDIA驱动程序支持OpenCL和Vulkan进行互操作

  OpenCL 和 Vulkan 之间的互操作在移动和桌面平台上都有很强的需求。 NVIDIA 与 Khronos OpenCL 工作组密切合作,发布了一套临时跨供应商的 KHR 扩展。这些扩展使应用程序能够在 OpenCL 和 Vulkan 等 API 之间高效地共享数据,与使用隐式资源的前一代互操作 API 相比,灵活性显著提高。\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

准备去元宇宙过第二人生?小心别被骗了

准备去元宇宙过第二人生?小心别被骗了   电子发烧友网报道(文/黄山明)随着元宇宙在近期的大火,相信大家对于这一技术已不陌生。但元宇宙因为其特性,也需要建立合适的网络安全防护措施,来应对这项技术带来的独特挑战。并且在元宇宙想要得以持续,需要用去中心化的平权式共享机制与共治机制来作为保障,既要做大“蛋糕”,也要分好“蛋糕”。但问题在于,去中心化的元宇宙,在安全问题上也将面临更大的挑战。     先简单解释一下元\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

代工巨头再次换帅,中芯国际高管频频离职,业绩喜人之下原因为何?

电子发烧友网(文/黄山明)3月17日,中芯国际发出公告,公司代理董事长高永岗博士,获委任为中芯国际董事长,自2022年3月17日生效。而在半年前辞去中芯国际董事长职位的“芯片泰斗”周子学最终以身体原因为由,辞去了执行董事一职。   对于这一次的交接,有业内人士称这是一次完美的交接,对中芯国际乃至中国半导体产业都有着重要的影响。不过另一方面,自周子学辞任中芯国际董事长之后,其股价便一路走低,从半年前的21.1港元降至如今的\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

电子测量仪器企业普源精电上市!年营收超3亿,募资7.6亿加速自研芯片项目

电子发烧友网报道(文/莫婷婷)4月8日,普源精电在科创板上市,发行价格60.88元/股,公开发行股份约3032.74万股,占公司发行后总股本的比例为25%。该股上市当日开盘即破发,截至今日收盘,普源精电报39.78元,跌幅34.66%,总市值48.26亿元。   图源:东方财富   在上市之前,普源精电在招股书的风险因素中提到,“公司无法保证未来几年内实现盈利,公司上市后亦可能面临退市的风险”。2020年、2021年上半年,普源精电分别亏损2716.6万元、2036.48万元,连\” />

<meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部