This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bug in nrf_log when executing in RAM nrf52840

The bug shows when executing an application in RAM with nrf52840. Using SDK 16 but seems to show in older versions also.

The below function code is the first level of the bug,  The mask at 22 bits will cause the RAM address to be truncated to 22 bits.  This bit mask instruction is not even needed because the structure definition will cause the address to be truncated to 22 bits when the value is stored into  "addr".   The GCC compiler does this when it stores values into fields with set bit width.

#define STD_ADDR_MASK       ((uint32_t)(1U << 22) - 1U)

static inline void std_header_set(uint32_t severity_mid,
                                      char const * const p_str,
                                      uint32_t nargs,
                                      uint32_t wr_idx,
                                      uint32_t mask)
{


    //Prepare header - in reverse order to ensure that packet type is validated (set to STD as last action)
    uint32_t module_id = severity_mid >> NRF_LOG_MODULE_ID_POS;
    uint32_t dropped   = dropped_sat16_get();
    ASSERT(module_id < nrf_log_module_cnt_get());
    m_log_data.buffer[(wr_idx + 1) & mask] = module_id | (dropped << 16);

    if (NRF_LOG_USES_TIMESTAMP)
    {
        m_log_data.buffer[(wr_idx + 2) & mask] = m_log_data.timestamp_func();
    }

    nrf_log_header_t * p_header    = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
    p_header->base.std.severity    = severity_mid & NRF_LOG_LEVEL_MASK;
    p_header->base.std.nargs       = nargs;
    p_header->base.std.addr        = (uint32_t)(p_str) & STD_ADDR_MASK); ;;
    p_header->base.std.type        = HEADER_TYPE_STD;
    p_header->base.std.in_progress = 0;
}

The bug continues into the structure:

The structure below will cause a bug if you are executing in RAM.  Will generate code to truncate the address at 22 bits.   Never a good idea to make decision about address width.  Will break in the future.  The log output is garbage because it is truncated to an address in flash.  

typedef struct
{
    uint32_t type       : 2;
    uint32_t in_progress: 1;
    uint32_t severity   : 3;
    uint32_t nargs      : 4;
    uint32_t addr       : 22; /* FIXME TOM C  set to 32; causes bug if executing in RAM */
} nrf_log_std_header_t;

Related