281 lines
6.6 KiB
C
281 lines
6.6 KiB
C
/*
|
|
* Copyright (c) 2018 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_BACKEND_H_
|
|
#define ZEPHYR_INCLUDE_LOGGING_LOG_BACKEND_H_
|
|
|
|
#include <logging/log_msg.h>
|
|
#include <stdarg.h>
|
|
#include <sys/__assert.h>
|
|
#include <sys/util.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Logger backend interface
|
|
* @defgroup log_backend Logger backend interface
|
|
* @ingroup logger
|
|
* @{
|
|
*/
|
|
|
|
/* Forward declaration of the log_backend type. */
|
|
struct log_backend;
|
|
|
|
/**
|
|
* @brief Logger backend API.
|
|
*/
|
|
struct log_backend_api {
|
|
void (*put)(const struct log_backend *const backend,
|
|
struct log_msg *msg);
|
|
void (*put_sync_string)(const struct log_backend *const backend,
|
|
struct log_msg_ids src_level, uint32_t timestamp,
|
|
const char *fmt, va_list ap);
|
|
void (*put_sync_hexdump)(const struct log_backend *const backend,
|
|
struct log_msg_ids src_level, uint32_t timestamp,
|
|
const char *metadata, const uint8_t *data, uint32_t len);
|
|
|
|
void (*dropped)(const struct log_backend *const backend, uint32_t cnt);
|
|
void (*panic)(const struct log_backend *const backend);
|
|
void (*init)(void);
|
|
};
|
|
|
|
/**
|
|
* @brief Logger backend control block.
|
|
*/
|
|
struct log_backend_control_block {
|
|
void *ctx;
|
|
uint8_t id;
|
|
bool active;
|
|
};
|
|
|
|
/**
|
|
* @brief Logger backend structure.
|
|
*/
|
|
struct log_backend {
|
|
const struct log_backend_api *api;
|
|
struct log_backend_control_block *cb;
|
|
const char *name;
|
|
bool autostart;
|
|
};
|
|
|
|
extern const struct log_backend __log_backends_start[];
|
|
extern const struct log_backend __log_backends_end[];
|
|
|
|
/**
|
|
* @brief Macro for creating a logger backend instance.
|
|
*
|
|
* @param _name Name of the backend instance.
|
|
* @param _api Logger backend API.
|
|
* @param _autostart If true backend is initialized and activated together
|
|
* with the logger subsystem.
|
|
*/
|
|
#define LOG_BACKEND_DEFINE(_name, _api, _autostart) \
|
|
static struct log_backend_control_block UTIL_CAT(backend_cb_, _name) = \
|
|
{ \
|
|
.id = 0, \
|
|
.active = false, \
|
|
}; \
|
|
static const Z_STRUCT_SECTION_ITERABLE(log_backend, _name) = \
|
|
{ \
|
|
.api = &_api, \
|
|
.cb = &UTIL_CAT(backend_cb_, _name), \
|
|
.name = STRINGIFY(_name), \
|
|
.autostart = _autostart \
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Put message with log entry to the backend.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
* @param[in] msg Pointer to message with log entry.
|
|
*/
|
|
static inline void log_backend_put(const struct log_backend *const backend,
|
|
struct log_msg *msg)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
__ASSERT_NO_MSG(msg != NULL);
|
|
backend->api->put(backend, msg);
|
|
}
|
|
|
|
/**
|
|
* @brief Synchronously process log message.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
* @param[in] src_level Message details.
|
|
* @param[in] timestamp Timestamp.
|
|
* @param[in] fmt Log string.
|
|
* @param[in] ap Log string arguments.
|
|
*/
|
|
static inline void log_backend_put_sync_string(
|
|
const struct log_backend *const backend,
|
|
struct log_msg_ids src_level,
|
|
uint32_t timestamp, const char *fmt,
|
|
va_list ap)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
|
|
if (backend->api->put_sync_string) {
|
|
backend->api->put_sync_string(backend, src_level,
|
|
timestamp, fmt, ap);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Synchronously process log hexdump_message.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
* @param[in] src_level Message details.
|
|
* @param[in] timestamp Timestamp.
|
|
* @param[in] metadata Raw string associated with the data.
|
|
* @param[in] data Data.
|
|
* @param[in] len Data length.
|
|
*/
|
|
static inline void log_backend_put_sync_hexdump(
|
|
const struct log_backend *const backend,
|
|
struct log_msg_ids src_level,
|
|
uint32_t timestamp, const char *metadata,
|
|
const uint8_t *data, uint32_t len)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
|
|
if (backend->api->put_sync_hexdump) {
|
|
backend->api->put_sync_hexdump(backend, src_level, timestamp,
|
|
metadata, data, len);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Notify backend about dropped log messages.
|
|
*
|
|
* Function is optional.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
* @param[in] cnt Number of dropped logs since last notification.
|
|
*/
|
|
static inline void log_backend_dropped(const struct log_backend *const backend,
|
|
uint32_t cnt)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
|
|
if (backend->api->dropped != NULL) {
|
|
backend->api->dropped(backend, cnt);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Reconfigure backend to panic mode.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
*/
|
|
static inline void log_backend_panic(const struct log_backend *const backend)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
backend->api->panic(backend);
|
|
}
|
|
|
|
/**
|
|
* @brief Set backend id.
|
|
*
|
|
* @note It is used internally by the logger.
|
|
*
|
|
* @param backend Pointer to the backend instance.
|
|
* @param id ID.
|
|
*/
|
|
static inline void log_backend_id_set(const struct log_backend *const backend,
|
|
uint8_t id)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
backend->cb->id = id;
|
|
}
|
|
|
|
/**
|
|
* @brief Get backend id.
|
|
*
|
|
* @note It is used internally by the logger.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
* @return Id.
|
|
*/
|
|
static inline uint8_t log_backend_id_get(const struct log_backend *const backend)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
return backend->cb->id;
|
|
}
|
|
|
|
/**
|
|
* @brief Get backend.
|
|
*
|
|
* @param[in] idx Pointer to the backend instance.
|
|
*
|
|
* @return Pointer to the backend instance.
|
|
*/
|
|
static inline const struct log_backend *log_backend_get(uint32_t idx)
|
|
{
|
|
return &__log_backends_start[idx];
|
|
}
|
|
|
|
/**
|
|
* @brief Get number of backends.
|
|
*
|
|
* @return Number of backends.
|
|
*/
|
|
static inline int log_backend_count_get(void)
|
|
{
|
|
return __log_backends_end - __log_backends_start;
|
|
}
|
|
|
|
/**
|
|
* @brief Activate backend.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
* @param[in] ctx User context.
|
|
*/
|
|
static inline void log_backend_activate(const struct log_backend *const backend,
|
|
void *ctx)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
backend->cb->ctx = ctx;
|
|
backend->cb->active = true;
|
|
}
|
|
|
|
/**
|
|
* @brief Deactivate backend.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
*/
|
|
static inline void log_backend_deactivate(
|
|
const struct log_backend *const backend)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
backend->cb->active = false;
|
|
}
|
|
|
|
/**
|
|
* @brief Check state of the backend.
|
|
*
|
|
* @param[in] backend Pointer to the backend instance.
|
|
*
|
|
* @return True if backend is active, false otherwise.
|
|
*/
|
|
static inline bool log_backend_is_active(
|
|
const struct log_backend *const backend)
|
|
{
|
|
__ASSERT_NO_MSG(backend != NULL);
|
|
return backend->cb->active;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_BACKEND_H_ */
|