Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

non-preemptive multi-tasking

Posted by Andreas Ornetzeder on January 18, 2010
Hello everybody

My program uses 6 tasks (all of them have idle priority) and an UART iterrupt service routine. FreeRTOS is configured non-preemptive.

1)
How does FreeRTOS implement non-preemptive multi-tasking?
It seems that FreeRTOS doesn't always continue with the interrupted task after the ISR routine has finished. Seems that there is a task schedule and another ready task continues execution before. Is this how FreeRTOS does non-preemptive multi-tasking? This would imply that I have to lock shared resources even in non-preemptive mode?

2)
My ISR uses "xSemaphoreGiveFromISR". Interestingly this function always returns that a higher priority task was woken although all of my tasks are created with idle priority. I don't request a context switch in order to continue with the actually interrupted task. Does this has any effect on the non-preemptive scheduling behaviour?


Thanks
Andreas

RE: non-preemptive multi-tasking

Posted by Dave on January 18, 2010
The last parameter to xSemaphoreGiveFromISR() will return true if the woken task has priority *equal to* or higher than the executing task.

In co-operative mode the tick interrupt will not select a new task to run. Whether or not your UART interrupt does is up to you. If you call portEND_SWITCHING_ISR or taskYIELD or portYIELD_FROM_ISR or whatever the port you are using implements then a switch will occur. If you don't want that to happen then simply don't call the switch macro. In most cases if you don't want the interrupt to cause a task switch you can write the interrupt in the normal way, as the compiler manual and examples tell you to, without any special assembly code or macros at all.

RE: non-preemptive multi-tasking

Posted by Andreas Ornetzeder on January 18, 2010
Thank you for the quick response.

My ISR doesn't request a context switch.

Code:

extern void UART1IntHandler( void )
/*------------------------------------------------------------------------*/
{
unsigned long ulStatus = UARTIntStatus( UART1_BASE, true );
UARTIntClear( UART1_BASE, ulStatus );
while ( UARTCharsAvail( UART1_BASE ) )
{
RingBufWriteOne( buf, UARTCharGetNonBlocking( UART1_BASE ) );
}
portBASE_TYPE xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR( _ctx_.dataAvailable, &xHigherPriorityTaskWoken );
}

Or does the xSemaphoreGiveFromISR() itself request a context switch?


RE: non-preemptive multi-tasking

Posted by Richard on January 18, 2010
Things would be so much easier if people would say which port they were using...

In any case, xHigherPriorityTaskWoken should be initialised to pdFALSE/0.

Regards.

RE: non-preemptive multi-tasking

Posted by Andreas Ornetzeder on January 18, 2010
Sorry.

I'm using FreeRTOS V5.0.3 for Luminary LM3S8962.

Regards
Andreas

RE: non-preemptive multi-tasking

Posted by Richard on January 18, 2010
“1)
How does FreeRTOS implement non-preemptive multi-tasking?
It seems that FreeRTOS doesn't always continue with the interrupted task after the ISR routine has finished. Seems that there is a task schedule and another ready task continues execution before. Is this how FreeRTOS does non-preemptive multi-tasking? This would imply that I have to lock shared resources even in non-preemptive mode?”


You use of xSemaphoreGiveFromISR() will allow the UART to unblock tasks, but because you are not calling portEND_SWITCHING_ISR() a switch to the unblocked task will not be performed. At least should not be performed, although it sounds like you are experiencing something different. How are you determining that a different task is being returned to?

“2)
My ISR uses "xSemaphoreGiveFromISR". Interestingly this function always returns that a higher priority task was woken although all of my tasks are created with idle priority. I don't request a context switch in order to continue with the actually interrupted task. Does this has any effect on the non-preemptive scheduling behaviour?”


I suspect that is because the variable is not being initialised. It should be initialised to pdFALSE before it is used.

Regards.

RE: non-preemptive multi-tasking

Posted by Andreas Ornetzeder on January 18, 2010
1)
I've implemented a central message module. Via a public API each task is able to create formatted messages and store them in a message container. Formatting messages is done via some kind of "sprintf" using a static character buffer. As I supposed that there will be no unintentional context switches this non-reentrant construction should work properly. The message module itself doesn't use any FreeRTOS functionality. Via serial communication I can pick up these messages one by one.

I observe two different problems:
- Some of the messages are corrupted as if the format buffer would be used concurrently by two different tasks.
- Sometimes the message sequence is invalid. I used a message sequence counter to determine this problem.

These problems occur whenever I produce UART traffic. If the UART ISR isn't called the message module works properly.
For testing purposes I've locked the message API using a FreeRTOS mutex to get rid of this problem.
But I would prefer to avoid this synchronisation or at least understand why my original implementation doesn't work in FreeRTOS non-preemptive mode.


2)
Doesn't make any difference whether or not I initialize the higherPriorityTaskWoken variable before use in "xSemaphoreGiveFromISR". But that doesn't matter a I really don't want a context switch when leaving the ISR.

Regards
Andreas

RE: non-preemptive multi-tasking

Posted by MEdwards on January 18, 2010
Do you have stack checking switched on? sprintf() can use a whole lot of stack, depending on which implementation you are using. Stack usage will go up when the UART is generating interrupts too.

RE: non-preemptive multi-tasking

Posted by Andreas Ornetzeder on January 18, 2010
Definitely no stack problem.

RE: non-preemptive multi-tasking

Posted by tgarner on January 18, 2010
Where do you observe the corruption ? Uart output ?
If your UART Tx is interrupt driven, you could possibly be calling transmit before the
last one completes

RE: non-preemptive multi-tasking

Posted by Andreas Ornetzeder on January 19, 2010
I use "UARTCharPut" to send serial data byte by byte. That isn't interrupt driven.
As I wrote before: If I use a mutex to lock access to the message API, everything works properly.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner