Цитата(Golikov A. @ May 8 2014, 01:25)

Единственный момент, мне казалось что переключение задач запускает все же таймер, время отведенное на задачу определяет приоритет потока, так? То есть по выходу интервала таймера он ставит флаг PendSV, и уже тот вызвавшись все делает, так?
Я не рассматривал операционок, где ведётся контроль времени на
активную задачу. Очевидно что такое может делаться только в ОС, допускающих задачи с равным приоритетом.
Я использую uCOS, а в ней не допускается двух задач с одинаковым приоритетом. Соответственно - всё время CPU всегда получает задача с наивысшим приоритетом, и
менее приоритетная задача может получить время только если все более приоритетные уйдут в ожидание. Это более простая организация ОС, мне её хватает.
Когда Вы говорите про таймер, Вы путаете два разных действия ОС - решедулинг (выбор новой задачи верхнего уровня, которой и будет теперь отдаваться время CPU)
и собственно - переключение контекста (передача управления с переключением стека и рабочих переменных ОС).
Так вот решедулинг выполняется
во-первых:
при выполнении любой операции ОС с объектами синхронизации ОС (семафорами, мьютексами и пр.). Т.е. - при вызове функций ОС ЗанятьСемафор(), ОсвободитьСемафор(), и т.п.
во-вторых:
в функции таймера, который отсчитывает счётчики времени приостановки задач (OSTimeDelay(N_тактов_таймера)) вызванные задачами для создания паузы в выполнении задач.
Решедулинг определяет - изменилась-ли текущая high-priority task? И, если изменилась, ставит запрос PendSV.
Например - задача вызвала ОжиданиеСемафора() который в настоящий момент занят. Тогда она будет переведена в состояние Wait (с опциональной привязкой дескриптора задачи к
семафору). Соответственно - нужно найти новую текущую high-priority task. Решедулинг просматривает список задач находящихся в активном состоянии (хотя-бы одна должна быть,
всегда имеется фоновая Idle-задача ОС, на самом низшем приоритете, которая никогда не должна уходить в Wait (не должна вызывать никаких функций ожидания ОС)), выбирает
имеющую высший приоритет и ставит запрос PendSV. То же самое происходит в любом другом вызове функций ОсвободитьСемафор() или Занять/ОсвободитьМьютекс() или
ПриостановитьЗадачуНаNТиков() и т.п.
Само переключение контекста делается всегда в одном месте - в ISR PendSV. Это избавляет от необходимости запрета прерываний на время работы функции переключения контекста -
она может быть прервана любым ISR и соответственно - совсем не мешает аппаратным прерываниям.
Единственное, что делается в системном таймере (относительно переключения задач ОС) - это декремент счётчиков задержек выполнения задач (если задача вызвала
ожидание функцией OSTimeDelay(N_тактов_таймера) и если какой-то из этих счётчиков обнулился, соответствующая задача переходит из состояния DELAYED в состояние ACTIVE и
вызывается Решедулинг().