Algorithm of work with GNSS via UART

Good Day.

I am using a custom board based on an nRF52840 microcontroller and a RYS8830 GNSS receiver connected to it via UART0. 

SDK v2.5.99 (Toolchain v2.5.0).

I want to get the coordinates of the board location (via asynchronous UART0) and output them to the terminal (via RTT and SWDIO programming connector ).

Could you please tell me how to correctly process incoming data from GNSS (NMEA message packet that arrives once per second) via UART? 

1. What is the correct action I should take in the UART callback function (uart_cb) when an NMEA data packet arrives (UART_RX_RDY)? 

2. In which part of the program should actions be performed to process incoming data? In the callback function (UART_RX_RDY), in the main function (main) or in an infinite loop (while(1))? 

I apologize for such basic questions, it's just that I'm new to programming.

I hope for your understanding and help.

Thanks.

Parents
  • Hi,

    You should not process the data in an interrupt (like a UART callback), so I would suggest that you use a worqeueue for that. See Workqueue Threads. You can refer to the Workqueue creation and work item submission Exercise for an eaxmple of using a workqueue.

  • Thank you, Einar, for your reply.
    Can you please tell me how to properly clear the receive buffer (rx_buf) of the UART?

    My plan is as follows, I receive data (NMEA messages) from the GNSS receiver and write it to rx_buf (buffer size 83 bytes) until the newline character '\n' arrives.

    /* Define the callback function for UART0 */
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	switch (evt->type) {
    
    	case UART_RX_RDY:
    		if(evt->data.rx.buf[evt->data.rx.offset] == '\n'){
    		    memcpy(rx_buf_cpy, rx_buf, sizeof(rx_buf));
    			k_work_submit_to_queue(&gnss_work_q, &gnss_work);
    			memset(rx_buf, 0, sizeof(rx_buf));
    		}
    		break;
    
    	case UART_RX_DISABLED:
    		uart_rx_enable(dev, rx_buf, sizeof rx_buf, RECEIVE_TIMEOUT);
    		break;
    
    	default:
    		break;
    	}
    }

    When a newline character is detected, I copy the contents of rx_buf to rx_buf_cpy using the memcpy function and send the data to the queue.

    static void gnss_work_cb (struct k_work *work){
    
       // Parsing rx_buf_cpy array
    }

    I then clear the receive buffer rx_buf in the UART callback function using the memset function. 

    But apparently my approach doesn't work, because after the first clearing of rx_buf no further writes are made to the buffer and the buffer remains empty.

    Please tell me how to do it correctly in my case. I will be grateful for any help.

Reply
  • Thank you, Einar, for your reply.
    Can you please tell me how to properly clear the receive buffer (rx_buf) of the UART?

    My plan is as follows, I receive data (NMEA messages) from the GNSS receiver and write it to rx_buf (buffer size 83 bytes) until the newline character '\n' arrives.

    /* Define the callback function for UART0 */
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
    	switch (evt->type) {
    
    	case UART_RX_RDY:
    		if(evt->data.rx.buf[evt->data.rx.offset] == '\n'){
    		    memcpy(rx_buf_cpy, rx_buf, sizeof(rx_buf));
    			k_work_submit_to_queue(&gnss_work_q, &gnss_work);
    			memset(rx_buf, 0, sizeof(rx_buf));
    		}
    		break;
    
    	case UART_RX_DISABLED:
    		uart_rx_enable(dev, rx_buf, sizeof rx_buf, RECEIVE_TIMEOUT);
    		break;
    
    	default:
    		break;
    	}
    }

    When a newline character is detected, I copy the contents of rx_buf to rx_buf_cpy using the memcpy function and send the data to the queue.

    static void gnss_work_cb (struct k_work *work){
    
       // Parsing rx_buf_cpy array
    }

    I then clear the receive buffer rx_buf in the UART callback function using the memset function. 

    But apparently my approach doesn't work, because after the first clearing of rx_buf no further writes are made to the buffer and the buffer remains empty.

    Please tell me how to do it correctly in my case. I will be grateful for any help.

Children
Related