Приостановка/запуск планировщика
Еще один способ реализации критической
секции в FreeRTOS — это приостановка рабо-
ты планировщика (suspending the scheduler).
В отличие от реализации критической
секции с помощью запрета прерываний (ма-
кросы taskENTER_CRITICAL() и taskEXIT_
CRITICAL()), которые защищают участок
кода от доступа как из задач, так и из преры-
ваний, реализация с помощью приостановки
планировщика защищает участок кода толь-
ко от доступа из другой задачи. Все прерыва-
ния микроконтроллера остаются разрешены.
Операция запуска планировщика после при-
остановки выполняется существенно дольше
макроса taskEXIT_CRITICAL(), это немаловаж-
но с точки зрения сокращения времени выпол-
нения критических секций в программе. Этот
момент следует учитывать при выборе способа
организации критических секций.
Приостановка планировщика выполняется
API-функцией vTaskSuspendAll(). Ее прото-
тип:
void vTaskSuspendAll( void );
После вызова vTaskSuspendAll() плани-
ровщик останавливается, переключения
контекста каждый системный квант вре-
мени не происходит, задача, которая вы-
звала vTaskSuspendAll(), будет выполнять-
ся сколь угодно долго до запуска плани-
ровщика. API-функция vTaskSuspendAll()
не влияет на прерывания: если до вызова
vTaskSuspendAll() они были разрешены,
то при возникновении прерываний их об-
работчики будут выполняться.
Если же обработчик прерывания выполнил
макрос принудительного переключения кон-
текста (portSWITCH_CONTEXT(), taskYIELD(),
portYIELD_FROM_ISR() и др. — в зависимости
от порта FreeRTOS), то запрос на переключение
контекста будет выполнен, как только работа
планировщика будет возобновлена.
Другие API-функции FreeRTOS нельзя вы-
зывать, когда планировщик приостановлен
вызовом vTaskSuspendAll().
Для возобновления работы планировщи-
ка служит API-функция xTaskResumeAll(), ее
прототип:
portBASE_TYPE xTaskResumeAll( void );
Возвращаемое значение может быть равно:
Достарыңызбен бөлісу: |