round-robin (time-slicing algo)

Hi, how is it possible to run two or more tasks with the same priority (using configUSE_PREEMPTION 1)? I don`t understand the time slicing algorithm. Task1: for( ;; ) { if( xSerialGetChar(&cByteRxed, RX_BLOCK_TIME ) ) {   cByteRxed = cByteRxed;   }   vTaskDelay( 200 ); } and the second task: for(;;) { vTaskDelayUntil( &xLastFlashTime, xFlashRate ); vParTestToggleLED( uxLED ); vTaskDelayUntil( &xLastFlashTime, xFlashRate ); vParTestToggleLED( uxLED ); } The configTICK_RATE_HZ is still 1000Hz (RTOS tick). How is it possible to share the available processor time (equal) to both tasks? best regards
Bernd

round-robin (time-slicing algo)

what will happen if both tasks (equal priority) don`t have any vTaskDelay() ?  Is only the first task running the whole time? How is it possible to determine that both tasks should only use 50% of the processor time (RTOS tick)?

round-robin (time-slicing algo)

A real-time system usually does not deal with time-sharing. A highest priority task runs until it either voluntarily relinguishes the processor (to sleep for example) or gets preempted by a higher priority task (which gets created or unblocked). This way, you make the best usage of the CPU since while your task is running you use 100% of it (minus the IRQ handlers) and do not spend any time switching context.

round-robin (time-slicing algo)

ok, if 2 or more tasks have the same priority, only one task is running and only if this task has to sleep e.g. another task with the same or lower priority will be executed. But in my example below, both tasks have a sleep time (using vTaskDelay() or vTaskDelayUntil(): At first both tasks were running, but after a short while only the idletask is running (for the whole time)… Which steps do I have to do to switch back to the flashled task (second task) for example?

round-robin (time-slicing algo)

could it be that both tasks are sleeping at the same time -> therefore (there`s no other task running) the idletask will be executed… and both task do not have any kind of mechanism to go back…. What will be a recommend way to start the flashtask (second task) again, after the vTaskDelayUntil() is over?

round-robin (time-slicing algo)

First off – all this is explained (hopefully) very clearly in the e-book, if you don’t mind me giving it a plug.  Also, the execution model is very traditional, and the behaviour similar to other systems. The following only applies if you have configUSE_PREEMPTION set to 1: FreeRTOS is a priorities pre-emptive system and will always run the highest priority task that is able to run.  By able to run I mean, not blocked waiting for a time (vTaskDelay(), etc.) or blocked waiting for a queue or semaphore event.  If a task become able to run and it has a priority above the currently running task it will pre-empt the currently running task and so run immediately. Where you have two tasks of the same priority that are both able to run (neither are blocked) then the scheduler will share processing time between them – but only if there are no higher priority tasks.  It does this by switching between them on each tick interrupt. Regards.

round-robin (time-slicing algo)

Reading Richard’s reply, I see that FreeRTOS does more than I thought. Is there a possibility to disable this time-sharing behaviour, and have the tick interrupt only deal with time-related issues?

round-robin (time-slicing algo)

Mmm, it looks like setting configUSE_PREEMPTION to 0 does just that. I thought it was dealing with general priority-based preemption in FreeRTOS, but tasks.c shows that it is only for same-priority tasks. Withdrawing my former question then :)

round-robin (time-slicing algo)

in theory: everything is clear to me according to this subject (”more tasks with the same priority”), but in practice it failed. For example: I`m using the unchanged version of the led_flash task (priority: 2) from the demo application. If only this task is running, everthing works as expected.
But now I installed a second task with the same priority: This task is waiting for new characters received by the usart (using a large blocking time). If I don`t place an additional vTaskDelay(), function within this task, only this task is running the whole time (the led is not flashing!) If I use the vTaskDelay() function in the second task, then this task will be executed only once, and after that only the idle-task is running…. Although there are many pkts received by the usart. task2:
for( ;; ) { /* Block on the queue that contains received bytes until a byte is
available. */
if( xSerialGetDmx0Char(&cByteRxed, dmxRX_BLOCK_TIME ) )
{
/* character received  */
cByteRxed = cByteRxed;
} // vTaskDelay( 2000 );
printf(”dmx_taskn”); }

round-robin (time-slicing algo)

I found the error! In the usart task I`m using this command:
if( xQueueReceive( xRxedDmx0Values, pcRxedChar, xBlockTime ) )
with  xBlockTime 0xffff It seems that there is a error, because without this command, everything is working as expected.