第一次接触嵌入式开发时,我也曾天真地认为删除Flash数据就像在电脑上清空回收站那么简单。直到某次固件升级把设备刷成砖头,才明白Flash存储器的擦除操作藏着大学问。普通硬盘删除文件只是修改文件索引,而Flash擦除却是实打实的物理操作——这就像用铅笔在纸上写字和用凿子在石板上刻字的区别。
Flash存储器的物理特性决定了它必须按块擦除。想象Flash是由无数个小格子组成的笔记本,每个格子初始状态都是1。写入数据相当于把某些格子改成0,但想把0改回1,必须整页撕掉重写。这就是为什么flash_erase命令必须指定128KB整数倍的起始地址——Flash的擦除粒度就是这么大。
MTD(Memory Technology Device)子系统在Linux中专门管理这类特殊存储器。我曾用cat /proc/mtd查看过开发板的Flash分区,输出结果里的erasesize字段赫然显示131072(即128KB)。这个数字不是随便定的,它直接对应Flash芯片的物理擦除单元大小。强行按非对齐地址擦除,就像试图撕开半页纸,结果只会导致整页损坏。
实际项目中我用过这样的命令:
bash复制flash_erase /dev/mtd3 0x80000 3
这个操作就像外科医生的三刀:
/dev/mtd3确定手术部位0x80000精确下刀位置(512KB处)3控制切除范围(3个擦除块)特别注意起始地址必须像棋盘格子一样对齐。有次我误用0x70000地址,系统直接报错Erase block start not aligned。后来用mtdinfo工具查看,发现这个Flash的擦除块大小确实是128KB,所以地址必须是0x20000的整数倍。
给物联网设备做远程升级时,我最爱用lock参数:
bash复制flash_erase /dev/mtd5 0x0 1 lock
这相当于给Flash区域上了把锁,防止意外写入。有次系统崩溃时,正是这个功能保护了关键配置分区。解锁时需要用flash_unlock命令,就像需要钥匙才能打开的保险箱。
我的血泪教训:某智能电表项目因为频繁小数据更新,导致Flash半年就报废。后来用flash_erase配合nandwrite优化写入策略,寿命提升10倍。这是因为Flash必须先擦除再写入,频繁局部更新会引起"写放大"——实际物理写入量远大于逻辑写入量。
合理的使用姿势应该是:
在劣质Flash芯片上工作时,我养成了这样的操作习惯:
bash复制flash_erase --badblocks /dev/mtd2 0x0 64
这个--badblocks选项会自动跳过坏块,就像扫地机器人避开家具。配合dmesg查看内核日志,能清晰看到坏块标记过程。记得有块开发板出厂时有3个坏块,正是靠这个方法避免了数据写入黑洞。
给工业控制器升级时,老板问我:"擦除16MB Flash要多久?"现场实测数据供参考:
建议关键操作前先用单块测试:
bash复制time flash_erase /dev/mtd0 0x0 1
这个time命令会显示实际耗时,避免产线停等超时。
某次批量烧录时,误操作擦除了存有MAC地址的分区。现在我的自动化脚本都会先检查:
bash复制if grep -q "config" /proc/mtd; then
dd if=/dev/mtd4 of=/tmp/config_backup.bin
fi
这个dd备份操作就像手术前的CT扫描,关键时刻能救命。特别注意要备份的MTD分区是否包含ro(只读)标志,有些校准数据一旦丢失就无法恢复。