2. STM32启动模式与系统存储器
在量产测试与自动化烧录场景中,理解STM32的启动模式是决定“从哪里烧、怎么烧、烧完从哪里跑”的根本前提。STM32的启动入口并非固定,而是由复位时BOOT引脚的电平组合决定,芯片内部据此把不同物理存储区映射到启动地址空间。对产线而言,这意味着同一颗芯片可以进入用户Flash运行、进入系统存储器执行出厂Bootloader,或进入内嵌SRAM执行临时程序。掌握这三条路径的切换条件,才能设计出可靠的量产入口。
一、BOOT引脚与启动模式选择
以常见的STM32F1/F4系列为例,复位释放瞬间,芯片会锁存BOOT0与BOOT1(部分型号为BOOT1/nBOOT1或仅BOOT0)的电平,并据此选择启动区域。典型组合如下:
| BOOT1 | BOOT0 | 启动模式 | 映射到0x0000_0000的区域 |
|---|---|---|---|
| x | 0 | 主Flash启动 | 用户Flash(0x0800_0000) |
| 0 | 1 | 系统存储器启动 | 系统存储器(出厂Bootloader) |
| 1 | 1 | 内嵌SRAM启动 | SRAM(0x2000_0000) |
需要特别注意的是,BOOT引脚只在复位采样时刻有效,运行中改变电平不会立即切换启动区,必须配合复位。因此产线若用GPIO或跳线控制BOOT0,应在复位前建立稳定电平,并在复位释放后保持足够时间。对于BOOT0悬空易受干扰的设计,建议加下拉电阻(如10kΩ)确保默认从Flash启动,避免上电误入Bootloader。
二、系统存储器与内置Bootloader协议
系统存储器是ST在出厂时写入并锁定的区域,用户不可擦写,其中存放着各系列对应的Bootloader。它支持通过USART、CAN、USB DFU、I2C、SPI等接口接收固件。以最常用的USART Bootloader为例,其协议基于“命令—应答”机制:上位机先发送0x7F进行自动波特率同步,芯片回0x79表示ACK;随后每条命令由“命令字节+取反校验”两字节组成,芯片同样以ACK/NACK回应。
常用命令包括:
- 0x00 Get:读取Bootloader版本及支持的命令列表,用于确认芯片是否处于Bootloader状态。
- 0x31 Write Memory:写入数据到指定地址,是烧录的核心命令。
- 0x43 Go:跳转到指定地址执行,用于烧录完成后启动用户程序。
- 0x21 Erase:按页或全片擦除,量产中通常先擦后写。
每条Write Memory命令的负载包含地址(4字节+校验)、数据长度N(1字节+校验,N最大256)、N字节数据及校验和。上位机需按此格式组包,并逐条等待ACK。若收到NACK,应重发或检查波特率、校验和与地址对齐。
// USART Bootloader 写内存命令帧示例(地址0x08000000,写4字节)
发送: 0x31 0xCE // Write Memory 命令 + 取反校验
接收: 0x79 // ACK
发送: 0x00 0x00 0x08 0x00 0xF7 // 地址 0x08000000 + 校验
接收: 0x79
发送: 0x04 0xFB // 长度4 + 校验
接收: 0x79
发送: 0x11 0x22 0x33 0x44 0x00 // 数据 + 校验和(0x00为示例)
接收: 0x79
三、系统存储器映射与量产入口选择
理解映射关系是选择量产入口的关键。复位后,芯片把所选启动区映射到0x0000_0000,同时该区仍保留其原始别名地址(如Flash在0x0800_0000)。因此用户程序的中断向量表必须位于启动区起始处,或在程序开头通过SCB->VTOR重定位向量表。若从系统存储器启动,Bootloader会占用0x0000_0000,用户程序需烧到Flash并在Go命令中指定入口地址。
在量产入口选择上,通常有三条策略。第一,调试器批量烧录:用SWD多路夹具直接写Flash,速度快、可控性强,适合大批量。第二,Bootloader串口烧录:产线只留UART测试点,通过上位机脚本进入系统存储器烧录,适合无调试器接口或已封壳的产品。第三,先烧测试固件再烧正式固件:利用SRAM启动运行临时测试程序,验证引脚与供电后再写入正式固件。
四、量产入口的实操判断
实际产线中,判断芯片是否成功进入Bootloader,可通过上位机发送0x7F后是否收到0x79来确认。若连续无响应,应检查:BOOT0是否在复位时被正确拉高、串口TX/RX是否交叉连接、波特率是否匹配(Bootloader自动波特率通常支持1200~115200)、以及芯片是否被读保护(RDP)锁定。若收到NACK,优先核对命令字节与取反校验是否成对、地址是否4字节对齐、数据长度是否超过256。
烧录完成后,通过0x43 Go命令跳转到用户程序入口(通常为0x0800_0000),并观察串口是否输出预期启动日志或心跳。若跳转后无反应,需确认写入地址与链接脚本一致、向量表已重定位、以及BOOT0是否已恢复为低电平以便下次上电从Flash启动。只有把“启动模式—协议交互—映射关系—结果判读”串成闭环,量产入口才真正可控。