100
КОМПОНЕНТЫ И ТЕХНОЛОГИИ •
№ 4 '2011
компоненты
микроконтроллеры
Например, пусть задача вызвала функ-
цию
xTicksToDelay(100) в момент времени,
когда счетчик квантов был равен 5000. Задача
сразу же блокируется, планировщик отдаст
управление другой задаче, а вызывающая за-
дача вернется в состояние готовности к вы-
полнению, только когда счетчик квантов до-
стигнет значения 5100. В течение времени,
пока счетчик квантов будет увеличиваться
от 5000 до 5100, планировщик будет выпол-
нять другие задачи, в том числе задачи с бо-
лее низким приоритетом.
Следует отметить, что программисту нет
необходимости отслеживать переполнение
счетчика квантов времени. API-функции,
связанные с отсчетом времени (в том числе
и
vTaskDelay()), берут эту обязанность на себя.
Рассмотрим учебную программу № 2, ко-
торая выполняет те же функции, что и про-
грамма № 1, но для создания задержек в ней
используется API-функция
vTaskDelay().
Кроме того, задаче при ее создании передает-
ся не абстрактное значение периода, а значе-
ние периода в миллисекундах:
#include
#include
#include
#include “FreeRTOS.h”
#include “task.h”
/* Структура, содержащая передаваемую в задачу информацию */
typedef struct TaskParam_t {
char string[32]; /* строка */
long period; /* период, миллисекунды*/
} TaskParam;
/* Объявление двух структур TaskParam */
TaskParam xTP1, xTP2;
/*-----------------------------------------------------------*/
/* Функция, реализующая задачу */
void vTask( void *pvParameters )
{
volatile TaskParam *pxTaskParam;
/* Преобразование типа void* к типу TaskParam* */
pxTaskParam = (TaskParam *) pvParameters;
for( ;; )
{
/* Вывести на экран строку, переданную в качестве параметра
при создании задачи */
puts( (const char*)pxTaskParam->string );
/* Задержка на время, заданное в миллисекундах */
/* pxTaskParam->period задан в миллисекундах /*
/* Разделив его на кол-во мс в кванте, получим кол-во квантов */
vTaskDelay(pxTaskParam->period / portTICK_RATE_MS);
}
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
/* Точка входа. С функции main() начнется выполнение программы. */
short main( void )
{
/* Заполнение полей структуры, передаваемой Задаче 1 */
strcpy(xTP1.string, “Task 1 is running”);
xTP1.period = 1000L;
/* 1000 мс */
/* Заполнение полей структуры, передаваемой Задаче 2 */
strcpy(xTP2.string, “Task 2 is running”);
xTP2.period = 3000L;
/* 3000 мс */
/* Создание Задачи 1 с приоритетом 1. Передача ей в качестве
параметра указателя на структуру xTP1 */
xTaskCreate( vTask, ( signed char * ) “Task1”, configMINIMAL_
STACK_SIZE, (void*)&xTP1, 1, NULL );
/* Создание Задачи 2 с приоритетом 2. Передача ей указателя
на структуру xTP2 */
xTaskCreate( vTask, ( signed char * ) “Task2”, configMINIMAL_
STACK_SIZE, (void*)&xTP2, 2, NULL );
/* Запуск планировщика */
vTaskStartScheduler();
return 1;
}
По результатам работы учебной програм-
мы № 2 (рис. 10) видно, что процессорное
время теперь получает как высокоприори-
тетная задача 2, так и низкоприоритетная за-
дача 1.
Выполнение задач в учебной программе
№ 2 приведено на рис. 11. Выполнение кода
планировщика в целях упрощения рисунка
не приводится. Б
óльшую часть времени про-
цессор бездействует, а следовательно, теперь
задачи очень экономно расходуют процес-
сорное время.
В момент времени (1) происходит запуск
планировщика. На этот момент Задача 1
и Задача 2 находятся в состоянии готовности
к выполнению, однако приоритет Задачи 2
выше, поэтому именно ей планировщик
передает управление. Задача 2 выполняет
полезную работу (выводит строку “Task 2
Достарыңызбен бөлісу: