• 正文
  • 相关推荐
申请入驻 产业图谱

介绍一个轻量化的嵌入式存储方案!

22小时前
129
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

大家好,我是杂烩君。

本次介绍一个极致轻量化嵌入式存储方案 ——UTFS(μTFS,micro TAR File System)

UTFS简介

UTFS项目地址:https://github.com/clisystems/utfs

MIT 开源协议

UTFS 是一款类 TAR 归档、面向扁平字节寻址存储的极简存储层,不是完整带目录、日志、磨损均衡的通用文件系统。

其定位是手写固化结构体的标准化替代方案

UTFS的特点:

体积极小:仅utfs.c + utfs.h两个源码文件,纯 C99 实现;

移植门槛极低:只需要实现sys_readsys_write两个底层读写函数;

零动态内存:全程无malloc/free,全部静态内存,不占用堆;

向前兼容:后续新增参数文件,不会破坏原有存储布局,升级不丢旧数据;

极低存储开销:每个文件仅 24 字节固定头部,数据无填充、无对齐浪费;

UTFS 不是 FatFS / LittleFS。它不做目录树、不做 journaling、也不做磨损均衡:

持久化的坑

嵌入式开发中,参数持久化常见的坑:

    直接写固定偏移 EEPROM/Flash,新增配置就要全量改存储布局,旧固件数据直接报废;手写结构体固化,多组参数分开存储,地址管理混乱,断电校验全靠自己造轮子;引入 FatFS/LittleFS,ROM 占用大、必须堆内存AVR、STM8 这类小 RAM 芯片直接跑不动;

很多产品的真实需求其实很朴素:

    上电把几块配置读进 RAM运行中改结构体字段合适的时候整表写回 EEPROM / Flash

这时候如果硬上完整文件系统,目录、权限、长文件名这些给人看的能力,往往用不上,代码和 RAM 却先涨一截。

反过来,继续手搓一个巨型 struct 钉在 0x0000,短期最快,长期最容易在加字段那天翻车。

手搓固定偏移 vs UTFS

左边那种布局,每个字段的地址都是产品契约的一部分;

右边 UTFS 的思路是:

每个文自带 24 字节头,按名字匹配,数据背靠背排布。以后加一个 calib,旧文件还是按名字找,而不是全员挪偏移。

demo:Linux PC 快速验证

cd Examples/gcc_linux
make
./main.bin -v

整体使用逻辑:

utfs_set + utfs_register:把本地 RAM 结构体和文件名绑定注册;

utfs_load:上电从 EEPROM/Flash 读取所有注册数据到 RAM;

utfs_save:参数修改后,一次性全量写入持久化介质。

UTFS 到底长什么样

名字可以记成 micro TAR File System(μTFS / uTFS)。灵感来自 TAR:Header + Data 重复拼接。

桌面 TAR 头是 512 字节一块,嵌入式扛不住,也用不上用户/用户组/权限那一套。

UTFS 把头压到 24 字节,后面紧跟数据,文件之间没有 padding。

最小闭环:register → load → save

UTFS 的使用节奏和传统 open/read/write/close不太一样。它更像:

一次性登记关心的文件,整表加载,整表保存。

UTFS 生命周期

典型写法可以:

utfs_init(false);

utfs_set(&sysfile, "system",  &sysdata, sizeof(sysdata));
utfs_register(&sysfile, UTFS_NOFLAGS, UTFS_NOOPT);

utfs_set(&appfile, "appdata", &appdata, sizeof(appdata));
utfs_register(&appfile, UTFS_NOFLAGS, UTFS_NOOPT);

utfs_load();

if (utfs_file_signature(&appfile) != 0xABCD) {
    memset(&appdata, 0, sizeof(appdata));
    utfs_file_signature_set(&appfile, 0xABCD);
    appdata.test_value = 1234;   // 首启默认值
}

/* 业务里照常改 RAM 里的结构体……需要落盘时: */
utfs_save();

登记要持久化的东西,整表装进 RAM,改完再整表交回去。

中间业务代码不用围着文件系统 API转,继续写结构体字段就行。

移植缝也刻意留得很窄:库自己不做 I/O,实现两个函数就行:

uint32_t sys_write(uint32_t address, void *ptr, uint32_t length);
uint32_t sys_read (uint32_t address, void *ptr, uint32_t length);

EEPROM、片内 Flash、外部 SPI/I²C Flash,只要能按地址读写字节,就能接。

总结

UTFS 适合的场景:

    仅存储少量配置结构体(≤5 组参数),不需要日志、大文件存储;小容量存储:1KB~16KB EEPROM、片内 Flash 参数分区;

欢迎大家在评论区聊聊,交流一下你的看法~

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

本公众号专注于嵌入式技术,包括但不限于C/C++、嵌入式、物联网、Linux等编程学习笔记,同时,公众号内包含大量的学习资源。欢迎关注,一同交流学习,共同进步!