nRF5 SDK Preprocessor Magic


#include <stdint.h>
#include <stddef.h>


typedef uint32_t ret_code_t;
typedef uint32_t (*nrf_log_timestamp_func_t)(void);

typedef enum
{
    NRF_LOG_SEVERITY_NONE,
    NRF_LOG_SEVERITY_ERROR,
    NRF_LOG_SEVERITY_WARNING,
    NRF_LOG_SEVERITY_INFO,
    NRF_LOG_SEVERITY_DEBUG,
    NRF_LOG_SEVERITY_INFO_RAW, /* Artificial level to pass information about skipping string postprocessing.*/
} nrf_log_severity_t;

typedef struct
{
    const char *       p_module_name;    ///< Module or instance name.
    uint8_t            info_color_id;    ///< Color code of info messages.
    uint8_t            debug_color_id;   ///< Color code of debug messages.
    nrf_log_severity_t compiled_lvl;     ///< Compiled highest severity level.
    nrf_log_severity_t initial_lvl;      ///< Severity level for given module or instance set on backend initialization.
} nrf_log_module_const_data_t;

#define _CONST                              const

#define CONCAT_2(p1, p2)                    CONCAT_2_(p1, p2)
#define CONCAT_2_(p1, p2)                   p1##p2
#define CONCAT_3(p1, p2, p3)                CONCAT_3_(p1, p2, p3)
#define CONCAT_3_(p1, p2, p3)               p1##p2##p3
#define STRINGIFY_(val)                     #val
#define STRINGIFY(val)                      STRINGIFY_(val)

#define GET_VA_ARG_1(...)                   GET_VA_ARG_1_(__VA_ARGS__, )
#define GET_VA_ARG_1_(a1, ...)              a1

#define GET_ARGS_AFTER_1(...)               GET_ARGS_AFTER_1_(__VA_ARGS__, )
#define GET_ARGS_AFTER_1_(a1, ...)          __VA_ARGS__

#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
    section_var __attribute__ ((section("." STRINGIFY(section_name)))) __attribute__((used))

#define NRF_LOG_ITEM_DATA(_name)            CONCAT_3(m_nrf_log_,_name,_logs_data)
#define NRF_LOG_ITEM_DATA_DYNAMIC(_name)    CONCAT_2(NRF_LOG_ITEM_DATA(_name),_dynamic)
#define NRF_LOG_ITEM_DATA_FILTER(_name)     CONCAT_2(NRF_LOG_ITEM_DATA(_name),_filter)
#define NRF_LOG_ITEM_DATA_CONST(_name)      CONCAT_2(NRF_LOG_ITEM_DATA(_name),_const)

#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name)  CONCAT_2(log_dynamic_data_,_module_name)
#define NRF_LOG_FILTER_SECTION_NAME(_module_name)   CONCAT_2(log_filter_data_,_module_name)
#define NRF_LOG_CONST_SECTION_NAME(_module_name)    CONCAT_2(log_const_data_,_module_name)

#define NRF_LOG_INTERNAL_CONST_ITEM_REGISTER(                                             \
            _name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl)     \
            NRF_SECTION_ITEM_REGISTER(NRF_LOG_CONST_SECTION_NAME(_name),                  \
            _CONST nrf_log_module_const_data_t NRF_LOG_ITEM_DATA_CONST(_name)) = {        \
                .p_module_name   = _str_name,                                             \
                .info_color_id   = (_info_color),                                         \
                .debug_color_id  = (_debug_color),                                        \
                .compiled_lvl    = (nrf_log_severity_t)(_compiled_lvl),                   \
                .initial_lvl     = (nrf_log_severity_t)(_initial_lvl),                    \
            }

#define NRF_LOG_INTERNAL_ITEM_REGISTER( \
                         _name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
    NRF_LOG_INTERNAL_CONST_ITEM_REGISTER(_name,                                                    \
                                         _str_name,                                                \
                                         _info_color,                                              \
                                         _debug_color,                                             \
                                         _initial_lvl,                                             \
                                         _compiled_lvl)

#define NRF_LOG_INTERNAL_MODULE_REGISTER() \
                   NRF_LOG_INTERNAL_ITEM_REGISTER(NRF_LOG_MODULE_NAME,                 \
                                                  STRINGIFY(NRF_LOG_MODULE_NAME),      \
                                                  NRF_LOG_INFO_COLOR,                  \
                                                  NRF_LOG_DEBUG_COLOR,                 \
                                                  NRF_LOG_INITIAL_LEVEL,               \
                                                  COMPILED_LOG_LEVEL)

#define NRF_LOG_MODULE_REGISTER() NRF_LOG_INTERNAL_MODULE_REGISTER()

#define NRF_LOG_INTERNAL_INIT(...)               \
        nrf_log_init(GET_VA_ARG_1(__VA_ARGS__),  \
                     GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__, LOG_TIMESTAMP_DEFAULT_FREQUENCY)))

#define NRF_LOG_INIT(...) NRF_LOG_INTERNAL_INIT(__VA_ARGS__)

#define NRF_LOG_MODULE_NAME                 app
#define NRF_LOG_INFO_COLOR                  NRF_LOG_COLOR_DEFAULT
#define NRF_LOG_DEBUG_COLOR                 NRF_LOG_COLOR_DEFAULT
#define NRF_LOG_INITIAL_LEVEL               NRF_LOG_LEVEL
#define NRF_LOG_LEVEL                       NRF_LOG_DEFAULT_LEVEL
#define COMPILED_LOG_LEVEL                  NRF_LOG_LEVEL
#define LOG_TIMESTAMP_DEFAULT_FREQUENCY     NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY


#define NRF_LOG_COLOR_DEFAULT               0
#define NRF_LOG_DEFAULT_LEVEL               3
#define NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY 0


NRF_LOG_MODULE_REGISTER();

ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq)
{
    (void)NRF_LOG_ITEM_DATA_CONST(app);

    return 0;
}

static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
}

int main(int argc, char *argv[])
{
    log_init();

    return 0;
}
const nrf_log_module_const_data_t m_nrf_log_app_logs_data_const
__attribute__ ((section("." "log_const_data_app")))
__attribute__((used)) = {
    .p_module_name = "app",
    .info_color_id = (0),
    .debug_color_id = (0),
    .compiled_lvl = (nrf_log_severity_t)(3),
    .initial_lvl = (nrf_log_severity_t)(3),
};

ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq)
{
    (void)m_nrf_log_app_logs_data_const;

    return 0;
}

static void log_init(void)
{
    ret_code_t err_code = nrf_log_init(
        ((void *)0),
        0
    );
}

int main(int argc, char *argv[])
{
    log_init();

    return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *