Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
log_core.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_CORE_H_
7#define ZEPHYR_INCLUDE_LOGGING_LOG_CORE_H_
8
9#include <logging/log_msg.h>
10#include <logging/log_core2.h>
12#include <stdbool.h>
13#include <stdint.h>
14#include <stdarg.h>
15#include <syscall.h>
16#include <sys/util.h>
17
18#define LOG_LEVEL_NONE 0U
19#define LOG_LEVEL_ERR 1U
20#define LOG_LEVEL_WRN 2U
21#define LOG_LEVEL_INF 3U
22#define LOG_LEVEL_DBG 4U
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28#ifndef CONFIG_LOG
29#define CONFIG_LOG_DEFAULT_LEVEL 0U
30#define CONFIG_LOG_MAX_LEVEL 0U
31#endif
32
33#if !defined(CONFIG_LOG) || defined(CONFIG_LOG_MINIMAL)
34#define CONFIG_LOG_DOMAIN_ID 0U
35#endif
36
37#define LOG_FUNCTION_PREFIX_MASK \
38 (((uint32_t)IS_ENABLED(CONFIG_LOG_FUNC_NAME_PREFIX_ERR) << \
39 LOG_LEVEL_ERR) | \
40 ((uint32_t)IS_ENABLED(CONFIG_LOG_FUNC_NAME_PREFIX_WRN) << \
41 LOG_LEVEL_WRN) | \
42 ((uint32_t)IS_ENABLED(CONFIG_LOG_FUNC_NAME_PREFIX_INF) << \
43 LOG_LEVEL_INF) | \
44 ((uint32_t)IS_ENABLED(CONFIG_LOG_FUNC_NAME_PREFIX_DBG) << LOG_LEVEL_DBG))
45
50#define Z_LOG_RESOLVED_LEVEL(_level, _default) \
51 Z_LOG_RESOLVED_LEVEL1(_level, _default)
52
53#define Z_LOG_RESOLVED_LEVEL1(_level, _default) \
54 __COND_CODE(_LOG_XXXX##_level, (_level), (_default))
55
56#define _LOG_XXXX0 _LOG_YYYY,
57#define _LOG_XXXX0U _LOG_YYYY,
58#define _LOG_XXXX1 _LOG_YYYY,
59#define _LOG_XXXX1U _LOG_YYYY,
60#define _LOG_XXXX2 _LOG_YYYY,
61#define _LOG_XXXX2U _LOG_YYYY,
62#define _LOG_XXXX3 _LOG_YYYY,
63#define _LOG_XXXX3U _LOG_YYYY,
64#define _LOG_XXXX4 _LOG_YYYY,
65#define _LOG_XXXX4U _LOG_YYYY,
66
81#define Z_LOG_EVAL(_eval_level, _iftrue, _iffalse) \
82 Z_LOG_EVAL1(_eval_level, _iftrue, _iffalse)
83
84#define Z_LOG_EVAL1(_eval_level, _iftrue, _iffalse) \
85 __COND_CODE(_LOG_ZZZZ##_eval_level, _iftrue, _iffalse)
86
87#define _LOG_ZZZZ1 _LOG_YYYY,
88#define _LOG_ZZZZ1U _LOG_YYYY,
89#define _LOG_ZZZZ2 _LOG_YYYY,
90#define _LOG_ZZZZ2U _LOG_YYYY,
91#define _LOG_ZZZZ3 _LOG_YYYY,
92#define _LOG_ZZZZ3U _LOG_YYYY,
93#define _LOG_ZZZZ4 _LOG_YYYY,
94#define _LOG_ZZZZ4U _LOG_YYYY,
95
101#define _LOG_LEVEL() Z_LOG_RESOLVED_LEVEL(LOG_LEVEL, CONFIG_LOG_DEFAULT_LEVEL)
102
109#define LOG_CONST_ID_GET(_addr) \
110 COND_CODE_1(CONFIG_LOG, ((__log_level ? log_const_source_id(_addr) : 0)), (0))
111
116#define LOG_CURRENT_MODULE_ID() (__log_level != 0 ? \
117 log_const_source_id(__log_current_const_data) : 0U)
118
123#define LOG_CURRENT_DYNAMIC_DATA_ADDR() (__log_level ? \
124 __log_current_dynamic_data : (struct log_source_dynamic_data *)0U)
125
130#define LOG_DYNAMIC_ID_GET(_addr) \
131 COND_CODE_1(CONFIG_LOG, ((__log_level ? log_dynamic_source_id(_addr) : 0)), (0))
132
133/* Set of defines that are set to 1 if function name prefix is enabled for given level. */
134#define Z_LOG_FUNC_PREFIX_0U 0
135#define Z_LOG_FUNC_PREFIX_1U COND_CODE_1(CONFIG_LOG_FUNC_NAME_PREFIX_ERR, (1), (0))
136#define Z_LOG_FUNC_PREFIX_2U COND_CODE_1(CONFIG_LOG_FUNC_NAME_PREFIX_WRN, (1), (0))
137#define Z_LOG_FUNC_PREFIX_3U COND_CODE_1(CONFIG_LOG_FUNC_NAME_PREFIX_INF, (1), (0))
138#define Z_LOG_FUNC_PREFIX_4U COND_CODE_1(CONFIG_LOG_FUNC_NAME_PREFIX_DBG, (1), (0))
139
149#define Z_LOG_STR_WITH_PREFIX2(...) \
150 "%s: " GET_ARG_N(1, __VA_ARGS__), (const char *)__func__\
151 COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__),\
152 (),\
153 (, GET_ARGS_LESS_N(1, __VA_ARGS__))\
154 )
155
156/* Macro handles case when no format string is provided: e.g. LOG_DBG().
157 * Handling of format string is deferred to the next level macro.
158 */
159#define Z_LOG_STR_WITH_PREFIX(...) \
160 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
161 ("%s", (const char *)__func__), \
162 (Z_LOG_STR_WITH_PREFIX2(__VA_ARGS__)))
163
169#define Z_LOG_STR(_level, ...) \
170 COND_CODE_1(UTIL_CAT(Z_LOG_FUNC_PREFIX_##_level), \
171 (Z_LOG_STR_WITH_PREFIX(__VA_ARGS__)), (__VA_ARGS__))
172
173/******************************************************************************/
174/****************** Internal macros for log frontend **************************/
175/******************************************************************************/
177#define Z_LOG_NARGS_POSTFIX_IMPL( \
178 _ignored, \
179 _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
180 _11, _12, _13, _14, N, ...) N
181
190#define Z_LOG_NARGS_POSTFIX(...) \
191 Z_LOG_NARGS_POSTFIX_IMPL(__VA_ARGS__, LONG, LONG, LONG, LONG, LONG, \
192 LONG, LONG, LONG, LONG, LONG, LONG, LONG, 3, 2, 1, 0, ~)
193
194#define Z_LOG_INTERNAL_X(N, ...) UTIL_CAT(_LOG_INTERNAL_, N)(__VA_ARGS__)
195
196#define Z_LOG_INTERNAL2(is_user_context, _src_level, ...) do { \
197 if (is_user_context) { \
198 log_from_user(_src_level, __VA_ARGS__); \
199 } else if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
200 log_string_sync(_src_level, __VA_ARGS__); \
201 } else { \
202 Z_LOG_INTERNAL_X(Z_LOG_NARGS_POSTFIX(__VA_ARGS__), \
203 _src_level, __VA_ARGS__); \
204 } \
205} while (false)
206
207#define Z_LOG_INTERNAL(is_user_context, _level, _source, _dsource, ...) do { \
208 uint16_t src_id = \
209 IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
210 LOG_DYNAMIC_ID_GET(_dsource) : LOG_CONST_ID_GET(_source); \
211 struct log_msg_ids src_level = { \
212 .level = _level, \
213 .domain_id = CONFIG_LOG_DOMAIN_ID, \
214 .source_id = src_id \
215 }; \
216 Z_LOG_INTERNAL2(is_user_context, src_level, \
217 Z_LOG_STR(_level, __VA_ARGS__)); \
218} while (0)
219
220#define _LOG_INTERNAL_0(_src_level, _str) \
221 log_0(_str, _src_level)
222
223#define _LOG_INTERNAL_1(_src_level, _str, _arg0) \
224 log_1(_str, (log_arg_t)(_arg0), _src_level)
225
226#define _LOG_INTERNAL_2(_src_level, _str, _arg0, _arg1) \
227 log_2(_str, (log_arg_t)(_arg0), (log_arg_t)(_arg1), _src_level)
228
229#define _LOG_INTERNAL_3(_src_level, _str, _arg0, _arg1, _arg2) \
230 log_3(_str, (log_arg_t)(_arg0), (log_arg_t)(_arg1), (log_arg_t)(_arg2), _src_level)
231
232#define __LOG_ARG_CAST(_x) (log_arg_t)(_x)
233
234#define __LOG_ARGUMENTS(...) FOR_EACH(__LOG_ARG_CAST, (,), __VA_ARGS__)
235
236#define _LOG_INTERNAL_LONG(_src_level, _str, ...) \
237 do { \
238 log_arg_t args[] = {__LOG_ARGUMENTS(__VA_ARGS__)};\
239 log_n(_str, args, ARRAY_SIZE(args), _src_level); \
240 } while (false)
241
242#define Z_LOG_LEVEL_CHECK(_level, _check_level, _default_level) \
243 (_level <= Z_LOG_RESOLVED_LEVEL(_check_level, _default_level))
244
245#define Z_LOG_CONST_LEVEL_CHECK(_level) \
246 (IS_ENABLED(CONFIG_LOG) && \
247 (Z_LOG_LEVEL_CHECK(_level, CONFIG_LOG_OVERRIDE_LEVEL, LOG_LEVEL_NONE) \
248 || \
249 ((IS_ENABLED(CONFIG_LOG_OVERRIDE_LEVEL) == false) && \
250 (_level <= __log_level) && \
251 (_level <= CONFIG_LOG_MAX_LEVEL) \
252 ) \
253 ))
254
255/*****************************************************************************/
256/****************** Defiinitions used by minimal logging *********************/
257/*****************************************************************************/
258void z_log_minimal_hexdump_print(int level, const void *data, size_t size);
259void z_log_minimal_vprintk(const char *fmt, va_list ap);
260void z_log_minimal_printk(const char *fmt, ...);
261
262#define Z_LOG_TO_PRINTK(_level, fmt, ...) do { \
263 z_log_minimal_printk("%c: " fmt "\n", \
264 z_log_minimal_level_to_char(_level), \
265 ##__VA_ARGS__); \
266} while (false)
267
268#define Z_LOG_TO_VPRINTK(_level, fmt, valist) do { \
269 z_log_minimal_printk("%c: ", z_log_minimal_level_to_char(_level)); \
270 z_log_minimal_vprintk(fmt, valist); \
271 z_log_minimal_printk("\n"); \
272} while (false)
273
274static inline char z_log_minimal_level_to_char(int level)
275{
276 switch (level) {
277 case LOG_LEVEL_ERR:
278 return 'E';
279 case LOG_LEVEL_WRN:
280 return 'W';
281 case LOG_LEVEL_INF:
282 return 'I';
283 case LOG_LEVEL_DBG:
284 return 'D';
285 default:
286 return '?';
287 }
288}
289
290#define Z_LOG_INST(_inst) COND_CODE_1(CONFIG_LOG, (_inst), NULL)
291
292/*****************************************************************************/
293/****************** Macros for standard logging ******************************/
294/*****************************************************************************/
295#define Z_LOG2(_level, _source, _dsource, ...) do { \
296 if (!Z_LOG_CONST_LEVEL_CHECK(_level)) { \
297 break; \
298 } \
299 if (IS_ENABLED(CONFIG_LOG_MINIMAL)) { \
300 Z_LOG_TO_PRINTK(_level, __VA_ARGS__); \
301 break; \
302 } \
303 \
304 bool is_user_context = k_is_user_context(); \
305 uint32_t filters = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
306 (_dsource)->filters : 0;\
307 if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && !is_user_context && \
308 _level > Z_LOG_RUNTIME_FILTER(filters)) { \
309 break; \
310 } \
311 if (IS_ENABLED(CONFIG_LOG2)) { \
312 int _mode; \
313 void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
314 (void *)_dsource : (void *)_source; \
315 Z_LOG_MSG2_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), _mode, \
316 CONFIG_LOG_DOMAIN_ID, _src, _level, NULL,\
317 0, __VA_ARGS__); \
318 } else { \
319 Z_LOG_INTERNAL(is_user_context, _level, \
320 _source, _dsource, __VA_ARGS__);\
321 } \
322 if (false) { \
323 /* Arguments checker present but never evaluated.*/ \
324 /* Placed here to ensure that __VA_ARGS__ are*/ \
325 /* evaluated once when log is enabled.*/ \
326 z_log_printf_arg_checker(__VA_ARGS__); \
327 } \
328} while (false)
329
330#define Z_LOG(_level, ...) \
331 Z_LOG2(_level, __log_current_const_data, __log_current_dynamic_data, __VA_ARGS__)
332
333#define Z_LOG_INSTANCE(_level, _inst, ...) \
334 Z_LOG2(_level, \
335 COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, (NULL), (Z_LOG_INST(_inst))), \
336 (struct log_source_dynamic_data *)COND_CODE_1( \
337 CONFIG_LOG_RUNTIME_FILTERING, \
338 (Z_LOG_INST(_inst)), (NULL)), \
339 __VA_ARGS__)
340
341/*****************************************************************************/
342/****************** Macros for hexdump logging *******************************/
343/*****************************************************************************/
344#define Z_LOG_HEXDUMP2(_level, _source, _dsource, _data, _len, ...) do { \
345 const char *_str = GET_ARG_N(1, __VA_ARGS__); \
346 if (!Z_LOG_CONST_LEVEL_CHECK(_level)) { \
347 break; \
348 } \
349 bool is_user_context = k_is_user_context(); \
350 uint32_t filters = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
351 (_dsource)->filters : 0;\
352 \
353 if (IS_ENABLED(CONFIG_LOG_MINIMAL)) { \
354 Z_LOG_TO_PRINTK(_level, "%s", _str); \
355 z_log_minimal_hexdump_print(_level, \
356 (const char *)_data, _len);\
357 break; \
358 } \
359 if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && !is_user_context && \
360 _level > Z_LOG_RUNTIME_FILTER(filters)) { \
361 break; \
362 } \
363 if (IS_ENABLED(CONFIG_LOG2)) { \
364 int mode; \
365 void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
366 (void *)_dsource : (void *)_source; \
367 Z_LOG_MSG2_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), mode, \
368 CONFIG_LOG_DOMAIN_ID, _src, _level, \
369 _data, _len, \
370 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
371 (), \
372 (COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
373 ("%s", __VA_ARGS__), (__VA_ARGS__)))));\
374 break; \
375 } \
376 uint16_t src_id = \
377 IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
378 LOG_DYNAMIC_ID_GET(_dsource) : LOG_CONST_ID_GET(_source);\
379 struct log_msg_ids src_level = { \
380 .level = _level, \
381 .domain_id = CONFIG_LOG_DOMAIN_ID, \
382 .source_id = src_id, \
383 }; \
384 if (is_user_context) { \
385 log_hexdump_from_user(src_level, _str, \
386 (const char *)_data, _len); \
387 } else if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
388 log_hexdump_sync(src_level, _str, (const char *)_data, _len); \
389 } else { \
390 log_hexdump(_str, (const char *)_data, _len, src_level); \
391 } \
392} while (false)
393
394#define Z_LOG_HEXDUMP(_level, _data, _length, ...) \
395 Z_LOG_HEXDUMP2(_level, \
396 __log_current_const_data, \
397 __log_current_dynamic_data, \
398 _data, _length, __VA_ARGS__)
399
400#define Z_LOG_HEXDUMP_INSTANCE(_level, _inst, _data, _length, _str) \
401 Z_LOG_HEXDUMP2(_level, \
402 COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, (NULL), (Z_LOG_INST(_inst))), \
403 (struct log_source_dynamic_data *)COND_CODE_1( \
404 CONFIG_LOG_RUNTIME_FILTERING, \
405 (Z_LOG_INST(_inst)), (NULL)), \
406 _data, _length, _str)
407
408/*****************************************************************************/
409/****************** Filtering macros *****************************************/
410/*****************************************************************************/
411
413#define LOG_LEVEL_BITS 3U
414
416#define LOG_FILTER_SLOT_SIZE LOG_LEVEL_BITS
417
419#define LOG_FILTERS_NUM_OF_SLOTS (32 / LOG_FILTER_SLOT_SIZE)
420
422#define LOG_FILTER_SLOT_MASK (BIT(LOG_FILTER_SLOT_SIZE) - 1U)
423
428#define LOG_FILTER_SLOT_SHIFT(_id) (LOG_FILTER_SLOT_SIZE * (_id))
429
430#define LOG_FILTER_SLOT_GET(_filters, _id) \
431 ((*(_filters) >> LOG_FILTER_SLOT_SHIFT(_id)) & LOG_FILTER_SLOT_MASK)
432
433#define LOG_FILTER_SLOT_SET(_filters, _id, _filter) \
434 do { \
435 *(_filters) &= ~(LOG_FILTER_SLOT_MASK << \
436 LOG_FILTER_SLOT_SHIFT(_id)); \
437 *(_filters) |= ((_filter) & LOG_FILTER_SLOT_MASK) << \
438 LOG_FILTER_SLOT_SHIFT(_id); \
439 } while (false)
440
441#define LOG_FILTER_AGGR_SLOT_IDX 0
442
443#define LOG_FILTER_AGGR_SLOT_GET(_filters) \
444 LOG_FILTER_SLOT_GET(_filters, LOG_FILTER_AGGR_SLOT_IDX)
445
446#define LOG_FILTER_FIRST_BACKEND_SLOT_IDX 1
447
448/* Return aggregated (highest) level for all enabled backends, e.g. if there
449 * are 3 active backends, one backend is set to get INF logs from a module and
450 * two other backends are set for ERR, returned level is INF.
451 */
452#define Z_LOG_RUNTIME_FILTER(_filter) \
453 LOG_FILTER_SLOT_GET(&_filter, LOG_FILTER_AGGR_SLOT_IDX)
454
458#define LOG_LEVEL_INTERNAL_RAW_STRING LOG_LEVEL_NONE
459
460extern struct log_source_const_data __log_const_start[];
461extern struct log_source_const_data __log_const_end[];
462
469
470#define Z_LOG_PRINTK(...) do { \
471 if (IS_ENABLED(CONFIG_LOG_MINIMAL) || !IS_ENABLED(CONFIG_LOG2)) { \
472 z_log_minimal_printk(__VA_ARGS__); \
473 break; \
474 } \
475 int _mode; \
476 if (0) {\
477 z_log_printf_arg_checker(__VA_ARGS__); \
478 } \
479 Z_LOG_MSG2_CREATE(!IS_ENABLED(CONFIG_USERSPACE), _mode, \
480 CONFIG_LOG_DOMAIN_ID, NULL, \
481 LOG_LEVEL_INTERNAL_RAW_STRING, NULL, 0, __VA_ARGS__);\
482} while (0)
483
484
490static inline const char *log_name_get(uint32_t source_id)
491{
492 return __log_const_start[source_id].name;
493}
494
501{
502 return __log_const_start[source_id].level;
503}
504
513 const struct log_source_const_data *data)
514{
515 return ((uint8_t *)data - (uint8_t *)__log_const_start)/
516 sizeof(struct log_source_const_data);
517}
518
520static inline uint32_t log_sources_count(void)
521{
522 return log_const_source_id(__log_const_end);
523}
524
525extern struct log_source_dynamic_data __log_dynamic_start[];
526extern struct log_source_dynamic_data __log_dynamic_end[];
527
532#define LOG_ITEM_DYNAMIC_DATA(_name) UTIL_CAT(log_dynamic_, _name)
533
534#define LOG_INSTANCE_DYNAMIC_DATA(_module_name, _inst) \
535 LOG_ITEM_DYNAMIC_DATA(LOG_INSTANCE_FULL_NAME(_module_name, _inst))
536
544{
545 return &__log_dynamic_start[source_id].filters;
546}
547
556{
557 return ((uint8_t *)data - (uint8_t *)__log_dynamic_start)/
558 sizeof(struct log_source_dynamic_data);
559}
560
561/* Initialize runtime filters */
562void z_log_runtime_filters_init(void);
563
564/* Notify log_core that a backend was enabled. */
565void z_log_notify_backend_enabled(void);
566
568static inline __printf_like(1, 2)
569void z_log_printf_arg_checker(const char *fmt, ...)
570{
571 ARG_UNUSED(fmt);
572}
573
579void log_0(const char *str, struct log_msg_ids src_level);
580
587void log_1(const char *str,
588 log_arg_t arg1,
589 struct log_msg_ids src_level);
590
598void log_2(const char *str,
599 log_arg_t arg1,
600 log_arg_t arg2,
601 struct log_msg_ids src_level);
602
611void log_3(const char *str,
612 log_arg_t arg1,
613 log_arg_t arg2,
614 log_arg_t arg3,
615 struct log_msg_ids src_level);
616
624void log_n(const char *str,
625 log_arg_t *args,
626 uint32_t narg,
627 struct log_msg_ids src_level);
628
636void log_hexdump(const char *str, const void *data, uint32_t length,
637 struct log_msg_ids src_level);
638
645void log_string_sync(struct log_msg_ids src_level, const char *fmt, ...);
646
654void log_hexdump_sync(struct log_msg_ids src_level, const char *metadata,
655 const void *data, uint32_t len);
656
667void log_generic(struct log_msg_ids src_level, const char *fmt, va_list ap,
668 enum log_strdup_action strdup_action);
669
679static inline void log2_generic(uint8_t level, const char *fmt, va_list ap)
680{
681 z_log_msg2_runtime_vcreate(CONFIG_LOG_DOMAIN_ID, NULL, level,
682 NULL, 0, fmt, ap);
683}
684
694uint32_t log_count_args(const char *fmt);
695
702void log_generic_from_user(struct log_msg_ids src_level,
703 const char *fmt, va_list ap);
704
711bool log_is_strdup(const void *buf);
712
717void log_free(void *buf);
718
723
731
738
741void z_log_dropped(void);
742
747uint32_t z_log_dropped_read_and_clear(void);
748
754bool z_log_dropped_pending(void);
755
765void __printf_like(2, 3) log_from_user(struct log_msg_ids src_level,
766 const char *fmt, ...);
767
768/* Internal function used by log_from_user(). */
769__syscall void z_log_string_from_user(uint32_t src_level_val, const char *str);
770
782uint32_t z_log_get_s_mask(const char *str, uint32_t nargs);
783
794void log_hexdump_from_user(struct log_msg_ids src_level, const char *metadata,
795 const void *data, uint32_t len);
796
797/* Internal function used by log_hexdump_from_user(). */
798__syscall void z_log_hexdump_from_user(uint32_t src_level_val,
799 const char *metadata,
800 const uint8_t *data, uint32_t len);
801
802/******************************************************************************/
803/********** Mocros _VA operate on var-args parameters. ***************/
804/********* Intended to be used when porting other log systems. ***************/
805/********* Shall be used in the log entry interface function. ***************/
806/********* Speed optimized for up to three arguments number. ***************/
807/******************************************************************************/
808#define Z_LOG_VA(_level, _str, _valist, _argnum, _strdup_action)\
809 __LOG_VA(_level, \
810 __log_current_const_data, \
811 __log_current_dynamic_data, \
812 _str, _valist, _argnum, _strdup_action)
813
814#define __LOG_VA(_level, _source, _dsource, _str, _valist, _argnum, _strdup_action) do { \
815 if (!Z_LOG_CONST_LEVEL_CHECK(_level)) { \
816 break; \
817 } \
818 if (IS_ENABLED(CONFIG_LOG_MINIMAL)) { \
819 Z_LOG_TO_VPRINTK(_level, _str, _valist); \
820 break; \
821 } \
822 \
823 bool is_user_context = k_is_user_context(); \
824 uint32_t filters = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
825 _dsource->filters : 0;\
826 if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && !is_user_context && \
827 _level > Z_LOG_RUNTIME_FILTER(filters)) { \
828 break; \
829 } \
830 if (IS_ENABLED(CONFIG_LOG2)) { \
831 z_log_msg2_runtime_vcreate(CONFIG_LOG_DOMAIN_ID, _source, \
832 _level, NULL, 0, _str, _valist); \
833 break; \
834 } \
835 uint16_t _id = \
836 IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
837 LOG_DYNAMIC_ID_GET(_dsource) : LOG_CONST_ID_GET(_source);\
838 struct log_msg_ids src_level = { \
839 .level = _level, \
840 .domain_id = CONFIG_LOG_DOMAIN_ID, \
841 .source_id = _id \
842 }; \
843 __LOG_INTERNAL_VA(is_user_context, \
844 src_level, \
845 _str, _valist, _argnum, \
846 _strdup_action); \
847} while (false)
848
861static inline log_arg_t z_log_do_strdup(uint32_t msk, uint32_t idx,
862 log_arg_t param,
863 enum log_strdup_action action)
864{
865#ifndef CONFIG_LOG_MINIMAL
866 char *z_log_strdup(const char *str);
867
868 if (msk & (1 << idx)) {
869 const char *str = (const char *)param;
870 /* is_rodata(str) is not checked,
871 * because log_strdup does it.
872 * Hence, we will do only optional check
873 * if already not duplicated.
874 */
875 if (action == LOG_STRDUP_EXEC || !log_is_strdup(str)) {
876 param = (log_arg_t)z_log_strdup(str);
877 }
878 }
879#else
880 ARG_UNUSED(msk);
881 ARG_UNUSED(idx);
882 ARG_UNUSED(action);
883#endif
884 return param;
885}
886
887#define __LOG_INTERNAL_VA(is_user_context, _src_level, _str, _valist, \
888 _argnum, _strdup_action) \
889do { \
890 if (is_user_context) { \
891 log_generic_from_user(_src_level, _str, _valist); \
892 } else if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
893 log_generic(_src_level, _str, _valist, _strdup_action); \
894 } else if (_argnum == 0) { \
895 _LOG_INTERNAL_0(_src_level, _str); \
896 } else { \
897 uint32_t mask = (_strdup_action != LOG_STRDUP_SKIP) ? \
898 z_log_get_s_mask(_str, _argnum) \
899 : 0; \
900 \
901 if (_argnum == 1) { \
902 _LOG_INTERNAL_1(_src_level, _str, \
903 z_log_do_strdup(mask, 0, \
904 va_arg(_valist, log_arg_t), _strdup_action));\
905 } else if (_argnum == 2) { \
906 _LOG_INTERNAL_2(_src_level, _str, \
907 z_log_do_strdup(mask, 0, \
908 va_arg(_valist, log_arg_t), _strdup_action), \
909 z_log_do_strdup(mask, 1, \
910 va_arg(_valist, log_arg_t), _strdup_action));\
911 } else if (_argnum == 3) { \
912 _LOG_INTERNAL_3(_src_level, _str, \
913 z_log_do_strdup(mask, 0, \
914 va_arg(_valist, log_arg_t), _strdup_action), \
915 z_log_do_strdup(mask, 1, \
916 va_arg(_valist, log_arg_t), _strdup_action), \
917 z_log_do_strdup(mask, 2, \
918 va_arg(_valist, log_arg_t), _strdup_action));\
919 } else { \
920 log_generic(_src_level, _str, _valist, _strdup_action);\
921 } \
922 } \
923} while (false)
924
925#include <syscalls/log_core.h>
926
927#ifdef __cplusplus
928}
929#endif
930
931#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_CORE_H_ */
void
Definition: eswifi_shell.c:15
unsigned long log_arg_t
Log argument type.
Definition: log_msg.h:29
static uint32_t * log_dynamic_filters_get(uint32_t source_id)
Get pointer to the filter set of the log source.
Definition: log_core.h:543
uint32_t log_get_strdup_longest_string(void)
Get length of the longest string duplicated.
uint32_t log_get_strdup_pool_utilization(void)
Get maximal number of simultaneously allocated buffers for string duplicates.
void log_free(void *buf)
Free allocated buffer.
void log_hexdump_sync(struct log_msg_ids src_level, const char *metadata, const void *data, uint32_t len)
Process log hexdump message synchronously.
void log_string_sync(struct log_msg_ids src_level, const char *fmt,...)
Process log message synchronously.
#define LOG_LEVEL_INF
Definition: log_core.h:21
static void log2_generic(uint8_t level, const char *fmt, va_list ap)
Writes a generic log message to the logging v2.
Definition: log_core.h:679
uint32_t log_count_args(const char *fmt)
Returns number of arguments visible from format string.
#define CONFIG_LOG_DOMAIN_ID
Definition: log_core.h:34
void log_hexdump_from_user(struct log_msg_ids src_level, const char *metadata, const void *data, uint32_t len)
Log binary data (displayed as hexdump) from user mode context.
void log_n(const char *str, log_arg_t *args, uint32_t narg, struct log_msg_ids src_level)
Standard log with arguments list.
#define LOG_LEVEL_WRN
Definition: log_core.h:20
void log_generic(struct log_msg_ids src_level, const char *fmt, va_list ap, enum log_strdup_action strdup_action)
Writes a generic log message to the log.
uint32_t log_get_strdup_pool_current_utilization(void)
Get current number of allocated buffers for string duplicates.
static const char * log_name_get(uint32_t source_id)
Get name of the log source.
Definition: log_core.h:490
void log_generic_from_user(struct log_msg_ids src_level, const char *fmt, va_list ap)
Writes a generic log message to the log from user mode.
void log_1(const char *str, log_arg_t arg1, struct log_msg_ids src_level)
Standard log with one argument.
static uint8_t log_compiled_level_get(uint32_t source_id)
Get compiled level of the log source.
Definition: log_core.h:500
void log_3(const char *str, log_arg_t arg1, log_arg_t arg2, log_arg_t arg3, struct log_msg_ids src_level)
Standard log with three arguments.
log_strdup_action
Enum with possible actions for strdup operation.
Definition: log_core.h:464
@ LOG_STRDUP_CHECK_EXEC
Definition: log_core.h:467
@ LOG_STRDUP_EXEC
Definition: log_core.h:466
@ LOG_STRDUP_SKIP
Definition: log_core.h:465
static uint32_t log_dynamic_source_id(struct log_source_dynamic_data *data)
Get index of the log source based on the address of the dynamic data associated with the source.
Definition: log_core.h:555
#define LOG_LEVEL_ERR
Definition: log_core.h:19
void log_0(const char *str, struct log_msg_ids src_level)
Standard log with no arguments.
#define LOG_LEVEL_DBG
Definition: log_core.h:22
static uint32_t log_const_source_id(const struct log_source_const_data *data)
Get index of the log source based on the address of the constant data associated with the source.
Definition: log_core.h:512
bool log_is_strdup(const void *buf)
Check if address belongs to the memory pool used for transient.
void log_2(const char *str, log_arg_t arg1, log_arg_t arg2, struct log_msg_ids src_level)
Standard log with two arguments.
static uint32_t log_sources_count(void)
Get number of registered sources.
Definition: log_core.h:520
void log_from_user(struct log_msg_ids src_level, const char *fmt,...)
Log a message from user mode context.
void log_hexdump(const char *str, const void *data, uint32_t length, struct log_msg_ids src_level)
Hexdump log.
__UINT32_TYPE__ uint32_t
Definition: stdint.h:60
__UINT8_TYPE__ uint8_t
Definition: stdint.h:58
Part of log message header identifying source and level.
Definition: log_msg.h:85
Constant data associated with the source of log messages.
Definition: log_instance.h:16
uint8_t level
Definition: log_instance.h:18
const char * name
Definition: log_instance.h:17
Dynamic data associated with the source of log messages.
Definition: log_instance.h:29
uint32_t filters
Definition: log_instance.h:30
static fdata_t data[2]
Definition: test_fifo_contexts.c:15
Misc utilities.