AnsweredAssumed Answered

UART Recieve Missing characters

Question asked by Ben Griffiths on Jun 12, 2018
Latest reply on Jun 14, 2018 by Ben Griffiths

I'm using the Kinetis SDK and FreeRTOS.

 

I'm using the UART to output and input debug data within in a task. E.g I will send message like;

•Sensor Task Started

•Measurment Read

etc....

And I expect the console task to handle incoming string such as:

•"RESET/r" reset

•"CAL/r" send a mesasge to sensor task to re-cal sensor

etc...

Transmitting data is fine, recieving is not. Basically the UART recieve functions are regularly missing characters.

 

The incoming strings can be any length (within reason) and can be recieved at any time (again within reason). Most of the SDK functions rely on awaiting a specific number of characters and the RTOS recieve function is blocking, which is as useful as a choclacte teapot.

 

I've tried using both a ring buffer method and just using an interrupt driven method (the ring buffer method is below). Recieving of characters is sketchy at best.

 

Is there a better way of recieving characters using the SDK or is it best to write my own custom code (to peform the same/similar function as the Ring Buffer example below)

 

 

Ring Buffer Method

void console_init(void)
{
  port_pin_config_t config;
  uint32_t uart_clock_freq;

 

  CLOCK_EnableClock(kCLOCK_Uart2);
  uart_clock_freq = CLOCK_GetFreq(kCLOCK_BusClk);

 

  UART_GetDefaultConfig(&uart_config);  // Not really needed as we set all the parameters below.
  uart_config.baudRate_Bps = 57600U;  // We limited to what baud-rates we can set.
  uart_config.parityMode = kUART_ParityDisabled;
  uart_config.enableTx = true;
  uart_config.enableRx = true;
  UART_Init(UART2, &uart_config, uart_clock_freq);

 

  UART_TransferCreateHandle(UART2, &uart_handle, UART_Callback_FN, NULL);

 

  // Other Init stuff here
}

 

static void console_task_func(void *p_data)
{
  uint32_t queue_timeout;
  uint8_t local_cns_buffer[RECEIVE_BUFF_SIZE] = {0};
  uint8_t local_cns_index = 0;
  uint8_t *buff_ptr;
  size_t count;
  bool success;

 

  buff_ptr = (uint8_t *)receive_buffer;  // Casting here to prevent a warning about discarding volatile qualifier.
  receive_transfer.data = buff_ptr;
  receive_transfer.dataSize = 1;

 

  UART_TransferStartRingBuffer(UART2, &uart_handle, ringBuffer, RING_BUFFER_SIZE);

 

  while (1)
  {
    console_msg_t msg;

 

    if ( UART_TransferReceiveNonBlocking(UART2, &uart_handle, &receive_transfer, &count) == kStatus_Success )
    {
      if (count >= 1)
      {
        data_recieved = true;
        
        //....... Then do something with the data recievd........
      }
    }
    
    queue_timeout = 5;
 
    success = xQueueReceive(console_msg_queue, &msg, queue_timeout);

 

    if (!success)
    {
      /* Entirely possible to timeout here. In this event re-queue */
      continue;
    }

 

    switch (msg.opcode)
    {
    // Handling orf incoming messages here (Not related to UART)

 

    default:
      configASSERT_wConsole(false);
      break;
    }
  }
}

Outcomes