0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32单片机实现固件在线升级(IAP)

撞上电子 2023-12-16 08:00 次阅读


1,固件升级方案综述

单片机的固件升级方式有很多种。1、ICP:简单说就是在单片机开发时使用烧录器升级程序,比如使用J-Link烧录单片机程序。2、ISP:在单片机内部实现了基于通信接口(如串口、I2C、SPI等等)的FLASH引导程序,配合厂家提供的烧录软件工具或自行开发的软件实现程序烧录。3、IAP:是指单片机程序开发好之后在运行过程中由外部用户发起的在线升级,这种升级方式一般由用户自行设计升级方案,方案灵活性和自由度较高,在智能家居汽车电子物联网设备中常用的OTA即空中下载技术原理也与之类似。

2,划分FALSH存储区域

STM32系列单片机中,程序存储在内部FLASH中,按照不同的单片机型号FLASH大小有所不同,有64KB、128KB、512KB等等。以STM32F407VET6系列单片机为例,内置FLASH大小为512KB,存储地址为0x08000000-0x0807FFFF。单片机每次程序复位时从0x08000000的位置开始执行主程序,如果不做IAP则这512KB空间都可以用来存储用户编写的APP程序。

若要实现IAP功能则必须将FLASH空间划分为几个部分,每部分都存储一个可以独立运行的程序文件(可以理解为几个独立的单片机工程):

1、引导程序,每次复位时程序默认执行此程序,在接下来的执行过程中可以跳转到用户编写的程序,因此这部分程序是固化在以0x08000000为起始的区域中。在引导程序中可以对电路系统作出一些自检和初始化检查的工作,因此该程序又称为bootloader或boot程序,需要注意的是在设计bootloader时要提前规定好程序空间的大小,比如规定程序存储区域为0x08000000-0x8007FFF,则bootlader程序存储空间为32KB,编写boot程序时要注意这一点

2、用户需要升级的新程序,这部分包含了用户的业务代码,复杂的运算逻辑和算法实现均在这一部分完成,称为APP程序,该部分程序一般存储在bootloader区域之后的FLASH中。用一个不是特别恰当的例子类比bootloader和APP:bootloader相当于电脑组装时的BIOS,APP则相当于操作系统,电脑开机时首先运行BIOS,完成后跳转运行到操作系统。

3、升级之前的老版APP备份。这部分相当于电脑系统更新前对老系统的备份,一旦在升级过程中发生错误需要还原到备份系统,防止系统升级失败成砖。同样的APP与APP备份将剩余的FLASH平分,以上述booloader为例,APP程序及其备份所占区域为:(512-32)/2=240KB,因此编写的APP程序编译后的占用的FLASH空间不得超过240KB,这一点可以通过查验.map文件确认,对于不同FLASH大小的芯片可以类比以上计算方法确认自己的程序大小上限(在此插入一句,改变编译器的优化等级可以改变最后的程序大小,但是高的优化等级对程序编写规范要求更高,因此优化等级应该在一开始设计APP之前就确定好,中途变更会带来不可预测的问题)。

以STM32F407VET6单片机为例划分后的FALSH存储框图如下所示:

2fd4bc9e-9ba6-11ee-9788-92fbcf53809c.jpg

3,BOOTLADER设计

根据上面的描述,bootloader主要有完成以下功能:

1、系统自检

2、实现APP程序跳转

3、升级过程中接收APP文件并存储到对应的FLASH区域

功能1、3对于不同的系统要求不同,自检的内容以及实现文件传输的物理层接口和链路协议不同,不在此过多描述。下面主要给出APP跳转的部分代码:

#define APP_ADDR 0x08008000 //应用程序起始地址 typedef void (*pFunction)(void); //重定义pFunction为void(*)(void)函数指针类型void jump(void){ uint32_t APP_ADDR_Buff=0; //缓存APP地址数值 uint32_t APP_ADDR_Value=0; //APP地址的内容 uint32_t Jump_ADDR; //跳转的目标地址 pFunction Jump_APP; //跳转的目标函数指针 APP_ADDR_Buff = APPLICATION_ADDRESS; //用户程序的首地址 APP_ADDR_Value = (*(volatile uint32_t*)APP_ADDR_Buff);//取出首地址里面的值 if (( APP_ADDR_Value & 0x2FFE0000 ) == 0x20000000) //判断APP首地址里面存的栈顶地址值是否合法 { DISABLE_INTERRUPTS(); //关总中断,使用不同的库写法不同,不可直接复制 RCC_DeInit();//将外设RCC寄存器重设为缺省值,使用不同的库写法不同,不可直接复制 Jump_ADDR = *(volatile uint32_t*)(APP_ADDR_Buff + 4);//APP起始地址第二个字为程序开始地址(新程序复位地址) //指针函数指向用户程序地址,也就是PC指针goto到用户程序起始地址 Jump_APP = (pFunction)Jump_ADDR; //取出程序地址给指针函数 __set_MSP(*(volatile uint32_t*)APP_ADDR_Buff); //初始化APP的堆栈指针 Jump_APP(); //执行指针函数,实现程序跳转 } else { ErrorHandle(); //抛出异常 }}int main(void){
SystemInit();//系统时钟初始化 SYSInit(); //系统初始化 delay_ms(200); if(ReadProgramAPPFlag()) //如果需要更新APP { APP_FlashWrite(); //接收APP文件数据,并将APP程序存储到指定位置 if(APP_Check()) //APP文件校验通过,将新的APP程序更新到备份区域 APP_Backup(); else //否则恢复备份区 APP_Restore(); ResetProgramAPPFlag(); //对完成升级的标志复位 } jump(); //正常情况下运行到这一步时APP区域已经正确写入程序文件 while(1); }

其中ReadProgramDoneFlag()是判断程序应该是先接收升级文件再跳转还是直接跳转的标志,在APP中如果有升级需求则对这个标志置位,在bootloader中完成文件接收之后对标志复位,需要注意的是这个标志位不是全局变量也不是局部变量,要保证程序跳转,初始化堆栈之后这个标志的值不受影响,因此该标志变量最佳选择是写在外部EEPROM或内置FLASH中,读写标志的操作其实是对EEPROM或FLASH的读写。

4,编写APP程序

APP程序中实现了用户的业务代码,和由APP跳转回bootloader的逻辑,实际的操作还是对上文中程序存储Flag的读写,这部分逻辑实现的流程图如下图所示:

2fe11638-9ba6-11ee-9788-92fbcf53809c.jpg

由于APP程序对应的是另外一个工程文件,因此在工程设置中要将FLASH的偏移地址向下移动,空出bootlader的区域,比如上文中bootloader区域是0x08000000-0x08008000,因此APP工程的FLASH起始地址是0x8008000,偏移量是0x8000,这一点非常重要。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6001

    文章

    43973

    浏览量

    620835
  • STM32
    +关注

    关注

    2239

    文章

    10671

    浏览量

    348743
  • IAP
    IAP
    +关注

    关注

    2

    文章

    161

    浏览量

    23964
收藏 人收藏

    评论

    相关推荐

    关于程序在线升级

    想请教各位高手:1、是不是只有支持IAP功能的单片机才可以实现程序的在线升级啊?2、STM32
    发表于 05-12 14:37

    STM32 IAP在线升级

    STM32很强大的一个功能是支持IAP在线升级IAP(In-Application Programming),即在“应用程序中编程 ",通
    发表于 03-09 15:56

    E85F3325单片机IAP在线升级教程

    51单片机IAP在线升级爱矽半导体E85F3325单片机IAP
    发表于 07-15 07:44

    如何用IAP功能实现单片机远程升级

    工程师在做产品的时候有时候会有远程对产品进行升级的需求。对于没有开发过此功能的工程师会不知道从何下手,本文就以HC32L110为例介绍国产超低功耗华大单片机如何用IAP功能实现
    发表于 11-01 08:14

    如何去实现stm32IAP在线升级

    如何去实现stm32IAP在线升级呢?需要注意哪些事情呢?
    发表于 11-29 07:35

    如何实现STM32在线升级IAP功能?

    如何实现STM32在线升级IAP功能?
    发表于 11-30 06:22

    8051系列单片机固件升级iap声明

    8051系列单片机固件升级iap声明:#define UPGRADE_FLAG 0xaa //升级标志位#define APP_START_
    发表于 12-01 07:01

    STC51单片机实现IAP远程升级过程分享

    参考STC15单片机功能和应用电路STC8A单片机功能和应用电路STC51单片机实现IAP远程升级
    发表于 01-27 06:08

    如何去实现STM32在线升级IAP功能呢

    最近因项目需求要实现STM32在线升级IAP功能,先将这几天的学习体会和IAP的具体
    发表于 02-21 06:26

    GD32单片机STM32远程下载手机程序升级固件下载局域网网页升级工具

    。 使用STM32固件服务器方式,很容易解决了,STM32系列单片机在线升级问题。该方式支持手
    发表于 11-10 15:03

    stm32单片机自我升级程序IAP

    stm32 单片机自我升级程序IAP,详细的介绍,分析
    发表于 06-17 15:42 22次下载

    如何使用CPUID和AES算法实现STM32单片机固件升级

    针对STM32系统固件升级时使用同一个文件易被非法复制使用的缺陷,提出并实现了一种一个STM32芯片使用一个唯一
    发表于 11-19 15:14 35次下载
    如何使用CPUID和AES算法<b class='flag-5'>实现</b><b class='flag-5'>STM32</b><b class='flag-5'>单片机</b>的<b class='flag-5'>固件</b><b class='flag-5'>升级</b>

    51单片机IAP在线升级

    51单片机IAP在线升级爱矽半导体E85F3325单片机IAP
    发表于 11-11 19:21 11次下载
    51<b class='flag-5'>单片机</b><b class='flag-5'>IAP</b><b class='flag-5'>在线</b><b class='flag-5'>升级</b>

    STM32通过IAP实现固件升级的分析与示例

    大部分MCU都可以通过IAP对片内flash进行读写来实现固件升级。这里主要是STM32如何实现
    发表于 12-14 18:50 11次下载
    <b class='flag-5'>STM32</b>通过<b class='flag-5'>IAP</b><b class='flag-5'>实现</b><b class='flag-5'>固件</b><b class='flag-5'>升级</b>的分析与示例

    AT32 MCU如何使用IAP通过USART实现固件在线升级更新

    AT32 MCU如何使用IAP通过USART实现固件在线升级更新
    的头像 发表于 09-19 16:51 1174次阅读
    AT32 MCU如何使用<b class='flag-5'>IAP</b>通过USART<b class='flag-5'>实现</b>对<b class='flag-5'>固件</b>的<b class='flag-5'>在线</b><b class='flag-5'>升级</b>更新