16
16
#include <stdlib.h>
17
17
#include <stdio.h>
18
18
#include <time.h>
19
+ #include <stdbool.h>
20
+ #include <string.h>
21
+ #include <sys/queue.h>
19
22
#include <sys/lock.h>
20
23
21
24
#include "esp_libc.h"
@@ -55,9 +58,126 @@ static uint32_t IRAM_ATTR esp_log_early_timestamp()
55
58
}
56
59
57
60
#ifndef BOOTLOADER_BUILD
61
+
62
+ #ifdef CONFIG_LOG_SET_LEVEL
63
+ #define GLOBAL_TAG "*"
64
+
65
+ typedef struct uncached_tag_entry_ {
66
+ SLIST_ENTRY (uncached_tag_entry_ ) entries ;
67
+ uint8_t level ; // esp_log_level_t as uint8_t
68
+ char tag [0 ]; // beginning of a zero-terminated string
69
+ } uncached_tag_entry_t ;
70
+
71
+ static esp_log_level_t s_global_tag_level = ESP_LOG_VERBOSE ;
72
+ static SLIST_HEAD (log_tags_head , uncached_tag_entry_ ) s_log_uncached_tags = SLIST_HEAD_INITIALIZER (s_log_uncached_tags );
73
+ static uncached_tag_entry_t * s_uncached_tag_entry_prev ;
74
+ #endif /* CONFIG_LOG_SET_LEVEL */
75
+
58
76
static _lock_t s_lock ;
59
77
static putchar_like_t s_putchar_func = & putchar ;
60
78
79
+ #ifdef CONFIG_LOG_SET_LEVEL
80
+ /**
81
+ * @brief get entry by inputting tag
82
+ */
83
+ static bool esp_log_get_tag_entry (const char * tag , uncached_tag_entry_t * * entry )
84
+ {
85
+ uncached_tag_entry_t * it = NULL ;
86
+
87
+ SLIST_FOREACH (it , & s_log_uncached_tags , entries ) {
88
+ if (!strcmp (it -> tag , tag )) {
89
+ //one tag in the linked list match, update the level
90
+ * entry = it ;
91
+ //quit with it != NULL
92
+ return true;
93
+ }
94
+ }
95
+
96
+ return false;
97
+ }
98
+
99
+ static void clear_log_level_list (void )
100
+ {
101
+ uncached_tag_entry_t * it = NULL ;
102
+
103
+ SLIST_FOREACH (it , & s_log_uncached_tags , entries ) {
104
+ SLIST_REMOVE (& s_log_uncached_tags , it , uncached_tag_entry_ , entries );
105
+ free (it );
106
+ }
107
+ }
108
+
109
+ /**
110
+ * @brief get level by inputting tag
111
+ */
112
+ static esp_log_level_t esp_log_get_level (const char * tag )
113
+ {
114
+ esp_log_level_t out_level ;
115
+ uncached_tag_entry_t * entry ;
116
+
117
+ _lock_acquire_recursive (& s_lock );
118
+
119
+ if (s_uncached_tag_entry_prev && !strcmp (s_uncached_tag_entry_prev -> tag , tag )) {
120
+ out_level = (esp_log_level_t )s_uncached_tag_entry_prev -> level ;
121
+ goto exit ;
122
+ }
123
+
124
+ if (esp_log_get_tag_entry (tag , & entry ) == true) {
125
+ out_level = (esp_log_level_t )entry -> level ;
126
+ s_uncached_tag_entry_prev = entry ;
127
+ goto exit ;
128
+ } else
129
+ out_level = s_global_tag_level ;
130
+
131
+ exit :
132
+ _lock_release_recursive (& s_lock );
133
+ return out_level ;
134
+ }
135
+
136
+ /**
137
+ * @brief check if system should output data
138
+ */
139
+ static inline bool should_output (esp_log_level_t user_level , esp_log_level_t system_level )
140
+ {
141
+ return user_level <= system_level ;
142
+ }
143
+
144
+ /**
145
+ * @brief set log level for given tag
146
+ */
147
+ void esp_log_level_set (const char * tag , esp_log_level_t level )
148
+ {
149
+ size_t bytes ;
150
+ uncached_tag_entry_t * entry , * new_entry ;
151
+
152
+ _lock_acquire_recursive (& s_lock );
153
+
154
+ if (!strcmp (tag , GLOBAL_TAG )) {
155
+ s_global_tag_level = level ;
156
+ clear_log_level_list ();
157
+ goto exit ;
158
+ }
159
+
160
+ if (esp_log_get_tag_entry (tag , & entry ) == true) {
161
+ entry -> level = level ;
162
+ goto exit ;
163
+ }
164
+
165
+ bytes = strlen (tag ) + 1 ;
166
+
167
+ new_entry = malloc (sizeof (uncached_tag_entry_t ) + bytes );
168
+ if (!new_entry )
169
+ goto exit ;
170
+
171
+ new_entry -> level = level ;
172
+ memcpy (new_entry -> tag , tag , bytes );
173
+
174
+ SLIST_INSERT_HEAD (& s_log_uncached_tags , new_entry , entries );
175
+
176
+ exit :
177
+ _lock_release_recursive (& s_lock );
178
+ }
179
+ #endif /* CONFIG_LOG_SET_LEVEL */
180
+
61
181
static int esp_log_write_str (const char * s )
62
182
{
63
183
int ret ;
@@ -114,9 +234,15 @@ void esp_log_write(esp_log_level_t level, const char *tag, const char *fmt, ...
114
234
int ret ;
115
235
va_list va ;
116
236
char * pbuf ;
117
- char prefix = level >= ESP_LOG_MAX ? 'N' : s_log_prefix [level ];
237
+ char prefix ;
238
+
239
+ _lock_acquire_recursive (& s_lock );
240
+
241
+ #ifdef CONFIG_LOG_SET_LEVEL
242
+ if (!should_output (level , esp_log_get_level (tag )))
243
+ goto exit ;
244
+ #endif
118
245
119
- _lock_acquire (& s_lock );
120
246
#ifdef CONFIG_LOG_COLORS
121
247
static char buf [16 ];
122
248
uint32_t color = level >= ESP_LOG_MAX ? 0 : s_log_color [level ];
@@ -128,7 +254,7 @@ void esp_log_write(esp_log_level_t level, const char *tag, const char *fmt, ...
128
254
goto exit ;
129
255
}
130
256
#endif
131
-
257
+ prefix = level >= ESP_LOG_MAX ? 'N' : s_log_prefix [ level ];
132
258
ret = asprintf (& pbuf , "%c (%d) %s: " , prefix , esp_log_timestamp (), tag );
133
259
if (ret < 0 )
134
260
goto out ;
@@ -159,7 +285,7 @@ void esp_log_write(esp_log_level_t level, const char *tag, const char *fmt, ...
159
285
s_putchar_func ('\n' );
160
286
161
287
exit :
162
- _lock_release (& s_lock );
288
+ _lock_release_recursive (& s_lock );
163
289
}
164
290
165
291
/**
@@ -169,10 +295,10 @@ putchar_like_t esp_log_set_putchar(putchar_like_t func)
169
295
{
170
296
putchar_like_t tmp ;
171
297
172
- _lock_acquire (& s_lock );
298
+ _lock_acquire_recursive (& s_lock );
173
299
tmp = s_putchar_func ;
174
300
s_putchar_func = func ;
175
- _lock_release (& s_lock );
301
+ _lock_release_recursive (& s_lock );
176
302
177
303
return tmp ;
178
304
}
0 commit comments