Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
log_msg.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_MSG_H_
7#define ZEPHYR_INCLUDE_LOGGING_LOG_MSG_H_
8
11#include <zephyr/sys/cbprintf.h>
12#include <zephyr/sys/atomic.h>
14#include <zephyr/sys/util.h>
15#include <string.h>
16#include <zephyr/toolchain.h>
17
18#ifdef __GNUC__
19#ifndef alloca
20#define alloca __builtin_alloca
21#endif
22#else
23#include <alloca.h>
24#endif
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#define LOG_MSG_DEBUG 0
31#define LOG_MSG_DBG(...) IF_ENABLED(LOG_MSG_DEBUG, (printk(__VA_ARGS__)))
32
33#ifdef CONFIG_LOG_TIMESTAMP_64BIT
35#else
37#endif
38
45
46#define Z_LOG_MSG_LOG 0
47
48#define Z_LOG_MSG_PACKAGE_BITS 11
49
50#define Z_LOG_MSG_MAX_PACKAGE BIT_MASK(Z_LOG_MSG_PACKAGE_BITS)
51
52#define LOG_MSG_GENERIC_HDR \
53 MPSC_PBUF_HDR;\
54 uint32_t type:1
55
63
69
72/* Attempting to keep best alignment. When address is 64 bit and timestamp 32
73 * swap the order to have 16 byte header instead of 24 byte.
74 */
75#if (INTPTR_MAX > INT32_MAX) && !defined(CONFIG_LOG_TIMESTAMP_64BIT)
77 const void *source;
78#else
79 const void *source;
81#endif
82#if defined(CONFIG_LOG_THREAD_ID_PREFIX)
83 void *tid;
84#endif
85#if defined(CONFIG_LOG_CORE_ID_PREFIX)
86 uint8_t core_id;
87#endif
88};
89/* Messages are aligned to alignment required by cbprintf package. */
90#define Z_LOG_MSG_ALIGNMENT CBPRINTF_PACKAGE_ALIGNMENT
91
92#define Z_LOG_MSG_PADDING \
93 ((sizeof(struct log_msg_hdr) % Z_LOG_MSG_ALIGNMENT) > 0 ? \
94 (Z_LOG_MSG_ALIGNMENT - (sizeof(struct log_msg_hdr) % Z_LOG_MSG_ALIGNMENT)) : \
95 0)
96
97struct log_msg {
99 /* Adding padding to ensure that cbprintf package that follows is
100 * properly aligned.
101 */
102 uint8_t padding[Z_LOG_MSG_PADDING];
104};
105
109BUILD_ASSERT(sizeof(struct log_msg) % Z_LOG_MSG_ALIGNMENT == 0,
110 "Log msg size must aligned");
114
115
119
125
130enum z_log_msg_mode {
131 /* Runtime mode is least efficient but supports all cases thus it is
132 * treated as a fallback method when others cannot be used.
133 */
134 Z_LOG_MSG_MODE_RUNTIME,
135 /* Mode creates statically a string package on stack and calls a
136 * function for creating a message. It takes code size than
137 * Z_LOG_MSG_MODE_ZERO_COPY but is a bit slower.
138 */
139 Z_LOG_MSG_MODE_FROM_STACK,
140
141 /* Mode calculates size of the message and allocates it and writes
142 * directly to the message space. It is the fastest method but requires
143 * more code size.
144 */
145 Z_LOG_MSG_MODE_ZERO_COPY,
146
147 /* Mode optimized for simple messages with 0 to 2 32 bit word arguments.*/
148 Z_LOG_MSG_MODE_SIMPLE,
149};
150
151#define Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, _plen, _dlen) \
152{ \
153 .valid = 0, \
154 .busy = 0, \
155 .type = Z_LOG_MSG_LOG, \
156 .domain = (_domain_id), \
157 .level = (_level), \
158 .package_len = (_plen), \
159 .data_len = (_dlen), \
160}
161
162#define Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt) \
163 (CBPRINTF_PACKAGE_FIRST_RO_STR_CNT(_cstr_cnt) | \
164 (IS_ENABLED(CONFIG_LOG_MSG_APPEND_RO_STRING_LOC) ? \
165 CBPRINTF_PACKAGE_ADD_STRING_IDXS : 0))
166
167#ifdef CONFIG_LOG_USE_VLA
168#define Z_LOG_MSG_ON_STACK_ALLOC(ptr, len) \
169 long long _ll_buf[DIV_ROUND_UP(len, sizeof(long long))]; \
170 long double _ld_buf[DIV_ROUND_UP(len, sizeof(long double))]; \
171 (ptr) = (sizeof(long double) == Z_LOG_MSG_ALIGNMENT) ? \
172 (struct log_msg *)_ld_buf : (struct log_msg *)_ll_buf; \
173 if (IS_ENABLED(CONFIG_LOG_TEST_CLEAR_MESSAGE_SPACE)) { \
174 /* During test fill with 0's to simplify message comparison */ \
175 memset((ptr), 0, (len)); \
176 }
177#else /* Z_LOG_MSG_USE_VLA */
178/* When VLA cannot be used we need to trick compiler a bit and create multiple
179 * fixed size arrays and take the smallest one that will fit the message.
180 * Compiler will remove unused arrays and stack usage will be kept similar
181 * to vla case, rounded to the size of the used buffer.
182 */
183#define Z_LOG_MSG_ON_STACK_ALLOC(ptr, len) \
184 long long _ll_buf32[32 / sizeof(long long)]; \
185 long long _ll_buf48[48 / sizeof(long long)]; \
186 long long _ll_buf64[64 / sizeof(long long)]; \
187 long long _ll_buf128[128 / sizeof(long long)]; \
188 long long _ll_buf256[256 / sizeof(long long)]; \
189 long double _ld_buf32[32 / sizeof(long double)]; \
190 long double _ld_buf48[48 / sizeof(long double)]; \
191 long double _ld_buf64[64 / sizeof(long double)]; \
192 long double _ld_buf128[128 / sizeof(long double)]; \
193 long double _ld_buf256[256 / sizeof(long double)]; \
194 if (sizeof(long double) == Z_LOG_MSG_ALIGNMENT) { \
195 ptr = (len > 128) ? (struct log_msg *)_ld_buf256 : \
196 ((len > 64) ? (struct log_msg *)_ld_buf128 : \
197 ((len > 48) ? (struct log_msg *)_ld_buf64 : \
198 ((len > 32) ? (struct log_msg *)_ld_buf48 : \
199 (struct log_msg *)_ld_buf32)));\
200 } else { \
201 ptr = (len > 128) ? (struct log_msg *)_ll_buf256 : \
202 ((len > 64) ? (struct log_msg *)_ll_buf128 : \
203 ((len > 48) ? (struct log_msg *)_ll_buf64 : \
204 ((len > 32) ? (struct log_msg *)_ll_buf48 : \
205 (struct log_msg *)_ll_buf32)));\
206 } \
207 if (IS_ENABLED(CONFIG_LOG_TEST_CLEAR_MESSAGE_SPACE)) { \
208 /* During test fill with 0's to simplify message comparison */ \
209 memset((ptr), 0, (len)); \
210 }
211#endif /* Z_LOG_MSG_USE_VLA */
212
213#define Z_LOG_MSG_ALIGN_OFFSET \
214 offsetof(struct log_msg, data)
215
216#define Z_LOG_MSG_LEN(pkg_len, data_len) \
217 (offsetof(struct log_msg, data) + (pkg_len) + (data_len))
218
219#define Z_LOG_MSG_ALIGNED_WLEN(pkg_len, data_len) \
220 DIV_ROUND_UP(ROUND_UP(Z_LOG_MSG_LEN(pkg_len, data_len), \
221 Z_LOG_MSG_ALIGNMENT), \
222 sizeof(uint32_t))
223
224/*
225 * With Zephyr SDK 0.14.2, aarch64-zephyr-elf-gcc (10.3.0) fails to ensure $sp
226 * is below the active memory during message construction. As a result,
227 * interrupts happening in the middle of that process can end up smashing active
228 * data and causing a logging fault. Work around this by inserting a compiler
229 * barrier after the allocation and before any use to make sure GCC moves the
230 * stack pointer soon enough
231 */
232
233#define Z_LOG_ARM64_VLA_PROTECT() compiler_barrier()
234
235#define _LOG_MSG_SIMPLE_XXXX0 1
236#define _LOG_MSG_SIMPLE_XXXX1 1
237#define _LOG_MSG_SIMPLE_XXXX2 1
238
239/* Determine if amount of arguments (less than 3) qualifies to simple message. */
240#define LOG_MSG_SIMPLE_ARG_CNT_CHECK(...) \
241 COND_CODE_1(UTIL_CAT(_LOG_MSG_SIMPLE_XXXX, NUM_VA_ARGS_LESS_1(__VA_ARGS__)), (1), (0))
242
243/* Set of marcos used to determine if arguments type allows simplified message creation mode. */
244#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_0(fmt) 1
245#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_1(fmt, arg) Z_CBPRINTF_IS_WORD_NUM(arg)
246#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_2(fmt, arg0, arg1) \
247 Z_CBPRINTF_IS_WORD_NUM(arg0) && Z_CBPRINTF_IS_WORD_NUM(arg1)
248
253#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK(...) \
254 UTIL_CAT(LOG_MSG_SIMPLE_ARG_TYPE_CHECK_, NUM_VA_ARGS_LESS_1(__VA_ARGS__))(__VA_ARGS__)
255
268#define LOG_MSG_SIMPLE_CHECK(...) \
269 COND_CODE_1(CONFIG_64BIT, (0), (\
270 COND_CODE_1(LOG_MSG_SIMPLE_ARG_CNT_CHECK(__VA_ARGS__), ( \
271 LOG_MSG_SIMPLE_ARG_TYPE_CHECK(__VA_ARGS__)), (0))))
272
273/* Helper macro for handing log with one argument. Macro casts the first argument to uint32_t. */
274#define Z_LOG_MSG_SIMPLE_CREATE_1(_source, _level, ...) \
275 z_log_msg_simple_create_1(_source, _level, GET_ARG_N(1, __VA_ARGS__), \
276 (uint32_t)(uintptr_t)GET_ARG_N(2, __VA_ARGS__))
277
278/* Helper macro for handing log with two arguments. Macro casts arguments to uint32_t.
279 */
280#define Z_LOG_MSG_SIMPLE_CREATE_2(_source, _level, ...) \
281 z_log_msg_simple_create_2(_source, _level, GET_ARG_N(1, __VA_ARGS__), \
282 (uint32_t)(uintptr_t)GET_ARG_N(2, __VA_ARGS__), \
283 (uint32_t)(uintptr_t)GET_ARG_N(3, __VA_ARGS__))
284
285/* Call specific function based on the number of arguments.
286 * Since up 2 to arguments are supported COND_CODE_0 and COND_CODE_1 can be used to
287 * handle all cases (0, 1 and 2 arguments). When tracing is enable then for each
288 * function a macro is create. The difference between function and macro is that
289 * macro is applied to any input arguments so we need to make sure that it is
290 * always called with proper number of arguments. For that it is wrapped around
291 * into another macro and dummy arguments to cover for cases when there is less
292 * arguments in a log call.
293 */
294#define Z_LOG_MSG_SIMPLE_FUNC2(arg_cnt, _source, _level, ...) \
295 COND_CODE_0(arg_cnt, \
296 (z_log_msg_simple_create_0(_source, _level, GET_ARG_N(1, __VA_ARGS__))), \
297 (COND_CODE_1(arg_cnt, ( \
298 Z_LOG_MSG_SIMPLE_CREATE_1(_source, _level, __VA_ARGS__, dummy) \
299 ), ( \
300 Z_LOG_MSG_SIMPLE_CREATE_2(_source, _level, __VA_ARGS__, dummy, dummy) \
301 ) \
302 )))
303
313#define LOG_MSG_SIMPLE_FUNC(_source, _level, ...) \
314 Z_LOG_MSG_SIMPLE_FUNC2(NUM_VA_ARGS_LESS_1(__VA_ARGS__), _source, _level, __VA_ARGS__)
315
326#define Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, ...) \
327 IF_ENABLED(LOG_MSG_SIMPLE_ARG_CNT_CHECK(__VA_ARGS__), (\
328 LOG_MSG_SIMPLE_FUNC(_source, _level, __VA_ARGS__); \
329 ))
330
331#define Z_LOG_MSG_STACK_CREATE(_cstr_cnt, _domain_id, _source, _level, _data, _dlen, ...) \
332do { \
333 int _plen; \
334 uint32_t _options = Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt) | \
335 CBPRINTF_PACKAGE_ADD_RW_STR_POS; \
336 if (is_null_no_warn((void *)GET_ARG_N(1, __VA_ARGS__))) { \
337 _plen = 0; \
338 } else { \
339 CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG_ALIGN_OFFSET, _options, \
340 __VA_ARGS__); \
341 /* When GCOV was enabled it was seen that compilation could fail here. */ \
342 /* Adding protection like this helps. It is compile time resolved code */ \
343 /* so has no impact on performance. */ \
344 if (_plen < 0) { \
345 break; \
346 } \
347 } \
348 TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_SHADOW) \
349 struct log_msg *_msg; \
350 TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_SHADOW) \
351 Z_LOG_MSG_ON_STACK_ALLOC(_msg, Z_LOG_MSG_LEN(_plen, 0)); \
352 Z_LOG_ARM64_VLA_PROTECT(); \
353 if (_plen != 0) { \
354 CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, \
355 _plen, Z_LOG_MSG_ALIGN_OFFSET, _options, \
356 __VA_ARGS__);\
357 } \
358 struct log_msg_desc _desc = \
359 Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, \
360 (uint32_t)_plen, _dlen); \
361 LOG_MSG_DBG("creating message on stack: package len: %d, data len: %d\n", \
362 _plen, (int)(_dlen)); \
363 z_log_msg_static_create((void *)(_source), _desc, _msg->data, (_data)); \
364} while (false)
365
366#ifdef CONFIG_LOG_SPEED
367#define Z_LOG_MSG_SIMPLE_CREATE(_cstr_cnt, _domain_id, _source, _level, ...) do { \
368 int _plen; \
369 CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG_ALIGN_OFFSET, \
370 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt), \
371 __VA_ARGS__); \
372 size_t _msg_wlen = Z_LOG_MSG_ALIGNED_WLEN(_plen, 0); \
373 struct log_msg *_msg = z_log_msg_alloc(_msg_wlen); \
374 struct log_msg_desc _desc = \
375 Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, (uint32_t)_plen, 0); \
376 LOG_MSG_DBG("creating message zero copy: package len: %d, msg: %p\n", \
377 _plen, _msg); \
378 if (_msg) { \
379 CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, _plen, \
380 Z_LOG_MSG_ALIGN_OFFSET, \
381 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt), \
382 __VA_ARGS__); \
383 } \
384 z_log_msg_finalize(_msg, (void *)_source, _desc, NULL); \
385} while (false)
386#else
387/* Alternative empty macro created to speed up compilation when LOG_SPEED is
388 * disabled (default).
389 */
390#define Z_LOG_MSG_SIMPLE_CREATE(...)
391#endif
392
393/* Macro handles case when local variable with log message string is created. It
394 * replaces original string literal with that variable.
395 */
396#define Z_LOG_FMT_ARGS_2(_name, ...) \
397 COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
398 (COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
399 (_name), (_name, GET_ARGS_LESS_N(1, __VA_ARGS__)))), \
400 (__VA_ARGS__))
401
411#define Z_LOG_FMT_ARGS(_name, ...) \
412 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
413 (NULL), \
414 (Z_LOG_FMT_ARGS_2(_name, ##__VA_ARGS__)))
415
416#if defined(CONFIG_LOG_USE_TAGGED_ARGUMENTS)
417
418#define Z_LOG_FMT_TAGGED_ARGS_2(_name, ...) \
419 COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
420 (_name, Z_CBPRINTF_TAGGED_ARGS(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
421 GET_ARGS_LESS_N(1, __VA_ARGS__))), \
422 (GET_ARG_N(1, __VA_ARGS__), \
423 Z_CBPRINTF_TAGGED_ARGS(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
424 GET_ARGS_LESS_N(1, __VA_ARGS__))))
425
436#define Z_LOG_FMT_TAGGED_ARGS(_name, ...) \
437 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
438 (Z_CBPRINTF_TAGGED_ARGS(0)), \
439 (Z_LOG_FMT_TAGGED_ARGS_2(_name, ##__VA_ARGS__)))
440
441#define Z_LOG_FMT_RUNTIME_ARGS(...) \
442 Z_LOG_FMT_TAGGED_ARGS(__VA_ARGS__)
443
444#else
445
446#define Z_LOG_FMT_RUNTIME_ARGS(...) \
447 Z_LOG_FMT_ARGS(__VA_ARGS__)
448
449#endif /* CONFIG_LOG_USE_TAGGED_ARGUMENTS */
450
451/* Macro handles case when there is no string provided, in that case variable
452 * is not created.
453 */
454#define Z_LOG_MSG_STR_VAR_IN_SECTION(_name, ...) \
455 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
456 (/* No args provided, no variable */), \
457 (static const char _name[] \
458 __in_section(_log_strings, static, _CONCAT(_name, _)) __used __noasan = \
459 GET_ARG_N(1, __VA_ARGS__);))
460
468#define Z_LOG_MSG_STR_VAR(_name, ...) \
469 IF_ENABLED(CONFIG_LOG_FMT_SECTION, \
470 (Z_LOG_MSG_STR_VAR_IN_SECTION(_name, ##__VA_ARGS__)))
471
511#if defined(CONFIG_LOG_ALWAYS_RUNTIME) || !defined(CONFIG_LOG)
512#define Z_LOG_MSG_CREATE2(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
513 _level, _data, _dlen, ...) \
514do {\
515 Z_LOG_MSG_STR_VAR(_fmt, ##__VA_ARGS__) \
516 z_log_msg_runtime_create((_domain_id), (void *)(_source), \
517 (_level), (uint8_t *)(_data), (_dlen),\
518 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt) | \
519 (IS_ENABLED(CONFIG_LOG_USE_TAGGED_ARGUMENTS) ? \
520 CBPRINTF_PACKAGE_ARGS_ARE_TAGGED : 0), \
521 Z_LOG_FMT_RUNTIME_ARGS(_fmt, ##__VA_ARGS__));\
522 (_mode) = Z_LOG_MSG_MODE_RUNTIME; \
523} while (false)
524#else /* CONFIG_LOG_ALWAYS_RUNTIME || !CONFIG_LOG */
525#define Z_LOG_MSG_CREATE3(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
526 _level, _data, _dlen, ...) \
527do { \
528 Z_LOG_MSG_STR_VAR(_fmt, ##__VA_ARGS__); \
529 bool has_rw_str = CBPRINTF_MUST_RUNTIME_PACKAGE( \
530 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt), \
531 __VA_ARGS__); \
532 if (IS_ENABLED(CONFIG_LOG_SPEED) && (_try_0cpy) && ((_dlen) == 0) && !has_rw_str) {\
533 LOG_MSG_DBG("create zero-copy message\n");\
534 Z_LOG_MSG_SIMPLE_CREATE(_cstr_cnt, _domain_id, _source, \
535 _level, Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \
536 (_mode) = Z_LOG_MSG_MODE_ZERO_COPY; \
537 } else { \
538 IF_ENABLED(UTIL_AND(IS_ENABLED(CONFIG_LOG_SIMPLE_MSG_OPTIMIZE), \
539 UTIL_AND(UTIL_NOT(_domain_id), UTIL_NOT(_cstr_cnt))), \
540 ( \
541 bool can_simple = LOG_MSG_SIMPLE_CHECK(__VA_ARGS__); \
542 if (can_simple && ((_dlen) == 0) && !k_is_user_context()) { \
543 compiler_barrier(); \
544 LOG_MSG_DBG("create fast message\n"); \
545 Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, \
546 Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \
547 _mode = Z_LOG_MSG_MODE_SIMPLE; \
548 break; \
549 } \
550 ) \
551 ) \
552 LOG_MSG_DBG("create on stack message\n");\
553 Z_LOG_MSG_STACK_CREATE(_cstr_cnt, _domain_id, _source, _level, _data, \
554 _dlen, Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \
555 (_mode) = Z_LOG_MSG_MODE_FROM_STACK; \
556 } \
557 (void)(_mode); \
558} while (false)
559
560#if defined(__cplusplus)
561#define Z_AUTO_TYPE auto
562#else
563#define Z_AUTO_TYPE __auto_type
564#endif
565
566/* Macro for getting name of a local variable with the exception of the first argument
567 * which is a formatted string in log message.
568 */
569#define Z_LOG_LOCAL_ARG_NAME(idx, arg) COND_CODE_0(idx, (arg), (_v##idx))
570
571/* Create local variable from input variable (expect for the first (fmt) argument). */
572#define Z_LOG_LOCAL_ARG_CREATE(idx, arg) \
573 COND_CODE_0(idx, (), (Z_AUTO_TYPE Z_LOG_LOCAL_ARG_NAME(idx, arg) = Z_ARGIFY(arg)))
574
575/* First level of processing creates stack variables to be passed for further processing.
576 * This is done to prevent multiple evaluations of input arguments (in case argument
577 * evaluation has side effects, e.g. it is a non-pure function call).
578 */
579#define Z_LOG_MSG_CREATE2(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source, \
580 _level, _data, _dlen, ...) \
581do { \
582 FOR_EACH_IDX(Z_LOG_LOCAL_ARG_CREATE, (;), __VA_ARGS__); \
583 Z_LOG_MSG_CREATE3(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
584 _level, _data, _dlen, \
585 FOR_EACH_IDX(Z_LOG_LOCAL_ARG_NAME, (,), __VA_ARGS__)); \
586} while (false)
587#endif /* CONFIG_LOG_ALWAYS_RUNTIME || !CONFIG_LOG */
588
589
590#define Z_LOG_MSG_CREATE(_try_0cpy, _mode, _domain_id, _source,\
591 _level, _data, _dlen, ...) \
592 Z_LOG_MSG_CREATE2(_try_0cpy, _mode, UTIL_CAT(Z_LOG_FUNC_PREFIX_, _level), \
593 _domain_id, _source, _level, _data, _dlen, \
594 Z_LOG_STR(_level, __VA_ARGS__))
595
602struct log_msg *z_log_msg_alloc(uint32_t wlen);
603
617void z_log_msg_finalize(struct log_msg *msg, const void *source,
618 const struct log_msg_desc desc, const void *data);
619
626__syscall void z_log_msg_simple_create_0(const void *source, uint32_t level,
627 const char *fmt);
628
636__syscall void z_log_msg_simple_create_1(const void *source, uint32_t level,
637 const char *fmt, uint32_t arg);
638
647__syscall void z_log_msg_simple_create_2(const void *source, uint32_t level,
648 const char *fmt, uint32_t arg0, uint32_t arg1);
649
660__syscall void z_log_msg_static_create(const void *source,
661 const struct log_msg_desc desc,
662 uint8_t *package, const void *data);
663
685void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source,
686 uint8_t level, const void *data,
687 size_t dlen, uint32_t package_flags,
688 const char *fmt,
689 va_list ap);
690
712static inline void z_log_msg_runtime_create(uint8_t domain_id,
713 const void *source,
714 uint8_t level, const void *data,
715 size_t dlen, uint32_t package_flags,
716 const char *fmt, ...)
717{
718 va_list ap;
719
720 va_start(ap, fmt);
721 z_log_msg_runtime_vcreate(domain_id, source, level,
722 data, dlen, package_flags, fmt, ap);
723 va_end(ap);
724}
725
726static inline bool z_log_item_is_msg(const union log_msg_generic *msg)
727{
728 return msg->generic.type == Z_LOG_MSG_LOG;
729}
730
737static inline uint32_t log_msg_get_total_wlen(const struct log_msg_desc desc)
738{
739 return Z_LOG_MSG_ALIGNED_WLEN(desc.package_len, desc.data_len);
740}
741
749{
750 const union log_msg_generic *generic_msg = (const union log_msg_generic *)item;
751
752 if (z_log_item_is_msg(generic_msg)) {
753 const struct log_msg *msg = (const struct log_msg *)generic_msg;
754
755 return log_msg_get_total_wlen(msg->hdr.desc);
756 }
757
758 return 0;
759}
760
767static inline uint8_t log_msg_get_domain(struct log_msg *msg)
768{
769 return msg->hdr.desc.domain;
770}
771
778static inline uint8_t log_msg_get_level(struct log_msg *msg)
779{
780 return msg->hdr.desc.level;
781}
782
789static inline const void *log_msg_get_source(struct log_msg *msg)
790{
791 return msg->hdr.source;
792}
793
801
809{
810 return msg->hdr.timestamp;
811}
812
819static inline void *log_msg_get_tid(struct log_msg *msg)
820{
821#if defined(CONFIG_LOG_THREAD_ID_PREFIX)
822 return msg->hdr.tid;
823#else
824 ARG_UNUSED(msg);
825 return NULL;
826#endif
827}
828
835static inline uint8_t log_msg_get_core_id(struct log_msg *msg)
836{
837#if defined(CONFIG_LOG_CORE_ID_PREFIX)
838 return msg->hdr.core_id;
839#else
840 ARG_UNUSED(msg);
841 return 0;
842#endif
843}
844
853static inline uint8_t *log_msg_get_data(struct log_msg *msg, size_t *len)
854{
855 *len = msg->hdr.desc.data_len;
856
857 return msg->data + msg->hdr.desc.package_len;
858}
859
868static inline uint8_t *log_msg_get_package(struct log_msg *msg, size_t *len)
869{
870 *len = msg->hdr.desc.package_len;
871
872 return msg->data;
873}
874
878
879#include <zephyr/syscalls/log_msg.h>
880
881#ifdef __cplusplus
882}
883#endif
884
885#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_MSG_H_ */
static const void * log_msg_get_source(struct log_msg *msg)
Get message source data.
Definition log_msg.h:789
int16_t log_msg_get_source_id(struct log_msg *msg)
Get log message source ID.
static uint8_t log_msg_get_level(struct log_msg *msg)
Get log message level.
Definition log_msg.h:778
static void * log_msg_get_tid(struct log_msg *msg)
Get Thread ID.
Definition log_msg.h:819
static uint8_t log_msg_get_domain(struct log_msg *msg)
Get log message domain ID.
Definition log_msg.h:767
static uint8_t log_msg_get_core_id(struct log_msg *msg)
Get Core ID.
Definition log_msg.h:835
static uint32_t log_msg_generic_get_wlen(const union mpsc_pbuf_generic *item)
Get length of the log item.
Definition log_msg.h:748
#define LOG_MSG_GENERIC_HDR
Definition log_msg.h:52
static uint32_t log_msg_get_total_wlen(const struct log_msg_desc desc)
Get total length (in 32 bit words) of a log message.
Definition log_msg.h:737
static uint8_t * log_msg_get_package(struct log_msg *msg, size_t *len)
Get string package.
Definition log_msg.h:868
static log_timestamp_t log_msg_get_timestamp(struct log_msg *msg)
Get timestamp.
Definition log_msg.h:808
static uint8_t * log_msg_get_data(struct log_msg *msg, size_t *len)
Get data buffer.
Definition log_msg.h:853
#define NULL
Definition iar_missing_defs.h:20
#define BUILD_ASSERT(EXPR, MSG...)
Definition llvm.h:51
uint32_t log_timestamp_t
Definition log_msg.h:36
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT64_TYPE__ uint64_t
Definition stdint.h:91
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__INT16_TYPE__ int16_t
Definition stdint.h:73
Definition log_msg.h:56
uint32_t domain
Definition log_msg.h:58
uint32_t package_len
Definition log_msg.h:60
uint32_t level
Definition log_msg.h:59
uint32_t data_len
Definition log_msg.h:61
Definition log_msg.h:116
uint32_t type
Definition log_msg.h:117
Definition log_msg.h:70
struct log_msg_desc desc
Definition log_msg.h:71
log_timestamp_t timestamp
Definition log_msg.h:80
const void * source
Definition log_msg.h:79
Definition log_msg.h:97
uint8_t data[]
Definition log_msg.h:103
uint8_t padding[((sizeof(struct log_msg_hdr) % CBPRINTF_PACKAGE_ALIGNMENT) > 0 ?(CBPRINTF_PACKAGE_ALIGNMENT -(sizeof(struct log_msg_hdr) % CBPRINTF_PACKAGE_ALIGNMENT)) :0)]
Definition log_msg.h:102
struct log_msg_hdr hdr
Definition log_msg.h:98
Constant data associated with the source of log messages.
Definition log_instance.h:17
Dynamic data associated with the source of log messages.
Definition log_instance.h:23
Misc utilities.
Macros to abstract toolchain specific capabilities.
Definition log_msg.h:120
union mpsc_pbuf_generic buf
Definition log_msg.h:121
struct log_msg log
Definition log_msg.h:123
struct log_msg_generic_hdr generic
Definition log_msg.h:122
Definition log_msg.h:64
const struct log_source_const_data * fixed
Definition log_msg.h:65
struct log_source_dynamic_data * dynamic
Definition log_msg.h:66
void * raw
Definition log_msg.h:67
Generic packet header.
Definition mpsc_packet.h:49