logging: Refactoring 'in place' mode to reduce memory footprint

Changed 'in place' mode to bypass logger system and directly
call active backends. With this approach memory footprint of
the logger can be significantly reduced in terms of RAM and ROM.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2019-01-10 08:37:15 +01:00 committed by Carles Cufí
commit 1d9e5ee108
13 changed files with 276 additions and 119 deletions

View file

@ -28,6 +28,12 @@ struct log_backend;
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, u32_t timestamp,
const char *fmt, va_list ap);
void (*put_sync_hexdump)(const struct log_backend *const backend,
struct log_msg_ids src_level, u32_t timestamp,
const char *metadata, const u8_t *data, u32_t len);
void (*dropped)(const struct log_backend *const backend, u32_t cnt);
void (*panic)(const struct log_backend *const backend);
@ -94,6 +100,53 @@ static inline void log_backend_put(const struct log_backend *const backend,
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,
u32_t timestamp, const char *fmt,
va_list ap)
{
__ASSERT_NO_MSG(backend);
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,
u32_t timestamp, const char *metadata,
const u8_t *data, u32_t len)
{
__ASSERT_NO_MSG(backend);
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.
*

View file

@ -161,9 +161,15 @@ extern "C" {
#define _LOG_INTERNAL_X(N, ...) UTIL_CAT(_LOG_INTERNAL_, N)(__VA_ARGS__)
#define __LOG_INTERNAL(_src_level, ...) \
_LOG_INTERNAL_X(_LOG_NARGS_POSTFIX(__VA_ARGS__), \
_src_level, __VA_ARGS__)
#define __LOG_INTERNAL(_src_level, ...) \
do { \
if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
log_string_sync(_src_level, __VA_ARGS__); \
} else { \
_LOG_INTERNAL_X(_LOG_NARGS_POSTFIX(__VA_ARGS__), \
_src_level, __VA_ARGS__);\
} \
} while (0)
#define _LOG_INTERNAL_0(_src_level, _str) \
log_0(_str, _src_level)
@ -246,17 +252,23 @@ extern "C" {
/******************************************************************************/
/****************** Macros for hexdump logging ********************************/
/******************************************************************************/
#define __LOG_HEXDUMP(_level, _id, _filter, _data, _length, _str) \
do { \
if (_LOG_CONST_LEVEL_CHECK(_level) && \
(_level <= LOG_RUNTIME_FILTER(_filter))) { \
struct log_msg_ids src_level = { \
.level = _level, \
.source_id = _id, \
.domain_id = CONFIG_LOG_DOMAIN_ID \
}; \
log_hexdump(_str, _data, _length, src_level); \
} \
#define __LOG_HEXDUMP(_level, _id, _filter, _data, _length, _str) \
do { \
if (_LOG_CONST_LEVEL_CHECK(_level) && \
(_level <= LOG_RUNTIME_FILTER(_filter))) { \
struct log_msg_ids src_level = { \
.level = _level, \
.source_id = _id, \
.domain_id = CONFIG_LOG_DOMAIN_ID \
}; \
\
if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
log_hexdump_sync(src_level, _str, \
_data, _length); \
} else { \
log_hexdump(_str, _data, _length, src_level); \
} \
} \
} while (false)
#define _LOG_HEXDUMP(_level, _data, _length, _str) \
@ -322,6 +334,11 @@ extern "C" {
#define LOG_RUNTIME_FILTER(_filter) LOG_LEVEL_DBG
#endif
/** @brief Log level value used to indicate log entry that should not be
* formatted (raw string).
*/
#define LOG_LEVEL_INTERNAL_RAW_STRING LOG_LEVEL_NONE
extern struct log_source_const_data __log_const_start[0];
extern struct log_source_const_data __log_const_end[0];
@ -484,6 +501,24 @@ void log_hexdump(const char *str,
*/
int log_printk(const char *fmt, va_list ap);
/** @brief Process log message synchronously.
*
* @param src_level Log message details.
* @param fmt String to format.
* @param ... Variable list of arguments.
*/
void log_string_sync(struct log_msg_ids src_level, const char *fmt, ...);
/** @brief Process log hexdump message synchronously.
*
* @param src_level Log message details.
* @param metadata Raw string associated with the data.
* @param data Data.
* @param len Data length.
*/
void log_hexdump_sync(struct log_msg_ids src_level, const char *metadata,
const u8_t *data, u32_t len);
/**
* @brief Writes a generic log message to the log.
*

View file

@ -65,7 +65,7 @@ extern "C" {
u16_t ext : 1
/** @brief Number of bits used for storing length of hexdump log message. */
#define LOG_MSG_HEXDUMP_LENGTH_BITS 13
#define LOG_MSG_HEXDUMP_LENGTH_BITS 14
/** @brief Maximum length of log hexdump message. */
#define LOG_MSG_HEXDUMP_MAX_LENGTH ((1 << LOG_MSG_HEXDUMP_LENGTH_BITS) - 1)
@ -102,7 +102,6 @@ BUILD_ASSERT_MSG((sizeof(struct log_msg_std_hdr) == sizeof(u16_t)),
/** Part of log message header specific to hexdump log message. */
struct log_msg_hexdump_hdr {
COMMON_PARAM_HDR();
u16_t raw_string : 1;
u16_t length : LOG_MSG_HEXDUMP_LENGTH_BITS;
};
@ -234,20 +233,6 @@ static inline u32_t log_msg_timestamp_get(struct log_msg *msg)
return msg->hdr.timestamp;
}
/** @brief Check if message is a raw string (see CONFIG_LOG_PRINTK).
*
* @param msg Message
*
* @retval true Message contains raw string.
* @retval false Message does not contain raw string.
*/
static inline bool log_msg_is_raw_string(struct log_msg *msg)
{
return (msg->hdr.params.generic.type == LOG_MSG_TYPE_HEXDUMP) &&
(msg->hdr.params.hexdump.raw_string == 1);
}
/** @brief Check if message is of standard type.
*
* @param msg Message