1 /**
2 * @file lv_log.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_log.h"
10 #if LV_USE_LOG
11
12 #include <stdarg.h>
13 #include <string.h>
14 #include "lv_printf.h"
15 #include "../hal/lv_hal_tick.h"
16
17 #if LV_LOG_PRINTF
18 #include <stdio.h>
19 #endif
20
21 /*********************
22 * DEFINES
23 *********************/
24
25 /**********************
26 * TYPEDEFS
27 **********************/
28
29 /**********************
30 * STATIC PROTOTYPES
31 **********************/
32
33 /**********************
34 * STATIC VARIABLES
35 **********************/
36 static lv_log_print_g_cb_t custom_print_cb;
37
38 /**********************
39 * MACROS
40 **********************/
41
42 /**********************
43 * GLOBAL FUNCTIONS
44 **********************/
45
46 /**
47 * Register custom print/write function to call when a log is added.
48 * It can format its "File path", "Line number" and "Description" as required
49 * and send the formatted log message to a console or serial port.
50 * @param print_cb a function pointer to print a log
51 */
lv_log_register_print_cb(lv_log_print_g_cb_t print_cb)52 void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb)
53 {
54 custom_print_cb = print_cb;
55 }
56
57 /**
58 * Add a log
59 * @param level the level of log. (From `lv_log_level_t` enum)
60 * @param file name of the file when the log added
61 * @param line line number in the source code where the log added
62 * @param func name of the function when the log added
63 * @param format printf-like format string
64 * @param ... parameters for `format`
65 */
_lv_log_add(lv_log_level_t level,const char * file,int line,const char * func,const char * format,...)66 void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * func, const char * format, ...)
67 {
68 if(level >= _LV_LOG_LEVEL_NUM) return; /*Invalid level*/
69
70 static uint32_t last_log_time = 0;
71
72 if(level >= LV_LOG_LEVEL) {
73 va_list args;
74 va_start(args, format);
75
76 /*Use only the file name not the path*/
77 size_t p;
78 for(p = strlen(file); p > 0; p--) {
79 if(file[p] == '/' || file[p] == '\\') {
80 p++; /*Skip the slash*/
81 break;
82 }
83 }
84
85 uint32_t t = lv_tick_get();
86 static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error", "User"};
87
88 #if LV_LOG_PRINTF
89 printf("[%s]\t(%" LV_PRId32 ".%03" LV_PRId32 ", +%" LV_PRId32 ")\t %s: ",
90 lvl_prefix[level], t / 1000, t % 1000, t - last_log_time, func);
91 vprintf(format, args);
92 printf(" \t(in %s line #%d)\n", &file[p], line);
93 #else
94 if(custom_print_cb) {
95 char buf[512];
96 #if LV_SPRINTF_CUSTOM
97 char msg[256];
98 lv_vsnprintf(msg, sizeof(msg), format, args);
99 lv_snprintf(buf, sizeof(buf), "[%s]\t(%" LV_PRId32 ".%03" LV_PRId32 ", +%" LV_PRId32 ")\t %s: %s \t(in %s line #%d)\n",
100 lvl_prefix[level], t / 1000, t % 1000, t - last_log_time, func, msg, &file[p], line);
101 #else
102 lv_vaformat_t vaf = {format, &args};
103 lv_snprintf(buf, sizeof(buf), "[%s]\t(%" LV_PRId32 ".%03" LV_PRId32 ", +%" LV_PRId32 ")\t %s: %pV \t(in %s line #%d)\n",
104 lvl_prefix[level], t / 1000, t % 1000, t - last_log_time, func, (void *)&vaf, &file[p], line);
105 #endif
106 custom_print_cb(buf);
107 }
108 #endif
109
110 last_log_time = t;
111 va_end(args);
112 }
113 }
114
lv_log(const char * buf)115 void lv_log(const char * buf)
116 {
117 #if LV_LOG_PRINTF
118 puts(buf);
119 #endif
120 if(custom_print_cb) custom_print_cb(buf);
121 }
122
123 /**********************
124 * STATIC FUNCTIONS
125 **********************/
126
127 #endif /*LV_USE_LOG*/
128