1 /*
2  * Copyright 2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  */
9 
10 #ifndef __FSL_COMPONENT_LOG_H__
11 #define __FSL_COMPONENT_LOG_H__
12 
13 /* log component usage:
14  *   step 1,
15  *     #define LOG_ENABLE 1
16  *   step 2,
17  *     #include "fsl_component_log.h"
18  *   step 3,
19  *     LOG_MODULE_DEFINE(<module name>, <module log level>);
20  *
21  * Note: LOG_ENABLE could be re-defined as a MODULE enabled flag such as
22  *       #define LOG_ENABLE module_LOG_ENABLED_FLAG
23  *
24  *   For example,
25  *   In source file 1,
26  *     #define LOG_ENABLE MODULE1_LOG_ENABLE
27  *     #include "fsl_component_log.h"
28  *     LOG_MODULE_DEFINE(module1, kLOG_LevelTrace);
29  *   In source file 2,
30  *     #define LOG_ENABLE MODULE2_LOG_ENABLE
31  *     #include "fsl_component_log.h"
32  *     LOG_MODULE_DEFINE(module2, kLOG_LevelDebug);
33  */
34 
35 #include "fsl_common.h"
36 #include "fsl_component_log_config.h"
37 
38 /*!
39  * @addtogroup fsl_component_log
40  * @{
41  */
42 
43 #if defined(__cplusplus)
44 extern "C" {
45 #endif /* _cplusplus */
46 
47 /*******************************************************************************
48  * Definitions
49  ******************************************************************************/
50 
51 #if LOG_ENABLE_TIMESTAMP
52 #define LOG_TIMESTAMP_GET LOG_GetTimestamp()
53 #else
54 #define LOG_TIMESTAMP_GET 0
55 #endif
56 
57 /*! @brief log error code*/
58 typedef enum _log_status
59 {
60     kStatus_LOG_Success         = kStatus_Success,                  /*!< Success */
61     kStatus_LOG_Error           = MAKE_STATUS(kStatusGroup_LOG, 1), /*!< Failed */
62     kStatus_LOG_Initialized     = MAKE_STATUS(kStatusGroup_LOG, 2), /*!< Initialized */
63     kStatus_LOG_Uninitialized   = MAKE_STATUS(kStatusGroup_LOG, 3), /*!< Uninitialized */
64     kStatus_LOG_LackResource    = MAKE_STATUS(kStatusGroup_LOG, 4), /*!< Lack resource */
65     kStatus_LOG_BackendExist    = MAKE_STATUS(kStatusGroup_LOG, 5), /*!< Backend exists */
66     kStatus_LOG_BackendNotFound = MAKE_STATUS(kStatusGroup_LOG, 6), /*!< Backend not found */
67 } log_status_t;
68 
69 #if LOG_ENABLE_FILE_WITH_PATH > 0
70 /*!
71  * @brief Source file name definition
72  * @details Define LOG_FILE_NAME with \__FILE\__ when config LOG_ENABLE_FILE_WITH_PATH is enabled.
73  */
74 #define LOG_FILE_NAME __FILE__
75 #else
76 #define LOG_FILE_NAME_INTERCEPT(s, n)                                                           \
77     ((sizeof(s) >= (n)) && (((s)[sizeof(s) - (n)] == '/') || ((s)[sizeof(s) - (n)] == '\\'))) ? \
78         ((s) + sizeof(s) - ((n)-1))
79 #define LOG_FILE_NAME_RECURSIVE(f, s, n) \
80     f(s, n) : f(s, n + 1) : f(s, n + 2) : f(s, n + 3) : f(s, n + 4) : f(s, n + 5) : f(s, n + 6) : f(s, n + 7)
81 #define LOG_FILE_NAME_SET(f, f1, s, n) \
82     f(f1, s, n)                        \
83         : f(f1, s, n + 8)              \
84         : f(f1, s, n + 16)             \
85         : f(f1, s, n + 24) : f(f1, s, n + 32) : f(f1, s, n + 40) : f(f1, s, n + 48) : f(f1, s, n + 56)
86 /*!
87  * @brief Source file name definition
88  * @details There is a macro \__BASE_FILE\__ could be used to get the current source file name in GCC. While
89  * the macro is unsupported by IAR in default, the \__BASE_FILE\__ is same as \__FILE\__ in IAR.
90  * To support the macro \__BASE_FILE\__, the extra option --no_path_in_file_macros should be added
91  * for IAR. But on Keil, only the source file name cannot be got through the macro \__BASE_FILE\__.
92  *
93  * So, log component adds a macro LOG_FILE_NAME to get the current source file name during the
94  * compilation phase, when config LOG_ENABLE_FILE_WITH_PATH is disabled.
95  * There is a limitation, the length of file name should be not less than 2,
96  * and the supported MAX length of file name is 66 bytes. Otherwise the original string of \__FILE\__
97  * will be linked.
98  */
99 #define LOG_FILE_NAME LOG_FILE_NAME_SET(LOG_FILE_NAME_RECURSIVE, LOG_FILE_NAME_INTERCEPT, __FILE__, 3) : __FILE__
100 #endif
101 
102 #if (LOG_ENABLE_ASYNC_MODE > 0)
103 
104 /* Define the log argument type */
105 #ifndef LOG_ARGUMENT_TYPE
106 #define LOG_ARGUMENT_TYPE unsigned long
107 #endif
108 
109 /* Get the log argument count MACRO set. The max argument count is 16 for application. */
110 #define _LOG_COUNT_ARGUMENT(N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17, COUNT, \
111                             ...)                                                                                   \
112     COUNT
113 #define LOG_COUNT_ARGUMENT(...) \
114     _LOG_COUNT_ARGUMENT(__VA_ARGS__, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
115 
116 #define LOG_FORMAT_ARG(x) ((LOG_ARGUMENT_TYPE)(x))
117 
118 #define LOG_LIST_ARGUMENT_1(arg, ...)  LOG_FORMAT_ARG(arg)
119 #define LOG_LIST_ARGUMENT_2(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_1(__VA_ARGS__)
120 #define LOG_LIST_ARGUMENT_3(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_2(__VA_ARGS__)
121 #define LOG_LIST_ARGUMENT_4(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_3(__VA_ARGS__)
122 #define LOG_LIST_ARGUMENT_5(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_4(__VA_ARGS__)
123 #define LOG_LIST_ARGUMENT_6(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_5(__VA_ARGS__)
124 #define LOG_LIST_ARGUMENT_7(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_6(__VA_ARGS__)
125 #define LOG_LIST_ARGUMENT_8(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_7(__VA_ARGS__)
126 #define LOG_LIST_ARGUMENT_9(arg, ...)  LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_8(__VA_ARGS__)
127 #define LOG_LIST_ARGUMENT_10(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_9(__VA_ARGS__)
128 #define LOG_LIST_ARGUMENT_11(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_10(__VA_ARGS__)
129 #define LOG_LIST_ARGUMENT_12(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_11(__VA_ARGS__)
130 #define LOG_LIST_ARGUMENT_13(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_12(__VA_ARGS__)
131 #define LOG_LIST_ARGUMENT_14(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_13(__VA_ARGS__)
132 #define LOG_LIST_ARGUMENT_15(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_14(__VA_ARGS__)
133 #define LOG_LIST_ARGUMENT_16(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_15(__VA_ARGS__)
134 #define LOG_LIST_ARGUMENT_17(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_16(__VA_ARGS__)
135 #define LOG_LIST_ARGUMENT_18(arg, ...) LOG_FORMAT_ARG(arg), LOG_LIST_ARGUMENT_17(__VA_ARGS__)
136 
137 #define _LOG_LIST_ARGUMENT_CAT(macro, sub) macro##sub
138 #define LOG_LIST_ARGUMENT_CAT(macro, sub)  _LOG_LIST_ARGUMENT_CAT(macro, sub)
139 #define LOG_LIST_ARGUMENT(...)             LOG_LIST_ARGUMENT_CAT(LOG_LIST_ARGUMENT_, LOG_COUNT_ARGUMENT(__VA_ARGS__))(__VA_ARGS__)
140 
141 #endif
142 
143 /*!
144  * @brief log level definition
145  *
146  * @details The log level behavior is following,@n
147  * If level is kLOG_LevelTrace, trace, debug, info, warning, error, and fatal of log level will be printed.@n
148  * If level is kLOG_LevelDebug, debug, info, warning, error, and fatal of log level will be printed.@n
149  * If level is kLOG_LevelInfo, info, warning, error, and fatal of log level will be printed.@n
150  * If level is kLOG_LevelWarning, warning, error, and fatal of log level will be printed.@n
151  * If level is kLOG_LevelError, error, and fatal of log level will be printed.@n
152  * If level is kLOG_LevelFatal, only fatal of log level will be printed.@n
153  * If level is kLOG_LevelNone, no log level will be printed.@n
154  */
155 typedef enum log_level
156 {
157     kLOG_LevelNone = 0, /*!< LOG level none */
158     kLOG_LevelFatal,    /*!< LOG level fatal */
159     kLOG_LevelError,    /*!< LOG level error */
160     kLOG_LevelWarning,  /*!< LOG level warning */
161     kLOG_LevelInfo,     /*!< LOG level info */
162     kLOG_LevelDebug,    /*!< LOG level debug */
163     kLOG_LevelTrace,    /*!< LOG level trace */
164 } log_level_t;
165 
166 /*!
167  * @brief log module type
168  */
169 typedef struct log_module
170 {
171     const char *logModuleName; /*!< Log module name */
172     log_level_t level;         /*!< Log level of the module */
173 } log_module_t;
174 
175 /*!
176  * @brief Puts function type for log backend.
177  */
178 typedef void (*log_backend_puts_t)(uint8_t *buffer, size_t length);
179 
180 /*!
181  * @brief Gets dump buffer from log backend.
182  */
183 typedef log_status_t (*log_backend_get_dump_buffer_t)(uint8_t **buffer, size_t *length);
184 
185 /*!
186  * @brief Backend of log
187  *
188  */
189 typedef struct log_backend
190 {
191     struct log_backend *next;  /*!< Next log backend pointer */
192     log_backend_puts_t putStr; /*!< Put data function of log backend */
193 } log_backend_t;
194 
195 /*!
196  * @brief Defines the log backend
197  *
198  * @details This macro is used to define the log backend. The static global variable with
199  * parameter name is defined by the macro. And calling the function
200  * log_backend_register to register the backend with defined static global
201  * variable.
202  * For example, if there is a backend named test, the reference code is following,
203  * @code
204  *   static void puts(uint8_t *buffer, size_t length)
205  *   {
206  *       ...
207  *   }
208  *   LOG_BACKEND_DEFINE(test, puts);
209  * @endcode
210  *
211  * @param name The name of the log backend.
212  * @param puts The log string output function with log_backend_puts_t type.
213  */
214 #define LOG_BACKEND_DEFINE(name, puts) static log_backend_t name = {NULL, puts}
215 
216 #if (LOG_ENABLE > 0)
217 
218 #if (LOG_ENABLE_ASYNC_MODE > 0)
219 /*!
220  * @brief Filter the log
221  *
222  * @details This macro is used to filter the log. The macro is used by the
223  * macro LOG_FATAL/LOG_ERR/LOG_WRN/LOG_INF/LOG_DBG/LOG_TRACE.
224  * Only when the following two conditions are met at the same time,
225  * 1. The priority of the log message level is valid.
226  * 2. The priority of the log message level is higher than the module log
227  * level.@n
228  * The macro should not be used by application directly.
229  */
230 #define _LOG_PRINTF(logger, logLevel, format, ...)                                                            \
231     if (((logLevel > kLOG_LevelNone) && ((logger)->level >= logLevel)))                                       \
232     {                                                                                                         \
233         LOG_ARGUMENT_TYPE argValueList[] = {LOG_LIST_ARGUMENT(__VA_ARGS__)};                                  \
234         LOG_AsyncPrintf(logger, logLevel, LOG_TIMESTAMP_GET, format, ARRAY_SIZE(argValueList), argValueList); \
235     }
236 #else
237 /*!
238  * @brief Filter the log
239  *
240  * @details This macro is used to filter the log. The macro is used by the
241  * macro LOG_FATAL/LOG_ERR/LOG_WRN/LOG_INF/LOG_DBG/LOG_TRACE.
242  * Only when the following two conditions are met at the same time,
243  * 1. The priority of the log message level is valid.
244  * 2. The priority of the log message level is higher than the module log
245  * level.@n
246  * The macro should not be used by application directly.
247  */
248 #define _LOG_PRINTF(logger, logLevel, format, ...)                            \
249     if (((logLevel > kLOG_LevelNone) && ((logger)->level >= logLevel)))       \
250     {                                                                         \
251         LOG_Printf(logger, logLevel, LOG_TIMESTAMP_GET, format, __VA_ARGS__); \
252     }
253 #endif
254 
255 /*!
256  * @brief Defines the log module
257  *
258  * @details This macro is used to define the log module for each driver/component/middleware.
259  * The macro should be added to source code of each module.
260  * This is an example, the code block should be placed at the end of the header file
261  * including of the source code.
262  * The macro is only valid when LOG_ENABLE is set.
263  *
264  * @code
265  * #define LOG_ENABLE 1
266  * #include "fsl_component_log.h"
267  * LOG_MODULE_DEFINE(hello_world, kLOG_LevelDebug);
268  * @endcode
269  *
270  * @param name The name string of the log module.
271  * @param level The debug level of the log module.
272  */
273 #define LOG_MODULE_DEFINE(name, level) static const log_module_t s_LogModuleLogger = {#name, level};
274 
275 /*!
276  * @brief Writes the fatal level log formatted output to the backend.
277  *
278  * @details Call this function to write the fatal level log formatted output to the backend.
279  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
280  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
281  * The macro is only valid when LOG_ENABLE is set.
282  * This is an example,
283  * The source code is,
284  * @code
285  *   LOG_ERR("cycle %d", count);
286  * @endcode
287  * The output string is,
288  * @code
289  *            0: FATAL hello_world.c:50:cycle 0
290  * @endcode
291  *
292  * @param   format Format control string.
293  */
294 #define LOG_FATAL(format, ...) \
295     _LOG_PRINTF(&s_LogModuleLogger, kLOG_LevelFatal, "%s:%d:" format "\r\n", LOG_FILE_NAME, __LINE__, ##__VA_ARGS__);
296 
297 /*!
298  * @brief Writes the error level log formatted output to the backend.
299  *
300  * @details Call this function to write the error level log formatted output to the backend.
301  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
302  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
303  * The macro is only valid when LOG_ENABLE is set.
304  * This is an example,
305  * The source code is,
306  * @code
307  *   LOG_ERR("cycle %d", count);
308  * @endcode
309  * The output string is,
310  * @code
311  *            0: ERROR hello_world.c:50:cycle 0
312  * @endcode
313  *
314  * @param   format Format control string.
315  */
316 #define LOG_ERR(format, ...) \
317     _LOG_PRINTF(&s_LogModuleLogger, kLOG_LevelError, "%s:%d:" format "\r\n", LOG_FILE_NAME, __LINE__, ##__VA_ARGS__);
318 
319 /*!
320  * @brief Writes the warning level log formatted output to the backend.
321  *
322  * @details Call this function to write the warning level log formatted output to the backend.
323  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
324  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
325  * The macro is only valid when LOG_ENABLE is set.
326  * This is an example,
327  * The source code is,
328  * @code
329  *   LOG_WRN("cycle %d", count);
330  * @endcode
331  * The output string is,
332  * @code
333  *            0: WARN  hello_world.c:50:cycle 0
334  * @endcode
335  *
336  * @param   format Format control string.
337  */
338 #define LOG_WRN(format, ...) \
339     _LOG_PRINTF(&s_LogModuleLogger, kLOG_LevelWarning, "%s:%d:" format "\r\n", LOG_FILE_NAME, __LINE__, ##__VA_ARGS__);
340 
341 /*!
342  * @brief Writes the info level log formatted output to the backend.
343  *
344  * @details Call this function to write the info level log formatted output to the backend.
345  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
346  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
347  * The macro is only valid when LOG_ENABLE is set.
348  * This is an example,
349  * The source code is,
350  * @code
351  *   LOG_INF("cycle %d", count);
352  * @endcode
353  * The output string is,
354  * @code
355  *            0: INFO  hello_world.c:50:cycle 0
356  * @endcode
357  *
358  * @param   format Format control string.
359  */
360 #define LOG_INF(format, ...) \
361     _LOG_PRINTF(&s_LogModuleLogger, kLOG_LevelInfo, "%s:%d:" format "\r\n", LOG_FILE_NAME, __LINE__, ##__VA_ARGS__);
362 
363 /*!
364  * @brief Writes the debug level log formatted output to the backend.
365  *
366  * @details Call this function to write the debug level log formatted output to the backend.
367  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
368  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
369  * The macro is only valid when LOG_ENABLE is set.
370  * This is an example,
371  * The source code is,
372  * @code
373  *   LOG_DBG("cycle %d", count);
374  * @endcode
375  * The output string is,
376  * @code
377  *            0: DEBUG hello_world.c:50:cycle 0
378  * @endcode
379  *
380  * @param   format Format control string.
381  */
382 #define LOG_DBG(format, ...) \
383     _LOG_PRINTF(&s_LogModuleLogger, kLOG_LevelDebug, "%s:%d:" format "\r\n", LOG_FILE_NAME, __LINE__, ##__VA_ARGS__);
384 
385 /*!
386  * @brief Writes the trace level log formatted output to the backend.
387  *
388  * @details Call this function to write the trace level log formatted output to the backend.
389  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
390  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
391  * The macro is only valid when LOG_ENABLE is set.
392  * This is an example,
393  * The source code is,
394  * @code
395  *   LOG_TRACE("cycle %d", count);
396  * @endcode
397  * The output string is,
398  * @code
399  *            0: TRACE hello_world.c:50:cycle 0
400  * @endcode
401  *
402  * @param   format Format control string.
403  */
404 #define LOG_TRACE(format, ...) \
405     _LOG_PRINTF(&s_LogModuleLogger, kLOG_LevelTrace, "%s:%d:" format "\r\n", LOG_FILE_NAME, __LINE__, ##__VA_ARGS__);
406 
407 #else
408 
409 #define LOG_MODULE_DEFINE(name, level)
410 #define LOG_FATAL(format, ...)
411 #define LOG_ERR(format, ...)
412 #define LOG_WRN(format, ...)
413 #define LOG_INF(format, ...)
414 #define LOG_DBG(format, ...)
415 #define LOG_TRACE(format, ...)
416 
417 #endif
418 #if LOG_ENABLE_TIMESTAMP
419 /*! @brief get time stamp function */
420 typedef unsigned int (*log_get_timestamp_callback_t)(void);
421 #endif
422 
423 /*******************************************************************************
424  * API
425  ******************************************************************************/
426 
427 /*!
428  * @brief Initializes the log component with the user configuration structure.
429  *
430  * @details This function configures the log component with user-defined settings.
431  * The user can configure the configuration structure.
432  * Example below shows how to use this API to configure the log component.
433  *  @code
434  *   LOG_Init();
435  *  @endcode
436  *
437  * @retval kStatus_LOG_Success The Log component initialization succeed.
438  * @retval kStatus_LOG_Initialized Log component has been initialized.
439  * @retval kStatus_LOG_LackResource Lack of resource.
440  */
441 log_status_t LOG_Init(void);
442 
443 /*!
444  * @brief De-initializes the log component.
445  *
446  * @details This function de-initializes the log component.
447  *
448  * @retval kStatus_LOG_Success The log component de-initialization succeed.
449  */
450 log_status_t LOG_Deinit(void);
451 
452 /*!
453  * @brief Prints the format log string.
454  *
455  * @details This function prints the format log string. The timestamp and color are added to prefix by function.
456  * The log string color feature is set by the macro LOG_ENABLE_COLOR.
457  * The log string time stamp feature is set by the macro LOG_ENABLE_TIMESTAMP.
458  *
459  * @param module the log module.
460  * @param level log level.
461  * @param timeStamp current timestamp.
462  * @param format formated log string.
463  */
464 void LOG_Printf(log_module_t const *module, log_level_t level, unsigned int timeStamp, char const *format, ...);
465 
466 #if (LOG_ENABLE_ASYNC_MODE > 0)
467 /*!
468  * @brief Prints the format log string in asynchronous mode.
469  *
470  * @details This function prints the format log string in asynchronous mode. The timestamp and color are added to prefix
471  * by function. The log string color feature is set by the macro LOG_ENABLE_COLOR. The log string time stamp feature is
472  * set by the macro LOG_ENABLE_TIMESTAMP.
473  *
474  * @param module the log module.
475  * @param level log level.
476  * @param timeStamp current timestamp.
477  * @param format formated log string.
478  * @param argc argument count.
479  * @param argv argument value array.
480  */
481 void LOG_AsyncPrintf(log_module_t const *module,
482                      log_level_t level,
483                      unsigned int timeStamp,
484                      char const *format,
485                      uint32_t argc,
486                      LOG_ARGUMENT_TYPE argv[]);
487 
488 /*!
489  * @brief Dump the log bufferred in log component.
490  *
491  * @details This function dumps one log bufferred in log component.
492  * Only the buffer and length are valid, the outLength will be filled with valid value.
493  * The message will be discarded when the message is more than LOG_MAX_MEESSAGE_LENGTH or buffer length
494  * passed by the function.
495  *
496  * @param buffer The buffer to dump the message.
497  * @param length The buffer length of the passed buffer.
498  * @param outLength return the message length.
499  */
500 void LOG_Dump(uint8_t *buffer, size_t length, size_t *outLength);
501 #endif
502 
503 /*!
504  * @brief Registers backend.
505  *
506  * @details This function registers the backend. The parameter of the function is defined by
507  * macro LOG_BACKEND_DEFINE.
508  *
509  * Example below shows how to use this API to register the backend.
510  * step 1, define the backend node by calling LOG_BACKEND_DEFINE.
511  *  @code
512  *   static void puts(uint8_t *buffer, size_t length)
513  *   {
514  *       ...
515  *   }
516  *   LOG_BACKEND_DEFINE(test, puts);
517  *  @endcode
518  * step 2, call function LOG_BackendRegister to register the backend in
519  * same source file.
520  *  @code
521  *   LOG_BackendRegister(&test);
522  *  @endcode
523  *
524  * @param backend The new backend.
525  *
526  * @retval kStatus_LOG_Success The backend is registered.
527  * @retval kStatus_LOG_Uninitialized The log component is not initialized.
528  * @retval kStatus_LOG_BackendExist The backend has been registered.
529  */
530 log_status_t LOG_BackendRegister(log_backend_t *backend);
531 
532 /*!
533  * @brief Unregisters backend.
534  *
535  * @details This function unregisters the backend.
536  *
537  * @param backend The backend.
538  *
539  * @retval kStatus_LOG_Success The backend is unregistered.
540  * @retval kStatus_LOG_Uninitialized The log component is not initialized.
541  * @retval kStatus_LOG_BackendNotFound the backend is not found.
542  */
543 log_status_t LOG_BackendUnregister(log_backend_t *backend);
544 
545 #if LOG_ENABLE_TIMESTAMP
546 /*!
547  * @brief Sets the get timestamp function callback.
548  *
549  * @details This function sets the get timestamp function callback.
550  * The feature is controlled by the macro LOG_ENABLE_TIMESTAMP.
551  *
552  * @param getTimeStamp get time stamp function callback.
553  *
554  * @retval kStatus_LOG_Success Succeed.
555  * @retval kStatus_LOG_Uninitialized The log component is not initialized.
556  */
557 log_status_t LOG_SetTimestamp(log_get_timestamp_callback_t getTimeStamp);
558 /*!
559  * @brief Gets current timestamp.
560  *
561  * @details This function gets current timestamp.
562  * The feature is controlled by the macro LOG_ENABLE_TIMESTAMP.
563  *
564  * @return Current timestamp.
565  */
566 unsigned int LOG_GetTimestamp(void);
567 #endif
568 
569 #if defined(__cplusplus)
570 }
571 #endif
572 /*! @} */
573 #endif /* __FSL_COMPONENT_LOG_H__ */
574