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 :
/*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;
}
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.
I think either LPUART or UART, the SDK make bad example for FreeRTOS, take a look this post
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...
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.
Regards
Daniel
Ok thank you Daniel. Where can I find this update ? Do I need to build again SDK at https://kex.nxp.com ?
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
Ok got it Thanks for you help.