====== 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~~