STM32的在线升级(IAP)实现方法:BOOT+APP原理详解
0 工具准备
Keil uVision5
Cortex M3权威指南(中文)
STM32参考手册
1 在线升级(IAP)设计思路
为了实现STM32的在线升级(IAP)功能,通常会将STM32的FLASH划分为BOOT和APP两个部分,BOOT就是引导APP的引导程序,当我们需要在线升级时就可以通过BOOT来实现。BOOT和APP在FLASH中的分布如下:

原理分析:
(1)当STM32复位后会跳转到FLASH首地址,也就是0x08000000的位置,读取1-4Byte获取主堆栈指针初始值(栈顶值)并设置,然后读取5-8Byte获取复位中断服务函数入口地址并执行,进入BOOT程序
(2)BOOT程序根据用户选择升级APP或者跳转到APP
(2.1)如果用户选择升级APP则擦除APP所在扇区,按照一定协议将APP程序复制到FLASH的APP扇区
(2.2)如果用户选择跳转到APP,首先关闭全局中断及清除中断挂起标志,设置主堆栈指针,跳转到APP的复位中断服务函数**(相当于做了(1)中内核干的事情)**
2 BOOT设计
这里介绍一下BOOT跳转到APP函数的设计思路:
void Jump_to_APP(void)
{uint32_t i=0;void (*SysMemBootJump)(void);/* 关闭全局中断 */__disable_irq();/* 关闭滴答定时器,复位到默认值 */SysTick->CTRL = 0;SysTick->LOAD = 0;SysTick->VAL = 0;/* 设置所有时钟到默认状态,使用HSI时钟 */RCC_DeInit();/* 关闭所有中断,清除所有中断挂起标志 */for (i = 0; i < 8; i++){NVIC->ICER[i]=0xFFFFFFFF;NVIC->ICPR[i]=0xFFFFFFFF;}/* 使能全局中断 */__enable_irq();/* 跳转到系统BootLoader,首地址是MSP,地址+4是复位中断服务程序地址 */SysMemBootJump = (void (*)(void)) (*((uint32_t *) (FLASH_APP_ADDR + 4)));/* 设置主堆栈指针 */__set_MSP(*(uint32_t *)FLASH_APP_ADDR);/* 跳转到APP */SysMemBootJump();/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */while (1){}
}
相关知识:
(1)涉及到的NVIC寄存器
(1.1)NVIC->ICER,中断失能寄存器,写入1失能中断

(1.2)NVIC->ICPR,中断挂起清除寄存器,写入1清除中断挂起

(2)APP二进制文件含义
bin文件:

Byte1-4:0x20014168
Byte5-8:0x080101A1
Byte9-12:0x08012D75
Byte13-16:0x08012851
map文件:
__initial_sp 0x20014168 Data 0 startup_stm32f40xx.o(STACK)
Reset_Handler 0x080101a1 Thumb Code 8 startup_stm32f40xx.o(.text)
NMI_Handler 0x08012d75 Thumb Code 2 stm32f4xx_it.o(i.NMI_Handler)
HardFault_Handler 0x08012851 Thumb Code 8 stm32f4xx_it.o(i.HardFault_Handler)
可以看到,APP工程的bin文件含义如下:
Byte1-4:0x20014168 主堆栈指针初始值(栈顶值)
Byte5-8:0x080101A1 复位中断服务函数地址
Byte9-12:0x08012D75 NMI中断服务函数地址
Byte13-16:0x08012851 HardFault中断服务函数地址
该部分的定义在STM32的参考手册上也可以看到:

其实,我们只需要关注主堆栈指针初始值(栈顶值)和复位中断服务函数地址即可。如果想要了解APP前几个byte的全部内容,可以参看STM32参考手册的“STM32F405xx/07xx 和 STM32F415xx/17xx 的向量表”。
弄清楚了上述的寄存器使用方法和APP的bin文件内容后,接下来BOOT中跳转到APP的操作原理就一目了然了:
(1)关闭全局中断,避免被打断
(2)关闭滴答定时器,复位到默认值,为后面的APP营造一个纯净的环境
(3)设置所有时钟到默认状态,为后面APP营造一个纯净的环境
(4)关闭所有中断同时清除所有中断挂起标志,避免APP使能中断后异常触发等情况
(5)使能全局中断,避免APP部分没有打开全局中断
(6)函数指针指向APP的复位中断服务函数(也就是APP的第5-8Byte)
(7)设置主堆栈指针(也就是APP的前4Byte)
(8)跳转到APP
以上有2个地方需要特别注意:
(1)APP的复位中断服务函数地址是APP的第5-8Byte
(2)APP的主堆栈指针初始值(栈顶值)是APP的前4Byte
3 APP设计
APP设计时只需要修改工程的flash起始地址以及中断向量偏移地址寄存器即可。
(1)修改FLASH起始地址

如果我们的APP存放在FLASH的0x8010000开始的位置,则将FLASHA的起始地址修改为0x8010000即可。
(2)修改中断向量偏移地址
BOOT下我们的中断向量偏移地址为0x08000000和默认值一样无须特别设置,APP下由于FLASH起始地址被修改到0x8010000,因此需要将中断向量偏移地址设置为0x1000:
#define VECT_TAB_OFFSET 0x10000
相关寄存器如下:

当STM32发生了中断需要响应时,内核会根据向量表偏移量寄存器的值在相应的FLASH空间找到异常服务函数入口地址(中断服务函数入口地址保存工作由编译器完成)。上电后的向量表如下:

假设我们设置的VTOR的值为0x8010000,在发生了硬错误时,会跳转到0x8010000+0x0000000C的位置找到硬错误中断服务函数地址并执行。这也是我们为什么需要在APP中设置VTOR的原因(BOOT里已经默认设置为0x0x8000000),保证我们的中断能够正确执行。
4 总结
(1)APP程序需要修改FLASH起始地址和向量表偏移量寄存器,以便内核能够在中断发生时进入正确的中断服务函数
(2)BOOT程序跳转到APP的过程实际上就是模拟内核的操作
(3)BOOT跳转到APP之前一定要失能所有中断、清除所有中断挂起标志,营造一个纯净的环境
相关文章:
STM32的在线升级(IAP)实现方法:BOOT+APP原理详解
0 工具准备 Keil uVision5 Cortex M3权威指南(中文) STM32参考手册 1 在线升级(IAP)设计思路 为了实现STM32的在线升级(IAP)功能,通常会将STM32的FLASH划分为BOOT和APP两个部分,BOO…...
【芯片DFX】Arm调试架构篇
【芯片DFX】万字长文带你搞懂JTAG的门门道道【芯片DFX】ARM:CoreSight、ETM、PTM、ITM、HTM、ETB等常用术语解析...
ES应用_ES实战
依靠知识库使用es总结一些使用技巧。 1 快速入门 ES是将查询语句写成类似json的形式,通过关键字进行查询和调用。 1.1 创建 下面创建了一个主分片为5,副本分片为1的ES结构。ES本身是一种noschema的结构,但是可以通过指定mapping编程schema的…...
Ubuntu上如何找到设备,打印串口日志
dmesg 找设备 sudo mincom -s 配置minicom mincom 打印串口日志 PS: Windows上使用MobaXterm / putty / Xshell / SecureCRT等 ubuntu串口的安装和使用(usb转串口)_ubuntu上如何把usb设备映射到tty-CSDN博客...
本地映射测试环境域名,解决登录测试环境后,也可以使用本地域名访问,可以正常跑本地项目
问题:单点登录进入系统不使用token,是将token携带在cookie中,登录成功后每次调用接口,都会在cookie中自动携带,这样导致即使在本地使用proxy代理解决了跨域,但由于本地域名不一致,也无法进行本地…...
VSCode使用Remote SSH远程连接Windows 7
结论 VSCode Server不能启动,无法建立连接。 原因 .vscode-server 目录中的 node.exe 无法运行。 原因是Node.js仅在Windows 8.1、Windows Server 2012 R2或更高版本上受支持。 由于vscode基于node.js v14,不支持Windows 7操作系统。 另ÿ…...
uniapp中uview组件库丰富的Calendar 日历用法
目录 基本使用 #日历模式 #单个日期模式 #多个日期模式 #日期范围模式 #自定义主题颜色 #自定义文案 #日期最大范围 #是否显示农历 #默认日期 基本使用 通过show绑定一个布尔变量用于打开或收起日历弹窗。通过mode参数指定选择日期模式,包含单选/多选/范围…...
云原生Kubernetes:K8S集群实现容器运行时迁移(docker → containerd) 与 版本升级(v1.23.14 → v1.24.1)
目录 一、理论 1.K8S集群升级 2.环境 3.升级策略 4.master1节点迁移容器运行时(docker → containerd) 5.master2节点迁移容器运行时(docker → containerd) 6.node1节点容器运行时迁移(docker → containerd) 7.升级集群计划(v1.23.14 → v1.24.1&#…...
Redis 数据结构和常用命令
* 代表多个,?代表一个 (不用全部敲出来,按住tab可以自动补全) -2是无效,-1是永久有效 ;贴心小提示:内存非常宝贵,对于一些数据,我们应当给他一些过期时间&a…...
Docker 容器命令总汇
目录 1、创建Docker容器(不启动) 2、创建Docker容器(启动) 3、列出正在运行的容器 4、停止和启动容器 5、重启容器 6、进入容器 7、查看容器信息 8、查看容器日志 9、删除容器和镜像 10、重命名容器 11、从旧容器复制数…...
react + redux 之 美团案例
1.案例展示 2.环境搭建 克隆项目到本地(内置了基础静态组件和模版) git clone http://git.itcast.cn/heimaqianduan/redux-meituan.git 安装所有依赖 npm i 启动mock服务(内置了json-server) npm run serve 启动前端服务 npm…...
【形式语言与自动机/编译原理】CFG-->Greibach-->NPDA(2)
本文将详细讲解《形式语言与自动机》(研究生课程)或《编译原理》(本科生课程)中的上下文无关文法(CFG)转换成Greibach范式,再转成下推自动机(NPDA)识别语言是否可以被接受…...
14.用户管理
目录 1、权限表 1、user表 1.用户列 2.权限列 3.安全列 4.资源控制列 2、db表和host 表 1.用户列 2.权限列 3. tables_priv 表和 columns _priv 表 4.procs_priv 表 2、账户管理 1. 登录和退出MySQL服务器 2、创建普通用户: 1.使用CREATE USER语创建…...
【交叉编译环境】安装arm-linux交叉编译环境到虚拟机教程(简洁版本)
就是看到了好些教程有些繁琐,我就写了一个 我这个解压安装的交叉编译环境是Linaro GCC的一个版本,可以用于在x86_64的主机上编译arm-linux-gnueabihf的目标代码 步骤来了 在你的Ubuntu系统中创建一个目录,例如/usr/local/arm,然后…...
感染了后缀为.[sqlback@memeware.net].2700勒索病毒如何应对?数据能够恢复吗?
导言: 近期,[sqlbackmemeware.net].2700 勒索病毒成为网络安全的一大威胁。该勒索病毒采用高度复杂的加密算法,将用户文件加密并勒索赎金。了解该病毒的特征对于有效恢复被加密数据以及预防进一步感染至关重要。如果受感染的数据确实有恢复的…...
[Linux开发工具]——vim使用
Linux编辑器——vim的使用 一、什么是集成开发环境?二、什么是vim?三、vim的概念四、vim的基本操作五、vim命令模式命令集5.1 移动光标5.2 删除文字5.3 复制粘贴5.4 其他操作 六、vim底行模式命令集6.1 首先在命令模式下shift;进入末行模式。…...
【教学类-43-11】 20231231 3*3宫格数独提取单元格坐标数字的通用模板(做成2*2=4套、3*2=6套)
背景需求: 1、以前做单元格填充,都是制作N个分开的单元格 (表格8) 2、这次做五宫格数独的Word模板,我图方便,就只用了一个大表格,第六行第六列隐藏框线,看上去就是分开的ÿ…...
Spring Boot日志:从Logger到@Slf4j的探秘
写在前面 Hello大家好,今日是2024年的第一天,祝大家元旦快乐🎉 2024第一篇文章从SpringBoot日志开始 文章目录 一、前言二、日志有什么用?三、日志怎么用?四、自定义日志打印💬 常见日志框架说明4.1 在程序…...
英飞凌TC3xx之一起认识GTM系列(六)如何实现GTM与VADC关联的配置
英飞凌TC3xx之一起认识GTM系列(六)如何实现GTM与VADC关联的配置 1 GTM与ADC的接口2 GTM与VADC的连接2.1 VADC 到 GTM 的连接2.1.1 简要介绍2.1.2 应用举例2.2 EVADC到 GTM的连接2.2.1 应用举例3 总结本文介绍实现GTM与VADC的连接性的相关寄存器配置。 1 GTM与ADC的接口 由英…...
【基础】【Python网络爬虫】【6.数据持久化】Excel、Json、Csv 数据保存(附大量案例代码)(建议收藏)
Python网络爬虫基础 数据持久化(数据保存)1. Excel创建数据表批量数据写入读取表格数据案例 - 豆瓣保存 Excel案例 - 网易新闻Excel保存 2. Json数据序列化和反序列化中文指定案例 - 豆瓣保存Json案例 - Json保存 3. Csv写入csv列表数据案例 - 豆瓣列表保…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
二叉树-144.二叉树的前序遍历-力扣(LeetCode)
一、题目解析 对于递归方法的前序遍历十分简单,但对于一位合格的程序猿而言,需要掌握将递归转化为非递归的能力,毕竟递归调用的时候会调用大量的栈帧,存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧,而非…...
