SeanLib系列函数库-SDCache

📅 2026/7/9 18:36:49
SeanLib系列函数库-SDCache
查看其它库函数说明请点击此处跳转到SeanLib主页1. 本篇内容在需要频繁地向SD卡中写入日志的项目中为了减少SD卡实际的擦写频次提高SD卡寿命特别设计了本函数库原理是在单片机的备份区SRAM中开辟一块缓存区多次少量的写入操作都会将数据暂存在此缓存中积累到一定数量或距离上一次写入达到一定时间时再执行实际向SD卡中写入的操作即落盘。2. 使用说明要使用该功能请将SDCache.h和SDCache.c两个文件添加到项目工程中。2.1 头文件介绍头文件中提供了两个自定义的宏请根据自己的项目情况进行设置#defineCACHE_USE_OS1#defineCACHE_SAVE_PERIOD60000CACHE_USE_OS:设置当前工程是否使用os系统这决定了如何执行落盘、是否创建互斥锁来保护缓存区。如果使用了os本函数库将支持发送任务通知唤醒指定的任务执行落盘而且本函数库将会自动创建互斥量以确保线程安全。如果不使用os则不会发送任务通知也不会创建互斥锁。为何这样设计在使用os的项目中任何任务都可能会添加log添加log之后都有可能触发落盘而落盘的过程需要耗费较长的时间经过实测写入一个小文件打开文件、写入文件、关闭文件的过程耗费了40-50ms因此需要将落盘的代码执行过程放到优先级较低的任务中执行这样当添加完一条log进入缓存区后会发送一个任务通知唤醒落盘任务开始执行避免影响重要任务的实时性。CACHE_SAVE_PERIOD:设置自动保存周期每次添加完一条log都会记录下当前时刻在调用Cache_AutoSave执行自动保存时距离上次添加记录的时间超过该值将执行落盘详细过程后面再细讲。本库提供了下面几个函数#ifCACHE_USE_OS//使用os时支持唤醒任务/******************************************************************************* * 功 能: [可选] 设置唤醒任务设置后在每次调用 Cache_Write 函数向缓存区中写入数 * 据时都会检查是否需要执行落盘若需要则会向唤醒任务发送任务通知若未 * 设置唤醒任务也可以通过定时调用 Cache_AutoSave 函数来执行落盘 * 参 数: * Task: 指定一个接收任务通知的任务句柄通常在该任务中执行落盘 * 返回值: 无 *******************************************************************************/voidCache_SetWeakupTask(xTaskHandle Task);#endif/******************************************************************************* * 功 能: 设置指定文件缓存区的文件保存路径如果设置的路径与之前存在的路径不同 * 会立即将缓存区中已有的数据存入原来的路径如果保存失败旧数据不会丢 * 失而新路径仍会生效 * 参 数: * FileNum : 指定的文件缓存区范围0-2 * Path : 文件的完整路径指定的文件不存在时会自动创建但目录需要自行创建 * 返回值: 执行成功返回Sean_OK否则返回Sean_NG *******************************************************************************/Sean_Result_tCache_SetPath(unsignedcharFileNum,char*Path);/******************************************************************************* * 功 能: 向指定文件缓存区中写入数据 * 参 数: * FileNum : 指定的文件缓存区范围0-2 * format : 格式化字符串 * ... : 可变参数 * 返回值: 执行成功返回Sean_OK否则返回Sean_NG *******************************************************************************/Sean_Result_tCache_Write(unsignedcharFileNum,constchar*format,...);/******************************************************************************* * 功 能: 自动保存函数需要定时调用或在保存任务唤醒后调用调用该函数并不一定 * 会实际执行落盘而是先检查是否需要落盘条件满足缓存区数据将满或距离 * 上次写入记录时间超过一定值时才会实际执行落盘但在系统启动后的第一次 * 调用时一定会保存一次 * 参 数: 无 * 返回值: 执行成功返回Sean_OK否则返回Sean_NG *******************************************************************************/Sean_Result_tCache_AutoSave(void);注释很详细就不再细讲了。另外编写实现一个外部函数需要在SeanLib.c中实现//获取系统滴答计数器单位ms裸机程序中用HAL_GetTick, 其它系统中可自定义externunsignedintSean_GetTick(void);2.2 初始化本库已通过MSH创建一个初始化命令会自动初始化备份区SRAM并创建三份缓存区也就是说支持三个文件的缓存写入操作每个缓存区1K字节。缓存区中设置有初始化标志不会重复初始化但当取下VBAT的电池整个缓存区将会被重置。用户代码中只需要设置文件保存路径即可Cache_SetPath(0,0:/Log/log_20260701.txt);Cache_SetPath(1,0:/Log/data_20260701.txt);Cache_SetPath(2,0:/Log/error_20260701.txt);然后设置唤醒任务Cache_SetWeakupTask(Task_Log);2.3 添加log到缓存区可以编写一些简化的操作宏#defineAdd_SysLog(format,...)Cache_Write(0,format,##__VA_ARGS__)在用户任务中按照想要的格式添加log到缓存区Add_SysLog([%02hhu:%02hhu:%02hhu:%03hu] [%s] [%s]: %s\r\n,Log-Hour,Log-Min,Log-Sec,Log-SubSec,Log-LogType,Log-TaskName,Log-LogMsg);2.4 执行落盘在Task_Log任务中执行自动落盘voidStartTaskLog(void*argument)//log保存任务{while(1){Cache_AutoSave();//将本次上电之前已存在的数据落盘ulTaskNotifyTake(pdTRUE,portMAX_DELAY);//等待函数库唤醒任务}}如果没有设置唤醒任务可以在一个优先级低一些的任务中定时调用Cache_AutoSave函数。Cache_AutoSave函数中的部分代码if(Sean_GetTick()-Cache.TickCACHE_SAVE_PERIOD)//需要保存时才调用保存函数{if(Save_One(FileNum)!Sean_OK){srtSean_NG;}}