Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
8-CHto-takoe-mnogozadachnost.docx
Скачиваний:
6
Добавлен:
18.09.2019
Размер:
5.81 Mб
Скачать

Структура простейшего приложения под uCos-II

int main (void) {

OSInit(); // Инициализация ОС

// Создание первичной Задачи

OSTaskCreate( AppStartTask, // Адрес точки входа

(void *)0,

(OS_STK *)&Stk1[TASK_STK_SIZE-1], // Адрес стека

TASK_START_5 // Приоритет Задачи

);

OSStart(); // Запуск многозадачности

return 0; // Никогда не выполнится

}

// Первичная Задача

static void AppStartTask (void *pdata) {

.. .. .. // Здесь можно запустить системный таймер

// Создание других Задач

OSTaskCreate( Task1,

(void *)0,

(OS_STK *)&Stk2[TASK_STK_SIZE-1],

TASK1_9

);

OSTaskCreate( Task2,

(void *)0,

(OS_STK *)&AppTask2Stk[TASK_STK_SIZE-1],

TASK2_10

);

OSTaskDel(OS_PRIO_SELF); // Первичная Задача удаляет себя (необязательно)

}

static void Task1 (void *pdata) { // Задача, выполняющая полезную работу

unsigned long Var; // Локальные переменные

while (TRUE) { // Задача содержит бесконечный цикл

.. .. .. // Код, выполняющий полезную работу

OSTaskSuspend(OS_PRIO_SELF);

}

}

Структура многозадачного приложения

Код Задачи1 Код Задачи2 ………..

Что происходит при создании Задачи

Как начинается работа многозадачного приложения

«Создание» задачи

Код функции, удовлетворяющий требованиям к Задаче (не возвращает значения, не завершается выходом через завершающую скобку) должен быть оттранслирован и загружен в память. Но вызов этой функции обычным способом производить не надо.

Вместо этого надо сообщить Ядру о том, что эту Задачу следует исполнять. Это действие носит название «создать Задачу. Для этого есть системная функция OSTaskCreate(…) (см. далее). Эта функция для «создаваемой» Задачи заполняет специальную структуру – блок управления Задачей Task Control Block TCB. И в дальнейшем Диспетчер Задач будет учитывать все такие Задачи в процессах планирования и диспетчеризации (время от времени каждую из них запускать на выполнение). В TCB в частности, для каждой Задачи указан ее приоритет. В uC/OS каждая созданная Задача должна иметь уникальный приоритет в пределах от 0 (наивысший) до 62 (наинизший). Некоторые из значений приоритета могут быть зарезервированы для специального использования Операционной системой.

Поля блока управления Задачей

OSTCBStkPtr содержит указатель на текущую вершину стека Задачи. МикроСи/ОС-II позволяет каждой Задаче иметь свой стек, размер которого может быть индивидуальным для каждой Задачи. Размещение этого поля первым в данной структуре упрощает процедуру обращения к нему на ассемблере.

OSTCBExtPtr содержит указатель на определяемое пользователем расширение блока управления Задачей. Этот указатель позволяет расширять блок управления Задачей микроСи/ОС-II без вмешательства в исходный код системы. Поле OSTCBExtPtr используется только функцией OSTaskCreateExt(), поэтому OS_TASK_CREATE_EXT_EN должна быть установлена в 1. Вы можете создать структуру, которая содержит имя Задачи, отслеживать время выполнения Задачи, количество переключений контекста, и проч. Обратите внимание, что для облегчения вычисления смещения данного поля в структуре, этот указатель размещен сразу после указателя стека, на случай, если возникнет необходимость обратиться к этому полю на ассемблере.

OSTCBStkBottom содержит указатель на «дно» стека Задачи. Если стек процессора растёт в памяти в сторону увеличения адресов, OSTCBStkBottom будет указывать на наименьший адрес участка памяти, занимаемого стеком. Аналогично, если стек процессора растёт в памяти в сторону уменьшения адресов, OSTCBStkBottom будет указывать на наибольший адрес, занимаемый стеком. Поле OSTCBStkBottom используется функцией OSTaskStkChk() для проверки размера стека Задачи во время её выполнения. Это позволяет определять величину свободного стекового пространства каждой задачи. Проверка стека поддерживается только при создании Задачи при помощи OSTaskCreateExt(), поэтому OS_TASK_CREATE_EXT_EN должна быть установлена в 1.

OSTCBStkSize содержит размер стека в элементах, а не в байтах. Это значит, что, если стек содержит тысячу 32-разрядных элементов, его действительный размер будет равен 4000 байтам. Аналогично, при 16-разрядных элементах величина стека составит 2000 байтов для 1000 элементов. OSTCBStkSize используется функцией OSTaskStkChk(), поэтому OS_TASK_CREATE_EXT_EN также должна быть установлена в 1.

OSTCBOpt содержит "опции", или аргументы, которые могут быть переданы функции OSTaskCreateExt(). Поэтому это поле действительно только когда OS_TASK_CREATE_EXT_EN установлена равной 1. Текущая версия микроСи/ОС-II (ver.2.80) допускает только три возможные опции (см. uCOS_II.H ) : OS_TASK_OPT_STK_CHK, OS_TASK_OPT_STK_CLR, OS_TASK_OPT_SAVE_FP. OS_TASK_OPT_STK_CHK применяется для информирования OSTaskCreateExt() о том, что для создаваемой Задачи необходимо включить проверку стека. OS_TASK_OPT_STK_CLR обозначает, что область стека при создании Задачи должна быть предварительно очищена. Это необходимо сделать, если вы предполагаете использовать проверку стека. Если область стека не будет очищена, а затем вы создадите и уничтожите задачу, проверка стека покажет неправильное его использование. Если создаваемая Задача никогда не будет снята, а код, выполняющийся при старте системы, очищает всю оперативную память, вы можете сэкономить время процессора, НЕ указывая эту опцию. OS_TASK_OPT_STK_CLR увеличивает время выполнения OSTaskCreateExt(), так как требуется очистить область стека, причём чем больше стек, тем больше времени потребуется. Наконец, OS_TASK_OPT_SAVE_FP уведомляет OSTaskCreateExt() о том, что Задача будет производить вычисления с плавающей точкой, и, если процессор поддерживает такие вычисления аппаратно, содержимое регистров создаваемой Задачи, участвующих в этих вычислениях тоже необходимо сохранять в стеке при переключении контекста.

OSTCBId содержит идентификатор Задачи. В версиях до 2.80 включительно, это поле не используется, и зарезервировано для будущих расширений.

OSTCBNext и OSTCBPrev используются для связывания блоков управления Задачей OS_TCB в списковую структуру. Цепь из блоков OS_TCB используется OSTimeTick() для обновления полей OSTCBDly каждой Задачи. Связывание блоков OS_TCB производится при создании Задачи, а при удалении Задачи блок OS_TCB удаляется из этого списка.

OSTCBEventPtr содержит указатель на блок управления событиями и будет обсуждаться позже (см. МежЗадачное взаимодействие и синхронизация).

OSTCBMsg содержит указатель на сообщение, отправленное Задаче. Использование этого поля будет обсуждаться позже (см. МежЗадачное взаимодействие и синхронизация).

OSTCBDly используется при необходимости задержать выполнение Задачи на определённое число периодов системного таймера, или если Задаче необходимо дожидаться возникновения некоторого события определённое время (тайм-аут). В последнем случае это поле содержит число тиков таймера, которое Задаче позволено ожидать события. Когда это число равно нулю, Задача либо не должна задерживаться вообще, либо необходимо дожидаться возникновения события неопределённое время (т.е. без тайм-аута).

OSTCBStat содержит состояние Задачи. Когда содержимое OSTCBStat равно нулю, Задача готова к выполнению. OSTCBStat также может принимать другие значения, описываемые в uCOS_II.H.

OSTCBPrio содержит приоритет Задачи, который тем выше, чем меньше величина OSTCBPrio.

OSTCBX, OSTCBY, OSTCBBitX и OSTCBBitY используются для ускорения процессов перевода Задачи в состояния готовности и ожидания события и позволяют избегать вычисления их величин во время исполнения Задачи. Вместо этого, содержимое данных полей вычисляется при создании Задачи, либо при изменении её приоритета следующим образом:

OSTCBY = priority >> 3;

OSTCBBitY = OSMapTbl[priority >> 3];

OSTCBX = priority & 0x07;

OSTCBBitX = OSMapTbl[priority & 0x07];

OSTCBDelReq - булева переменная, служащая признаком запроса на удаление задачи. Использование этого поля будет обсуждаться позже (см. Управление Задачами).