当前位置: 首页 > news >正文

Boot Loader

目录

程序的升级方式

Boot引脚配置组合

复位

系统复位:

软件复位

低功耗管理复位

电源复位

内存分配

2) 先建立 Flash 内存模型

方案一:双区划分(Bootloader + App)

2.1 分区示意

2.2 关键配置

2.3 方案一适用场景

2.4 方案一风险与对策

方案二:三区划分(Bootloader + App1 + App2)

3.1 分区示意

3.2 升级流程(A/B 分区思想)

3.3 启动标志位

3.4 方案二适用场景

3.5 与方案一对比

实践章节:从零配置双区 Bootloader

4.1 统一内存映射头文件

4.2 编译与烧录顺序

4.3 调试技巧

常见问题 FAQ

系列扩展(可选后续文章)


程序的升级方式

ICP连线编程:(SWD,ST-Link)可以直接覆盖写入到Flash。

ISP系统内编程:通过内置的BootLoader程序,从串口(UART)、USB、CAN、I2C、SPI等接口来更新程序,不依赖烧录器。

IAP程序内编程:是指在程序运行过程中,由MCU自己控制擦除和重写内部Flash,完成固件升级。

触发特定的条件会进入 IAP Boot Loader程序 自己完成程序的升级更新,通常 IAP Boot Loader程序在flash的最开始位置优先判断当前是否需要进行更新程序

控制升级

(1)传输升级之后的程序到开发板的存储空间

(2)更改 IAP Boot Loader的升级flag

(3)重新上电 让程序执行boot loader

FLASH是按页进行擦除的

(1)小容量和中容量产品页大小都是1K 大容量产品时2K

(2)flash 起始地址都是0x0800 0000

Boot引脚配置组合
Boot1Boot0启动模式说明
X0主闪存存储器从内置Flash启动,正常操作模式
01系统存储器从系统存储器启动,用于串口/USB等ISP编程
11内置SRAM从SRAM启动,用于调试和特殊应用

注:X表示"无关"(0或1都可以)

复位

系统复位:

当发生以下任一事件时,产生一个系统复位:

1. NRST引脚上的低电平(外部复位)

2. 窗口看门狗计数终止(WWDG复位)

3. 独立看门狗计数终止(IWDG复位)

4. 软件复位(SW复位)

5. 低功耗管理复位

软件复位
低功耗管理复位
电源复位

(1)上电/掉电复位(POR/PDR复位)

(2)从待机模式中返回

电源复位将复位除了备份区域外的所有寄存器。

备份域复位

烧录的文件类型

BIN文件是一种二进制文件,它包含了纯粹的二进制数据,没有任何附加格式或地址信息。

(1)如果烧录bin文件需要指定flash的地址

(2)中断向量表4字节对齐 64字节(第一个四字节是RAM起始地址——RAM起始地址+栈大小,第二个四字节是复位中断——写入flash地址+4)

(3)函数代码=>指令码

(4)常量字符串

(5)全局变量初始值

keil中配置生成bin文件:$K\ARM\ARMCC\bin\fromelf.exe --bin --output=.\OUTPUT\@L.bin !L

HEX文件是用ASCII字符表示的文本文件,它包含了程序数据以及地址和校验等附加信息。每行以冒号(:)起始,后面每两个字母是一个8bit的16进制数;

系统内boot loader

(1)通过控制boot0和boot1引脚电平位01复位进入到boot loader模式中

(2)使用串口完成数据的烧录 串口参数默认为115200 默认使用偶校验 数据位8 停止位1

(3)存储位置特殊0x1FFF F000

自定义

(1)区别:程序本身存放的位置不同 flash中 地址是起始位置0x0800 0000(程序冲突的问题:boot loader程序和执行的Application程序需要存放在不同的位置;AB区存放 B区一定要存放在flash起始的位置;假设boot loader程序是4KB≈4096 那么A区程序最小的地址可用就是0x0800 1000;考虑安全问题可以安排boot loader比较大的空间来使用16K A程序的地址0x0800 4000)

(2)功能:串口挂起等待接收程序数据=>写道对应的flash当中

复位之后一直执行boot loader,只能跳转执行到Application。

相同开发板栈大小是一样的 栈顶地址可以通用

复位中断地址=>确定的flash地址

程序在编译的时候一定要制定好专门的起始Flash位置

内存分配

1) 我们使用Bootloader的时候有以下几种方法:

方案一:

我们将flash分为两个区,分别是bootloader、app。通过更改起始地址和app程序的中断向量偏移地址将bootloader和app放在两个区域。如下图所示;

方案二:

我们将flash分为三个区,分别是bootloader、app1、app2

2) 先建立 Flash 内存模型

以常见 STM32 为例(32KB Bootloader + 剩余给 App):

┌─────────────────────────────────────┐ 0x0800_0000

│ Bootloader 区 │ 16~32 KB

├─────────────────────────────────────┤ 0x0800_8000 (示例)

│ Application 区 │ 剩余 Flash

├─────────────────────────────────────┤

│ 可选:参数/标志位区 │

└─────────────────────────────────────┘ 0x080F_FFFF

要点:

  • 起始地址:链接脚本里FLASH ORIGIN/LENGTH
  • 向量表偏移:SCB->VTOR = App 起始地址(Cortex-M)
  • 跳转:Bootloader 校验 App 后,设置 SP、PC 并跳转

方案一:双区划分(Bootloader + App)

2.1 分区示意

Flash 存储器校验通过后跳转Bootloader0x0800_0000Application0x0800_8000

区域起始地址大小作用

Bootloader

0x0800_0000

32 KB

上电首先运行,负责升级/跳转

App

0x0800_8000

224 KB

业务固件

2.2 关键配置

① Bootloader 链接脚本(示例)

MEMORY

{

FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K

RAM (xrw): ORIGIN = 0x20000000, LENGTH = 64K

}

② App 链接脚本

MEMORY

{

FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 224K

RAM (xrw): ORIGIN = 0x20000000, LENGTH = 64K

}

③ App 启动时设置向量表偏移

#define APP_START_ADDR 0x08008000U

void app_init(void)

{

SCB->VTOR = APP_START_ADDR;

__enable_irq();

}

或在system_stm32xxx.c中:

#define VECT_TAB_OFFSET 0x8000U

SCB->VTOR when the app starts

④ Bootloader 跳转到 App

typedef void (*pFunction)(void);

void jump_to_app(uint32_t app_addr)

{

uint32_t sp = *(volatile uint32_t *)app_addr;

uint32_t pc = *(volatile uint32_t *)(app_addr + 4);

pFunction jump = (pFunction)pc;

__disable_irq();

SCB->VTOR = app_addr;

__set_MSP(sp);

jump();

}

2.3 方案一适用场景

  • 简单 OTA,只需一个 App 槽位
  • Flash 较小、成本敏感
  • 升级策略:先擦 App 区再写入,失败则 Bootloader 仍可运行

2.4 方案一风险与对策

风险对策

升级中断导致 App 损坏

双备份(见方案二)或外部 Flash 暂存

向量表未重定位

启动 HardFault

地址配置不一致

统一维护memory_map.h


方案二:三区划分(Bootloader + App1 + App2)

3.1 分区示意

Flash 三区模型当前运行OTA 写入校验成功,切换BootloaderApp1 运行区App2 备份/升级区

典型布局(256 KB Flash 示例):

区域地址范围大小角色

Bootloader

0x0800_0000

32 KB

启动与切换

App1

0x0800_8000

112 KB

当前运行固件

App2

0x0802_4000

112 KB

新固件下载区

3.2 升级流程(A/B 分区思想)

1. 下载新固件到 App22. 校验 CRC/签名3. 拷贝 App2 → App1(或切换启动标志)4. 跳转到 App1 运行OTA 服务器BootloaderApp1 运行区App2 下载区

3.3 启动标志位

在 Flash 或 EEPROM 中保存:

typedef struct {

uint32_t magic; // 0xDEADBEEF

uint8_t active_slot; // 0=App1, 1=App2

uint32_t app1_crc;

uint32_t app2_crc;

} boot_info_t;

Bootloader 逻辑:

  1. boot_info
  2. 校验 active slot 的 CRC
  3. 失败则尝试另一槽位
  4. 跳转至有效 App

3.4 方案二适用场景

  • 需要安全 OTA,升级失败可回滚
  • 产品级 IoT、汽车、工业设备
  • Flash 足够大(通常 ≥ 512 KB 更从容)

3.5 与方案一对比

对比项方案一(双区)方案二(三区)

Flash 占用

省空间

多占一个 App 槽

升级安全性

中等

高(A/B 备份)

实现复杂度

中高

回滚能力

典型产品

简单 MCU 产品

路由器、智能设备


实践章节:从零配置双区 Bootloader

4.1 统一内存映射头文件

// memory_map.h

#define FLASH_BASE 0x08000000U

#define BL_SIZE (32 * 1024)

#define APP_START (FLASH_BASE + BL_SIZE)

#define APP_SIZE (224 * 1024)

#define VECT_TAB_OFFSET BL_SIZE

Bootloader 与 App 工程都#include "memory_map.h",避免地址写错。

4.2 编译与烧录顺序

  1. 先编译 Bootloader → 烧录到0x0800_0000
  2. 再编译 App(带偏移链接脚本)→ 烧录到0x0800_8000
  3. 上电:Bootloader 运行 → 跳转 App

4.3 调试技巧

  • 用 J-Link / ST-Link 查看 Flash 内容
  • 断点打在jump_to_app前,检查 SP、PC
  • readelf -l app.elf确认 Load Address

常见问题 FAQ

Q1:App 能直接烧在 0x0800_0000 吗?
不能。会与 Bootloader 冲突,且向量表地址错误。

Q2:RAM 需要分区吗?
一般 Bootloader 与 App 共用 RAM;跳转前需关闭外设、清中断,避免 Bootloader 状态影响 App。

Q3:三区时 App1、App2 链接脚本一样吗?
起始地址不同,需两套ORIGIN;或同一套模板,编译时传入不同宏。

Q4:如何实现回滚?
升级前把 App1 备份到 App2;新固件失败时 Bootloader 从 App2 恢复或切换启动槽。


系列扩展

  1. 《Cortex-M 向量表与 VTOR 深度解析》
  2. 《OTA 固件签名与 CRC 校验实战》
  3. 《从双区升级到三区的迁移指南》
  4. 《STM32 / ESP32 Bootloader 完整工程模板》
http://www.jsqmd.com/news/1069635/

相关文章:

  • 没有修改文件,但git却显示很多文件被changes
  • 终极指南:如何用Ice轻松管理你的macOS菜单栏
  • SiemensPLC编程语言从入门到精通(更新中)
  • 【RHCA+】分枝条件
  • go2rtc终极指南:5分钟快速上手RTSP转WebRTC视频流转发工具
  • Luminous:简单轻量无依赖的JavaScript灯箱库,让图片展示更出彩
  • 实战指南:构建OpenUSD自定义渲染器的架构设计与实现路径
  • laravel-acl中间件使用教程:保护路由和控制器的安全实践
  • phpMQTT 代码解析:深入理解MQTT协议在PHP中的实现原理
  • Trippy网络诊断工具:五分钟快速上手指南,让网络问题无处遁形
  • rpi-firmware项目历史与未来:从旧仓库到raspberrypi官方仓库的演进之路
  • AI(学习笔记第三十课)langchain v1.0(dcode学习(2))
  • agent面试必备9-AI Agent 核心框架大揭秘
  • 图漾相机升级固件(待更新)
  • 如何彻底告别文献附件管理混乱:Zotero Attanger终极指南
  • 2026年7月更新:7月国际学术会议清单信息一览
  • VoxCPM2:突破传统TTS限制,解锁30语言无令牌语音合成新纪元
  • 终极指南:用Ice彻底掌控你的macOS菜单栏,打造清爽高效桌面
  • AI Agent 面试题 791:如何设计Agent的回归测试的优先级排序?
  • 如何为Newton物理引擎定制渲染管线:从原理到实战
  • svn迁移仓库里某个目录到新仓库
  • AUTOSAR CP 文档切分方法说明
  • 终极指南:5分钟快速部署哲学AI助手OpenHermes-2.5-Strix-Philosophy
  • 本草模型终极指南:基于中文医学知识的大语言模型指令微调完整解决方案
  • 5分钟快速上手:使用Pop框架为iOS应用添加专业级物理动画
  • CC Switch配置
  • 5分钟学会AI全自动短视频制作:MoneyPrinterTurbo终极指南
  • N_m3u8DL-RE深度解析:专业级流媒体下载实战指南
  • 高玩篇2:EA多品种多周期组合——大白科普
  • 如何用5分钟告别“英语打字恐惧症“?Qwerty Learner 终极解决方案