STM32-bootloader引导程序跳转机制笔记 - 教程

news/2025/12/11 1:01:00/文章来源:https://www.cnblogs.com/ljbguanli/p/19333723

STM32-bootloader引导程序跳转机制笔记 - 教程

STM32F103C8T6 引导程序跳转机制笔记

适用场景:自定义 Bootloader 位于 Flash 起始 8KB( 0x08000000–0x08001FFF ),应用程序(APP)从 0x08002000 开始,芯片为 STM32F103C8T6(Flash 64KB、SRAM 20KB)。

关键内存与向量表

Memory Map 总览

如果有不懂的地方可以参考我的另一篇博客***STM32内存分配与堆栈***

地址高 ───────────────────────────────────────────────────────────
0xE000E000  System Control Space(NVIC、SCB、SysTick 等)└─ 核心控制寄存器区,软件不可搬移
0x40000000  外设寄存器空间(AHB/APB)└─ GPIO、USART、TIM、RCC、FLASH 控制器等
0x20000000  SRAM(20KB:0x20000000–0x20004FFF)├─ 堆(heap)通常自低地址向上增长└─ 栈(stack)通常自高地址向下增长(由 MSP/PSP 指向)
0x08000000  主 Flash(64KB:0x08000000–0x0800FFFF)├─ Bootloader(8KB):0x08000000–0x08001FFF└─ APP(56KB):     0x08002000–0x0800FFFF
(系统内置 Bootloader 位于“System Memory”专有区域,不在主 Flash 范围)
地址低 ───────────────────────────────────────────────────────────

点击keil的小魔术棒也可以看到如何进行内存分配
在这里插入图片描述
关注下面的ROM和RAM起始位置和区域大小

为什么要检查“栈指针必须落在 SRAM”

  • ARM Cortex-M 的固件格式规定:镜像开头的第一个 32 位值就是该固件的初始栈指针(MSP)
  • 栈需要在可读写的 RAM 中工作,因此这个值必须落在芯片的 SRAM 地址范围(F103C8 为 0x20000000–0x20004FFF )
    F103C8的RAM是20kB所以一般肯定是会指向栈顶0x20004FFF,因为栈是向低地址生长,这样也会更安全
  • 如果把 MSP 设为 0x20000000 (RAM 起点的低地址),第一次入栈就会越界到更低的地址(不在 SRAM),立刻触发错误(通常 HardFault)
  • 检查意义:快速判断指定地址上是否真的烧写了“像样的”APP
    • 合法示例: 0x20001234
    • 非法示例: 0x00000000 、 0xFFFFFFFF (通常是空闪存)或落在 Flash 的地址(不可作为栈)
      示例检查(两种写法,任选其一):
uint32_t msp = *(uint32_t*)APP_ADDRESS;
// 掩码法:判断起始段是否为 0x2000...
bool sp_ok = ((msp & 0x2FFE0000) == 0x20000000);
// 或范围法:判断落在 20KB SRAM 区间
bool sp_ok2 = (msp >= 0x20000000U && msp < 0x20005000U);

跳转前为何要做这么多“清场”操作

从 Bootloader 切换到 APP,本质上是一次“小型上下文切换”。目标是让 APP 进入时的环境与“芯片刚复位”尽可能一致,避免把 Bootloader 的状态“泄露”给 APP。

  • 关闭全局中断 __disable_irq() 防止在切换过程中,Bootloader 的中断(如 SysTick)突然触发,引发混乱。
  • 停用与清理 SysTick HAL_DeInit() 后, SysTick->CTRL/LOAD/VAL = 0 Bootloader 和 APP 都会配置各自的 SysTick;先关闭 Bootloader 的,避免互相干扰。
  • 清除 NVIC 状态(使能位与挂起位) 遍历 NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; 确保没有残留的中断在 APP 进入后意外触发。
  • 重定位向量表 SCB->VTOR = APP_ADDRESS 让所有中断从 APP 的向量表进入,而不是仍指向 Bootloader 的表。
  • 切换主栈指针 __set_MSP((uint32_t)APP_ADDRESS) 按 APP 向量表指定的初始栈指针重置 MSP。
  • 获取复位入口并跳转 reset = (uint32_t)(APP_ADDRESS + 4); 转为函数指针并调用。
  • 重新打开中断 __enable_irq() 让 APP 初始化后的 SysTick、中断能正常工作;这是解决 HAL_Delay() 卡住的关键。
    这些步骤缺一不可;省略任一步都可能导致不可预测的问题(如 HardFault、延时卡死、外设异常等)。

跳转代码示例

typedef void (* pFunction)(void);
void JumptoApplicaitoin(void){
uint32_t app_sp = *(__IO uint32_t*)APP_ADDRESS;
if((app_sp & 0x2FFE0000) == 0x20000000){
//关闭现有中断
__disable_irq();
//停用 HAL 和系统节拍
HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL  = 0;
//清除 NVIC 状态
for (uint32_t i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
//重定位中断向量
SCB->VTOR = APP_ADDRESS;
//取 APP 的复位入口
pFunction app_reset_handler = (pFunction)(*(__IO uint32_t*)(APP_ADDRESS + 4));
//设置主栈指针: __set_MSP(*(uint32_t*)APP_ADDRESS) ,按 APP 的向量表重置栈。
__set_MSP(app_sp);
//再打开中断
__enable_irq();
//调用复位入口
app_reset_handler();
}
}

要点:

  • APP_ADDRESS 对齐到 0x200 (如 0x08002000 )
  • __enable_irq() 放在跳转前,保证 APP 的 SysTick/中断可用

APP 工程链接设置(Keil/MDK 示例)

  • IROM1 Start: 0x08002000

  • IROM1 Size: 0x0000E000 (= 64KB - 8KB)

  • IRAM1 Start: 0x20000000

  • IRAM1 Size: 0x00005000 (20KB)
    校验方法(强烈建议):

  • 查看 .map 文件或 .htm / .axf 导出信息,确认

    • 向量表地址: 0x08002000
    • [0] MSP 在 0x20000000–0x20004FFF
    • [1] 复位入口在 0x08002000 之后的 Thumb 地址(最低位为 1)

常见坑点与后果

烧录与启动流程推荐

  1. 使用调试器烧录 Bootloader 到 0x08000000 (8KB 内)。
  2. 将 APP 烧录到 0x08002000 (通过 Keil 的 IROM1 设置或自定义 scatter)。
  3. 复位芯片:Bootloader 自检后直接跳到 APP 运行;无 APP 则闪灯。

调试建议

IAP(在线升级)扩展思路

  • 层次化设计:Bootloader 负责通信与写 Flash,APP 专注业务逻辑
  • 只擦/写 APP 区(1KB 页擦除),保护 Bootloader 区
  • 在 Bootloader 中做固件校验(CRC/签名)与回滚策略
  • 合理的接口与协议(UART/CAN/USB/SD 等),避免断电砖机

结论

应用程序app的分区跳转和升级app可以为你的小创意或者毕设增加亮点,想要stm32f103c8t6的bootloader模板工程可以点赞加收藏下方评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/997577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析:心率变异性计算算法(HRV)

深入解析:心率变异性计算算法(HRV)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mona…

Unlock Super Remote Diagnosis on Launch Smartlink C with 1-Time Activation Card

Problem: Remote Diagnostics Barriers in European/American Auto Repair In the dynamic world of automotive repair, European and American mechanics and car owners alike face a common challenge: complex ve…

.gitignore 的匹配规则

.gitignore 是使用 Git 的日常开发时一个非常常见的文件。它负责告诉 Git 哪些文件或目录应当被忽略,不被加入版本控制。必须掌握。 基本规则.gitignore 文件对其所在目录以及所有子目录生效。每行一条规则:空行:无…

无法在Debian13 VSCode中使用fcitx5输入中文

根据 https://fcitx-im.org/wiki/Setup_Fcitx_5/zh-cn 编辑下面两个文件,然后重启电脑 vim /etc/environmentXMODIFIERS=@im=fcitx GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitxvim /etc/profileexport XMODIFIERS=@im=fc…

Debian 13安装rime中文输入法

删除无关输入法,并安装fcitx5-rime sudo apt purge --autoremove fcitx* fcitx5* ibus* sudo apt install fcitx5-rime图形设置,启用输入法 安装白霜拼音输入方案和词库。重启 systemctl reboot本文来自博客园,作者…

[LabVIEW随笔-10] -基础知识3

1、列表框1.1 创建列表框列表框同简单控件一样,有“新式”、“系统”和“古典”三种不同风格。列表框控件位于“列表与表格”控件选板中列表框的外观与一般的字符串控件比较相似,列表框控件内含的数据类型是 132,它…

0_C++的基础语法(上)

今天这个C++基础语法上面部分我们就假设你有c语言基础,不会去重复讲C语言一样的内容,然后只讲算法比赛中会用到的内容,不讲类,对象之类的内容。本次不讲STL,STL部分我会放在下一篇部分讲的。恋爱可以不谈,算法不能…

linux进线程

进线程 1. 什么是进程,什么是线程,区别在那?进程是系统资源分配的基本单位,线程是程序执行的最小单位,一个进程可以包含多个线程 进程有自己独立的地址空间,每新建一个进程,系统都会给进程分配独立的地址空间,…

Codeforces Round 1069 (Div. 2)

因为各种原因,最近几天的做题量与强度有所下降,时间不多了希望未来可以更加努力,以此为戒 B 这一套的难度感觉划分的不太对,这个B题反而比C题难得多 这个B题的思维还是挺巧妙的,显然是个构造,我竟然没有想出来 异…

Old-Java类集框架随笔

结构 Map ├── HashMap │ └── LinkedHashMap ├── SortedMap (接口) │ └── TreeMap └── Hashtable (遗留类,线程安全) Collection ├── List(ListIterator可用) │ ├── ArrayList │ ├…

第51天(中等题 数据结构)

打卡第五十一天 2道中等题题目:思路:前缀和+哈希表,同余定理 代码: int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int,int> cnt; // 哈希表int ans = 0, s = 0; // 答…

对《AI元人文构想:从“伦理规范”向“技术合标”的范式扩展》的评价与展望(深化版)

迈向“全域可靠性”的工程宣言:一篇深度评述 对《AI元人文构想:从“伦理规范”向“技术合标”的范式扩展》的评价与展望 引言:一次理论-工程范式的关键跃迁 《AI元人文构想:从“伦理规范”向“技术合标”的范式扩展…

Claude使用体验

1.使用cli版本的Claude 安装 首先安装好node和npm,直接下载即可 https://nodejs.org/en 然后安装Claude clinpm install -g @anthropic-ai/claude-code --registry=https://registry.npmjs.org/安装完成就是这样查看C…

适合 Linux 强者的方式 freertos学习

适合 Linux 强者的方式 freertos学习✅ 适合 Linux 强者的方式 Step 1:对标理解LinuxFreeRTOSpthread xTaskmutex xSemaphoresignal task notifyIRQ ISRscheduling priority👉 把 FreeRTOS 当 “没有 MMU 的 Linux”…

网络故障具体排错

还是从物理层进行排查,查看crc循环冗余校验码是否持续增加,那么可能是物理线路异常,光衰过大,光模块插入异常,查看内存,风扇,cpu等设备问题可以通过命令进行自检,如dis cpu ,dis mamary ,dis fan 然后查看二…

Git 中文文件名显示为转义码(乱码)的解决方案

问题描述 在使用 Git 时,如果文件名包含中文或其他非 ASCII 字符,执行 git status 等命令时会看到类似这样的输出: $ git status On branch main Untracked files:(use "git add <file>..." to inc…

真相:大量硬件场景 根本跑不了 Linux

真相:大量硬件场景 根本跑不了 Linux2️⃣ 真相:大量硬件场景 根本跑不了 Linux 你以后真做设备,会遇到这些情况:场景LinuxFreeRTOS成本 < 20 MCU ❌ ✅启动 < 50ms ❌ ✅512KB Flash ❌ ✅精确定时 ⚠️ ✅…

Windows-GameBar-ErrorLog

Windows-GameBar-ErrorLog导航 (返回顶部)1. ms-gamingoverlay1.1 安装相关应用及组件 1.2 注册表关闭 1.3 注册表关闭-方式2 1.4 组策略禁用2. Xbox Game Bar2.1 xbox地区问题3. Reg-help1. ms-gamingoverlay1.1 安装…

S7-PLCSIM Advanced V6.0同网段不同电脑之间网络配置

场景: 电脑A:安装了TIA Portal V19和S7-PLCSIM Advanced V6.0。 电脑B:使用wpf上位机通过ModbusTcp/S7与S7-PLCSIM Advanced V6.0通信。 两台电脑IP为同网段,需要将S7-PLCSIM Advanced V6.0仿真的PLC的IP设置为同一…

记录一些波波的话

记录一些波波的话2025.12.10 关于学和玩 波波曰:“其实就三种,一种是前面过得很舒服,后面比较难受;第二种是把困难分成一段一段自己能接受的,平均一下;第三种就是前面过得很苦,后面就躺平了。那要我说我就偏向于…