STM32WLE5基于SRAM存储数据的固件远程更新方案咨询
STM32WLE5 SRAM转Flash固件更新实操步骤
一、先验证SRAM中固件的有效性
- 对比校验值:用CRC32或SHA256计算SRAM中固件数据的哈希值,和服务器下发的校验码匹配,排除传输错误
- 检查固件头:确认固件开头的**初始栈指针(SP)**在STM32WLE5的合法地址范围(Flash或SRAM),复位向量地址指向有效的Flash代码区域(避免跳转到非法地址)
二、准备Flash擦写的安全环境
- 关闭全局中断:执行
__disable_irq();,防止擦写过程被中断打断引发硬件异常 - 禁用外设与DMA:关闭所有正在运行的外设时钟、DMA通道,避免干扰Flash控制器操作
- 解锁Flash控制器:STM32 Flash默认锁定,需执行解锁序列:
FLASH->KEYR = 0x45670123; // FLASH_KEY1 FLASH->KEYR = 0xCDEF89AB; // FLASH_KEY2
注:WLE5的Flash寄存器KEY值与大部分STM32通用,若有差异以官方手册为准
三、擦除并写入目标Flash区域
- 确定擦除扇区:根据你的应用分区规划,找到要更新的Flash扇区(比如主应用区对应的扇区),执行扇区擦除操作:
FLASH->CR |= FLASH_CR_SER; // 启用扇区擦除 FLASH->CR |= (扇区号 << FLASH_CR_SNB_Pos); // 指定要擦除的扇区 FLASH->CR |= FLASH_CR_STRT; // 触发擦除 while (FLASH->SR & FLASH_SR_BSY); // 等待擦除完成 FLASH->CR &= ~FLASH_CR_SER; // 关闭扇区擦除模式
- 逐字写入Flash:STM32 Flash要求32位对齐写入,循环读取SRAM中的固件数据,写入目标Flash地址:
uint32_t* src_addr = (uint32_t*)SRAM_FIRMWARE_START; uint32_t* dest_addr = (uint32_t*)FLASH_APP_START; uint32_t firmware_size = FIRMWARE_SIZE / 4; // 按32位字计算数量 for (uint32_t i = 0; i < firmware_size; i++) { FLASH->CR |= FLASH_CR_PG; // 启用编程模式 *dest_addr++ = *src_addr++; // 写入一个32位字 while (FLASH->SR & FLASH_SR_BSY); // 等待写入完成 FLASH->CR &= ~FLASH_CR_PG; // 关闭编程模式 }
四、验证Flash写入结果
- 逐字节比对SRAM固件与Flash内容,确保每个字节都一致,排除写入错误
- 重新锁定Flash控制器:执行
FLASH->CR |= FLASH_CR_LOCK;,防止后续误操作
五、切换至新固件运行
- 更新向量表偏移(如果新固件不在Flash默认起始地址):
SCB->VTOR = FLASH_APP_START; // 设置向量表基地址为新固件起始地址
- 跳转到新固件的复位向量:
typedef void (*pFunction)(void); uint32_t jump_sp = *(uint32_t*)FLASH_APP_START; // 读取新固件的初始SP uint32_t jump_addr = *(uint32_t*)(FLASH_APP_START + 4); // 读取复位向量地址 pFunction jump_to_app = (pFunction)jump_addr; __set_MSP(jump_sp); // 设置主栈指针 jump_to_app(); // 跳转到新固件
关键注意事项
- SRAM分区规划:STM32WLE5的SRAM范围是
0x20000000~0x2000FFFF(64KB),要确保固件存入的地址不覆盖当前应用的栈、堆区域,建议用高地址段(比如0x2000C000之后)存储固件 - 固件格式:必须是编译后的二进制文件(.bin),直接按地址写入Flash,不能用hex或elf格式
- 电源保障:Flash擦写过程中绝对不能断电,建议在更新前检测电源电压,确保供电稳定
内容的提问来源于stack exchange,提问作者Foreen
相关产品推荐
相关产品推荐

