文件系统模块
ElenixOS 使用统一的路径格式,即 POSIX-style 路径。所有文件操作都必须通过存储服务进行,系统内无法直接访问底层文件系统。
LVGL 文件系统集成
LVGL 文件系统驱动作为适配层工作:
- 拦截所有 LVGL 文件操作
- 将其转换为 eos_service_storage API 调用
- 确保所有文件访问都通过 ElenixOS 存储沙箱
架构
LVGL → FS driver → eos_service_storage → eos_fs_port
为什么 LV_FS_DEFAULT_DRIVE_LETTER 必须固定?
LVGL 使用"驱动器字母"机制(例如 'S:/path')来选择文件系统驱动。如果路径不包含驱动器字母,LVGL 会回退到 LV_FS_DEFAULT_DRIVE_LETTER。
在 ElenixOS 中:
- 向应用程序暴露单一的统一文件系统
- 所有路径应为 POSIX-style(例如 "/data/config.json")
- LVGL 驱动在内部处理驱动器字母转换
因此,LV_FS_DEFAULT_DRIVE_LETTER 必须指向 ElenixOS 驱动,否则 LVGL 可能会将文件操作路由到意外的后端。
#if LV_FS_DEFAULT_DRIVE_LETTER != EOS_LVGL_FS_LETTER
#error "LV_FS_DEFAULT_DRRIVE_LETTER must match EOS_LVGL_FS_LETTER"
#endif
路径处理
路径规范化
_storage_sanitize_path 函数确保所有路径都带有 EOS_SYS_ROOT_DIR 前缀:
- 如果路径已经包含系统根目录前缀,则保持不变
- 如果路径以 "/" 开头(绝对路径),则添加系统根目录前缀
- 如果路径是相对路径,则添加系统根目录前缀
JSON 存储 API
存储服务提供了一套完整的 JSON 文件操作接口,用于读取和修改 JSON 格式的配置文件。
加载 JSON 文件
从存储中加载 JSON 文件:
cJSON *eos_storage_json_load(const char *path);
返回 cJSON 根对象,失败时返回 NULL。
保存 JSON 文件
将 cJSON 对象保存到文件:
eos_result_t eos_storage_json_save(const char *path, cJSON *root);
布尔值操作
bool eos_storage_json_get_bool(const char *path, const char *key, bool default_value);
eos_result_t eos_storage_json_set_bool(const char *path, const char *key, bool value);
字符串操作
char *eos_storage_json_get_string(const char *path, const char *key, const char *default_value);
eos_result_t eos_storage_json_set_string(const char *path, const char *key, const char *value);
返回的字符串需要使用 eos_free 释放内存。
数值操作
double eos_storage_json_get_number(const char *path, const char *key, double default_value);
eos_result_t eos_storage_json_set_number(const char *path, const char *key, double value);
JSON 对象操作
cJSON *eos_storage_json_get_json(const char *path, const char *key);
eos_result_t eos_storage_json_set_json(const char *path, const char *key, cJSON *json_value);
返回的 cJSON 对象使用完后需要调用 cJSON_Delete 释放。
创建 JSON 文件
如果文件不存在,则创建包含默认内容的 JSON 文件:
eos_result_t eos_storage_json_create_if_not_exist(const char *path, const char *default_json);
文件系统操作
检查文件类型
bool eos_storage_is_dir(const char *path);
bool eos_storage_is_file(const char *path);
bool eos_storage_is_valid_filename(const char *name);
写入文件
向文件写入字符串(自动在末尾添加换行符):
eos_result_t eos_storage_puts(const char *s, eos_file_t fp);
创建目录
如果目录不存在,则创建:
eos_result_t eos_storage_mkdir_if_not_exist(const char *path);
递归创建目录树:
eos_result_t eos_storage_mkdir_recursive(const char *path);
创建文件
如果文件不存在,则创建并写入默认内容:
eos_result_t eos_storage_create_file_if_not_exist(const char *path, const char *default_content);
读取文件
将整个文件内容读入动态分配的缓冲区(仅适用于文本文件):
char *eos_storage_read_file(const char *path);
返回动态分配的缓冲区,使用完后需要使用 eos_free 释放。
写入文件
eos_result_t eos_storage_write_file(const char *path, const void *data, size_t data_size);
立即写入(绕过延迟写入器)
eos_result_t eos_storage_write_file_immediate(const char *path, const void *data, size_t data_size);
char *eos_storage_read_file_immediate(const char *path);
延迟文件写入器 (Deferred File Writer)
延迟文件写入器用于批量写入文件,减少频繁的 Flash 写入操作,延长 Flash 寿命。
工作原理
- 写入数据时,先写入缓冲区
- 调用
eos_dfw_sync()时,将缓冲区数据同步到文件系统
同步缓冲区到文件系统
void eos_dfw_sync(void);
写入数据
bool eos_dfw_write(const char *path, const uint8_t *data, size_t data_size);
返回 true 表示任务已添加到队列,将在下一次调用 eos_dfw_sync() 时写入文件。
读取文件数据
uint8_t *eos_dfw_read(const char *path);
成功返回文件内容,失败返回 NULL。需要手动释放返回的指针。
初始化
void eos_dfw_init(void);
LVGL 文件系统注册
注册 LVGL 文件系统驱动,将所有文件操作路由到 ElenixOS 存储服务:
void eos_lvgl_fs_register(void);