STM32+fafts+Easylogger输入日志功能

Easylooger本身是带日志输出到文件功能的,但是Easylogger本身源码用的不是Fafts的接口函数,所以需要移植。

要让Easylogger能够输出日志到sd卡总共分三补。

第一步,移植STM32+SD卡驱动。

第二步,移植stm32+FAFTS文件系统。

第三步,修改Easylogger日志输出驱动文件。

由于第一步和第二步网上教程比较多,就不再重复写,同时Easylogger移植的文章也不少也就不写了。只写关键的第三步,如何修改Easylogger日志输出驱动文件,使调用log_x("日志")是能输出日志到sd卡,并按照日期和时间进行存储。

最终实现功能是按日期建立文件夹,并按照时间存成不同的log文件。

首先修改ElogFileCfg结构体增加int current;当前用用户名序号。

typedef struct {
    char *name;              /* file name */
    size_t max_size;         /* file max size */
    int max_rotate;          /* max rotate file count */
    int current;			 /* current file name num */
} ElogFileCfg;

核心的"elog_file.c"修改如下:里面有个获取rtc日期需要用户自己实现。

/*
 * 自动根据日期建立文件夹,并根据时间创建对应的日志文件,
 * 文件大小由ELOG_FILE_MAX_SIZE决定。
*/
#define LOG_TAG    "elog.file"

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

#include "elog_file.h"
#include "ff.h"

size_t elog_file_get_strtime(char *s,size_t maxsize);

/* initialize OK flag */
static bool init_ok = false;
static FIL logfile;
static ElogFileCfg local_cfg;
static char logname[100];
static char dir_path[20];

/**
 * @brief  获取新的文件名字
 * @param[in] name:文件名指针
 * @param[in] len:文件名字最大长度
 * @retval 0:成功,-1:失败
 */
uint8_t elog_get_new_name(char *name,uint8_t len)
{
	uint16_t i;
	char path[256];
	char time_str[20];
    FIL tmp_fp;
    elog_file_get_strtime(time_str,20);

	for (i = 0; i < ELOG_FILE_MAX_ROTATE; i++) {

		snprintf(path, len, "%s/%s_%d", dir_path,time_str,i);
		if(f_open(&tmp_fp, path, FA_READ) == FR_OK){
			/*能打开说明已经存在*/
			f_close(&tmp_fp);
		}else{
			strcpy(name,path);
			return 0;
		}
	}
	return -1;
}
ElogErrCode elog_file_init(void)
{
    ElogErrCode result = ELOG_NO_ERR;
    ElogFileCfg cfg;
    FRESULT f_res;

    /* 得到当前日期 */
	time_t t;
	struct tm *info;
	t = rtc_readBJtime();
	info = gmtime(&t);
	strftime(dir_path,20,"0:/%Y%m%d",info);
    if (init_ok)
        goto __exit;

    elog_file_port_init();
	/*新建对应文件夹*/
	f_res = f_mkdir(dir_path);
	if(f_res != FR_OK)
	{

	}

    cfg.max_size = ELOG_FILE_MAX_SIZE;
    cfg.max_rotate = ELOG_FILE_MAX_ROTATE;
    elog_get_new_name(logname,100);
    cfg.name = logname;
    elog_file_config(&cfg);

    init_ok = true;
__exit:
    return result;
}
/**
  * @brief 返回当前时间的字符串 格式为012951
  * @param s:指向目标数组的指针,用来复制产生的 C 字符串
  * @param maxsize: 被复制到 str 的最大字符数。
  * @retval 如果产生的 C 字符串小于 size 个字符(包括空结束字符),
  * 	则会返回复制到 str 中的字符总数(不包括空结束字符),否则返回零。
  */
size_t elog_file_get_strtime(char *s,size_t maxsize) {
	time_t t;
	struct tm *info;
	t = rtc_readBJtime();
	info = gmtime(&t);
	return strftime(s,maxsize,"%H%M%S",info);
}

void elog_file_write(const char *log, size_t size)
{
    size_t file_size = 0;
    uint32_t byteswritten;
    static size_t save_size = 0;
    ELOG_ASSERT(init_ok);
    ELOG_ASSERT(log);

    elog_file_port_lock();

    //f_lseek(&logfile,f_size(&logfile));
    file_size = f_size(&logfile);

    if (unlikely(file_size > local_cfg.max_size)) {
    	/* 关闭当前文件 */
        f_close(&logfile);
        /* 寻找新的文件名 */
        elog_get_new_name(logname,100);
        /* reopen the file */
        f_open(&logfile, logname, FA_OPEN_ALWAYS | FA_WRITE);
    }
    f_write(&logfile, log, size, (void *)&byteswritten);

    /*2k 一存 */
    if(file_size - save_size >= 2048)
    {
    	save_size =  file_size;
    	f_sync(&logfile);
    }



    elog_file_port_unlock();
}

void elog_file_deinit(void)
{
    ELOG_ASSERT(init_ok);

    ElogFileCfg cfg = {NULL, 0, 0};

    elog_file_config(&cfg);

    elog_file_port_deinit();

    init_ok = false;
}

void elog_file_config(ElogFileCfg *cfg)
{
	FRESULT res;
    elog_file_port_lock();

    if (cfg != NULL) {
        local_cfg.name = cfg->name;
        local_cfg.max_size = cfg->max_size;
        local_cfg.max_rotate = cfg->max_rotate;

        if (local_cfg.name != NULL && strlen(local_cfg.name) > 0)
        {
        	res = f_open(&logfile, local_cfg.name, FA_OPEN_ALWAYS | FA_WRITE);
            if( res != FR_OK)
            {
              printf("open error  = %d\n",res);
            }
        }
    }
    elog_file_port_unlock();
}

 "elog_port.c"核心修改如下:


/**
 * EasyLogger port initialize
 *
 * @return result
 */
ElogErrCode elog_port_init(void) {

    ElogErrCode result = ELOG_NO_ERR;
    output_lock = xSemaphoreCreateBinary();
    if(output_lock != NULL)
    {
    	xSemaphoreGive(output_lock);
    }
#if ELOG_FILE_ENABLE
    elog_file_init();
#endif
    isActive = 1;
    return result;
}

/**
 * EasyLogger port deinitialize
 *
 */
void elog_port_deinit(void) {

    /* add your code here */
#if ELOG_FILE_ENABLE
	elog_file_deinit();
#endif
	isActive = 0;
}

/**
 * output log port interface
 *
 * @param log output of log
 * @param size log size
 */
void elog_port_output(const char *log, size_t size) {
	if(isActive){f
	#if ELOG_FILE_ENABLE
		/* write the file */
		elog_file_write(log, size);
	#endif
	}
}

"elog_file_cfg.h"核心代码如下:

#ifndef _ELOG_FILE_CFG_H_
#define _ELOG_FILE_CFG_H_

/* EasyLogger file log plugin's using file name */
#define ELOG_FILE_NAME                 "0:mylog/log"/* @note you must define it for a value */

/* EasyLogger file log plugin's using file max size */
#define ELOG_FILE_MAX_SIZE          (1024*100)   /* @note you must define it for a value */

/* EasyLogger file log plugin's using max rotate file count */
#define ELOG_FILE_MAX_ROTATE       (10000)    /* @note you must define it for a value */

#endif /* _ELOG_FILE_CFG_H_ */

"elog_file_port.c"核心代码如下:


#include "elog_file.h"
#include "freertos.h"
#include "task.h"
#include "ff.h"
#include "ff_gen_drv.h"
#include "./drivers/sd_diskio.h"

uint8_t lock = 0;
static char SDPath[4]; /* SD disk logical drive path */
static FATFS SDFatFs;  /* File system object for SD disk logical drive */
/**
 * EasyLogger flile log pulgin port initialize
 *
 * @return result
 */
ElogErrCode elog_file_port_init(void)
{
	uint32_t res;
    ElogErrCode result = ELOG_NO_ERR;

    if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
    {
    	printf("easylogger Link the SD Disk I/O driver success\n");
    }
    /*##-2- Register the file system object to the FatFs module ##############*/
	 res = f_mount(&SDFatFs, (TCHAR const*)SDPath, 0);
    if( res != FR_OK)
    {
    	printf("Register the file system object to the FatFs module failed %ld \n",res);
    }
    /* add your code here */

    return result;
}

/**
 * file log lock
 */
void elog_file_port_lock(void) {

    /* add your code here */
	while(lock)
	{
		vTaskDelay(1);
	}
	lock = 1;
}

/**
 * file log unlock
 */
void elog_file_port_unlock(void) {

    /* add your code here */
	lock = 0;

}

/**
 * file log deinit
 */
void elog_file_port_deinit(void) {

    /* add your code here */

}

GitHub - armink/EasyLogger: An ultra-lightweight(ROM<1.6K, RAM<0.3k), high-performance C/C++ log library. | 一款超轻量级(ROM<1.6K, RAM<0.3k)、高性能的 C/C++ 日志库

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值