站内搜索
更多
FlashStore: 极简 A/B 分区配置存储方案

分类

技术干货

FlashStore: 极简 A/B 分区配置存储方案

原创
11
0
0
0

简介

简介:
更新时间:2026-07-31 09:40:29

FlashStore A/B Partition

A/B 双页 Flash 存储,面向小型 MCU。零依赖,28 bytes RAM。
https://github.com/createskyblue/flashstore-ab-partition

选哪个?

FlashStoreFlashDBLittleFS
定位单块配置可靠存储嵌入式键值数据库嵌入式文件系统
数据模型整块二进制键值对文件
读写方式Save/Load 整块Set/Get 按 keyOpen/Read/Write
磨损均衡
掉电保护✅ 双页冗余✅ 事务日志
RAM28 bytes极低较高(缓冲区)
适用配置参数,低频更新多配置项独立读写文件、日志、大块数据

5 分钟接入

  1. 复制 include/flash_store.hsrc/flash_store.c。需要加密再加 chacha20xxtea
  2. 实现 3 个回调:
bool my_read(void *ctx, uint32_t addr, uint8_t *out, size_t len) {
    memcpy(out, (void *)(uintptr_t)addr, len);  // 或 HAL 读
    return true;
}
bool my_erase(void *ctx, uint32_t addr, size_t len) {
    HAL_FLASH_ErasePage(addr);                  // 整页擦除
    return true;
}
bool my_program(void *ctx, uint32_t addr, const uint8_t *data, size_t len) {
    // 按 word 编程,或 memcpy(支持字节寻址的 flash)
    return true;
}
  1. 初始化并读写:
FlashStore store;
FlashStore_Config cfg = {
    .io.read = my_read, .io.erase = my_erase, .io.program = my_program,
    .page_a_address = 0x0800FE00,
    .page_b_address = 0x0800FE80,
    .page_size      = 128,
};
FlashStore_Init(&store, &cfg);
FlashStore_Save(&store, data, len);   // 写
FlashStore_Load(&store, data, len);   // 读

需要加密?推荐 ChaCha20——RFC 8439 标准,流密码不分块不要求对齐。实测 Cortex-M0 -Os:700B Flash + ~200B 栈,0 静态 RAM。极致省资源用 XXTEA,仅混淆级别,要求 4 字节对齐且 ≥8 字节。加密在外部做:encrypt → FlashStore_Save / FlashStore_Load → decrypt

为什么不会丢数据

A 写完才写 B。 任意时刻断电,至少一份完整数据在 flash 上。

Save:  A 先 → B 后     Load: 读两页 → CRC 验 → 返回好的 → 顺手修坏的
断电在…ABLoad 结果
空闲v2v2返回 v2
写 A 中途v1返回 v1,修 A
A 完成,B 前v2 (CRC=c2)v1 (CRC=c1)CRC 不同→A 新→返回 v2,修 B
写 B 中途v2返回 v2,下次修 B
两页都坏ERROR_NO_VALID_DATA

WARN_REPAIR_FAILED?修复时 erase/program 失败,正常不会发生——收到应检查硬件。

Header 结构

每页 12 字节 header + payload:

偏移字段含义
0magic (4B)0x46534142
4length (4B)payload 大小
8crc32 (4B)payload CRC32

资源占用(Cortex-M0 -Os 实测)

模块Flash静态 RAM
flash_store596 bytes28 bytes~20 bytes
chacha20700 bytes0~200 bytes
xxtea737 bytes0~0

flash_store 明细:Load 158B / Init 108B / load_page 104B / save_page 92B / Save 66B / CRC32 52B。按需链接,不用就不占。

状态码

返回值含义
OK正常
ERROR_ARGUMENT参数错误
ERROR_WRITE擦除或编程失败
ERROR_NO_VALID_DATA两页都坏了
WARN_REPAIR_FAILED数据正确但冗余修复失败

测试

cmake -S . -B build && cmake --build build && ./build/flash_store_tests.exe

9 个测试覆盖:正常读写、A 坏回退 B、B 坏从 A 修、CRC 裁决新旧、双页全坏、修复失败告警、参数校验、MaxDataSize。

License

MIT

添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1
按时间排序|按热度排序

底部导航