STM32启动流程与存储常见问题速查
本专题合并星球中关于启动链路、Flash/RAM 布局、时钟与调试下载的问答,按"上电 → 运行 → 出问题"的顺序整理成速查手册。
一、完整启动链路
上电复位后的标准流程(上电复位 ↓ 硬,Jack):
- 硬件复位:复位寄存器、外设回默认(时钟关闭);
- 执行 BootROM:初始化基础时钟(HSI)、必要外设,检测启动模式(BOOT 引脚/选项字节);
- 按模式跳转:主 Flash(0x08000000)/ 系统存储器(厂商 Bootloader,如 USB DFU)/ RAM(0x20000000);
- 用户 Bootloader(若有):PLL 倍频、深度外设初始化、OTA 检测,再跳应用程序复位向量;
- startup_xxx.s:复制 .data、清零 .bss,进
__main,最后到main()。
BOOT 三种启动方式对应引脚的三种连接,本质是把不同存储区映射到 0 地址(boot引脚的三种不同连接方式对应的三种不同的启动方式,Jack;系统存储器与主 Flash 的区别疑问见 BOOT的三种启动方式里面,系统存储器模式是从内部ROM中的出厂代码启动,Jack)。启动过程中断向量表通过链接被放到固件最前部,SystemInit 里可视宏定义再做偏移(USER_VECT_TAB_ADDRESS,一般不开)(老师,单片机从flash启动过程中,没有设置中断向量表地址,Jack)。把向量表搬到 RAM 可显著减少中断延时,对 ADC 等高速应用性能提升明显(重定位的用处: 1.进入用户空,Jack)。
时钟方面:上电先用内部晶振激励外部晶振,起振稳定后再切到 HSE(老师,请教下,单片机启动的时候是先用内部晶振,Jack);HSE 精度优于 HSI,两者都能把 APB 配到满频(HSE和HSI都可以将APB总线配置为满频,这样分别使用两者的区别在哪:,Jack)。FCLK 与 HCLK 的区别在于 CPU 休眠断供 HCLK 时,FCLK 仍驱动中断查询等唤醒逻辑(STM32中的FCLK和HCLK时钟的区别,Jack)。启动文件的栈按 8 字节对齐(老师,我们单片机的栈在使用时,是多少字节对齐,Jack)。
二、分散加载、重定位与存储布局
- 分散加载 vs 重定位:分散加载决定 .data 最终放 RAM 哪个地址(链接期,Keil 里的 scatter file);重定位是启动时把 .data 从 FLASH 拷到 RAM 并修正引用(运行期)(老师,这里为什么不是分散加载,,Jack)。
- RW/ZI 不能放 Flash 执行:全局变量运行中频繁修改,Flash 只能整扇区擦写,放 Flash 会拖垮速度(老师 有个问题 rw和zi段可以不放在sram,Jack)。
- 单片机选 NOR Flash:NOR 支持字节级随机读取、可 XIP 直接执行代码,适合存程序;NAND 按块寻址,适合大容量数据存储(老师,单片机一般使用 NOR Flash 还是 NAND Flash?为什么,Jack;完整启动链见 上电复位 ↓ 硬)。
- 内部 Flash vs EEPROM 存临时数据:内部 Flash 写入要解锁/上锁/关中断,写多了持续十到近百毫秒,高实时系统无法接受;但 Bootloader 跳转时用内部 Flash 做标志位没问题——那时没有任务在跑(老师,为什么内部flash空间还有剩余,我们却依然要去eeprom存储一些临时数据,Jack)。擦除内部 Flash 后死机是常见实操问题(stm32擦除内部flash后死机,死在第二张图有人遇到过,不破不立)。
- 固件加密烧写流程:先把密文搬进内部 RAM 解密,再刷入内部 Flash(一般是先把密文搬运到内部ram,然后内部ram进行解密,再刷入内部flash,Jack)。
- OTA 与双 Bank:支持双 Bank 的 MCU 才能做 A/B bank 冗余回滚,Flash 需求也更大;不支持双 Bank 只能搬移覆盖(老师,支持双bank的MCU才,Jack1024)。通过以太网做 IAP(在应用中编程)有官方手册可查(这本手册主要介绍了STM32Cube 固件通过以太网实现 :在应用中编程:,立芯嵌入式)。
- 外部存储控制器:STM32 叫 FSMC/FMC,GD32/HC32 叫 EXMC,N32 有时也叫 EXMC(EXMC = External,Jack)。
三、总线与启动模式的冷知识
- STM32F411 中 D-BUS 能否访问 SRAM 取决于启动方式:从 SRAM 启动时 SRAM 物理地址 0x20000000 被映射到 0,D-BUS 才能访问(STM32F411中D-BUS可以访问到SRAM,高耦合)。D-Code 总线与 SRAM 的关系是高频疑问(各位大佬好,有个问题想请教一下。D-Code是否可以访问SRAM数据?如图一所写,🍊)。
- 汇编层面:PC 装即将执行的指令地址,LR 装函数返回后要执行的地址(老师,PC和LR寄存器的理解不够透彻,能再说下,Jack);"清除 R3"实际是读 R3 指向的内存到 R0、清最低位再写回——ARM 的算术逻辑操作只能在寄存器间进行(老师,为什么清除R3的值会这么麻烦,把值给r0 清除r0的值然后再赋值给R3,Jack)。
- C 类型长度平台相关:标准只规定
char ≤ int ≤ long的大小关系,int 在 32 位 STM32 是 4 字节、16 位 8051 上可能 2 字节(char 类型在 C 标准中是 1 字节(通常为 8 位,Jack)。
四、调试与下载故障速查
| 现象 | 原因/对策 | 来源 |
|---|---|---|
| 卡死后 JLink 检测不到芯片,复位后能检测到 | DAP 时钟已停、JTAG 状态机无法对频(RCC 时钟故障);可用 CmBacktrace 打栈回溯(需外挂 Flash 存日志)、外接 trace 非侵入调试 | 请问单片机卡死,同时jlink链接无法检测到芯片,复位后可以检测得到(Jack) |
| HardFault 中 LR = 0xFFFFFFF1 | 进入 HardFault 前已处于中断中:线程 → 中断 → HardFault | 当你在错误中断(Hardfault)中看到LR是0xFFFFFFF1时(Jack) |
| CmBacktrace 错误处理函数为何能收参数 | 汇编里把 LR/SP 存入寄存器传参 | 老师,Cmbacktrace中这个错误处理这个函数为什么能传函数参数(Jack) |
| JLink 下载失败 | 调低 JLink 频率(如 5kHz) | 遇到单片机Jlink下载失败,如下图片怎么办(Jack) |
| SWD 引脚复用成 GPIO 后无法烧录 | 初始化 GPIO 前读引脚电平,为高则留作下载口不配置;SWD 冲突的本质是"不要初始化串口/外设" | 问题1: gpio如果是复用成swd用做jlink烧录,它在建立通信的时候、烧录引脚和GPIO共用了咋整?(Jack) |
| CubeMX 打开生成文件报错 | 未安装对应芯片包(F1/F4 各装各的) | 老师,打开cubemx生成的文件,结果是这样,是哪里没有安装(Jack) |
| MPU 保护数组越界 | 高级玩法:用 MPU 保护数组周围地址,越界立即 HardFault,离线调试利器 | 问:有点疑问,我们用 MCU,裸机或者用RTOS,不是都可以至今访问硬件么(Jack) |
来源笔记
- 上电复位 ↓ 硬 | Jack
- boot引脚的三种不同连接方式对应的三种不同的启动方式 | Jack
- BOOT的三种启动方式里面,系统存储器模式是从内部ROM中的出厂代码启动 | Jack
- 老师,单片机从flash启动过程中,没有设置中断向量表地址 | Jack
- 重定位的用处: 1.进入用户空 | Jack
- 老师,请教下,单片机启动的时候是先用内部晶振 | Jack
- HSE和HSI都可以将APB总线配置为满频,这样分别使用两者的区别在哪: | Jack
- STM32中的FCLK和HCLK时钟的区别 | Jack
- 老师,我们单片机的栈在使用时,是多少字节对齐 | Jack
- 老师,这里为什么不是分散加载, | Jack
- 老师 有个问题 rw和zi段可以不放在sram | Jack
- 老师,单片机一般使用 NOR Flash 还是 NAND Flash?为什么 | Jack
- 老师,为什么内部flash空间还有剩余,我们却依然要去eeprom存储一些临时数据 | Jack
- stm32擦除内部flash后死机,死在第二张图有人遇到过 | 不破不立
- 一般是先把密文搬运到内部ram,然后内部ram进行解密,再刷入内部flash | Jack
- 老师,支持双bank的MCU才 | Jack1024
- 这本手册主要介绍了STM32Cube 固件通过以太网实现 :在应用中编程: | 立芯嵌入式
- EXMC = External | Jack
- STM32F411中D-BUS可以访问到SRAM | 高耦合
- 各位大佬好,有个问题想请教一下。D-Code是否可以访问SRAM数据?如图一所写 | 🍊
- 老师,PC和LR寄存器的理解不够透彻,能再说下 | Jack
- 老师,为什么清除R3的值会这么麻烦,把值给r0 清除r0的值然后再赋值给R3 | Jack
- char 类型在 C 标准中是 1 字节(通常为 8 位 | Jack
- 请问单片机卡死,同时jlink链接无法检测到芯片,复位后可以检测得到 | Jack
- 当你在错误中断(Hardfault)中看到LR是0xFFFFFFF1时 | Jack
- 老师,Cmbacktrace中这个错误处理这个函数为什么能传函数参数 | Jack
- 遇到单片机Jlink下载失败,如下图片怎么办 | Jack
- 问题1: gpio如果是复用成swd用做jlink烧录,它在建立通信的时候 | Jack
- 烧录引脚和GPIO共用了咋整? | Jack
- 老师,打开cubemx生成的文件,结果是这样,是哪里没有安装 | Jack
- 问:有点疑问,我们用 MCU,裸机或者用RTOS,不是都可以至今访问硬件么 | Jack