====== OSA : Флаги ====== ===== Введение ===== Флаги, по сути, очень похожи на бинарные семафоры. Есть две принципиальные разницы: - одним сервисом можно обработать несколько флагов сразу (например, можно ждать установки хотя бы одного из нескольких флагов или установки сразу нескольких); - после завершения ожидания флаги, в отличие от бинарных семафоров, не сбрасываются. Применение флагов может быть полезным, когда какой-то задаче для продолжения работы необходимы результаты работы сразу нескольких задач. Например, задаче для вычисления каких-то физических параметров необходимы сведения о температуре, давлении и влажности. Каждая из этих физических величил измеряется в отдельной задаче, которая по завершении измерения устанавливает соответствующий флаг. #include 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 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); // Начиная отсюда, переходим в режим охраны: // подаем звуковые и световые сигналы, берем под охрану все датчики и пр. ... } } ~~UP~~ ===== Объявление флагов ===== Флаги могут быть 8-, 16- и 32-разрядные. В программе объявляются так: OST_FLAG MyFlag1; // 8-разрядные флаги OST_FLAG16 MyFlag2; // 16-разрядные флаги OST_FLAG32 MyFlag3; // 32-разрядные флаги Флаги можно определять в любом банке памяти, например: bank2 OST_FLAG16 MyFlag; В программе могут одновременно использоваться флаги разных разрядностей. Для работы с флагами их нужно создать сервисом ##[[osa:ref:allservices:OS_Flag_Create|OS_Flag_Create]]##. Этого можно и не делать, но тогда их начальное значение будет не определено. Ниже приведены все системные сервисы для работы с флагами. ~~UP~~ ===== Сервисы для работы с флагами. ===== ^ Сервис ^ Аргументы ^ Описание ^ Свойства ^ | **Создание** |||| | ##[[osa:ref:allservices:OS_Flag_Create|OS_Flag_Create]]## | ''(flags)'' | Создает флаги (фактически просто сбрасывает все флаги) | | | **Управление** |||| | ##[[osa:ref:allservices:OS_Flag_Init|OS_Flag_Init]]## | ''(flags, value)'' | Устанавливает все флаги в заданное значение | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | ##[[osa:ref:allservices:OS_Flag_Set|OS_Flag_Set]]## | ''(flags, mask)'' | Установка флагов по маске | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | ##[[osa:ref:allservices:OS_Flag_Clear|OS_Flag_Clear]]## | ''(flags, mask)'' | Сброс флагов по маске | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | **Проверка** |||| | ''bool ''\\ ##[[osa:ref:allservices:OS_Flag_Check_AllOn|OS_Flag_Check_AllOn]]## | ''(flags, mask)'' | Проверить, все ли флаги по маске установлены | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | ''bool ''\\ ##[[osa:ref:allservices:OS_Flag_Check_On|OS_Flag_Check_On]]## | ''(flags, mask)'' | Проверить, есть ли хотя бы один установленный флаг по маске | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | ''bool ''\\ ##[[osa:ref:allservices:OS_Flag_Check_AllOff|OS_Flag_Check_AllOff]]## | ''(flags, mask)'' | Проверить, все ли флаги по маске сброшены | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | ''bool ''\\ ##[[osa:ref:allservices:OS_Flag_Check_Off|OS_Flag_Check_Off]]## | ''(flags, mask)'' | Проверить, есть ли хотя бы один сброшенный флаг по маске | {{osa:ref:attr_call_can_int.png|Есть расширенный сервис с суффиксом _I для работы в прерывании}} | | **Ожидание** |||| | ##[[osa:ref:allservices:OS_Flag_Wait_AllOn|OS_Flag_Wait_AllOn]]## | ''(flags, mask)'' | Ожидаем установки всех флагов по маске | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} | | ##[[osa:ref:allservices:OS_Flag_Wait_On|OS_Flag_Wait_On]]## | ''(flags, mask)'' | Ожидаем установки хотя бы одного флага из маски | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} | | ##[[osa:ref:allservices:OS_Flag_Wait_AllOff|OS_Flag_Wait_AllOff]]## | ''(flags, mask)'' | Ожидаем сброса всех флагов по маске | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} | | ##[[osa:ref:allservices:OS_Flag_Wait_Off|OS_Flag_Wait_Off]]## | ''(flags, mask)'' | Ожидаем сброса хотя бы одного флага из маски | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}} | | ##[[osa:ref:allservices:OS_Flag_Wait_AllOn_TO|OS_Flag_Wait_AllOn_TO]]## | ''(flags, mask, timeout)'' | Ожидаем установки всех флагов по маске с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} | | ##[[osa:ref:allservices:OS_Flag_Wait_On_TO|OS_Flag_Wait_On_TO]]## | ''(flags, mask, timeout)'' | Ожидаем установки хотя бы одного флага из маски с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} | | ##[[osa:ref:allservices:OS_Flag_Wait_AllOff_TO|OS_Flag_Wait_AllOff_TO]]## | ''(flags, mask, timeout)'' | Ожидаем сброса всех флагов по маске с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} | | ##[[osa:ref:allservices:OS_Flag_Wait_Off_TO|OS_Flag_Wait_Off_TO]]## | ''(flags, mask, timeout)'' | Ожидаем сброса хотя бы одного флага из маски с выходом по таймауту | {{osa:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}}{{osa:ref:attr_call_ct_sw.png|Переключает контекст}}{{osa:ref:attr_call_to.png|Использует системный таймер}} | ~~UP~~