Bootstrap

文件系统的作用

在一个完整的嵌入式系统中,进行一个简单的操作(如读取传感器数据并保存到文件)通常会涉及多个步骤。这些步骤包括硬件初始化、数据采集、处理、存储以及与外部系统交互。以下是一个通用的操作流程及文件系统在其中的作用。


嵌入式系统的操作流程

读取传感器数据并保存到文件为例,整个流程分为以下几步:

1. 系统启动和初始化
  • 硬件初始化

    • MCU 启动,从闪存加载固件到 RAM。
    • 初始化系统时钟、GPIO、通信总线(如 I2C/SPI)。
    • 启动设备驱动程序,准备传感器和存储设备。
  • 文件系统挂载

    • 如果系统中使用了闪存,需要挂载文件系统(如 LittleFS、SPIFFS)。
    • 检查文件系统是否存在或是否损坏,必要时格式化。

文件系统作用:
此时,文件系统确保存储介质上的数据结构合法,并为后续操作提供读写接口。


2. 数据采集
  • MCU 通过传感器驱动程序(I2C/SPI/ADC 等)采集数据。
  • 对采集到的原始数据进行简单处理或过滤(如单位转换、去噪等)。

文件系统作用:
此步与文件系统无直接关系,数据尚未存储。


3. 数据处理
  • 将采集到的数据存储到内存(RAM)中。
  • 可能进行进一步处理,如:
    • 数据格式化(JSON、二进制、CSV 等)。
    • 数据合并或压缩,减少存储需求。

文件系统作用:
此步仍与文件系统无直接关联,但准备好数据后会调用文件系统接口进行存储。


4. 数据存储(与文件系统密切相关)
  • 文件操作过程:

    1. 打开文件:
      lfs_file_open(&lfs, &file, "data.txt", LFS_O_WRONLY | LFS_O_CREAT);
      
      文件系统根据文件名检查是否存在,如果不存在则创建。
    2. 写入数据:
      lfs_file_write(&lfs, &file, buffer, size);
      
      文件系统将数据写入指定文件,并处理底层的闪存写入。
    3. 关闭文件:
      lfs_file_close(&lfs, &file);
      
      文件系统刷新数据到物理存储器并关闭文件,确保数据一致性。
  • 额外操作:

    • 如果存储设备满了,文件系统可以管理文件删除、重命名等操作。

文件系统作用:
文件系统在这一阶段负责:

  1. 抽象存储操作,使开发者只需关注文件接口而非底层闪存操作。
  2. 数据可靠性,通过日志结构和磨损均衡保证存储器寿命和数据一致性。

5. 数据上传(可选)
  • MCU 将存储在闪存中的文件通过通信模块(如 WiFi、BLE、UART)发送到外部系统。
  • 发送后,可选择清理文件系统中的旧数据。

文件系统作用:
文件系统提供文件的读取接口,用于发送前的数据加载。例如:

lfs_file_open(&lfs, &file, "data.txt", LFS_O_RDONLY);
lfs_file_read(&lfs, &file, buffer, size);
lfs_file_close(&lfs, &file);

6. 系统待机或继续操作
  • MCU 进入低功耗模式或等待下一次采集任务。
  • 文件系统挂载状态保留,或在低功耗模式中卸载以节省资源。

文件系统作用:
文件系统需要确保在下一次挂载时仍能正常访问数据。


文件系统在流程中的关键作用

  1. 初始化阶段

    • 格式化或挂载存储介质,确保文件系统有效。
    • 提供 API,方便后续读写操作。
  2. 数据写入阶段

    • 负责将数据从 RAM 转移到闪存。
    • 提供原子性操作,避免数据丢失或损坏。
    • 管理闪存的磨损均衡,延长设备寿命。
  3. 数据读取阶段

    • 提供文件读取接口,用于上传或处理存储的数据。
  4. 系统维护阶段

    • 管理存储空间(如删除旧文件)。
    • 在设备重启后确保数据一致性。

流程总结图

[启动与初始化]
    |
    +---> 挂载文件系统
    |
[数据采集]
    |
[数据处理]
    |
[数据存储 (文件系统核心操作)]
    |
[数据上传/读取]
    |
[系统待机或下一循环]

例子代码:完整实现

#include "lfs.h"

// LittleFS 配置
struct lfs_config cfg = {
    .read = flash_read,
    .prog = flash_prog,
    .erase = flash_erase,
    .sync = flash_sync,
    .block_size = 512,
    .block_count = 1024,
    .cache_size = 64,
    .lookahead_size = 64,
};

lfs_t lfs;           // 文件系统对象
lfs_file_t file;     // 文件对象

void main() {
    // 系统初始化
    system_init();
    sensor_init();

    // 文件系统挂载
    if (lfs_mount(&lfs, &cfg)) {
        lfs_format(&lfs, &cfg);
        lfs_mount(&lfs, &cfg);
    }

    // 数据采集
    int sensor_data = read_sensor();

    // 数据处理
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "Sensor Value: %d\n", sensor_data);

    // 数据存储
    lfs_file_open(&lfs, &file, "data.txt", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND);
    lfs_file_write(&lfs, &file, buffer, strlen(buffer));
    lfs_file_close(&lfs, &file);

    // 系统待机
    lfs_unmount(&lfs);
    system_sleep();
}

;