В частности для FreeRTOS при установленном "#define
configUSE_PREEMPTION 1" она становится вытесняющей и
планировщик(-у) вызывается/ему отдаётся управление: - [1] по системному таймеру;
- [2] задача освобождает процессор (например уходит Sleep();/Delay(); или явно освобождает Yield(); );
- [2] задача посредством очереди/семафора/мьютекса "передаёт" управление задаче с приоритетом выше чем у неё;
- [2] в прерывании явно указывается вызов определённой задачи по irqYield() после выхода из этого прерывания.
Таким образом ОС переключает задачи по "тикам" и приоритетам по [1] до тех пор пока не наступит что-либо из [2] (смена задач по необходимости и приоритетам) - после этого она ведёт себя как вытесняющая до окончания условий [2].
Переключения задач разумеется выполняется с соблюдением их приоритетов.
Т.е. планировщик вызывается не только по [1], но и при [2].