assert error in LPUART_RTOS_Receive()

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

assert error in LPUART_RTOS_Receive()

1,707 Views
mr_max
Contributor IV

Hello ,

 

I just got an assert() error with my project (which use KL17Z256 with KSDKv2 and FreeRTOS).

 

I need to deal with a GSM module. LPUART0 peripheral is used for this task.

 

And sometime, an assert() error occurred and the __assert_func() reported me this message in my terminal  : 

ASSERT ERROR " ev == 0 ": file "../drivers/fsl_lpuart_freertos.c" Line "278" function name "LPUART_RTOS_Receive"

 

The " ev " pointed by assert seem to be the returned value of xEventGroupClearBits() where the event bit RTOS_UART_COMPLET is cleared before doing a non blocking receive transfer (see code at the end, line 41). Also, jumping into the assert function loop the MCU forever (see code below).

 

#elif(defined(__GNUC__))
void __assert_func(const char *file, int line, const char *func, const char *failedExpr)
{
    PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func);
    for (;;)
    {
        __asm("bkpt #0");
    }
}
#endif /* (defined(__CC_ARM)) ||  (defined (__ICCARM__)) */
#endif /* NDEBUG */

*assert function loop forever the MCU when occurred

 

I commented the assert function in fsl_freertos_lpuart.c file and it solved the problem but I believe this asserting have its own reason to be there. So maybe I should not do that.... (?)

 

So the questions are :

 

  1. Why asserting occurred during LPUART_RTOS_Receive() ?
  2. Why the return value of xEventGroupClearBits() should never be equal to zeros in this case ?

 

/*FUNCTION**********************************************************************
 *
 * Function Name : LPUART_RTOS_Recv
 * Description   : Receives chars for the application
 *
 *END**************************************************************************/
int LPUART_RTOS_Receive(lpuart_rtos_handle_t *handle, uint8_t *buffer, uint32_t length, size_t *received)
{
    EventBits_t ev;
    size_t n = 0;
    int retval = kStatus_Success;

    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;
    }

    if (pdFALSE == xSemaphoreTake(handle->rx_sem, portMAX_DELAY))
    {
        /* We could not take the semaphore, exit with 0 data received */
        return kStatus_Fail;
    }

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

    ev = xEventGroupClearBits(handle->rx_event, RTOS_UART_COMPLETE);
    assert(ev == 0); // ##### ASSERT PROBLEM IS HERE ! #########

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

    if (n < length)
    {
        ev = xEventGroupWaitBits(handle->rx_event, RTOS_UART_COMPLETE, pdTRUE, pdFALSE, portMAX_DELAY);
        if (ev & RTOS_UART_COMPLETE)
        {
            n = length;
        }
        else
        {
            retval = kStatus_Fail;
        }
    }

    if (pdFALSE == xSemaphoreGive(handle->rx_sem))
    {
        /* We could not post the semaphore, exit with error */
        retval = kStatus_Fail;
    }

    if (received != NULL)
    {
        *received = n;
    }

    return retval;
}

 

Labels (1)
7 Replies

1,152 Views
carlnormansuret
Contributor V

Ive got the latest SDK and still get kStatus_LPUART_RxHardwareOverrun errors with FreeRToS LPUART driver interface.

the serial port is standard 8N1 115200baud,This error fires because the interrupt has not read the byte in the RX buffer and a new byte has arrived.

I tried making the NVIC_SetPriority(115200_LPUART_RX_TX_IRQn, 1);  so its higher than the tick task (it is set to 3). Is this right? nothing else is running, its just a simple modem chat program getting network connection information, there is no other interrupts firing

If i was runnign this in a slow 8 bit processor with my own code it would easily run the interrupt and get the data in to a ring buffer before a new byte arrives. This processor should easily handle this with its ring buffer.

0 Kudos

1,152 Views
phantomgz
Contributor III

I think either LPUART or UART, the SDK make bad example for FreeRTOS, take a look this post

https://community.nxp.com/thread/443015 

0 Kudos

1,152 Views
carlnormansuret
Contributor V

Not a related issue, this is the ring buffer overflowing. 

I get kStatus_LPUART_RxHardwareOverrun which is saying there is a byte still in the rx byte when another arrives... 

0 Kudos

1,152 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi Maxime:

I would suggest you download the latest ksdk . From the release notes we can see that in LPUART driver, the needless check of event flags and assert in LPUART_RTOS_Receive was removed.

pastedImage_1.png

Regards

Daniel

1,152 Views
mr_max
Contributor IV

Ok thank you Daniel. Where can I find this update ? Do I need to build again SDK at https://kex.nxp.com ?

0 Kudos

1,152 Views
danielchen
NXP TechSupport
NXP TechSupport

Yes.   

/*FUNCTION**********************************************************************
 *
 * Function Name : LPUART_RTOS_Recv
 * Description   : Receives chars for the application
 *
 *END**************************************************************************/
int LPUART_RTOS_Receive(lpuart_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;

    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 */
    LPUART_TransferReceiveNonBlocking(handle->base, handle->t_state, &handle->rxTransfer, &n);

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

    /* 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;
}

Regards

Daniel

1,152 Views
mr_max
Contributor IV

Ok got it Thanks for you help.

0 Kudos