banner
NEWS LETTER

嵌入式 Linux 系列 11:存储、Flash 寿命和异常断电保护

Scroll down

嵌入式设备经常被直接断电。配置文件、日志、数据库、升级状态如果没有设计好,异常断电后就可能损坏。存储设计不是文件能写进去就结束了,还要考虑写入频率、原子性和 Flash 寿命。

一、先区分存储类型

常见介质:

  • NOR Flash。
  • NAND Flash。
  • eMMC。
  • SD 卡。
  • SPI NAND。

常见文件系统:

  • ext4。
  • squashfs。
  • ubifs。
  • jffs2。
  • tmpfs。

只读 rootfs 常用 squashfs,配置和日志放到可写 data 分区。

二、哪些数据需要持久化

需要持久化:

  • 设备配置。
  • 网络配置。
  • 证书和密钥。
  • OTA 状态。
  • 关键业务数据。
  • 必要日志。

不适合持久化:

  • 高频 debug 日志。
  • 临时缓存。
  • 可从云端恢复的数据。
  • 运行时中间状态。

高频写入会影响 Flash 寿命。

三、原子写配置

不要直接覆盖配置文件。推荐:

1
2
3
4
写 tmp
-> fsync tmp
-> rename
-> fsync 目录

C 示例:

1
2
3
4
5
6
FILE *fp = fopen("/data/config/app.json.tmp", "w");
fputs(json, fp);
fflush(fp);
fsync(fileno(fp));
fclose(fp);
rename("/data/config/app.json.tmp", "/data/config/app.json");

这样断电后通常保留旧文件或新文件,不容易得到半个文件。

四、双备份配置

更稳的方式是保存两份:

1
2
app.json.a
app.json.b

每份带:

  • version。
  • sequence。
  • checksum。

启动时选择 checksum 正确且 sequence 最大的一份。

这对关键配置很有价值。

五、控制日志写入

日志要有上限:

1
2
3
app.log
app.log.1
app.log.2

不要无限写:

1
tail -f huge.log

也不要每秒刷大量状态日志到 Flash。调试版本可以多写,量产版本要控制频率。

六、异常断电测试

必须做断电测试:

  1. 写配置时断电。
  2. 写日志时断电。
  3. OTA 写入时断电。
  4. 第一次启动初始化 data 时断电。
  5. 数据库提交时断电。

测试后检查:

1
2
3
fsck
cat /data/config/app.json
ls -l /data/log

异常断电问题越早测越好,等设备部署后再遇到会很被动。

其他文章
目录导航 置顶
  1. 1. 一、先区分存储类型
  2. 2. 二、哪些数据需要持久化
  3. 3. 三、原子写配置
  4. 4. 四、双备份配置
  5. 5. 五、控制日志写入
  6. 6. 六、异常断电测试
请输入关键词进行搜索