KDS UART Driver for FreeRTOS, Hanging

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

KDS UART Driver for FreeRTOS, Hanging

1,789 Views
Cdn_aye
Senior Contributor I

I have spent considerable time looking through the posts for a Kinetis FreeRTOS UART driver that works in an embedded system without failing in the simplest edge conditions. By that I mean, all the drivers I have tried in the examples must have the exact number of char's asked must be read by the driver or the driver fails to return. So a loss of char's on the Rx will cause to the driver to hang. I have read that a single char read is the way around this, but I find that to be a poor solution at best. There is no timeout mechanism on the driver.

Can anyone offer a solution please to a driver that does not hang and will timeout when all the char's are not received in a required timeout period? Under MQX this was possible by detecting the first char and checking the system time for the duration. This can be done if we rewrite the entire driver or try to patch the existing driver. The problem being that patching a distributed code section means understanding the nuances of the design which has not been explained then adding the relevant code additions. Again this leads to time and problems and then it may be best to start from zero and redo it all when the debugging and oversights are counted in.

Any direction would be appreciated.

Thanks

Robert

4 Replies

1,371 Views
gerardo_rodriguez
NXP Employee
NXP Employee

Hello Robert,

Unfortunately, the FreeRTOS UART driver included with the SDK does not have such feature. As you mention, you would need to modify the driver to implement a timeout feature. 

The UART_RTOS_Receive() function waits for an event generated by the UART callback. Have you tried adding a timeout value to this event wait? You could then handle the case where the timeout value was reached.

Regards,

Gerardo

0 Kudos

1,371 Views
Cdn_aye
Senior Contributor I

Hello Gerado

Thank you for your reply.

I have spent a few days trying different methods of implementing a time out without success.

I have a test string that I send out and a known length returned from and on board device that has the UART interface. I can receive exactly the correct number of char’s of the returned string, any fewer than that and the driver hangs.

I have tried using a callback with a timer that sets a flag, the driver checks the flag when it has run out of characters. That causes the return buffer to be null for some reason. I then tried using a binary semaphore and breaking out of the loop when the call back signals the timeout has lapsed. That also causes a failure to receive a valid buffer. In fact even asking for the exact known number of characters with this code added even when not called, causes the buffer to be returned empty. This I do not understand.

I have tried a multitude of ways with the interrupt driven and now polled and can not get this to work.

I have attached the code and would appreciate any advice you can give.

The main module, is r12.c and starts a task called Bt_Mon_Tsk, that task sends a command through the OutputFcns.c module, u32Fn_BtCmd, this is the code that sends out the string, and receives the reply. The callback r12.c/…uartCharTimeOutCallback gives the semaphore.

Bt_Mon_task, calls OutputFcns.c/…u32Fn_BtCmd(geBT_TEST_STR)

Which calls the write and read driver for the uart. The write driver works ok, it is the read that is a problem.

u32Fn_BtReadStr

starts the timer then calls

UART_ReadBlocking(UART0,

gca_rxBuffer,

14);

This last driver is in the module fsl_uart.c

status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length)

{

assert(data);

uint32_t statusFlag;

while (length--)

{

while (!base->RCFIFO)

{

statusFlag = UART_GetStatusFlags(base);

if (statusFlag & kUART_RxOverrunFlag)

{

return kStatus_UART_RxHardwareOverrun;

}

if (statusFlag & kUART_NoiseErrorFlag)

{

return kStatus_UART_NoiseError;

}

if (statusFlag & kUART_FramingErrorFlag)

{

return kStatus_UART_FramingError;

}

if (statusFlag & kUART_ParityErrorFlag)

{

return kStatus_UART_ParityError;

}

if( xSemaphoreTake(gs_uartIRQSemBinary, (TickType_t) 0) ){

return kStatus_UART_CharTimeout;

}

}

*(data++) = base->D;

}

return kStatus_Success;

}

Since I am running in a task in Polled mode I do not use the FromISR calls in FreeRTOS. But adding the if(xSemaphoreTake… kills the return buffer even if the length is exactly the length of the string. This I can’t figure out.

Any help would be appreciated.

Should I post this as a formal SR, or is this ok on the community forum?

Thanks

Regards

Robert

0 Kudos

1,371 Views
gerardo_rodriguez
NXP Employee
NXP Employee

Hi Robert,

 

I thought you were using the UART FreeRTOS driver from the SDK, but from your code I see that you are using directly the fsl_uart.c driver. My recommendation is to use the fsl_uart_freertos.c driver and modify the UART_RTOS_Receive() function to support a timeout feature.

 

You can add a timeout to the xEventGroupWaitBits() and if this function returns without any event bit set, it means that the xTicksToWait have passed. You can then return a timeout error code such as kStatus_Timeout and handle this case in your application.

 

An example using the UART FreeRTOS driver can be found at “<SDK>\boards\<board>\rtos_examples\freertos_uart”

 

Please let me know if you have any question about this approach.

 

Regards,

Gerardo

0 Kudos

1,371 Views
Cdn_aye
Senior Contributor I

Thank you, Gerardo. I will follow your advice.

Regards

Robert

On May 15, 2018 3:20:37 PM gerardorodriguezespinoza