查看:
1072
|
回复:
0
|
【嵌入式SD NAND】基于FATFS/Littlefs文件系统的日志框架实现
|
雷龙发展
67
主题
6
回复 |
1#
电梯直达
文章目录【嵌入式】基于FATFS/Littlefs文件系统的日志框架实现 1. 概述 2. 设计概要 3. 设计实现 3.1 初始化 `init` 3.2 日志写入 `write` 3.3 日志读取 `read` 3.4 注销 `deinit` 3.5 全部代码汇总 4. 测试 5. 总结 1. 概述那么在移植好了文件系统之后,我们又应该如何应用文件系统呢? 很多人会说,这个简单,就操作文件嘛!open、read、write、close不就行了吗!当然对于简单的使用,掌握open、read、write、close,去存储一两个文件或者从一两个文件中简单的读取下数据这确实没有什么难度。但在实际应用中,特别是产品开发过程中,往往不只是简单的操作一两个文件就可以的,如果真是这样,那费那么大劲移植文件系统多少有点浪费! 在实际项目开发中,往往需要依托文件系统操作诸多的文件,操作诸多的数据。如通过配置文件配置机器设备信息、通过升级文件进行产品升级、通过存放字库文件实现多语言支持等等,这些都是比较简单的操作,读写不是很频繁,相对来说实现比较简单,还有一类需求读写会相当频繁,且大多数产品内都希望存在的,那便是日志文件,通过日志文件来记录设备的运行数据。日志文件不同于其他功能,其往往需要具备几个基本特性需求: 单个文件大小限制日志总大小空间占用限制自动循环覆盖 网上也有一些开源的日志框架,如 Log4j,不过大都是基于 java / c ++ 实现的,虽然功能比较全面,但比较繁杂,且也难以移植应用于嵌入式开发中。而在嵌入式开发中,可能也受限于资源限制,并没有发现不错的基于文件系统的开源日志框架(至少博主目前没有发现,有的话欢迎大家评论区讨论 ),对于如何实现一个日志框架很多人一下子可能没有头绪,综上,本文将分享一个简单的基于文件系统的日志程序以供大家思考。2. 设计概要我们需要实现的日志模块的核心需求为: 单个文件大小限制日志总大小空间占用限制自动循环覆盖对于一个模块,对外仅需提供其操作的接口即可,内部的算法实现均无需对外开放,而对于此日志模块,对外只需提供基本的以下四个接口即可: 初始化 init写日志 write读日志 read注销 deinit关于日志存储的核心思想如下: 写数据之前先判断当前操作的文件是否超出单个文件大小限制,如超出大小限制则进行日志轮转,创建一个新的日志文件并判断日志文件总大小是否超出限制,如果超出则删除最早的那一份日志文件 关于日志存储的详细设计如下: 日志文件格式采用:<filename>.log ,当当前文件达到单个文件大小之后,进行文件轮转; 假定当前限制日志每个日志文件大小为2048Byte,最多存储10个文件; 在日志模块源文件的代码中,我们可以看到实际每次操作文件的时候,都有调用一个函数锁操作,考虑到不同平台的锁操作实现不一样,因此将此部分通过函数导出来,放置在模块的端口文件中。不同的平台、系统根据各自的平台和系统的情况进行实现,如像裸机编程这类不需要进行锁操作的不进行函数实现即可。 日志模块端口头文件:simple_storage_port.c#ifndef __SIMPLE_STORAGE_PORT_H__#define __SIMPLE_STORAGE_PORT_H__ int log_file_init(void);int log_file_lock(void);int log_file_unlock(void); #endif /* __SIMPLE_STORAGE_PORT_H__ */ 日志模块端口源文件:simple_storage_port.h #include "simple_storage_port.h" int log_file_init(void){ return 0;} int log_file_lock(void){ return 0;} int log_file_unlock(void){ return 0;}4. 测试将以上代码进行运行测试,硬件平台如下: 控制器: stm32f103vet6,野火指南者开发板 存储芯片: CS创世 SD nand,型号:CSNP4GCR01-AMW 文件系统: FATFS,注意此日志不受文件系统限制 操作系统: RT-Thread,此模块与操作系统无关,此处只是方便使用故自行移植了rtthread
测试结果如下: msg> hello worldhello world hello world hello world hello world hello world hello world hello world hello world ...省略 msh > lstest.log 2046test.log.0 2046test.log.1 2046test.log.2 2046test.log.3 2046test.log.4 20465. 总结综上便是基于文件系统的简易日志模块设计的全部内容了,虽然简陋了点,但相信对于大部分没有接触过日志系统设计的人来说提供了很好的一条设计思路。 也正因为简易,给大家对于日志系统设计的优化留足了大量的优化空间。比如: 文件轮转的时候需要对每个文件的文件名进行修改,是否可以有更好的方式不用每个文件都修改呢? 文件名的设计是不方便阅读的,是否可以引入时间参数? 文件名设计如何引入了时间参数,当设备RTC备用电池掉电的时候又如何保证文件不会被错误覆盖? 文件的读取显然优化空间更大,实际上用户不应该传入rotate_num 参数,因为这是模块内部的参数,用户不可感知的 文件读取如何做到分多次读取一个文件的内容,且不会重复,是顺序读取? 等等,以上只是我简单想到的几点内容,大家不妨思考下如何实现方案更好呢?当然又还有哪些需求是需要引入的呢,也欢迎大家在评论区留言,关注我,后续抽时间再分享下改良版日志系统!!! 主营:CS创世 SD NAND(又叫贴片式 TF卡/贴片式SD卡)读写速度可达24/13 MB/S,韩国ATO Solution(SLC NAND、SPI NAND、MCP)、小容量TF卡存储芯片。
|
|