Receiver Overrun when using LPUART_ReadBlocking

cancel
Showing results for 
Search instead for 
Did you mean: 

Receiver Overrun when using LPUART_ReadBlocking

850 Views
beng_
Contributor III

I'm using LPUART_ReadBlocking() to read a string from the LPUART. I keep getting a return status of kStatus_LPUART_RxHardwareOverrun indicating there's been a Receiver Overrun.

As the function call is a blocking function, the foreground software should be doing nothing except waiting for the requisite number of characters to be received over the UART. So I can't understand how I keep getting a Receiver Overrun as it should have plenty of time to read the incoming characters.

I'm using Free RTOS on a KL17 uc. I'm using the LPUART at 9,600 bps.

Any suggestions?

0 Kudos
1 Reply

348 Views
mjbcswitzerland
Specialist V


Hi Ben

I think the problem is that this needs a high priority task running the blocking code (it will be polling the Rx flag) so that it doesn't miss receptions. If a task with higher priority than itself runs it will not allow the polling to take place for a certain amount of time, with the subsequent risk of overruns.
Essentially a time slice setup would be best but you need to guarantee that the task runs for its time slice at least once a ms for 9'600 Baud. For 115'200 it would need to be about every 90us.
Although possible, it is very inefficient (high CPU % load which must be very deterministic to ensure fairly low throughput without loss) and so represents a general issue in the environment, where interrupt driven operation would improve performance.

For high rates (or generally), DMA is the most appropriate method which allows MBaud on multiple LPUARTs with negligeable loading and no loss.

There is a turn-key FreeRTOS LPUART DMA solution integrated in to the uTasker project which was born of the requirement and difficulties with achieving high baud rates in real projects and the complications of adapting the necessary driver in exiting FreeRTOS based applications; this allows such existing FreeRTOS projects to operate on one or more high speed LPUARTS (or UARTs on other processors). This is based on a task that handles the DMA queuing as follows:

    if (xTaskCreate(                                             // FreeRTOS UART task
        uart_task,                                               // pointer to the task
        "uart_task",                                             // task name for kernel awareness debugging
        configMINIMAL_STACK_SIZE,                                // task stack size
        (void*)NULL,                                             // optional task startup argument
        (configMAX_PRIORITIES - 1),                              // initial priority
        NULL
        ) != pdPASS) {
        _EXCEPTION("FreeRTOS failed to initialise task");
        return;                                                  // this only happens when there was a failure to initialise the task (usually not enough heap)
    }


static void uart_task(void *pvParameters)
{
    QUEUE_TRANSFER length = 0;
    QUEUE_HANDLE uart_handle;
    unsigned char dataByte;
    vTaskDelay(500/portTICK_RATE_MS);                            // wait for 500ms in order to allow uTasker to configure UART interfaces
    uart_handle = fnGetUART_Handle();                            // get the UART handle
    fnDebugMsg("FreeRTOS Output\r\n");                           // test a UART transmission
    FOREVER_LOOP() {
        length = fnRead(uart_handle, &dataByte, 1);              // read a byte from the DMA input buffer (returns immediately)
        if (length != 0) {                                       // if something is available
            fnDebugMsg("Echo:");                                 // echo it back
            fnWrite(uart_handle, &dataByte, 1);                  // send the byte back
            fnDebugMsg("\r\n");                                  // with termination
        }
        else {                                                   // nothing in the input buffer
            vTaskDelay(1);                                       // wait a single tick to allow other tasks to execute
        }
    }
}


This shows a (can be) low priority task handling a simple echo function - in most applications the reception would be subsequently processed or passed to another task to handle frames and such.
The LPUART is configured in DMA mode (in the uTasker part, called just to initialise it) with a specified input buffer length. For example, with 1kByte buffer no data loss can be experienced at 115'200 Baud as long as the input is checked once every 100ms or so. A second blocking task can "wait" on an event from this task so that it "sees" the operation as a real blocking input (either on a "per input" or "per frame" basis) without any need for time slicing or high priority, making the system highly efficient.
In such an environment even pausing the debugger will not result in any data loss (until the user defined buffer eventually overflows).

Please tell me in case this solution would be of interest for your work.

Regards

Mark


Kinetis: http://www.utasker.com/kinetis.html
Kinetis KL25, KL26, KL27, KL28, KL82:
- http://http://www.utasker.com/kinetis/FRDM-KL25Z.html
- http://www.utasker.com/kinetis/TWR-KL25Z48M.html
- http://www.utasker.com/kinetis/FRDM-KL26Z.html
- http://www.utasker.com/kinetis/TEENSY_LC.html
- http://www.utasker.com/kinetis/FRDM-KL27Z.html
- http://www.utasker.com/kinetis/Capuccino-KL27.html
- http://www.utasker.com/kinetis/FRDM-KL28Z.html
- http://www.utasker.com/kinetis/FRDM-KL82Z.html

Build with: CW10.x, KDS, MCUXpresso, IAR, Keil, Greenhills, Crossworks, CooCox, Atollic, S32 Design Studio, GNU Make and Visual Studio

Free Open Source solution: https://github.com/uTasker/uTasker-Kinetis
Working project in 15 minutes video: https://youtu.be/K8ScSgpgQ6M

For better, faster, cheaper product developments consider the uTasker developer's version, professional Kinetis support, one-on-one training and complete fast-track project solutions to set you apart from the herd : http://www.utasker.com/support.html

0 Kudos