Which task runs

Hello,
1)Tow idle tasks Task_A and Task_B. A third Task_C is higher priority.
Task_C preempted Task_B and ran in 25% of time assigned to Task_B, then blocked itself. Would Task_B run to finish it’s time slot or Task_A would run?
2) if configUSE_TIME_SLICING 0 what’s the side effect on the schedule in switching the tasks?
3)In VxWorks RTOS, round robin assigns count(counter) for each task. If high priority task interrupted the lower, it runs and when it blocks itself the interrupted task runs to finish the count . Here in FreeRTOS, in every tick, the time slice switch form one to the other. Can please clarify?
4) “calling taskYIELD() will never result in a switch to a higher priority task”. My question is switching to which priority would occur ?
I’m wondering between richard_damon comment here:

and the definition in taskYIELD() here:

Regarding TaskYIELD() and switching.

The below information can also be obtained from the free to download book.

Task_A. If task A and B are the same priority they will take turns.

The configUSE_TIME_SLICING setting will have not effect in the case you describe because the first context switch it due to a higher priority task preempting a lower priority task (not a tick interrupts), and the second context switch is the higher priority task blocking and so allowing a lower priority task to run (also not a tick interrupt). configUSE_TIME_SLICING only has an effect on scheduling between tick interrupts when there are tasks of equal priority sharing the MCU.

FreeRTOS will always run the highest priority task that is able to run so assuming you are using preemption, taskYIELD() can never yield to a higher priority task because if there were a higher priority task then it would already be running. taskYIELD() can then only yield to a task of the same priority - which might be itself if the calling task is the only task at that priority.

1 Like

Slight correction, calling taskYIELD() might switch to a higher priority task if configUSE_PREEMPTION is set to 0, or if an ISR is written incorrectly and it doesn’t activate the scheduler after waking a higher priority task. Both of these cases ‘break’ the rule that FreeRTOS will always be running the highest priority ready task. With configUSE_PREEMPTION it is an explicit request to not do context switches except at the specific points (like a taskYIELD) to allow the program to use a more relaxed view of state sharing.

1 Like

Hi Richard,
" If configUSE_TIME_SLICING is set to 0 then the RTOS scheduler will still run the highest priority task that is in the Ready state, but will not switch between tasks of equal priority just because a tick interrupt has occurred."
Regarding equal priority, how and when the switching would occur?

Again - you can get this information yourself from the free to download book.

If you are not using time slicing then a context switch will occur any time a higher priority task is enters the ready state (assuming you are using preemption) or any time the currently running task enters the blocked state.

Note, I am talking about configUSE_PREEMPTION, not configUSE_TIME_SLICING.

configUSE_TIME_SLICING means that as long as a given task continues to run, it keeps it place at the front of its current priority level line.

One thing that definitely puts it to the end of the line is if the task blocks or yields, then it moves to the back of the line.

I would need to look at the code, but will trust Richard Barry about the behavior if it gets interrupted by a higher priority task.

Basically, configUSE_TIME_SLICING (which basically needs configUSE_PREEMPTION) does is insert a call to taskYIELD() at every tick interrupt into the currently running task.

1 Like

Can you please re-read to ensure that what you meant?

What configUSE_TIME_SLICING does is every system tick (assuming configUSE_PREEMPTION is enabled) is automatically run the scheduler, even if no higher priority task was woken from some delay/timeout expiring on that tick. This effectively makes the currently running task do a taskYIELD() at the point it is at, since that is basically just what a taskYIELD() call does. If the scheduler is currently suspended, then this yield is remembered and happens with the scheduler is resumed.

When ,

configUSE_TIME_SLICING 1
configUSE_PREEMPTION  1

Then on every tick, the running task would call taskYIELD() even if the running task is higher in the priority than the others. Is that correct?

Every tick the scheduler will run, and the highest priority task will be selected. If the currently running task is the only task ready at its priority level, it will continue (just like if it call taskYEILD) but if there is another ready task at that priority level then they will time slice between them.

1 Like