AnsweredAssumed Answered

what is the best way for Timeout on UART RX with MQX?

Question asked by Massimiliano Sturla on Oct 3, 2014
Latest reply on Sep 21, 2015 by Jianwu Tong

Hi to all,

I have develop (with support of another user of this community) an UART RX with demo board FRDM-K64 with MQX 4.1.1 using KDS 1.1.1

Now the code is that:

 

main.c:

 

#include <mqx.h>

#include <bsp.h>

#include <sem.h>

#include "main.h"

 

#if ! BSPCFG_ENABLE_IO_SUBSYSTEM

#error This application requires BSPCFG_ENABLE_IO_SUBSYSTEM defined non-zero in user_config.h. Please recompile BSP with this option.

#endif

 

#ifndef BSP_DEFAULT_IO_CHANNEL_DEFINED

#error This application requires BSP_DEFAULT_IO_CHANNEL to be not NULL. Please set corresponding BSPCFG_ENABLE_TTYx to non-zero in user_config.h and recompile BSP with this option.

#endif

 

#define MaxSci1_CHANNEL "ittyb:"

LWSEM_STRUCT    lwsemUartRX;

 

typedef struct rx_str_template

{

  char data_buf_RX[256];

  _mqx_uint nCharRx;

  _mqx_uint ConteggioInternoCharRicevuti;

 

} RX_STR, * RX_STR_PTR;

 

RX_STR rx_str;

 

void main_task (uint32_t initial_data){

   _task_id   task_id;

   uint32_t result;

   result = _lwsem_create(&lwsemUartRX, 0);

 

 

   if (result != MQX_OK) {

       printf("\nCreating lwsemUartRX failed: 0x%X", result);

       _task_block();

   }

 

   task_id = _task_create(0,READ_TASK, 0);

   printf("\nread_task created, id 0x%lX", task_id);

 

 

   while(1)

   {

    _lwsem_wait(&lwsemUartRX);

    printf("\nData:\n ");

    int i =0;

    for(i=0;i<rx_str.nCharRx;i++){

    printf("%c",rx_str.data_buf_RX[i]);

    }

    printf("\n");

   }

   _task_block();

}

 

 

void read_task(uint32_t initial_data){

  MQX_FILE_PTR MaxSci1_dev = NULL;

  bool disable_rx = FALSE;

  rx_str.nCharRx = 0;

 

  MaxSci1_dev =  fopen( MaxSci1_CHANNEL, NULL );

 

  if (MaxSci1_dev == NULL) {printf("\nError opening Sci1");}

  else{printf("\nSci1 opned!");}

   while (TRUE) {

    fread(&(rx_str.data_buf_RX[rx_str.nCharRx]), 1, 1, MaxSci1_dev);

    if(rx_str.data_buf_RX[rx_str.nCharRx] == 0x0D){

    _lwsem_post(&lwsemUartRX);

    }

    rx_str.nCharRx++;

   }

}

 

You can see that the receive-task give the semaphore on the stop byte 0x0D, now I want that the semaphore will be give when elaps 200msec, so I need to implement a TimeOut that it will refresh every time I receive a char and when will be triggered it will give me the semaphpore.

There are two ways, I suppose, to do that

- Interrupt

-internal check on receive byte.

 

For the second choice one user of this community tell me this way:

Do

{

bytesRead = fread(inBuffer,1,1,fd);

                _time_get_elapsed_ticks(&lastByteTime);

                memcpy(&inPacket[inPacketSize], inBuffer, bytesReaded);

                inPacketSize += bytesReaded;

                _time_get_elapsed_ticks(&now);

} while (_time_diff_milliseconds(&now, &lastByteTime, &overflow) <250);

 

But do not work because last time the cycle do/while condition will be check on the first byte of another packet because on last byte check condition, that are ok and cycle another time, and stuck on fread until next packet.

 

So I’m asking, how to do a timeout on last byte with interrupt and how to with internal cycle (if possible) ? what is the best in efficiency?

Many thanks,

Massimiliano

Outcomes