nRF9160 flush UART buffer.

Hello!

I'm currently working on a project that uses an Icarus IoT board that is connected to a camera through UART.
The board is taking pictures with the camera, gathers the picture data through UART, and then sends the picture to AWS with the help of LTE. However, after a certain amount of time the board stops sending pictures in the middle of a transmission. My guess is that the memory might be full because the buffer never gets flushed.
I've seen other posts using "app_uart_flush() " for the nRF5 series, but it does not seem to be in the library anymore, I might be wrong about this, but I can't find it.

so my question is:
Is there another way to flush the UART buffer for the nRF9160?

I've tried to use k_free(*name of buffer*), but I'm not certain if this is the correct function. The board just ends up rebooting as soon as it reaches this part of the code.
The buffer itself is defined as 

extern uint8_t read_buf[READ_BUF_SIZE];

Appreciate all help and answers, thank you!

  • app_uart_flush was relying on app_fifo_flush. Fifos are application level buffers that could be controlled in app, but I do not think you can do that when you are using Zephyr system calls to interfact with UART driver. 

    I've tried to use k_free(*name of buffer*), but I'm not certain if this is the correct function. The board just ends up rebooting as soon as it reaches this part of the code.

    Not sure why you are trying k_free here, are the buffers dynamically allocated? if so how k_free would help communicating with the uart driver to flush the driver. 

    Can you add more code snippets on how you are using read_buf in your code, i am confused by the use of k_free on the buffers and your interpretation of connecting this to uart?

  • These are the cases the buffer is being used:

    /* Buffers for reading UART */
    static uint8_t uart_buf[64];
    uint8_t read_buf[READ_BUF_SIZE];
    uint32_t read_buf_ptr = 0;

    void uart_cb(struct device *x) {
    	uart_irq_update(x);
    	int data_length = 0;
    
    	if (uart_irq_rx_ready(x)) {
    		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    		uart_buf[data_length] = 0;
    	}
    
        // Considering it reads just one character per time
    	uint8_t read_char = uart_buf[0];
    	read_buf[read_buf_ptr] = read_char;
        read_buf_ptr++;
    }

    I can elaborate further on the code if you have any questions.

    the usage of k_free is more a desperate measure than a reasonable one given the lack of alternatives. I saw it being used in one of Nordics UART samples and tried to recreate it. 

  • I've added "uart_irq_callback_set(uart, uart_cb)" to the last code snipped instead of k_free(read_buf). The code is not rebooting and might be a solution. Does it seem correct?

  • partly. This callback is called when there is uart irq triggered nd you can atleast manually flush the rx by reading the whole rx fifo using uart_fifo_read. There is no API natively to flush TX fifo as deep as i can see.

  • Not flushing TX should be fine, it's the RX that receives the biggest amount of data. When you say that it party works and manually flush the RX by reading the whole RX fifo. Do you mind showing me an example of how you would use uart_fifo_read in this case? It would be much appreciated!

Related