1 /*
2  * Copyright (c) 2019 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef ZEPHYR_LOG_BACKEND_STD_H_
7 #define ZEPHYR_LOG_BACKEND_STD_H_
8 
9 #include <logging/log_msg.h>
10 #include <logging/log_output.h>
11 #include <kernel.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /**
18  * @brief Logger backend interface for forwarding to standard backend
19  * @defgroup log_backend_std Logger backend standard interface
20  * @ingroup logger
21  * @{
22  */
23 
log_backend_std_get_flags(void)24 static inline uint32_t log_backend_std_get_flags(void)
25 {
26 	uint32_t flags = (LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP);
27 
28 	if (IS_ENABLED(CONFIG_LOG_BACKEND_SHOW_COLOR)) {
29 		flags |= LOG_OUTPUT_FLAG_COLORS;
30 	}
31 
32 	if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) {
33 		flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
34 	}
35 
36 	return flags;
37 }
38 
39 /** @brief Put log message to a standard logger backend.
40  *
41  * @param output	Log output instance.
42  * @param flags		Formatting flags.
43  * @param msg		Log message.
44  */
45 static inline void
log_backend_std_put(const struct log_output * const output,uint32_t flags,struct log_msg * msg)46 log_backend_std_put(const struct log_output *const output, uint32_t flags,
47 		    struct log_msg *msg)
48 {
49 	log_msg_get(msg);
50 
51 	flags |= log_backend_std_get_flags();
52 
53 	log_output_msg_process(output, msg, flags);
54 
55 	log_msg_put(msg);
56 }
57 
58 /** @brief Put a standard logger backend into panic mode.
59  *
60  * @param output	Log output instance.
61  */
62 static inline void
log_backend_std_panic(const struct log_output * const output)63 log_backend_std_panic(const struct log_output *const output)
64 {
65 	log_output_flush(output);
66 }
67 
68 /** @brief Report dropped messages to a standard logger backend.
69  *
70  * @param output	Log output instance.
71  * @param cnt		Number of dropped messages.
72  */
73 static inline void
log_backend_std_dropped(const struct log_output * const output,uint32_t cnt)74 log_backend_std_dropped(const struct log_output *const output, uint32_t cnt)
75 {
76 	log_output_dropped_process(output, cnt);
77 }
78 
79 /** @brief Synchronously process log message by a standard logger backend.
80  *
81  * @param output	Log output instance.
82  * @param flags		Formatting flags.
83  * @param src_level	Log message source and level.
84  * @param timestamp	Timestamp.
85  * @param fmt		Log string.
86  * @param ap		Log string arguments.
87  */
88 static inline void
log_backend_std_sync_string(const struct log_output * const output,uint32_t flags,struct log_msg_ids src_level,uint32_t timestamp,const char * fmt,va_list ap)89 log_backend_std_sync_string(const struct log_output *const output,
90 			    uint32_t flags, struct log_msg_ids src_level,
91 			    uint32_t timestamp, const char *fmt, va_list ap)
92 {
93 	int key;
94 
95 	flags |= LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP;
96 	if (IS_ENABLED(CONFIG_LOG_BACKEND_SHOW_COLOR)) {
97 		flags |= LOG_OUTPUT_FLAG_COLORS;
98 	}
99 
100 	if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) {
101 		flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
102 	}
103 
104 	if (IS_ENABLED(CONFIG_LOG_IMMEDIATE) &&
105 		IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
106 		/* In order to ensure that one log processing is not interrupted
107 		 * by another one, lock context for whole log processing.
108 		 */
109 		key = irq_lock();
110 	}
111 
112 	log_output_string(output, src_level, timestamp, fmt, ap, flags);
113 
114 	if (IS_ENABLED(CONFIG_LOG_IMMEDIATE) &&
115 		IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
116 		irq_unlock(key);
117 	}
118 }
119 
120 /** @brief Synchronously process hexdump message by a standard logger backend.
121  *
122  * @param output	Log output instance.
123  * @param flags		Formatting flags.
124  * @param src_level	Log message source and level.
125  * @param timestamp	Timestamp.
126  * @param metadata	String associated with a hexdump.
127  * @param data		Buffer to dump.
128  * @param length	Length of the buffer.
129  */
130 static inline void
log_backend_std_sync_hexdump(const struct log_output * const output,uint32_t flags,struct log_msg_ids src_level,uint32_t timestamp,const char * metadata,const uint8_t * data,uint32_t length)131 log_backend_std_sync_hexdump(const struct log_output *const output,
132 			     uint32_t flags, struct log_msg_ids src_level,
133 			     uint32_t timestamp, const char *metadata,
134 			     const uint8_t *data, uint32_t length)
135 {
136 	int key;
137 
138 	flags |= LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP;
139 	if (IS_ENABLED(CONFIG_LOG_BACKEND_SHOW_COLOR)) {
140 		flags |= LOG_OUTPUT_FLAG_COLORS;
141 	}
142 
143 	if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) {
144 		flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
145 	}
146 
147 	if (IS_ENABLED(CONFIG_LOG_IMMEDIATE) &&
148 		IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
149 		/* In order to ensure that one log processing is not interrupted
150 		 * by another one, lock context for whole log processing.
151 		 */
152 		key = irq_lock();
153 	}
154 
155 	log_output_hexdump(output, src_level, timestamp,
156 			metadata, data, length, flags);
157 
158 	if (IS_ENABLED(CONFIG_LOG_IMMEDIATE) &&
159 		IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
160 		irq_unlock(key);
161 	}
162 }
163 
164 /**
165  * @}
166  */
167 
168 #ifdef __cplusplus
169 }
170 #endif
171 
172 #endif /* ZEPHYR_LOG_BACKEND_STD_H_ */
173