找回密码
 立即注册
首页 业界区 安全 Easy_log移植笔记

Easy_log移植笔记

毕余馥 2025-6-11 14:56:39
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官方文档[github]

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

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

2.png

3.png

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

编译4个警告,原因:没有实现port.c中的函数
根据上面的链接实现port.c中函数
elog_port.c实现
  1. #include <elog.h>
  2. /*** extern header ***/
  3. #include "stdio.h"
  4. #include "stdint.h"
  5. #include "SEGGER_RTT.h"
  6. #include "FreeRTOS.h"
  7. #include "semphr.h"
  8. #include "stm32f4xx_hal.h"
  9. /*** global var *****/
  10. static SemaphoreHandle_t g_log_mutex = NULL;
  11. /**
  12. * EasyLogger port initialize
  13. *
  14. * @return result
  15. */
  16. ElogErrCode elog_port_init(void) {
  17.     ElogErrCode result = ELOG_NO_ERR;
  18.     /* add your code here */
  19.     SEGGER_RTT_Init();
  20.         g_log_mutex = xSemaphoreCreateMutex(); // 创建互斥锁
  21.     return result;
  22. }
  23. /**
  24. * EasyLogger port deinitialize
  25. *
  26. */
  27. void elog_port_deinit(void) {
  28.     /* add your code here */
  29.     vSemaphoreDelete(g_log_mutex); // 释放互斥锁资源
  30.     g_log_mutex = NULL;
  31. }
  32. /**
  33. * output log port interface
  34. *
  35. * @param log output of log
  36. * @param size log size
  37. */
  38. void elog_port_output(const char *log, size_t size) {
  39.    
  40.     /* add your code here */
  41.         SEGGER_RTT_printf(0, log ,size);
  42. }
  43. /**
  44. * output lock
  45. */
  46. void elog_port_output_lock(void) {
  47.    
  48.     /* add your code here */
  49.     if (g_log_mutex != NULL) {
  50.         xSemaphoreTake(g_log_mutex, portMAX_DELAY); // 阻塞式获取锁
  51.     }
  52. }
  53. /**
  54. * output unlock
  55. */
  56. void elog_port_output_unlock(void) {
  57.    
  58.     /* add your code here */
  59.     if (g_log_mutex != NULL) {
  60.         xSemaphoreGive(g_log_mutex); // 释放锁
  61.     }
  62. }
  63. /**
  64. * get current time interface
  65. *
  66. * @return current time
  67. */
  68. const char *elog_port_get_time(void) {
  69.    
  70.     /* add your code here */
  71.     static char time_buf[20];
  72.     uint32_t ticks = HAL_GetTick();
  73.     uint32_t ms = ticks % 1000;
  74.     uint32_t sec = (ticks / 1000) % 60;
  75.     uint32_t min = (ticks / 60000) % 60;
  76.     uint32_t hour = ticks / 3600000;
  77.     snprintf(time_buf, sizeof(time_buf), "%02lu:%02lu:%02lu.%03lu", hour, min, sec, ms);
  78.     return time_buf;
  79. }
  80. /**
  81. * get current process name interface
  82. *
  83. * @return current process name
  84. */
  85. const char *elog_port_get_p_info(void) {
  86.     /* add your code here */
  87.     return "main";
  88. }
  89. /**
  90. * get current thread name interface
  91. *
  92. * @return current thread name
  93. */
  94. const char *elog_port_get_t_info(void) {
  95.    
  96.     /* add your code here */
  97.         TaskHandle_t current_task = xTaskGetCurrentTaskHandle();
  98.     return (current_task != NULL) ? pcTaskGetName(current_task) : "Unknown";
  99. }
  100. //base FreeRTOS and stm32hal library
  101. //没有接入RTC时钟
复制代码
Eassylogger多种输出类型
5.png

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

6.png

出现warning
将elog.c中的宏修改恢复正常
  1. #define S_NORMAL                       "1m"
  2. //仅支持1,2,4的字符样式
复制代码
7.png

将elog.c中的宏修改恢复正常
  1. #define S_NORMAL                       "1m"
  2. //仅支持1,2,4的字符样式
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册