Zephyr API Documentation  3.6.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
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
60 uint32_t package_len:Z_LOG_MSG_PACKAGE_BITS;
62};
63
67 void *raw;
68};
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};
86/* Messages are aligned to alignment required by cbprintf package. */
87#define Z_LOG_MSG_ALIGNMENT CBPRINTF_PACKAGE_ALIGNMENT
88
89#define Z_LOG_MSG_PADDING \
90 ((sizeof(struct log_msg_hdr) % Z_LOG_MSG_ALIGNMENT) > 0 ? \
91 (Z_LOG_MSG_ALIGNMENT - (sizeof(struct log_msg_hdr) % Z_LOG_MSG_ALIGNMENT)) : \
92 0)
93
94struct log_msg {
96 /* Adding padding to ensure that cbprintf package that follows is
97 * properly aligned.
98 */
99 uint8_t padding[Z_LOG_MSG_PADDING];
101};
102
106BUILD_ASSERT(sizeof(struct log_msg) % Z_LOG_MSG_ALIGNMENT == 0,
107 "Log msg size must aligned");
115};
116
120 struct log_msg log;
121};
122
127enum z_log_msg_mode {
128 /* Runtime mode is least efficient but supports all cases thus it is
129 * treated as a fallback method when others cannot be used.
130 */
131 Z_LOG_MSG_MODE_RUNTIME,
132 /* Mode creates statically a string package on stack and calls a
133 * function for creating a message. It takes code size than
134 * Z_LOG_MSG_MODE_ZERO_COPY but is a bit slower.
135 */
136 Z_LOG_MSG_MODE_FROM_STACK,
137
138 /* Mode calculates size of the message and allocates it and writes
139 * directly to the message space. It is the fastest method but requires
140 * more code size.
141 */
142 Z_LOG_MSG_MODE_ZERO_COPY,
143
144 /* Mode optimized for simple messages with 0 to 2 32 bit word arguments.*/
145 Z_LOG_MSG_MODE_SIMPLE,
146};
147
148#define Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, _plen, _dlen) \
149{ \
150 .valid = 0, \
151 .busy = 0, \
152 .type = Z_LOG_MSG_LOG, \
153 .domain = _domain_id, \
154 .level = _level, \
155 .package_len = _plen, \
156 .data_len = _dlen, \
157}
158
159#define Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt) \
160 (CBPRINTF_PACKAGE_FIRST_RO_STR_CNT(_cstr_cnt) | \
161 (IS_ENABLED(CONFIG_LOG_MSG_APPEND_RO_STRING_LOC) ? \
162 CBPRINTF_PACKAGE_ADD_STRING_IDXS : 0))
163
164#ifdef CONFIG_LOG_USE_VLA
165#define Z_LOG_MSG_ON_STACK_ALLOC(ptr, len) \
166 long long _ll_buf[DIV_ROUND_UP(len, sizeof(long long))]; \
167 long double _ld_buf[DIV_ROUND_UP(len, sizeof(long double))]; \
168 ptr = (sizeof(long double) == Z_LOG_MSG_ALIGNMENT) ? \
169 (struct log_msg *)_ld_buf : (struct log_msg *)_ll_buf; \
170 if (IS_ENABLED(CONFIG_LOG_TEST_CLEAR_MESSAGE_SPACE)) { \
171 /* During test fill with 0's to simplify message comparison */ \
172 memset(ptr, 0, len); \
173 }
174#else /* Z_LOG_MSG_USE_VLA */
175/* When VLA cannot be used we need to trick compiler a bit and create multiple
176 * fixed size arrays and take the smallest one that will fit the message.
177 * Compiler will remove unused arrays and stack usage will be kept similar
178 * to vla case, rounded to the size of the used buffer.
179 */
180#define Z_LOG_MSG_ON_STACK_ALLOC(ptr, len) \
181 long long _ll_buf32[32 / sizeof(long long)]; \
182 long long _ll_buf48[48 / sizeof(long long)]; \
183 long long _ll_buf64[64 / sizeof(long long)]; \
184 long long _ll_buf128[128 / sizeof(long long)]; \
185 long long _ll_buf256[256 / sizeof(long long)]; \
186 long double _ld_buf32[32 / sizeof(long double)]; \
187 long double _ld_buf48[48 / sizeof(long double)]; \
188 long double _ld_buf64[64 / sizeof(long double)]; \
189 long double _ld_buf128[128 / sizeof(long double)]; \
190 long double _ld_buf256[256 / sizeof(long double)]; \
191 if (sizeof(long double) == Z_LOG_MSG_ALIGNMENT) { \
192 ptr = (len > 128) ? (struct log_msg *)_ld_buf256 : \
193 ((len > 64) ? (struct log_msg *)_ld_buf128 : \
194 ((len > 48) ? (struct log_msg *)_ld_buf64 : \
195 ((len > 32) ? (struct log_msg *)_ld_buf48 : \
196 (struct log_msg *)_ld_buf32)));\
197 } else { \
198 ptr = (len > 128) ? (struct log_msg *)_ll_buf256 : \
199 ((len > 64) ? (struct log_msg *)_ll_buf128 : \
200 ((len > 48) ? (struct log_msg *)_ll_buf64 : \
201 ((len > 32) ? (struct log_msg *)_ll_buf48 : \
202 (struct log_msg *)_ll_buf32)));\
203 } \
204 if (IS_ENABLED(CONFIG_LOG_TEST_CLEAR_MESSAGE_SPACE)) { \
205 /* During test fill with 0's to simplify message comparison */ \
206 memset(ptr, 0, len); \
207 }
208#endif /* Z_LOG_MSG_USE_VLA */
209
210#define Z_LOG_MSG_ALIGN_OFFSET \
211 offsetof(struct log_msg, data)
212
213#define Z_LOG_MSG_LEN(pkg_len, data_len) \
214 (offsetof(struct log_msg, data) + pkg_len + (data_len))
215
216#define Z_LOG_MSG_ALIGNED_WLEN(pkg_len, data_len) \
217 DIV_ROUND_UP(ROUND_UP(Z_LOG_MSG_LEN(pkg_len, data_len), \
218 Z_LOG_MSG_ALIGNMENT), \
219 sizeof(uint32_t))
220
221/*
222 * With Zephyr SDK 0.14.2, aarch64-zephyr-elf-gcc (10.3.0) fails to ensure $sp
223 * is below the active memory during message construction. As a result,
224 * interrupts happening in the middle of that process can end up smashing active
225 * data and causing a logging fault. Work around this by inserting a compiler
226 * barrier after the allocation and before any use to make sure GCC moves the
227 * stack pointer soon enough
228 */
229
230#define Z_LOG_ARM64_VLA_PROTECT() compiler_barrier()
231
232#define _LOG_MSG_SIMPLE_XXXX0 1
233#define _LOG_MSG_SIMPLE_XXXX1 1
234#define _LOG_MSG_SIMPLE_XXXX2 1
235
236/* Determine if amount of arguments (less than 3) qualifies to simple message. */
237#define LOG_MSG_SIMPLE_ARG_CNT_CHECK(...) \
238 COND_CODE_1(UTIL_CAT(_LOG_MSG_SIMPLE_XXXX, NUM_VA_ARGS_LESS_1(__VA_ARGS__)), (1), (0))
239
240/* Set of marcos used to determine if arguments type allows simplified message creation mode. */
241#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_0(fmt) 1
242#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_1(fmt, arg) Z_CBPRINTF_IS_WORD_NUM(arg)
243#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK_2(fmt, arg0, arg1) \
244 Z_CBPRINTF_IS_WORD_NUM(arg0) && Z_CBPRINTF_IS_WORD_NUM(arg1)
245
250#define LOG_MSG_SIMPLE_ARG_TYPE_CHECK(...) \
251 UTIL_CAT(LOG_MSG_SIMPLE_ARG_TYPE_CHECK_, NUM_VA_ARGS_LESS_1(__VA_ARGS__))(__VA_ARGS__)
252
265#define LOG_MSG_SIMPLE_CHECK(...) \
266 COND_CODE_1(CONFIG_64BIT, (0), (\
267 COND_CODE_1(LOG_MSG_SIMPLE_ARG_CNT_CHECK(__VA_ARGS__), ( \
268 LOG_MSG_SIMPLE_ARG_TYPE_CHECK(__VA_ARGS__)), (0))))
269
270/* Helper macro for handing log with one argument. Macro casts the first argument to uint32_t. */
271#define Z_LOG_MSG_SIMPLE_CREATE_1(_source, _level, ...) \
272 z_log_msg_simple_create_1(_source, _level, GET_ARG_N(1, __VA_ARGS__), \
273 (uint32_t)(uintptr_t)GET_ARG_N(2, __VA_ARGS__))
274
275/* Helper macro for handing log with two arguments. Macro casts arguments to uint32_t.
276 */
277#define Z_LOG_MSG_SIMPLE_CREATE_2(_source, _level, ...) \
278 z_log_msg_simple_create_2(_source, _level, GET_ARG_N(1, __VA_ARGS__), \
279 (uint32_t)(uintptr_t)GET_ARG_N(2, __VA_ARGS__), \
280 (uint32_t)(uintptr_t)GET_ARG_N(3, __VA_ARGS__))
281
282/* Call specific function based on the number of arguments.
283 * Since up 2 to arguments are supported COND_CODE_0 and COND_CODE_1 can be used to
284 * handle all cases (0, 1 and 2 arguments). When tracing is enable then for each
285 * function a macro is create. The difference between function and macro is that
286 * macro is applied to any input arguments so we need to make sure that it is
287 * always called with proper number of arguments. For that it is wrapped around
288 * into another macro and dummy arguments to cover for cases when there is less
289 * arguments in a log call.
290 */
291#define Z_LOG_MSG_SIMPLE_FUNC2(arg_cnt, _source, _level, ...) \
292 COND_CODE_0(arg_cnt, \
293 (z_log_msg_simple_create_0(_source, _level, GET_ARG_N(1, __VA_ARGS__))), \
294 (COND_CODE_1(arg_cnt, ( \
295 Z_LOG_MSG_SIMPLE_CREATE_1(_source, _level, __VA_ARGS__, dummy) \
296 ), ( \
297 Z_LOG_MSG_SIMPLE_CREATE_2(_source, _level, __VA_ARGS__, dummy, dummy) \
298 ) \
299 )))
300
310#define LOG_MSG_SIMPLE_FUNC(_source, _level, ...) \
311 Z_LOG_MSG_SIMPLE_FUNC2(NUM_VA_ARGS_LESS_1(__VA_ARGS__), _source, _level, __VA_ARGS__)
312
323#define Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, ...) \
324 IF_ENABLED(LOG_MSG_SIMPLE_ARG_CNT_CHECK(__VA_ARGS__), (\
325 LOG_MSG_SIMPLE_FUNC(_source, _level, __VA_ARGS__); \
326 ))
327
328#define Z_LOG_MSG_STACK_CREATE(_cstr_cnt, _domain_id, _source, _level, _data, _dlen, ...) \
329do { \
330 int _plen; \
331 uint32_t _options = Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt) | \
332 CBPRINTF_PACKAGE_ADD_RW_STR_POS; \
333 if (GET_ARG_N(1, __VA_ARGS__) == NULL) { \
334 _plen = 0; \
335 } else { \
336 CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG_ALIGN_OFFSET, _options, \
337 __VA_ARGS__); \
338 } \
339 TOOLCHAIN_IGNORE_WSHADOW_BEGIN \
340 struct log_msg *_msg; \
341 TOOLCHAIN_IGNORE_WSHADOW_END \
342 Z_LOG_MSG_ON_STACK_ALLOC(_msg, Z_LOG_MSG_LEN(_plen, 0)); \
343 Z_LOG_ARM64_VLA_PROTECT(); \
344 if (_plen != 0) { \
345 CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, \
346 _plen, Z_LOG_MSG_ALIGN_OFFSET, _options, \
347 __VA_ARGS__);\
348 } \
349 struct log_msg_desc _desc = \
350 Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, \
351 (uint32_t)_plen, _dlen); \
352 LOG_MSG_DBG("creating message on stack: package len: %d, data len: %d\n", \
353 _plen, (int)(_dlen)); \
354 z_log_msg_static_create((void *)_source, _desc, _msg->data, _data); \
355} while (false)
356
357#ifdef CONFIG_LOG_SPEED
358#define Z_LOG_MSG_SIMPLE_CREATE(_cstr_cnt, _domain_id, _source, _level, ...) do { \
359 int _plen; \
360 CBPRINTF_STATIC_PACKAGE(NULL, 0, _plen, Z_LOG_MSG_ALIGN_OFFSET, \
361 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt), \
362 __VA_ARGS__); \
363 size_t _msg_wlen = Z_LOG_MSG_ALIGNED_WLEN(_plen, 0); \
364 struct log_msg *_msg = z_log_msg_alloc(_msg_wlen); \
365 struct log_msg_desc _desc = \
366 Z_LOG_MSG_DESC_INITIALIZER(_domain_id, _level, (uint32_t)_plen, 0); \
367 LOG_MSG_DBG("creating message zero copy: package len: %d, msg: %p\n", \
368 _plen, _msg); \
369 if (_msg) { \
370 CBPRINTF_STATIC_PACKAGE(_msg->data, _plen, _plen, \
371 Z_LOG_MSG_ALIGN_OFFSET, \
372 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt), \
373 __VA_ARGS__); \
374 } \
375 z_log_msg_finalize(_msg, (void *)_source, _desc, NULL); \
376} while (false)
377#else
378/* Alternative empty macro created to speed up compilation when LOG_SPEED is
379 * disabled (default).
380 */
381#define Z_LOG_MSG_SIMPLE_CREATE(...)
382#endif
383
384/* Macro handles case when local variable with log message string is created. It
385 * replaces original string literal with that variable.
386 */
387#define Z_LOG_FMT_ARGS_2(_name, ...) \
388 COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
389 (COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
390 (_name), (_name, GET_ARGS_LESS_N(1, __VA_ARGS__)))), \
391 (__VA_ARGS__))
392
402#define Z_LOG_FMT_ARGS(_name, ...) \
403 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
404 (NULL), \
405 (Z_LOG_FMT_ARGS_2(_name, ##__VA_ARGS__)))
406
407#if defined(CONFIG_LOG_USE_TAGGED_ARGUMENTS)
408
409#define Z_LOG_FMT_TAGGED_ARGS_2(_name, ...) \
410 COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
411 (_name, Z_CBPRINTF_TAGGED_ARGS(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
412 GET_ARGS_LESS_N(1, __VA_ARGS__))), \
413 (GET_ARG_N(1, __VA_ARGS__), \
414 Z_CBPRINTF_TAGGED_ARGS(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
415 GET_ARGS_LESS_N(1, __VA_ARGS__))))
416
427#define Z_LOG_FMT_TAGGED_ARGS(_name, ...) \
428 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
429 (Z_CBPRINTF_TAGGED_ARGS(0)), \
430 (Z_LOG_FMT_TAGGED_ARGS_2(_name, ##__VA_ARGS__)))
431
432#define Z_LOG_FMT_RUNTIME_ARGS(...) \
433 Z_LOG_FMT_TAGGED_ARGS(__VA_ARGS__)
434
435#else
436
437#define Z_LOG_FMT_RUNTIME_ARGS(...) \
438 Z_LOG_FMT_ARGS(__VA_ARGS__)
439
440#endif /* CONFIG_LOG_USE_TAGGED_ARGUMENTS */
441
442/* Macro handles case when there is no string provided, in that case variable
443 * is not created.
444 */
445#define Z_LOG_MSG_STR_VAR_IN_SECTION(_name, ...) \
446 COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
447 (/* No args provided, no variable */), \
448 (static const char _name[] \
449 __in_section(_log_strings, static, _CONCAT(_name, _)) __used __noasan = \
450 GET_ARG_N(1, __VA_ARGS__);))
451
459#define Z_LOG_MSG_STR_VAR(_name, ...) \
460 IF_ENABLED(CONFIG_LOG_FMT_SECTION, \
461 (Z_LOG_MSG_STR_VAR_IN_SECTION(_name, ##__VA_ARGS__)))
462
502#if defined(CONFIG_LOG_ALWAYS_RUNTIME) || \
503 (!defined(CONFIG_LOG) && \
504 (!TOOLCHAIN_HAS_PRAGMA_DIAG || !TOOLCHAIN_HAS_C_AUTO_TYPE))
505#define Z_LOG_MSG_CREATE2(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
506 _level, _data, _dlen, ...) \
507do {\
508 Z_LOG_MSG_STR_VAR(_fmt, ##__VA_ARGS__) \
509 z_log_msg_runtime_create(_domain_id, (void *)_source, \
510 _level, (uint8_t *)_data, _dlen,\
511 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt) | \
512 (IS_ENABLED(CONFIG_LOG_USE_TAGGED_ARGUMENTS) ? \
513 CBPRINTF_PACKAGE_ARGS_ARE_TAGGED : 0), \
514 Z_LOG_FMT_RUNTIME_ARGS(_fmt, ##__VA_ARGS__));\
515 _mode = Z_LOG_MSG_MODE_RUNTIME; \
516} while (false)
517#else /* CONFIG_LOG_ALWAYS_RUNTIME */
518#define Z_LOG_MSG_CREATE3(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
519 _level, _data, _dlen, ...) \
520do { \
521 Z_LOG_MSG_STR_VAR(_fmt, ##__VA_ARGS__); \
522 bool has_rw_str = CBPRINTF_MUST_RUNTIME_PACKAGE( \
523 Z_LOG_MSG_CBPRINTF_FLAGS(_cstr_cnt), \
524 __VA_ARGS__); \
525 if (IS_ENABLED(CONFIG_LOG_SPEED) && _try_0cpy && ((_dlen) == 0) && !has_rw_str) {\
526 LOG_MSG_DBG("create zero-copy message\n");\
527 Z_LOG_MSG_SIMPLE_CREATE(_cstr_cnt, _domain_id, _source, \
528 _level, Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \
529 _mode = Z_LOG_MSG_MODE_ZERO_COPY; \
530 } else { \
531 IF_ENABLED(UTIL_AND(IS_ENABLED(CONFIG_LOG_SIMPLE_MSG_OPTIMIZE), \
532 UTIL_AND(UTIL_NOT(_domain_id), UTIL_NOT(_cstr_cnt))), \
533 ( \
534 bool can_simple = LOG_MSG_SIMPLE_CHECK(__VA_ARGS__); \
535 if (can_simple && ((_dlen) == 0) && !k_is_user_context()) { \
536 LOG_MSG_DBG("create fast message\n");\
537 Z_LOG_MSG_SIMPLE_ARGS_CREATE(_domain_id, _source, _level, \
538 Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \
539 _mode = Z_LOG_MSG_MODE_SIMPLE; \
540 break; \
541 } \
542 ) \
543 ) \
544 LOG_MSG_DBG("create on stack message\n");\
545 Z_LOG_MSG_STACK_CREATE(_cstr_cnt, _domain_id, _source, _level, _data, \
546 _dlen, Z_LOG_FMT_ARGS(_fmt, ##__VA_ARGS__)); \
547 _mode = Z_LOG_MSG_MODE_FROM_STACK; \
548 } \
549 (void)_mode; \
550} while (false)
551
552#if defined(__cplusplus)
553#define Z_AUTO_TYPE auto
554#else
555#define Z_AUTO_TYPE __auto_type
556#endif
557
558/* Macro for getting name of a local variable with the exception of the first argument
559 * which is a formatted string in log message.
560 */
561#define Z_LOG_LOCAL_ARG_NAME(idx, arg) COND_CODE_0(idx, (arg), (_v##idx))
562
563/* Create local variable from input variable (expect for the first (fmt) argument). */
564#define Z_LOG_LOCAL_ARG_CREATE(idx, arg) \
565 COND_CODE_0(idx, (), (Z_AUTO_TYPE Z_LOG_LOCAL_ARG_NAME(idx, arg) = (arg) + 0))
566
567/* First level of processing creates stack variables to be passed for further processing.
568 * This is done to prevent multiple evaluations of input arguments (in case argument
569 * evaluation has side effects, e.g. it is a non-pure function call).
570 */
571#define Z_LOG_MSG_CREATE2(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source, \
572 _level, _data, _dlen, ...) \
573do { \
574 _Pragma("GCC diagnostic push") \
575 _Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
576 FOR_EACH_IDX(Z_LOG_LOCAL_ARG_CREATE, (;), __VA_ARGS__); \
577 _Pragma("GCC diagnostic pop") \
578 Z_LOG_MSG_CREATE3(_try_0cpy, _mode, _cstr_cnt, _domain_id, _source,\
579 _level, _data, _dlen, \
580 FOR_EACH_IDX(Z_LOG_LOCAL_ARG_NAME, (,), __VA_ARGS__)); \
581} while (false)
582#endif /* CONFIG_LOG_ALWAYS_RUNTIME ||
583 * (!LOG && (!TOOLCHAIN_HAS_PRAGMA_DIAG || !TOOLCHAIN_HAS_C_AUTO_TYPE))
584 */
585
586
587#define Z_LOG_MSG_CREATE(_try_0cpy, _mode, _domain_id, _source,\
588 _level, _data, _dlen, ...) \
589 Z_LOG_MSG_CREATE2(_try_0cpy, _mode, UTIL_CAT(Z_LOG_FUNC_PREFIX_, _level), \
590 _domain_id, _source, _level, _data, _dlen, \
591 Z_LOG_STR(_level, __VA_ARGS__))
592
599struct log_msg *z_log_msg_alloc(uint32_t wlen);
600
614void z_log_msg_finalize(struct log_msg *msg, const void *source,
615 const struct log_msg_desc desc, const void *data);
616
623__syscall void z_log_msg_simple_create_0(const void *source, uint32_t level,
624 const char *fmt);
625
633__syscall void z_log_msg_simple_create_1(const void *source, uint32_t level,
634 const char *fmt, uint32_t arg);
635
644__syscall void z_log_msg_simple_create_2(const void *source, uint32_t level,
645 const char *fmt, uint32_t arg0, uint32_t arg1);
646
657__syscall void z_log_msg_static_create(const void *source,
658 const struct log_msg_desc desc,
659 uint8_t *package, const void *data);
660
682void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source,
683 uint8_t level, const void *data,
684 size_t dlen, uint32_t package_flags,
685 const char *fmt,
686 va_list ap);
687
709static inline void z_log_msg_runtime_create(uint8_t domain_id,
710 const void *source,
711 uint8_t level, const void *data,
712 size_t dlen, uint32_t package_flags,
713 const char *fmt, ...)
714{
715 va_list ap;
716
717 va_start(ap, fmt);
718 z_log_msg_runtime_vcreate(domain_id, source, level,
719 data, dlen, package_flags, fmt, ap);
720 va_end(ap);
721}
722
723static inline bool z_log_item_is_msg(const union log_msg_generic *msg)
724{
725 return msg->generic.type == Z_LOG_MSG_LOG;
726}
727
734static inline uint32_t log_msg_get_total_wlen(const struct log_msg_desc desc)
735{
736 return Z_LOG_MSG_ALIGNED_WLEN(desc.package_len, desc.data_len);
737}
738
746{
747 const union log_msg_generic *generic_msg = (const union log_msg_generic *)item;
748
749 if (z_log_item_is_msg(generic_msg)) {
750 const struct log_msg *msg = (const struct log_msg *)generic_msg;
751
752 return log_msg_get_total_wlen(msg->hdr.desc);
753 }
754
755 return 0;
756}
757
764static inline uint8_t log_msg_get_domain(struct log_msg *msg)
765{
766 return msg->hdr.desc.domain;
767}
768
775static inline uint8_t log_msg_get_level(struct log_msg *msg)
776{
777 return msg->hdr.desc.level;
778}
779
786static inline const void *log_msg_get_source(struct log_msg *msg)
787{
788 return msg->hdr.source;
789}
790
798
806{
807 return msg->hdr.timestamp;
808}
809
816static inline void *log_msg_get_tid(struct log_msg *msg)
817{
818#if defined(CONFIG_LOG_THREAD_ID_PREFIX)
819 return msg->hdr.tid;
820#else
821 ARG_UNUSED(msg);
822 return NULL;
823#endif
824}
825
834static inline uint8_t *log_msg_get_data(struct log_msg *msg, size_t *len)
835{
836 *len = msg->hdr.desc.data_len;
837
838 return msg->data + msg->hdr.desc.package_len;
839}
840
849static inline uint8_t *log_msg_get_package(struct log_msg *msg, size_t *len)
850{
851 *len = msg->hdr.desc.package_len;
852
853 return msg->data;
854}
855
860#include <syscalls/log_msg.h>
861
862#ifdef __cplusplus
863}
864#endif
865
866#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:786
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:775
static void * log_msg_get_tid(struct log_msg *msg)
Get Thread ID.
Definition: log_msg.h:816
static uint8_t log_msg_get_domain(struct log_msg *msg)
Get log message domain ID.
Definition: log_msg.h:764
static uint32_t log_msg_generic_get_wlen(const union mpsc_pbuf_generic *item)
Get length of the log item.
Definition: log_msg.h:745
#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:734
static uint8_t * log_msg_get_package(struct log_msg *msg, size_t *len)
Get string package.
Definition: log_msg.h:849
static log_timestamp_t log_msg_get_timestamp(struct log_msg *msg)
Get timestamp.
Definition: log_msg.h:805
static uint8_t * log_msg_get_data(struct log_msg *msg, size_t *len)
Get data buffer.
Definition: log_msg.h:834
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:113
uint32_t type
Definition: log_msg.h:114
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:94
uint8_t data[]
Definition: log_msg.h:100
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:99
struct log_msg_hdr hdr
Definition: log_msg.h:95
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:30
Macros to abstract toolchain specific capabilities.
Definition: log_msg.h:117
union mpsc_pbuf_generic buf
Definition: log_msg.h:118
struct log_msg log
Definition: log_msg.h:120
struct log_msg_generic_hdr generic
Definition: log_msg.h:119
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
Misc utilities.