Флаги, по сути, очень похожи на бинарные семафоры. Есть две принципиальные разницы:
Применение флагов может быть полезным, когда какой-то задаче для продолжения работы необходимы результаты работы сразу нескольких задач. Например, задаче для вычисления каких-то физических параметров необходимы сведения о температуре, давлении и влажности. Каждая из этих физических величил измеряется в отдельной задаче, которая по завершении измерения устанавливает соответствующий флаг.
#include <osa.h> OST_FLAG8 F_Sensors; #define TEMPERATURE_MEASURED 0x01 #define PRESSURE_MEASURED 0x02 #define HUMIDITY_MEASURED 0x04 void Task_Calc (void) { for (;;) { // Ждем завершения измерений OS_Flag_Wait_AllOn(F_Sensors, TEMPERATURE_MEASURED | PRESSURE_MEASURED | HUMIDITY_MEASURED); OS_Flag_Clear(F_Sensors, TEMPERATURE_MEASURED | PRESSURE_MEASURED | HUMIDITY_MEASURED); // Теперь можно начинать расчеты ... } }
Другим примером может служить постановка автомобильной сигнализации на охрану. Она может произойти при получении команды с брелока, но только после того, как все двери и багажник будут закрыты. Фрагмен задачи может выглядеть так:
#include <osa.h> OST_FLAG8 F_Doors; // Флаги, отражающие состояние каждой двери: 1 - открыта, 0 - закрыта // Устанавливаются и сбрасываются в задаче обработки датчиков #define DOORS_MASK 0x0F // Маска битов, отражающих состояние дверей #define TRUNK_MASK 0x30 // Маска битов, отражающих состояние капота и багажника void Task_Guard (void) { for (;;) { OS_Bsem_Wait(BS_CMD_GUARD); // Получили команду с брелока "Постановка на охрану" // Ждем, когда будут закрыты все двери, капот и багажник OS_Flag_Wait_AllOff(F_Doors, DOORS_MASK | TRUNK_MASK); // Начиная отсюда, переходим в режим охраны: // подаем звуковые и световые сигналы, берем под охрану все датчики и пр. ... } }
Флаги могут быть 8-, 16- и 32-разрядные. В программе объявляются так:
OST_FLAG MyFlag1; // 8-разрядные флаги OST_FLAG16 MyFlag2; // 16-разрядные флаги OST_FLAG32 MyFlag3; // 32-разрядные флаги
Флаги можно определять в любом банке памяти, например:
bank2 OST_FLAG16 MyFlag;
В программе могут одновременно использоваться флаги разных разрядностей.
Для работы с флагами их нужно создать сервисом OS_Flag_Create. Этого можно и не делать, но тогда их начальное значение будет не определено. Ниже приведены все системные сервисы для работы с флагами.
Сервис | Аргументы | Описание | Свойства |
---|---|---|---|
Создание | |||
OS_Flag_Create | (flags) | Создает флаги (фактически просто сбрасывает все флаги) | |
Управление | |||
OS_Flag_Init | (flags, value) | Устанавливает все флаги в заданное значение | |
OS_Flag_Set | (flags, mask) | Установка флагов по маске | |
OS_Flag_Clear | (flags, mask) | Сброс флагов по маске | |
Проверка | |||
bool OS_Flag_Check_AllOn | (flags, mask) | Проверить, все ли флаги по маске установлены | |
bool OS_Flag_Check_On | (flags, mask) | Проверить, есть ли хотя бы один установленный флаг по маске | |
bool OS_Flag_Check_AllOff | (flags, mask) | Проверить, все ли флаги по маске сброшены | |
bool OS_Flag_Check_Off | (flags, mask) | Проверить, есть ли хотя бы один сброшенный флаг по маске | |
Ожидание | |||
OS_Flag_Wait_AllOn | (flags, mask) | Ожидаем установки всех флагов по маске | |
OS_Flag_Wait_On | (flags, mask) | Ожидаем установки хотя бы одного флага из маски | |
OS_Flag_Wait_AllOff | (flags, mask) | Ожидаем сброса всех флагов по маске | |
OS_Flag_Wait_Off | (flags, mask) | Ожидаем сброса хотя бы одного флага из маски | |
OS_Flag_Wait_AllOn_TO | (flags, mask, timeout) | Ожидаем установки всех флагов по маске с выходом по таймауту | |
OS_Flag_Wait_On_TO | (flags, mask, timeout) | Ожидаем установки хотя бы одного флага из маски с выходом по таймауту | |
OS_Flag_Wait_AllOff_TO | (flags, mask, timeout) | Ожидаем сброса всех флагов по маске с выходом по таймауту | |
OS_Flag_Wait_Off_TO | (flags, mask, timeout) | Ожидаем сброса хотя бы одного флага из маски с выходом по таймауту |