LittleVGL 源码分析--srclv

    技术2022-07-11  73

    log配置信息:

    /*================ * Log settings *===============*/ /*================ * 日志设置 *===============*/ /*1: Enable the log module*/ /*1: 启用日志模块*/ #define LV_USE_LOG 1 #if LV_USE_LOG /* How important log should be added: * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information 跟踪大量日志以提供详细信息 * LV_LOG_LEVEL_INFO Log important events 重要事件 * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem如果发生了不想要发生的事情但没有引起错误,请记录 * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail 只有在系统可能出现故障时才会出现的严重问题 * LV_LOG_LEVEL_NONE Do not log anything不要记录任何内容 */ # define LV_LOG_LEVEL LV_LOG_LEVEL_WARN /* 1: Print the log with 'printf'; 用“printf”打印日志 * 0: user need to register a callback with `lv_log_register_print_cb` 用户需要使用注册回调 */ # define LV_LOG_PRINTF 1 #endif /*LV_USE_LOG*/ /* Export integer constant to binding.导出整型常量绑定。 * This macro is used with constants in the form of LV_<CONST> that 此宏与LV_<CONST>形式的常量一起使用: * should also appear on lvgl binding API such as Micropython也应该出现在lvgl绑定的API上,比如Micropython * * The default value just prevents a GCC warning.默认值只是防止GCC警告。 */ #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning

    lv_log.h

    /** * @file lv_log.h * */ #ifndef LV_LOG_H #define LV_LOG_H #ifdef __cplusplus extern "C" { #endif /********************* * INCLUDES *********************/ #include "../lv_conf_internal.h" #include <stdint.h> /********************* * DEFINES *********************/ /*Possible log level. For compatibility declare it independently from `LV_USE_LOG`*/ /*日志级别. 为了兼容性,请独立声明'LV_USE_LOG' */ #define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information 提供大量详细信息的日志*/ #define LV_LOG_LEVEL_INFO 1 /**< Log important events 记录重要事件*/ #define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem 如果发生了意外但没有引起问题,请记录*/ #define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail 仅系统崩溃时出现的严重问题*/ #define LV_LOG_LEVEL_USER 4 /**< Custom logs from the user 来自用户的自定义日志*/ #define LV_LOG_LEVEL_NONE 5 /**< Do not log anything 不要记录任何内容*/ #define _LV_LOG_LEVEL_NUM 6 /**< Number of log levels 日志级别数*/ LV_EXPORT_CONST_INT(LV_LOG_LEVEL_TRACE); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_INFO); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_WARN); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_ERROR); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_USER); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_NONE); typedef int8_t lv_log_level_t; #if LV_USE_LOG /********************** * TYPEDEFS **********************/ /** * Log print function. Receives "Log Level", "File path", "Line number", "Function name" and "Description". * 日志打印。 接收 "日志级别"、 "文件路径"、 "行号" 、"函数名"和"说明"。 */ typedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char *, uint32_t, const char *, const char *); /********************** * GLOBAL PROTOTYPES **********************/ /** * Register custom print/write function to call when a log is added. * It can format its "File path", "Line number" and "Description" as required * and send the formatted log message to a console or serial port. * @param print_cb a function pointer to print a log * 注册自定义打印/写入函数以在添加日志时调用。 * 它可以根据需要格式化“文件路径”、“行号”和“说明” * 并将格式化的日志消息发送到控制台或串行端口。 * @param print_cb打印日志的函数指针 */ void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb); /** * Add a log * @param level the level of log. (From `lv_log_level_t` enum) * @param file name of the file when the log added * @param line line number in the source code where the log added * @param func name of the function when the log added * @param format printf-like format string * @param ... parameters for `format` * 添加日志 * @param level日志级别 (From `lv_log_level_t` enum) * @param file添加日志时的文件名 * @param line添加日志在源代码中的行号 * @param func添加日志时函数名 * @param format printf-like格式字符串 * @param ...`format`的参数 */ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * func, const char * format, ...); /********************** * MACROS **********************/ #if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE #define LV_LOG_TRACE(...) _lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, __func__, __VA_ARGS__); #else #define LV_LOG_TRACE(...) \ { \ ; \ } #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO #define LV_LOG_INFO(...) _lv_log_add(LV_LOG_LEVEL_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__); #else #define LV_LOG_INFO(...) \ { \ ; \ } #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_WARN #define LV_LOG_WARN(...) _lv_log_add(LV_LOG_LEVEL_WARN, __FILE__, __LINE__, __func__, __VA_ARGS__); #else #define LV_LOG_WARN(...) \ { \ ; \ } #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_ERROR #define LV_LOG_ERROR(...) _lv_log_add(LV_LOG_LEVEL_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__); #else #define LV_LOG_ERROR(...) \ { \ ; \ } #endif #if LV_LOG_LEVEL <= LV_LOG_LEVEL_USER #define LV_LOG_USER(...) _lv_log_add(LV_LOG_LEVEL_USER, __FILE__, __LINE__, __func__, __VA_ARGS__); #else #define LV_LOG_USER(...) \ { \ ; \ } #endif #else /*LV_USE_LOG*/ /*Do nothing if `LV_USE_LOG 0`*/ #define _lv_log_add(level, file, line, ...) \ { \ ; \ } #define LV_LOG_TRACE(...) \ { \ ; \ } #define LV_LOG_INFO(...) \ { \ ; \ } #define LV_LOG_WARN(...) \ { \ ; \ } #define LV_LOG_ERROR(...) \ { \ ; \ } #define LV_LOG_USER(...) \ { \ ; \ } #endif /*LV_USE_LOG*/ #ifdef __cplusplus } /* extern "C" */ #endif #endif /*LV_LOG_H*/

    lv_log.c

    /** * @file lv_log.c * */ /********************* * INCLUDES *********************/ #include "lv_log.h" #if LV_USE_LOG #include <stdarg.h> #include <string.h> #include "lv_printf.h" #if LV_LOG_PRINTF #include <stdio.h> #endif /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ /********************** * STATIC VARIABLES **********************/ static lv_log_print_g_cb_t custom_print_cb; /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ /** * Register custom print/write function to call when a log is added. * It can format its "File path", "Line number" and "Description" as required * and send the formatted log message to a console or serial port. * @param print_cb a function pointer to print a log * 注册自定义打印/写入函数以在添加日志时调用。 * 它可以根据需要格式化“文件路径”、“行号”和“说明” * 并将格式化的日志消息发送到控制台或串行端口。 * @param print_cb打印日志的函数指针 */ void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb) { custom_print_cb = print_cb;//静态变量来承接 } /** * Add a log * @param level the level of log. (From `lv_log_level_t` enum) * @param file name of the file when the log added * @param line line number in the source code where the log added * @param func name of the function when the log added * @param format printf-like format string * @param ... parameters for `format` * 添加日志 * @param level日志级别 (From `lv_log_level_t` enum) * @param file添加日志时的文件名 * @param line添加日志在源代码中的行号 * @param func添加日志时函数名 * @param format printf-like格式字符串 * @param ...`format`的参数 */ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * func, const char * format, ...) { if(level >= _LV_LOG_LEVEL_NUM) return; /*Invalid level 无效级别*/ if(level >= LV_LOG_LEVEL) { va_list args; // 申请参数列表变量 va_start(args, format); // 申明最后一个传递给函数的已知的固定参数 char buf[256]; // "说明""Description" 可以在lv_log.h注释中找到出处 lv_vsnprintf(buf, sizeof(buf), format, args); //猜测:将参数format... 结合放到buf中 va_end(args); #if LV_LOG_PRINTF //用“printf”打印日志 /*Use only the file name not the path 只使用文件名而不是路径*/ size_t p; for(p = strlen(file); p > 0; p--) { if(file[p] == '/' || file[p] == '\\') { p++; /*Skip the slash 跳过斜杠*/ break; } } static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error", "User"}; printf("%s: %s \t(%s #%d %s())\n", lvl_prefix[level], buf, &file[p], line, func); //打印日志 #else // `lv_log_register_print_cb` 用户需要使用注册回调 if(custom_print_cb) custom_print_cb(level, file, line, func, buf); #endif } } /********************** * STATIC FUNCTIONS **********************/ #endif /*LV_USE_LOG*/

     

    总结

    log 可以从配置信息Log settings中找到相关的配置选项。 

    .h文件中:

    有日志级别

    #define LV_LOG_LEVEL_TRACE 0 /**< A lot of logs to give detailed information 提供大量详细信息的日志*/ #define LV_LOG_LEVEL_INFO 1 /**< Log important events 记录重要事件*/ #define LV_LOG_LEVEL_WARN 2 /**< Log if something unwanted happened but didn't caused problem 如果发生了意外但没有引起问题,请记录*/ #define LV_LOG_LEVEL_ERROR 3 /**< Only critical issue, when the system may fail 仅系统崩溃时出现的严重问题*/ #define LV_LOG_LEVEL_USER 4 /**< Custom logs from the user 来自用户的自定义日志*/ #define LV_LOG_LEVEL_NONE 5 /**< Do not log anything 不要记录任何内容*/ #define _LV_LOG_LEVEL_NUM 6 /**< Number of log levels 日志级别数*/

    还有函数

    void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb); void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * func, const char * format, ...);

    还有 宏

    #if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE #define LV_LOG_TRACE(...) _lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, __func__, __VA_ARGS__); #else #define LV_LOG_TRACE(...) \ { \ ; \ } #endif

     

    不明白的地方

    1.防止GCC警告的用法

    2. c的这个库 #include <stdarg.h>

    3.源代码#include "lv_printf.h"

       再看看这个函数怎么写的lv_vsnprintf(buf, sizeof(buf), format, args);

    Processed: 0.016, SQL: 9