单片机Flash为何写坏?掉电保护怎么做?
参数偶尔丢失或升级后配置变乱,常常不是存储单元突然坏了,而是写入流程没有尊重 Flash 的物理边界。单片机内部 Flash 若把擦写粒度和掉电窗口处理得太粗,少量配置也会被写成高风险操作。
Flash 写坏首先来自擦写粒度不等于变量粒度。应用只想改一个计数值,硬件可能必须先擦掉整页,再把同页里其他配置搬回去;擦除期间页面全为无效态,写入又只能按字或半页逐步完成。若多个参数、版本号和校验字混在同一页,任何一次小改动都会牵动整页寿命。频繁保存运行计数、故障码或通信参数时,单页很快接近擦写上限,表现为某些位只能写不能擦,配置开始出现随机错码。
磨损控制不能只在快到寿命时才想。把高频变化的数据与低频配置分区,给计数类数据做循环日志或磨损均衡,并在记录里加入序号和校验,才能避免一页被反复打穿。写之前还要比较新旧值,没变化就不要擦写;对必须频繁更新的状态,优先考虑 EEPROM、FRAM 或带掉电保持的备份域。单片机资源紧张时尤其要警惕把日志、参数和升级标记挤在同一页,因为省下的空间会在可靠性上还回来。
掉电窗口决定写入是否能被解释。电源下陷时,擦除可能已经完成,数据还没写回;校验字可能先写了,正文还缺几个字;也可能新记录写了一半,旧记录又被提前删除。若启动代码只按一个成功标志判断,就会把半成品当成有效配置。更危险的是,电压不足时继续写 Flash,编程电流和时序都可能不满足要求,留下的不是干净失败,而是难以预测的位错误。
稳妥的提交方式是双份或日志化,而不是原地覆盖。先把新记录写到空槽,正文、序号和校验全部完成后,再写一个最后提交标志;启动时按序号和校验选择最新有效记录。如果掉电发生在中间,旧记录仍能解释系统状态。写入前还应检查电源良好信号,棕断阈值要高于 Flash 最低编程电压,并预留足够保持时间完成当前最小写入单元。记录格式还要能识别全空页和半写页,不能把擦除态误认为默认有效值。单片机固件里这套流程看似啰嗦,却能把随机掉电转化为可恢复的事务失败。
验证时应故意在擦除前、擦除后、写正文、写校验和写提交标志各阶段切断电源,然后反复上电检查恢复结果。只做正常写入和一次重启,几乎无法覆盖最危险的窗口。还要在高温、低压和接近寿命的样片上复测,因为写入时间和失败概率都会改变。若系统允许在线升级,还要把升级镜像、运行参数和回滚标志分开注入故障,确认其中任一块损坏都不会拖垮启动路径。测试还应覆盖连续多次掉电,避免日志指针被反复推进到无效区。只有每个断点都能回到旧配置或新配置之一,才说明掉电保护真的闭合。
因此,Flash 可靠性不靠少写一句配置保存函数。把物理页、寿命和提交原子性一起设计,掉电才只会丢掉本次更新,不会毁掉系统状态。





