You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32启动时将RAM数据复制至Flash的实现步骤与原理问询

启动阶段RAM到Flash的复制:实现步骤与底层原理

先搞懂核心逻辑

Flash是非易失性只读存储,默认锁定防止误写,而且只能把存储单元的1改成0——要写入新数据,必须先擦除整页(把所有位恢复成1)。启动阶段把RAM内容复制到Flash,本质就是在系统刚启动时,把RAM里临时存的固件、配置数据之类的内容,持久化到Flash里,常见于固件升级、出厂数据烧录这类场景。

一步步实现(以STM32为例,其他MCU逻辑通用)

1. 提前摸清楚硬件参数

  • 查芯片手册,确定目标Flash的页大小、起始地址、总容量:比如STM32F103小容量型号是1KB/页,大容量是2KB/页,擦除和写入必须按页来。
  • 确认RAM中待复制数据的起始地址和长度:最好让数据长度是Flash页大小的整数倍,要是有零头,最后一页单独处理。

2. 解锁Flash控制器

Flash默认是锁死的,得先输密钥解锁。以STM32为例,操作FLASH_KEYR寄存器:

// STM32解锁示例
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;

原理:芯片厂商给Flash控制器设了密钥验证机制,只有写入正确的密钥序列,才能解除写保护,允许后续的擦除和写入操作。

3. 擦除目标Flash页

擦除是写入的前提,必须整页擦:

// STM32页擦除示例
while (FLASH->SR & FLASH_SR_BSY); // 等Flash空闲,忙的时候不能操作
FLASH->CR |= FLASH_CR_PER;        // 开启页擦除模式
FLASH->AR = FLASH_TARGET_PAGE_ADDR; // 指定要擦除的页起始地址
FLASH->CR |= FLASH_CR_STRT;       // 触发擦除
while (FLASH->SR & FLASH_SR_BSY); // 等擦完
FLASH->CR &= ~FLASH_CR_PER;       // 关闭页擦除模式

原理:Flash的存储单元是浮栅结构,擦除操作是给浮栅放电,把所有位恢复成逻辑1(也就是0xFF),这样才能后续写入(因为只能把1改成0)。

4. 从RAM往Flash写数据

按MCU的总线宽度(比如STM32是32位,按字写效率最高)循环写入:

// STM32按字写入示例
uint32_t *ram_src = (uint32_t *)RAM_DATA_START_ADDR;
uint32_t *flash_dst = (uint32_t *)FLASH_TARGET_START_ADDR;
uint32_t word_count = TOTAL_DATA_LEN / 4; // 按32位字计算数量

for (uint32_t i = 0; i < word_count; i++) {
    while (FLASH->SR & FLASH_SR_BSY); // 等空闲
    FLASH->CR |= FLASH_CR_PG;         // 开启编程模式
    *flash_dst++ = *ram_src++;        // 写入一个字
    while (FLASH->SR & FLASH_SR_BSY); // 等写入完成
    FLASH->CR &= ~FLASH_CR_PG;        // 关闭编程模式

    // 检查写入错误
    if (FLASH->SR & FLASH_SR_PGERR) {
        FLASH->SR |= FLASH_SR_PGERR; // 清错误标志
        // 这里加错误处理逻辑,比如停止复制、上报错误
        break;
    }
}

原理:编程时,Flash控制器给目标存储单元加高压,让浮栅捕获电子,对应位就变成0。每写完一个单元,必须关闭编程模式,防止误写。

5. 重新锁定Flash

操作完赶紧锁上,防止后续误操作:

FLASH->CR |= FLASH_CR_LOCK; // 锁定Flash控制器

必须注意的坑

  • 别被中断打断:启动阶段最好关中断,Flash操作被中断很容易出问题;要是非得开中断,把Flash操作的优先级设最高。
  • 电源要稳:擦除和写入Flash需要稳定的供电,电压波动可能直接搞坏Flash。
  • 写完要校验:复制完后,把Flash里的数据和RAM里的做CRC或者逐字节比对,确保没写错。
  • 别照搬代码:不同MCU的Flash寄存器不一样,比如NXP Kinetis系列的解锁序列、寄存器名称都和STM32不一样,一定要查自己芯片的参考手册。

内容的提问来源于stack exchange,提问作者Rakshit Sonawane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:27:32