LPCxpresso FreeRTOS USART receive timeout

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPCxpresso FreeRTOS USART receive timeout

1,826 Views
primate
Contributor III

Hello,

I am using the LPCxpresso 54628 board and have a question regarding lpcxpresso54628_rtos_examples_freertos_usart that I am testing. The (pooling) example runs fine but I want to add a timeout when nothing is received for a certain amount of time. The plan is to send a status request via USART Tx and if nothing is received (from a slave device2) within a time period then the device2 is declared dead and USART Tx continues to request status from other devices. If a status is received from device2 then the info is parsed and thereafter USART Tx continues to request status from other devices.

 

My question is what is the best method (resource vise) to implement a timeout in this FreeRTOS USART example when nothing is received? 

 

I have found quite a bit of questions around this matter but non of them have a solid straight answer. The closest I found is here (in spanish I think) and here (does not use FreeRTOS). 

 

The example mentioned is attached below for reference.

 

Thank you for any help.

Labels (1)
2 Replies

1,195 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi primate,

1.  What is the best method (resource vise) to implement a timeout in this FreeRTOS USART example when nothing is received? 

   I think you can add another tickless Task, check the tickcount, if your timeout happens, the UART still didn't receive the data which you want, you can do the other things you want, about the tickcount get, you can refer to the freertos_tickless project.

2. You said:

send a status request via USART Tx and if nothing is received (from a slave device2) within a time period then the device2 is declared dead and USART Tx continues to request status from other devices.

  I need to tell you that, to the UART, UART is connect to one to one, it can't be one to more than two, unless you use more than one UART modules.

Wish it helps you!

Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,195 Views
primate
Contributor III

Dear Kerry,

Thank you for the reply.

1. I will try the tickless, although in the meantime I have changed fsl_usart_freertos.c by adding USER_TIMEOUT and adding the timeout condition. 

int USART_RTOS_Receive(usart_rtos_handle_t *handle, uint8_t *buffer, uint32_t length, size_t *received)
{
    EventBits_t ev;
    size_t n = 0;
    int retval = kStatus_Fail;
    size_t local_received = 0;
    const TickType_t USER_TIMEOUT = 500 / portTICK_PERIOD_MS; 

    if (NULL == handle->base)
    {
        /* Invalid handle. */
        return kStatus_Fail;
    }
    if (0 == length)
    {
        if (received != NULL)
        {
            *received = n;
        }
        return 0;
    }
    if (NULL == buffer)
    {
        return kStatus_InvalidArgument;
    }

    /* New transfer can be performed only after current one is finished */
    if (pdFALSE == xSemaphoreTake(handle->rxSemaphore, portMAX_DELAY))
    {
        /* We could not take the semaphore, exit with 0 data received */
        return kStatus_Fail;
    }

    handle->rxTransfer.data = buffer;
    handle->rxTransfer.dataSize = (uint32_t)length;

    /* Non-blocking call */
    USART_TransferReceiveNonBlocking(handle->base, handle->t_state, &handle->rxTransfer, &n);

    ev = xEventGroupWaitBits(handle->rxEvent, RTOS_USART_COMPLETE | RTOS_USART_RING_BUFFER_OVERRUN, pdTRUE, pdFALSE,
              USER_TIMEOUT); //portMAX_DELAY);
    if (ev & RTOS_USART_RING_BUFFER_OVERRUN)
    {
        /* Stop data transfer to application buffer, ring buffer is still active */
        USART_TransferAbortReceive(handle->base, handle->t_state);
        /* Prevent false indication of successful transfer in next call of USART_RTOS_Receive.
           RTOS_USART_COMPLETE flag could be set meanwhile overrun is handled */
        xEventGroupClearBits(handle->rxEvent, RTOS_USART_COMPLETE);
        retval = kStatus_USART_RxRingBufferOverrun;
        local_received = 0;
    }
    else if (ev & RTOS_USART_COMPLETE)
    {
        retval = kStatus_Success;
        local_received = length;
    }

    else // xEventGroupWaitBits() returned because xTicksToWait ticks passed
        {
               /* Stop data transfer to application buffer, ring buffer is still active */
               USART_TransferAbortReceive(handle->base, handle->t_state);
               /* Prevent false indication of successful transfer in next call of USART_RTOS_Receive.
                  RTOS_USART_COMPLETE flag could be set meanwhile overrun is handled */
               xEventGroupClearBits(handle->rxEvent, RTOS_USART_COMPLETE);
            retval = kStatus_Timeout;
            local_received = 0;
        }
   
    /* Prevent repetitive NULL check */
    if (received != NULL)
    {
        *received = local_received;
    }

    /* Enable next transfer. Current one is finished */
    if (pdFALSE == xSemaphoreGive(handle->rxSemaphore))
    {
        /* We could not post the semaphore, exit with error */
        retval = kStatus_Fail;
    }
    return retval;
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

2. Maybe I did not clarify but I am using UART to drivea RS485 half duplex chip, which is then connected to more devices on the AB line.