在一个完整的嵌入式系统中,进行一个简单的操作(如读取传感器数据并保存到文件)通常会涉及多个步骤。这些步骤包括硬件初始化、数据采集、处理、存储以及与外部系统交互。以下是一个通用的操作流程及文件系统在其中的作用。
嵌入式系统的操作流程
以读取传感器数据并保存到文件为例,整个流程分为以下几步:
1. 系统启动和初始化
-
硬件初始化:
- MCU 启动,从闪存加载固件到 RAM。
- 初始化系统时钟、GPIO、通信总线(如 I2C/SPI)。
- 启动设备驱动程序,准备传感器和存储设备。
-
文件系统挂载:
- 如果系统中使用了闪存,需要挂载文件系统(如 LittleFS、SPIFFS)。
- 检查文件系统是否存在或是否损坏,必要时格式化。
文件系统作用:
此时,文件系统确保存储介质上的数据结构合法,并为后续操作提供读写接口。
2. 数据采集
- MCU 通过传感器驱动程序(I2C/SPI/ADC 等)采集数据。
- 对采集到的原始数据进行简单处理或过滤(如单位转换、去噪等)。
文件系统作用:
此步与文件系统无直接关系,数据尚未存储。
3. 数据处理
- 将采集到的数据存储到内存(RAM)中。
- 可能进行进一步处理,如:
- 数据格式化(JSON、二进制、CSV 等)。
- 数据合并或压缩,减少存储需求。
文件系统作用:
此步仍与文件系统无直接关联,但准备好数据后会调用文件系统接口进行存储。
4. 数据存储(与文件系统密切相关)
-
文件操作过程:
- 打开文件:
文件系统根据文件名检查是否存在,如果不存在则创建。lfs_file_open(&lfs, &file, "data.txt", LFS_O_WRONLY | LFS_O_CREAT);
- 写入数据:
文件系统将数据写入指定文件,并处理底层的闪存写入。lfs_file_write(&lfs, &file, buffer, size);
- 关闭文件:
文件系统刷新数据到物理存储器并关闭文件,确保数据一致性。lfs_file_close(&lfs, &file);
- 打开文件:
-
额外操作:
- 如果存储设备满了,文件系统可以管理文件删除、重命名等操作。
文件系统作用:
文件系统在这一阶段负责:
- 抽象存储操作,使开发者只需关注文件接口而非底层闪存操作。
- 数据可靠性,通过日志结构和磨损均衡保证存储器寿命和数据一致性。
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 进入低功耗模式或等待下一次采集任务。
- 文件系统挂载状态保留,或在低功耗模式中卸载以节省资源。
文件系统作用:
文件系统需要确保在下一次挂载时仍能正常访问数据。
文件系统在流程中的关键作用
-
初始化阶段:
- 格式化或挂载存储介质,确保文件系统有效。
- 提供 API,方便后续读写操作。
-
数据写入阶段:
- 负责将数据从 RAM 转移到闪存。
- 提供原子性操作,避免数据丢失或损坏。
- 管理闪存的磨损均衡,延长设备寿命。
-
数据读取阶段:
- 提供文件读取接口,用于上传或处理存储的数据。
-
系统维护阶段:
- 管理存储空间(如删除旧文件)。
- 在设备重启后确保数据一致性。
流程总结图
[启动与初始化]
|
+---> 挂载文件系统
|
[数据采集]
|
[数据处理]
|
[数据存储 (文件系统核心操作)]
|
[数据上传/读取]
|
[系统待机或下一循环]
例子代码:完整实现
#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();
}