non-preemptive multi-tasking

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

non-preemptive multi-tasking

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.

non-preemptive multi-tasking

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?

non-preemptive multi-tasking

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.

non-preemptive multi-tasking

Sorry. I’m using FreeRTOS V5.0.3 for Luminary LM3S8962. Regards
Andreas

non-preemptive multi-tasking

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.

non-preemptive multi-tasking

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

non-preemptive multi-tasking

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.

non-preemptive multi-tasking

Definitely no stack problem.

non-preemptive multi-tasking

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

non-preemptive multi-tasking

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.