Receiving random number of bytes over Fast UART

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
NaFi_2915566
Level 3
Level 3
First like received First like given

I am trying to receive random size messages over a high-speed (>1Mbps) UART.  I can create a thread and receive one byte at a time as discussed in (How to Receive unknown number of bytes) but I think it would be too much overhead to keep calling wiced_uart_receive_bytes() over and over one byte at a time.  One alternative seems to be to duplicate what uart_platform.c ::uart_receive_bytes_irq() does internally and read directly from the ring buffer, then I am losing all portability and may be fighting with other parts of the SDK for the semaphores and thread priorities.

Questions:

  1. Does the SDK queue incoming bytes at a lower layer if no one is asking for them?
  2. (assume the answer to 1 is yes) if I ask for many many bytes with zero timeout, will I just get everything in the RX ring buffer?    e.g.

#define RX_BUFFER_SIZE 30

uint8_t receivebuffer[RX_BUFFER_SIZE];

int expected_data_size;

loop {

   expected_data_size = RX_BUFFER_SIZE;

   wiced_uart_receive_bytes( MY_UART, &receivebuffer, &expected_data_size, WICED_NO_WAIT);

   processMyData( &receivebuffer, expected_data_size );

}

e.g. if there are 100 bytes already received, I'd get chunks of 30, 30, 30 10.

If the answer to both is yes, this seems like it could keep up with a fast UART while doing other things.

0 Likes
1 Solution
NaFi_2915566
Level 3
Level 3
First like received First like given

the above almost works but never stops looping (NO_WAIT)

But this modification seems to work:

  wiced_ring_buffer_t rx_buffer;

  uint8_t             rx_data[RX_BUFFER_SIZE];

  uint8_t             processingBuffer[RX_BUFFER_SIZE];

  ring_buffer_init(&rx_buffer, rx_data, RX_BUFFER_SIZE );

  wiced_uart_init(MY_UART, &uart_config, &rx_buffer);

  while ( 1 )

  {

      expected_data_size = 1;

      // wait forever for the first byte

      if ( wiced_uart_receive_bytes( MY_UART, &processingBuffer[0], &expected_data_size, WICED_NEVER_TIMEOUT ) == WICED_SUCCESS )

      {

        // now see how many more bytes we can get

        expected_data_size = RX_BUFFER_SIZE-1;

        wiced_uart_receive_bytes( MY_UART, &processingBuffer[1], &expected_data_size, WICED_NO_WAIT );

        expected_data_size++;  // add the one we got above

        WPRINT_APP_INFO(("Got %d\n",expected_data_size));

        // process what we have

        for(int i=0; i<expected_data_size; i++)

        {

        ...

        }

      }

  }

if I send more than RX_BUFFER_SIZE then we process in RX_BUFFER_SIZE.

next mystery: accidentally I set the ring buffer size to RX_BUFFER_SIZE but the lower layer stores more than RX_BUFFER_SIZE anyway

View solution in original post

0 Likes
1 Reply
NaFi_2915566
Level 3
Level 3
First like received First like given

the above almost works but never stops looping (NO_WAIT)

But this modification seems to work:

  wiced_ring_buffer_t rx_buffer;

  uint8_t             rx_data[RX_BUFFER_SIZE];

  uint8_t             processingBuffer[RX_BUFFER_SIZE];

  ring_buffer_init(&rx_buffer, rx_data, RX_BUFFER_SIZE );

  wiced_uart_init(MY_UART, &uart_config, &rx_buffer);

  while ( 1 )

  {

      expected_data_size = 1;

      // wait forever for the first byte

      if ( wiced_uart_receive_bytes( MY_UART, &processingBuffer[0], &expected_data_size, WICED_NEVER_TIMEOUT ) == WICED_SUCCESS )

      {

        // now see how many more bytes we can get

        expected_data_size = RX_BUFFER_SIZE-1;

        wiced_uart_receive_bytes( MY_UART, &processingBuffer[1], &expected_data_size, WICED_NO_WAIT );

        expected_data_size++;  // add the one we got above

        WPRINT_APP_INFO(("Got %d\n",expected_data_size));

        // process what we have

        for(int i=0; i<expected_data_size; i++)

        {

        ...

        }

      }

  }

if I send more than RX_BUFFER_SIZE then we process in RX_BUFFER_SIZE.

next mystery: accidentally I set the ring buffer size to RX_BUFFER_SIZE but the lower layer stores more than RX_BUFFER_SIZE anyway

0 Likes