毕余馥 发表于 2025-6-11 14:56:39

Easy_log移植笔记

Easy_log移植笔记

1. 目录结构


[*]demo 包含多平台移植示例,如 Linux、RT-Thread、裸机系统等,提供实际工程参考,帮助开发者快速适配不同环境。
[*]docs 存放中英文文档,详细说明库的配置、API 接口、移植方法及插件扩展机制。关键文档包括:

[*]api/kernel.md:核心接口函数定义及使用说明。
[*]port/kernel.md:跨平台移植的具体步骤和接口实现要求。

[*]easylogger(源码主目录)

[*]inc:公共头文件,包含核心功能定义:

[*]elog.h:日志级别、初始化、输出接口声明。
[*]elog_cfg.h:全局配置宏(如输出开关、缓冲区大小、异步模式使能)。

[*]src:核心实现代码:

[*]elog.c:日志初始化、格式化、过滤及输出调度逻辑。
[*]elog_utils.c:时间戳生成、线程安全控制等工具函数。
[*]elog_async.c:异步输出相关函数
[*]elog_buf.c:负责日志缓冲区的实现等函数

[*]port:平台适配层,需用户根据目标系统实现以下接口:

[*]elog_port.c:定义输出函数(如串口发送)、锁机制(如互斥量)、时间戳获取等。

[*]plugins(可选):扩展插件,支持功能动态增强:

[*]flash:基于 EasyFlash 的日志存储(无需文件系统)。
[*]file:文件日志转档及动态配置加载(开发中)。


[*]LICENSE 开源协议文件,明确库的使用条款。
[*]README.md 项目概览、特性列表、快速入门及编译配置说明。

[*]关键文件与配置


[*]移植依赖文件

[*]elog_port.c:必须针对目标平台实现输出函数(如 elog_port_output)及锁机制,确保多线程安全。
[*]elog_cfg.h:通过宏定义配置日志行为,例如静态过滤级别、异步输出缓冲区大小、RAW 格式支持等。

[*]插件扩展 通过 plugins 目录集成附加功能(如 Flash 存储),需在编译时启用对应插件并实现依赖接口(如 Flash 读写操作)。
2.移植

1. EasyLogger官方文档

EasyLogger 核心功能 API 说明
EasyLogger 核心功能移植说明
EasyLogger常见初始化方式
2. 移植

添加elog.c,elog_utils.c,elog_port.c并链接easylogger\inc中的header文件



编译4个报错,发现是没有定义elog_async和elog_buf相关实现的函数,不需要异步和缓冲功能,可以将
ELOG_ASYNC_OUTPUT_ENABLE和ELOG_BUF_OUTPUT_ENABLE
这两个宏注释掉

编译4个警告,原因:没有实现port.c中的函数
根据上面的链接实现port.c中函数
elog_port.c实现
#include <elog.h>

/*** extern header ***/
#include "stdio.h"
#include "stdint.h"

#include "SEGGER_RTT.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "stm32f4xx_hal.h"

/*** global var *****/
static SemaphoreHandle_t g_log_mutex = NULL;

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

    /* add your code here */
    SEGGER_RTT_Init();
      g_log_mutex = xSemaphoreCreateMutex(); // 创建互斥锁
    return result;
}

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

    /* add your code here */
    vSemaphoreDelete(g_log_mutex); // 释放互斥锁资源
    g_log_mutex = NULL;
}

/**
* output log port interface
*
* @param log output of log
* @param size log size
*/
void elog_port_output(const char *log, size_t size) {
   
    /* add your code here */
      SEGGER_RTT_printf(0, log ,size);

}

/**
* output lock
*/
void elog_port_output_lock(void) {
   
    /* add your code here */
    if (g_log_mutex != NULL) {
      xSemaphoreTake(g_log_mutex, portMAX_DELAY); // 阻塞式获取锁
    }
}

/**
* output unlock
*/
void elog_port_output_unlock(void) {
   
    /* add your code here */
    if (g_log_mutex != NULL) {
      xSemaphoreGive(g_log_mutex); // 释放锁
    }
}

/**
* get current time interface
*
* @return current time
*/
const char *elog_port_get_time(void) {
   
    /* add your code here */
    static char time_buf;
    uint32_t ticks = HAL_GetTick();
    uint32_t ms = ticks % 1000;
    uint32_t sec = (ticks / 1000) % 60;
    uint32_t min = (ticks / 60000) % 60;
    uint32_t hour = ticks / 3600000;
    snprintf(time_buf, sizeof(time_buf), "%02lu:%02lu:%02lu.%03lu", hour, min, sec, ms);
    return time_buf;
}

/**
* get current process name interface
*
* @return current process name
*/
const char *elog_port_get_p_info(void) {

    /* add your code here */
    return "main";
}

/**
* get current thread name interface
*
* @return current thread name
*/
const char *elog_port_get_t_info(void) {
   
    /* add your code here */
      TaskHandle_t current_task = xTaskGetCurrentTaskHandle();
    return (current_task != NULL) ? pcTaskGetName(current_task) : "Unknown";
}
//base FreeRTOS and stm32hal library
//没有接入RTC时钟Eassylogger多种输出类型

assert: 断言,用于在代码中发现逻辑错误或不应该发生的情况,不太常用
error:致命错误,出现这种情况程序就死机了
warning: 警告,用于提示可能存在的非致命性问题,代码仍然可以运行,但需要注意这些警告。
info: 用于输出一般性信息,帮助了解程序的运行状态。
debug: 用于输出调试信息,帮助开发人员进行问题排查。
verbose:冗长输出信息,任何无关紧要的可能都会输出,不太常用
3.移植出现的问题


出现warning
将elog.c中的宏修改恢复正常
#define S_NORMAL                     "1m"
//仅支持1,2,4的字符样式
将elog.c中的宏修改恢复正常
#define S_NORMAL                     "1m"
//仅支持1,2,4的字符样式
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Easy_log移植笔记