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

FIFO buffer clogging

-----------------------------EDIT--------------------------------------

I've changed topic name, because not buffer overwrite is the problem.

I need some mechanism for checking if my data packet can fit into FIFO buffer. If not, it should be just lost. It has to be all or nothing. It is unacceptable to print just part of data. I've implemented such mechanism, but it requires changes in SDK files, which I have to avoid. How should I do this?

----------

Hello,

I have custom device based on nRF52832. It is scanning for ble devices and prints the data throught the uart using NRF_LOG.

When there is a lot of devices (~100), FIFO buffer overwrites and data coming throught the uart are corrupted.

void uart_init(void)
{


uint32_t err_code;

const app_uart_comm_params_t comm_params =
  {
	.rx_pin_no    = RX_PIN_NUMBER,
	.tx_pin_no    = TX_PIN_NUMBER,
	// .rts_pin_no   = RTS_PIN_NUMBER,
	// .cts_pin_no   = CTS_PIN_NUMBER,
	.flow_control = APP_UART_FLOW_CONTROL_DISABLED,
	.use_parity   = false,
	.baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
  };

APP_UART_FIFO_INIT(&comm_params,
					UART_RX_BUF_SIZE,
					UART_TX_BUF_SIZE,
					uart_event_handle,
					APP_IRQ_PRIORITY_LOW,
					err_code);

APP_ERROR_CHECK(err_code);

uart_rx_buffer.p_data = malloc(UART_RX_BUF_SIZE);
memset(uart_rx_buffer.p_data, 0, UART_RX_BUF_SIZE);
uart_rx_buffer.size = 0;

app_uart_flush();
}

Enabling HWFC and increasing uart buffer does not help.

My temporary solution:

In app_uart_fifo.c change static app_fifo_t m_rx_fifo; and static app_fifo_t m_tx_fifo; to non static. Add this function to my code:

static __INLINE uint32_t fifo_length(app_fifo_t * const fifo)
{
  uint32_t tmp = fifo->read_pos;
  return fifo->write_pos - tmp;
}

Check if there is enough space in FIFO buffer to print next data packet:

    uint32_t available_count = m_tx_fifo.buf_size_mask - fifo_length(&m_tx_fifo) + 1;
    if (available_count > rc)
    {
        NRF_LOG_PRINTF("%s", msg);
 }

How can I prevent FIFO overwrites without changing the SDK? I prefer lost some data instead of recive corrupted data.

nRF52832

SDK11

SoftDevice s132

  • If the FIFO is full the app_uart_put(..) function should return NRF_ERROR_NO_MEM as this should be the return code from app_fifo_put(..).

    Do you change the UART_TX_BUF_SIZE to something higher? This should be a power of two or else the fifo will not work correctly (the size check uses bitmask).

    Why do you remove the static keyword before the fifo structs? This ensures that the fifo is not placed on the stack. I see you use malloc for the receive buffer, but I would much rather use static (malloc is generally not a good idea on an embedded system).

  • UART_TX_BUF_SIZE 2048 UART_RX_BUF_SIZE 512 So it is power of 2. I removed the static keyword before the fifo struct, because I need to have access to them in my function for checking how much space left in fifo buffer. I need to check if my data packet can fit in fifo buffer to prevent printing corrupted data. Example of correct output:

    @scan:abcdef12345
    @scan:abcdef12345
    @scan:abcdef12345
    

    Example of corrupted output because of fifo buffer overwrites, when a lot of NRF_LOG called:

    @scan:abcdef12345
    @scan:abcdef12345
    @scan:abcd@scan:abcd12@sca@sc
    

    How can I prevent it without editing SDK files?

  • Hi

    Unfortunately the logging API in SDK v11 is not thread safe, and if you are pushing a lot of data then it is possible to get data corruption.

    In SDK v12 a deferred mode was introduced, which should allow you to push updates without fear of corruption.

    If you are unable to upgrade to SDK v12 or v13 then you would probably need to implement something similar in the application, where you store the log messages temporarily in a buffer, and push them to the UART in thread (main) context from the main loop. Then you are also able to detect buffer overflow on your application buffer, and handle the situation as you see fit.

    Best regards
    Torbjørn

Related