# non-preemptive multi-tasking

**URL:** <https://forums.freertos.org/t/non-preemptive-multi-tasking/1536>\
**Category:** Kernel\
**Created:** [January 18, 2010, 10:45am UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536 "2010-01-18T10:45:20Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 10:45am UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/1 "2010-01-18T10:45:20Z")

</div>

**[gugl](https://sourceforge.net/u/gugl/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#591a):

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&nbsp; “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

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 10:53am UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/2 "2010-01-18T10:53:40Z")

</div>

**[davedoors](https://sourceforge.net/u/davedoors/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#c537):

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.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 11:52am UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/3 "2010-01-18T11:52:46Z")

</div>

**[gugl](https://sourceforge.net/u/gugl/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#9a3a):

Thank you for the quick response.

My ISR doesn’t request a context switch.

Code:

extern void UART1IntHandler( void )  
/\*------------------------------------------------\*/  
{  
&nbsp;&nbsp;&nbsp; unsigned long ulStatus = UARTIntStatus( UART1\_BASE, true );  
&nbsp;&nbsp;&nbsp; UARTIntClear( UART1\_BASE, ulStatus );  
&nbsp;&nbsp;&nbsp; while ( UARTCharsAvail( UART1\_BASE ) )  
&nbsp;&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RingBufWriteOne( buf, UARTCharGetNonBlocking( UART1\_BASE ) );  
&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp; portBASE\_TYPE xHigherPriorityTaskWoken;  
&nbsp;&nbsp;&nbsp; xSemaphoreGiveFromISR( \_ctx\_.dataAvailable, &xHigherPriorityTaskWoken );  
}

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

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [January 18, 2010, 11:58am UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/4 "2010-01-18T11:58:12Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#e3b2):

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.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 12:09pm UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/5 "2010-01-18T12:09:31Z")

</div>

**[gugl](https://sourceforge.net/u/gugl/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#2e73):

Sorry.

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

Regards  
Andreas

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [January 18, 2010, 1:50pm UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/6 "2010-01-18T13:50:59Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#dfca):

> 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.&nbsp; At least should not be performed, although it sounds like you are experiencing something different.&nbsp; 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.&nbsp; It should be initialised to pdFALSE before it is used.

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 2:39pm UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/7 "2010-01-18T14:39:48Z")

</div>

**[gugl](https://sourceforge.net/u/gugl/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#a2f0):

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

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 2:49pm UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/8 "2010-01-18T14:49:31Z")

</div>

**[edwards3](https://sourceforge.net/u/edwards3/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#e788):

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.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 3:09pm UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/9 "2010-01-18T15:09:43Z")

</div>

**[gugl](https://sourceforge.net/u/gugl/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#167e):

Definitely no stack problem.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 18, 2010, 5:30pm UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/10 "2010-01-18T17:30:31Z")

</div>

**[tgarner](https://sourceforge.net/u/tgarner/)** wrote on [Monday, January 18, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#b4ed):

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

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [January 19, 2010, 10:16am UTC](https://forums.freertos.org/t/non-preemptive-multi-tasking/1536/11 "2010-01-19T10:16:23Z")

</div>

**[gugl](https://sourceforge.net/u/gugl/)** wrote on [Tuesday, January 19, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/452eb807/#d71e):

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.
