ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

【嵌入式外设精学】Day17|Flash:页擦写、参数保存、掉电安全

【嵌入式外设精学】Day17|Flash:页擦写、参数保存、掉电安全 【嵌入式外设精学】Day17Flash页擦写、参数保存、掉电安全今天解决为什么不能像 RAM 随便写参数怎样存才抗掉电目录问题 2. 原理 3. 代码 4. 误区 5. 自测 6. 答案1. 问题存参数偶发坏写得很勤后来整片变砖2. 原理2.1 擦和写是两回事操作粒度意思擦页/扇区整块变“空白”写字/半字往空白里写改一个字节往往也要先擦整页再写回。2.2 寿命有限每块能擦写的次数有限常见万级到十万级看器件。不能每 10ms 存一次 PID。2.3 掉电安全双份 A/BA 页 / B 页都带“序号 校验” 保存写到“不是当前有效”的那一份 上电两份都读取校验过且序号大的这样写到一半掉电旧那份仍可用。3. 代码示例#includestdint.h#includestdbool.h#includestring.h#defineMAGIC0x5041524Dutypedefstruct{floatkp,ki,kd;}par_t;typedefstruct{uint32_tmagic;uint16_tver;uint16_tseq;par_tp;uint32_tcrc;}blob_t;/* 平台相关擦页、写、读、CRC */voidflash_erase_page(uint32_tpage);voidflash_write(uint32_taddr,constvoid*d,uint32_tn);voidflash_read(uint32_taddr,void*d,uint32_tn);uint32_tpage_addr(uint32_tpage);uint32_tcrc32_calc(constuint8_t*d,uint32_tn);staticvoidseal(blob_t*b){b-magicMAGIC;b-crccrc32_calc((constuint8_t*)b,(uint32_t)(sizeof(*b)-4u));}staticboolok(constblob_t*b){returnb-magicMAGICb-crccrc32_calc((constuint8_t*)b,(uint32_t)(sizeof(*b)-4u));}intparam_save(uint16_t*seq,constpar_t*in,uint32_tpage){blob_tb;memset(b,0,sizeof(b));b.seq(uint16_t)(*seq1u);b.p*in;seal(b);flash_erase_page(page);flash_write(page_addr(page),b,sizeof(b));*seqb.seq;return0;}boolparam_load(par_t*out,uint16_t*seq,uint32_tpage_a,uint32_tpage_b){blob_ta,b;flash_read(page_addr(page_a),a,sizeof(a));flash_read(page_addr(page_b),b,sizeof(b));if(ok(a)ok(b)){constblob_t*sel((int16_t)(a.seq-b.seq)0)?a:b;*outsel-p;*seqsel-seq;returntrue;}if(ok(a)){*outa.p;*seqa.seq;returntrue;}if(ok(b)){*outb.p;*seqb.seq;returntrue;}returnfalse;}保存时机按钮“保存参数”、关机前、模式切换——不要高频定时写。4. 常见误区误区正解Flash 当 EEPROM 随便改要擦写策略和寿命意识只存一份掉电可能半新半旧不加校验坏数据当参数用运行中频繁写寿命和掉电风险都大5. 自测双份 A/B 的好处为什么不能每圈都存 PID6. 答案写挂了还有旧有效数据取“校验过且更新”的那份。寿命不够且掉电时容易写坏应在明确“保存”时刻写。作者shuifanyu标签Flash掉电参数存储
返回列表