目录

IAP相关

IAP概念:

IAP与ICP/ISP的区别:

STM32F4的启动模式

FLASH相关

STM32F4 FLASH简介

STM32的内部闪存组织架构和其启动过程

应用IAP时的FLASH分配

IAP工程在Keil中的设置

跳转函数iap_load_app()相关

升级APP相关

APP程序编写和跳转相关

Demo程序实现


功能实现:

正常上电或复位后运行用户Bootloader程序,检查变量存储区的标志位。如果标志位为APP_FLAG则跳转到APP程序运行;如果标志位为BOOT_FLAG,则运行用户Bootloader程序,等待接收文件并准备IAP升级后跳转到新的APP程序运行。

APP程序运行时,完成正常功能;当接收到上位机从串口发来升级的指令后,会在FLASH中的变量存储区写下升级的标志位BOOT_FLAG,并且通过软复位返回用户Bootloader程序。Bootloader程序会接收新的程序文件并放到FLASH的APP空间,完成升级后会写下跳转标志位APP_FLAG,同时运行新的APP程序。

  • IAP相关

1.  IAP概念:

IAP(In Application Programming)即在应用编程,也就是用户可以使用自己的程序对单片机 Flash的某一区域进行烧写。当产品发布后,可以很方便的使用预留的通信接口(串口、USB、网口、蓝牙等)来完成程序的升级,避免使用ICP/ISP方式烧写程序。实现IAP技术的核心是一段预先烧写在单片机内部的IAP程序。这段程序主要负责与外部的上位机软件进行握手同步,然后通过外设通信接口将来自上位机软件的程序数据接收后写入内部指定的Flash区域,然后再跳转执行新写入的APP程序,从而达到程序更新的目的。

因此,实现IAP功能需要两套程序:

①  用户Bootloader程序。这部分程序一般存储在FLASH的起始位置,用来引导、升级App程序;

②App程序,即实现产品功能的程序。通过用户Bootloader来完成对App程序的更新升级,从而实现IAP功能。

2.  IAP与ICP/ISP的区别:

ICP(In-Circuit Programming)技术是通过在线仿真器对单片机进行程序烧写;ISP(In-System Programming)技术则是通过单片机内置的Bootloader程序(区别于IAP中的用户Bootloader程序)引导的烧写技术。无论是ICP技术还是ISP技术,都需要有机械性的操作如连接下载线,设置跳线帽等。若产品的电路板已经封装在外壳中,或者安装在狭小空间等难以触及的地方,要通过ICP或ISP技术对程序进行更新非常困难。使用IAP则可以避免以上问题,而且若使用远距离或无线的数据传输方案,甚至可以实现远程编程和无线编程,这是ICP或ISP技术无法做到的。

  • STM32F4的启动模式

图1  STM32F4启动模式

如图1所示,当BOOT0设置为0时,启动模式为用户闪存存储器启动。此时主闪存存储器被映射到启动空间(0x00000000),但仍然能够在原有的地址(0x80000000)访问,即闪存存储器可以在0x00000000和0x80000000这两个地址区域访问。

当BOOT0设置为1,BOOT1设置为0时,启动模式为从系统存储器启动。此时系统存储器被映射到启动空间(0x00000000),但仍然能够在他原有的地址(0x1FFFF000)访问。该模式用于串口下载。

当BOOT0设置为1,BOOT1设置为1时,只能在0x20000000开始的地址区访问SRAM。

  • FLASH相关

在开始编程之前,需要了解不同型号单片机的Flash容量和闪存模块组织,从而确定Flash分配。由于Flash在擦除时是以扇区(Sector)为单位进行,所以要在写程序之前确定好Flash的扇区分配,保证用户Bootloader程序、变量存储区和APP程序不能存在于一个扇区,防止更新程序或数据时误擦除其他数据,造成死机(踩坑点1)。

1. STM32F4 FLASH简介

STM32F411xC/E 产品的闪存模块组织如图2所示:

图2  STM32F4闪存模块组织

STM32F4的闪存模块由主存储器(Main memory)、系统存储器(System memory)、OPT区域和选项字节(Option bytes)等4部分组成。

主存储器(Main memory)部分用来存放代码和数据常数(如const类型的数据), 共有8个扇区。扇区0~3容量为16KB,扇区4容量为64KB,扇区5~7容量为128K,不同容量的STM32F411拥有的扇区数不同。此次使用的芯片是STM32F411CE,Flash大小为512KB,共有7个扇区,从图2可以看出主存储器的起始地址是 0x08000000。BOOT0接GND时,从0x08000000开始运行代码。

系统存储器(System memory)主要用来存放STM32F4的内置Bootloader代码。此代码在出厂时固化在STM32F4芯片内部,用来给主存储器下载代码。当 BOOT0接3.3V,BOOT1 接GND时,从该存储器启动(即进入串口下载模式)。

OTP区域,即一次性可编程区域,共528字节,被分成两个部分。前512字节(32字节为1块,共16块),可以用来存储一些用户数据(一次性的,写完一次永远不可以擦除),后面16字节用于锁定对应块。

选项字节(Option bytes)用于配置读保护、 BOR级别、软件/硬件看门狗以及器件处于待机或停止模式下的复位。

闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制机构。

在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。

2. STM32的内部闪存组织架构和其启动过程

STM32的内部闪存地址起始于0x08000000,一般情况下,程序文件就从此地址开始写入。STM32内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,而这张“中断向量表”的起始地址是0x8000004。当中断来临,STM32的内部硬件机制会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。

图3  STM32正常运行流程图

STM32常规的程序运行流程如图3所示:

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

图4  加入IAP之后程序运行流程图

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

加入IAP程序后,程序运行流程图如图4所示:

  • STM32复位后,从地址为0x8000004处取出复位中断向量的地址,并跳转执行复位中断服务程序,随后跳转至IAP程序的main函数,如图4中标号①、②所示。这个过程和图1相应部分是一致的。
  • 执行完IAP过程后(STM32内部多出了新写入的程序,图4中以灰色底纹方格表示,地址始于0x8000004+N+M)跳转至新写入程序的复位中断向量表,如图4中标号④所示。取出新程序的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数,其过程如图4的标号③所示。新程序的main函数应该也具有永不返回的特性。同时应该注意在STM32的内部存储空间在不同的位置上出现了2个中断向量表。
  • 在新程序main函数执行的过程中,一个中断请求来临,PC指针仍会回转至地址为0x8000004中断向量表处,而不是新程序的中断向量表,这是由STM32的硬件机制决定的,如图4中标号⑤所示。
  • 根据中断源跳转至对应的中断服务,如图4中标号⑥所示。注意此时是跳转至了新程序的中断服务程序中。
  • 中断服务执行完毕后,返回main函数。如图4中标号⑧所示。

总结:

通过以上两个过程的分析, IAP 程序必须满足两个要求:

  • 新程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始;
  • 必须将新程序的中断向量表做相应的移动,移动的偏移量为 x。

3. 应用IAP时的FLASH分配

此次设计程序时将Flash分为3部分:

  • 0x08000000 ~ 0x08010000-1: 64K(Sector0~Sector3),用于存放用户Bootloader程序;
  • 0x08010000 ~ 0x08020000-1: 64K(Sector4),作为变量存储区,用来存放程序运行标志位等;
  • 0x08020000 ~ 0x08080000-1:384K(Secror5~Secror7),用于存放APP程序。
  • IAP工程在Keil中的设置

  1. 设置Flash分区:

因为用户Bootloader程序和APP程序都是单独的工程,所以要分别在Keil中设置IROM1的大小(踩坑点2):

① 用户Bootloader工程

Options for Target -> Target -> IROM1 设置0x08000000~0x0800FFFF的64K空间作为用户Bootloader程序存储区:

图5  用户Bootloader工程起始地址设置

② APP工程

Options for Target -> Target -> IROM1 设置0x08020000~0x0807FFFF的384K空间作为APP程序存储区:

图6  APP工程起始地址设置

2. 设置中断向量表偏移量:

在系统启动的时候,会首先调用SystemInit函数初始化时钟系统,同时SystemInit还完成了中断向量表的设置。STM32通过VTOR寄存器存放中断向量表的起始地址,对于Flash APP,需要设置中断向量表的偏移量为0x20000,设置方法为在Flash APP的main函数最开头处添加一行代码实现中断向量表的起始地址的重映射(踩坑点3):

SCB->VTOR = FLASH_BASE | 0x20000;    //FLASH_BASE为0x80000000

图7  设置中断向量表偏移

3.生成.bin文件:

IAP更新需要用到.bin文件,而MDK默认生成的是.hex文件。可通过MDK自带的格式转换工具“fromelf.exe”来实现“.axf”文件到“.bin”文件的转换。该工具在MDK的安装目录\ARM\ARMCC\bin文件夹。“fromelf.exe”转换工具的语法格式为: fromelf [options] input_file。

① 打开Flash APP工程文件Options for Target ->USER选项卡,在After Build/Rebuild菜单下勾选Run #1,User Command栏中填写如下内容,注意修改生成的.bin文件名与.axf文件名相同:图8  编译后生成.bin文件

② 打开Linker选项卡,勾选“Use Memory Layout from Target Dialog”

图9  STM32的默认链接文件配置

编译成功后,会在相应文件夹下看到生成.bin文件。得到.bin文件之后,只需要将该文件传送给单片机,即可执行 IAP 升级。

图10  编译后生成.bin文件

4.  APP 程序的生成步骤总结:

①  设置APP程序的起始地址和存储空间大小

②  设置中断向量表偏移量,即重新设置 SCB->VTOR 的值

③  设置编译后运行fromelf.exe,生成.bin文件,用于IAP更新

经过以上3个步骤,就可以得到一个格式为.bin的APP程序,通过用户Bootloader程序即可实现更新。

  • 跳转函数iap_load_app()相关

//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(uint32_t appxaddr)
{ if(((*(__IO uint32_t*)appxaddr) & 0x2FFE0000) == 0x20000000)    //检查栈顶地址是否合法.在0x2000 0000 - 0x 2000 2000之间{     jump2app=(iapfun)*(__IO uint32_t*)(appxaddr+4);       //用户代码区第二个字为程序开始地址(复位地址)        MSR_MSP(*(__IO uint32_t*)appxaddr);                 //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)jump2app();                                 //跳转到APP.}
}            

该函数位于iap.c文件中,用于实现用户Bootloader程序到APP程序的互相跳转。

1.  if(((*(__IO uint32_t*)appxaddr) & 0x2FFE0000) == 0x20000000)

判断栈顶地址值是否在0x20000000 ~ 0x20002000之间。在iap.h文件中定义了应用程序的起始地址为0x08020000,那么*(__IO uint32_t*)appxaddr即取0x08020000开始到0x08020003的4个字节的值。因为APP应用程序的“中断向量表”放置在0x08020000开始的位置,而中断向量表里第一个放的就是栈顶地址,参考图4。

该语句即通过判断栈顶地址值是否正确(是否在0x20000000 ~ 0x20002000之间,因为栈顶地址就是整个地址空间中SRAM所在的位置) 来判断应用程序是否已经下载了,因为应用程序的启动文件刚开始就去初始化栈空间,如果栈顶值正确,说明已经下载应用程序并且已执行启动文件的初始化。

2.  jump2app=(iapfun)*(__IO uint32_t*)(appxaddr+4);

appxaddr+4即0x08020004 ,该地址存放的是图4中第二个“中断向量表”的第二项“Reset_Handler”。

  • 升级APP相关

升级即新程序替换旧程序的过程。因此升级的实质就是擦除原有数据所在的Flash扇区,再将新数据写入的过程。STM32F4的Flash在编程时,必须要求其写入地址的Flash扇区 是被擦除了的(扇区内的值必须是 0XFFFFFFFF),否则无法写入。对STM32F4的Flash编程步骤如下:

  1. 检查 FLASH_SR 中的 BSY 位,确保当前未执行任何 FLASH 操作
  2. 将 FLASH_CR 寄存器中的 PG 位置 1,激活 FLASH 编程
  3. 针对所需存储器地址(主存储器块或 OTP 区域内)执行数据写入操作:
    • 并行位数为 x8 时按字节写入(PSIZE=00)
    • 并行位数为 x16 时按半字写入(PSIZE=01)
    • 并行位数为 x32 时按字写入(PSIZE=02)
    • 并行位数为 x64 时按双字写入(PSIZE=03)
  4. 等待 BSY 位清零,完成一次编程。

按以上四步操作,就可以完成一次Flash编程。不过有几点要注意:

  1. 编程前,要确保要写如地址的Flash已经擦除
  2. 要先解锁(否则不能操作 FLASH_CR)
  3. 编程操作对OPT 区域也有效,方法相同

将新程序写入Flash指定区域函数具体在stmflah.c 和stmflash.h中实现。

  • APP程序编写和跳转相关

1.  APP应用程序的主要功能包含两个方面:

①  除升级功能外的所有应用功能

②   跳转至用户Bootloader程序准备升级

2.  跳转至用户Bootloader的两种方式:

①  使用跳转函数iap_load_app();

②  软重启Reboot

Demo中使用软重启完成从APP程序到用户Bootloader的跳转。

  • Demo程序实现

1.  使用STM32F411CEU6芯片,上电后运行APP程序,串口显示Start to Execute APP Program...,LED(PB4)以10Hz频率闪烁

2.  通过串口调试助手发送abc到串口6,程序跳转至用户Bootloader,等待接收文件更新,此时LED频率变为2Hz。注意串口参数设置,勾选“发送新行”:

若发送的数据不是abc,则提示“Error Message! Please Check the Command and Try Again!”

3.  在串口调试助手中点击打开文件,选择需要更新的APP的bin格式文件,点击发送。此时串口调试助手会显示接收到的文件大小并判断接收到的文件格式是否正确,若发送的文件格式正确,则完成更新后重新开始执行APP程序

若发送的文件不正确,则提示“Illegal Flash Applications! Please Check Your File and Try Again!”,此时可重新发送正确文件。

Demo源码:利用STM32F411实现IAP测试程序https://download.csdn.net/download/Tiffany982/76638993

STM32F4 IAP实现总结相关推荐

  1. STM32F4 IAP学习笔记

    STM32 IAP学习 一. IAP介绍 ​ IAP(in application programming)即在应用中编程.即用户可以在程序运行的过程中对user flash部分的区域进行烧写,主要用 ...

  2. 【单片机】一文彻底搞懂单片机程序烧录

    前言   任何和电子相关的专业的同学,相信在大学期间都会接触到一个非常常用的设备--单片机,但是由于课程时间有限,很多人的学习主要还是为了完成课设任务,而不会去思考或研究其中的一些细节,其中就包括学习 ...

  3. stm32带BootLoader情况下,需要重新映射中断向量表

    应用程序起来第一件事,映射中断向量表.因为M0中断向量表在0x0,所以起来的时候把程序首地址0x8004000映射到ram0x200000000,然后配置一下__HAL_SYSCFG_REMAPMEM ...

  4. 微雪的stm32学习资料

    http://www.waveshare.net/wiki/Main_Page里面有很多资料 STM32开发软件 目录 编译软件 Keil MDK STM32CubeMX 下载软件 STM32 ISP ...

  5. (实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验】【正点原子】【原创】

    文章目录 ❤2023重新理解记录 其它文章链接,独家吐血整理 实验现象 主程序 IAP初始化程序 代码讲解 文章目录 ❤2023重新理解记录 其它文章链接,独家吐血整理 实验现象 主程序 IAP初始化 ...

  6. STM32F4单片机bootloader及在线升级IAP基本原理

    STM32F407基础总结系列(三) STM32F4bootloader及在线升级IAP基本原理 一 .前言 二.背景知识补充 2.1 系统启动过程 2.2 内存映射分布 三.bootloader 3 ...

  7. STM32F4启动流程分析

    前言 因为在做有关STM32F407ZET6的项目,其中一项内容是通过IAP来对STM32进行在线升级,那么首先需要对STM32的启动流程需要做到详细了解. 硬件及调试配置说明: 使用芯片:STM32 ...

  8. IAP升级功能编写初期的一些困惑与疑问---完成功能后的总结

    IAP的源码等资料我上传了,压缩包内有12个文件,,链接地址(要积分的辛苦收集的你们就给点积分吧) 还有另一篇博客总结的IAP:http://www.aiuxian.com/article/p-201 ...

  9. STM32通过USB实现Bootlader/IAP功能

    前沿: 最近在做STM32的USB Bootlader/IAP功能,也就是通过USB实现固件升级,本文介绍下实现的基本思路,希望对实现IAP的同学一个参考,改方法已经在产品中得到实际应用并验证是比较合 ...

最新文章

  1. BringWindowToTop(), SetForegroundWindow(), SetActiveWindow()
  2. Spring - Java/J2EE Application Framework 应用框架 第 7 章 事务管理
  3. 2.2.5 调度算法:时间片轮转 优先级调度 多级反馈队列
  4. Ubuntu 安装firefox中文版 (启用google翻译功能)
  5. [Docker]Docker快速上手学习笔记
  6. 课堂作业整理三 (集合:list接口)
  7. 华为机试HJ23:删除字符串中出现次数最少的字符
  8. 贵州大数据崛起背后的阿里云力量
  9. RocketMQ开发指导之二——RocketMQ部署
  10. python IDE 集合
  11. cell的各种使用和赋值 总结
  12. SpringAOP简单案例
  13. word封面背景及水印背景
  14. java编程实现行列式计算应用_基于java的行列式计算程序
  15. c语言实训总结报告综合,c语言综合性实验总结
  16. 基于QQ空间API和jsonp跨域的QQ空间背景音乐查询
  17. 程序员的幽默笑话(深意爆笑)
  18. 张勇卸任淘宝董事长,戴珊接任;苹果称不送充电器已节省55万吨矿石;Windows彻底告别SMB1传输协议|极客头条
  19. 利用微信API将你的微信变为聊天机器人
  20. 少用的却实用的计算机知识

热门文章

  1. 公司法人代表变更需要多少钱?
  2. 一文详解elasticsearch的索引生命周期管理—rollover+curator—ilm
  3. 助力奈雪,发掘茶饮品牌元宇宙新玩法
  4. 论文阅读-MLPD:Multi-Label Pedestrian Detector in Multispectral Domain(海康威视研究院实习项目)
  5. 异常(Exception)
  6. 一文看懂:网址,URL,域名,IP地址,DNS,域名解析
  7. 1分钟理清楚C++类模板和模板类区别
  8. 2019年六月前端面试经验总结
  9. halcon学习之路
  10. 渡河问题matlab程序,商人渡河问题(MATLAB版)