Application:
NRF_LOG_sth puts a log entry into ringbuffer.NRF_LOG_FLUSH() is enforced: calls nrf_log_frontend_dequeue() in loop until ringbuffer empty.Frontend:
nrf_log_frontend_dequeue() and:nrf_log_frontend_dequeue():log_mempool to fit log entry.nrf_log_backend_is_enabled(p_backend)nrf_log_backend_putnrf_log_frontend_dequeue() return false if ringbuffer is empty<uml> participant Application as APP queue “Circular Buffer\nNRF_LOG_BUFSIZE” as CB queue “log_mempool\ndynamic memory pool” as MEM control “nrf_log_frontend_dequeue()” as DE note over MEM NRF_LOG_MSGPOOL_ELEMENT_SIZE
NRF_LOG_MSGPOOL_ELEMENT_COUNT endnote control “backend RTT” as B1 control “backend UART” as B2 control “backend x” as B3
APP → CB: NRF_LOG_INFO() activate CB APP → CB: NRF_LOG_DEBUG() activate CB APP → CB: NRF_LOG_HEXDUMP() activate CB … APP → DE: NRF_LOG_PROCESS() activate DE DE ←- MEM: nrf_memobj_alloc() activate MEM activate DE CB –> DE: pop one entry deactivate CB DE –> DE: copy entry to allocated\nmempool object DE ←- DE: backend1:\ncheck filters and status DE –> B1: mempool object DE ←- DE: backend2:\ncheck filters and status DE –> B2: mempool object DE ←- DE: backend3:\ncheck filters and status DE –> B3: mempool object MEM ←- DE: nrf_memobj_put() deactivate MEM DE –> APP: return “circular buffer is empty” deactivate DE deactivate DE </uml>
NRF_LOG_MSGPOOL_ELEMENT_SIZE (20) x NRF_LOG_MSGPOOL_ELEMENT_COUNT (8)get/put counting semaphore locking mechanism, so one log entry can be passed to multiple log backends at time.NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE 64typedef struct { void (*put)(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_entry); void (*panic_set)(nrf_log_backend_t const * p_backend); void (*flush)(nrf_log_backend_t const * p_backend); } nrf_log_backend_api_t;
putput() - counting semaphore decremented)get() is called to lock it. And entry is pushed to own queue.NRF_CLI_DEFnrf_cli_process() –> cli_log_entry_process() gets entries from queue. It makes memobj free by put() after processing.panic_set:flush - empty function in most backends(void)cli_log_entry_process(p_cli, true);nrf_cli_process()cli_log_entry_process()do { } while loop until no log entries in CLI internal queue. So all entries are processed at once.p_cli→p_fprintf_ctx == nrf_cli_print_streamcli_write which maps to nrf_cli_uart_transport_api.write == cli_uart_writeSUMMARY:
NRF_LOG_BUFSIZE - so must be big enough to handle all entries until log processNRF_LOG_PROCESS()NRF_LOG_MSGPOOL_ELEMENT_SIZE (20) x NRF_LOG_MSGPOOL_ELEMENT_COUNT (8))NRF_LOG_MSGPOOL_ELEMENT_SIZE (20) x NRF_LOG_MSGPOOL_ELEMENT_COUNT (8) should be the same as NRF_LOG_BUFSIZE.NRF_CLI_DEF should be big enough to track all memobj log entries.nrf_cli_process()NRF_CLI_UART_DEF).