type
date
slug
category
icon
password
参考FAQs一、基础知识1.1 上电启动1.2 跳转配置1.3 APP 程序问题1.4 调试下载1.5 开源玩法二、基于 NAND、eMMC、SD 卡和 U 盘的 bootloader 实战2.1 APP 生成说明2.2 程序完整性检测 - CRC校验2.3 APP 程序版本控制2.4 NAND、eMMC、SD 卡和 U 盘驱动四、CANFD,I2C,SPI和串口方式更新APP五、升级案例
参考
BSP视频教程第22期:基于串口的XYZmodem文件传输协议实现,含上位机和下位机全开源,制作了一个Ymodem方式固件更新(2022-08-08)
FAQs
固件升级经验总结 鱼鹰谈单片机
APP程序怎么跳转到BootLoader程序?
- BootLoader 跳转到 APP 通过指针进行跳转
- APP 复位跳转到开始位置运行 BootLoader(通过指针跳转不可行)。关于复位可以参考这里。
- 内核复位:只复位内核,不复位外设(CMSIS-DAP是内核复位,KEIL 调试)
- 系统复位:芯片内核和外设均复位,如同按了复位按键
- 上电复位:和系统复位、按键复位一致,但需要增加额外硬件
APP程序和BootLoader之间是否会互相影响 ⭐⭐⭐
- 系统复位无需考虑外设影响
- 内核复位需考虑
- Bootloder 和 app 设置了不同的串口配置
- APP 在配置串口之前,可以先复位串口,再进行配置
- 让 BootLoade 程序在使用串口之前先进行复位
- XXX_DeInit()
- APP 跳转到 BootLoader,导致控制加热程序未控制,一定要做好切换的
状态保护
。
APP和BootLoader之间如何传递参数?
- Bootloader 增加冷启动过程(时间短暂)判断升级命令,单片机中暂时没有APP程序,也能够实现固件升级过程。是一种强制升级方法。
- App 决定升级,需要在进入BootLoader之前给它传递一个参数,告诉它,这次复位需要升级,不能直接跳到APP中运行。
- Flash中(擦除一个扇区,保存地址放在APP区还是BootLoader区)
- 后备域保存参数(需电池)
- 外部的FLASH空间,支持字节编程(具备这种芯片,并增加驱动代码)
- RAM传参(同名变量不行,指针直接操作)一旦使用完这个参数,必须清零
固件更新一到一半,因为某种原因失败了(通信错误、掉电),该如何处理?
- 保存两份APP程序,升级不成功,恢复成原来的系统
- BootLoader 程序判断是否升级成功,检查bin文件的大小。APP需用掉电不丢失的参数来保存是否升级成功。
跳过前8个字节,写入APP程序。最后再对前面8个字节写入,这样一来,就保证了程序的完整性,如果说你中途数据中断了(掉电或上位机中断),那么前面那8个字节肯定不会写入,也就无法正常进入APP中运行了。
如何确保更新的APP是你需要的APP,而不是别的一个APP
- 编写程序,增加标志,程序标志放在向量表的后面。当BootLoader在写前面8个字节前,只要再判断这个地址的标志位是否正确即可。
- 在 bin 文件中加几个字节标着文件的特殊性,测试阶段,更新频繁。
NVIC_SetVectorTable 偏移值设置注意事项
注意1:根据 boot bin文件大小,要扩展到0x200倍数,比如21633字节,设置为0x5500,就不行,跳到APP中运行会出现异常。
函数内部
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);

7:28 保存偏移值,因此
&0x1FFFFF80

打开工程的启动文件,有60个普通中断,另外有16个系统中断,一起是74个中断,由于74大于2的6次方(也就是64,),所以幂向上加1也就是2的7次方,即128,然后一个地址占用四个字节,所以得出128*4=512,也就是我苦苦寻觅的0x200。
- 方便扩充中断向量表
解释:比如现在需要48个中断向量那我就分配它48*4个字节空间,但是以后需要49个捏?考虑到拓展性所以还是多留空间的好
- 方便编程时的 FLASH 擦写
解释:给出一个 Offset 的相对固定的值,方便程序员在编程时提高效率,试想如果设置一个非常复杂的 boot 长度地址,每次修改都会浪费不少时间
实战技能分享,一劳永逸的解决BOOT跳转APP失败问题,含MDK AC5,AC6和IAR,同时制作了一个视频操作说明 https://www.armbbs.cn/forum.php?mod=viewthread&tid=109595

- 如何设置 BOOT 和 APP 都使用的变量,防止编译器优化
一、基础知识
1.1 上电启动


M3,M4内核
芯片上电复位后,要固定从 0x0000 0000 地址读取中断向量表,获取复位中断服务程序的入口地址后,进入复位中断服务程序,其中0x0000 0000是栈顶地址,0x0000 0004存的是复位中断服务程序地址。


- 既然ARM规定了M3,M4内核要从地址0x0000 0000读取中断向量表,而STM32设置Flash地址到0x0800 0000怎么办?STM32支持了个内存重映射功能,将地址0x0800 0000开始的内容重映射到首地址0x0000 0000中,这样就解决了从0x0000 0000读取中断向量表的问题。
- 对于M3、M4内核,不能更改 IROM1 地址,将前面扇区当作参数存储,这样程序就会找不到复位中断函数的运行地址。
- 一旦程序开始运行后,我们就可以随意设置中断向量表的位置了,中断向量表存到内部SRAM,我们就可以操作寄存器
SCB->VTOR 重新安排
,然后将0x0800 0000
的内容复制到设置的地址内即可。
图示,以STM32F407IGT6为例,0x0000 0000和0x0800 0000开始的程序对比:

你怎么保证0x08000 0000首地址存的就是中断向量表,我们不可以随意设置吗?
MDK对应的xxx.sct分散加载里面通过下面这句将这个RESET段放在了0x0800 0000优先存储。

既然设置到0x0800 0000这么麻烦,为什么不直接使用0x0000 0000?
这是因为STM32不仅可以从内部Flash启动,还可以从系统存储器(可以实现串口ISP,USB DFU等程序下载方式,这个程序是ST固化好的程序代码)和从内部SRAM启动,
我们将内部Flash安排到0x0000 0000显然是不行的。这样会导致系统存储器或者内部SRAM无法重映射到0x0000 0000了。

了解了M3和M4,M7是怎么个执行情况呢?
M7内核芯片比较灵活了,改变了固定从0x0000 0000地址读取中断向量表的问题,以STM32H7为例,可以从 0x0000 0000 到 0x3FFF 0000 所有地址进行启动。
专门安排了个选项字节来配置。

H7里面没有重映射了,它的首地址0x0000 0000安排给ITCM RAM空间使用了。
1.2 跳转配置
- 将APP程序加载到支持运行程序的 Flash 或者 RAM中
- 复位 RCC 时钟
- 复位所有开启的外设
- 关闭滴答(在复位 RCC 时钟之后)
- 关闭所有中断
- 设置跳转PC、SP和 Control 寄存器
- 裸机和RTOS跳转的异同


1.3 APP 程序问题
- APP 程序入口依然是复位中断服务程序。
- 注意设置 APP 的中断向量表地址。
- BOOT 占用的RAM空间可以全部被APP使用。
- APP程序版本号和程序完整性问题(CRC校验或者MD5校验实现)
- 固件加密。
- APP调回到BOOT,使用
NVIC_SystemReset
软件复位。
1.4 调试下载
- 大家仅需将BOOT下载进去后,就可以传统方式调试APP的程序。
- APP或者BOOT程序排查问题。
1.5 开源玩法
stm32-iap-uart-boot
havenxie • Updated Mar 12, 2025

二、基于 NAND、eMMC、SD 卡和 U 盘的 bootloader 实战

2.1 APP 生成说明
- 修改中断向量表偏移
- IROM 配置对应一致
2.2 程序完整性检测 - CRC校验
- 拷贝位置
- hex 文件转化位 bin 文件
- 获取 bin 文件大小并显示
- 在bin文件末尾添加CRC校验码
-crop 0 %indexdx%
从头到尾-STM32_Little_Endian
针对硬件CRC小端%indexdx%
生成CRC添加位置
运行日志
2.3 APP 程序版本控制
startup_stm32f40_41xxx.s 中保留位可以存储版本号,用于实现版本控制。

打开 hex 文件,0x02010000 小端序存储版本号。

2.4 NAND、eMMC、SD 卡和 U 盘驱动
- 16GB 以上,大于 32GB,使用 exFAT
- 消费机和工业级
CPU Flash 使用高版本 HAL 库

增加了临时 APP 分区,解密验证有效在复制到APP运行,即使复制过程掉电了。还可以运行临时APP,起到双备份的作用。
四、CANFD,I2C,SPI和串口方式更新APP
协议说明

五、升级案例
IAP升级程序使用补充说明
新单兵IAP升级流程
- PC APP需过滤数据,目前PC APP无法调整,待网络通讯调整后设计
- WAN口设计增加
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/mcu_devframe_iap
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!