Биты событий и Группы событий(Event Bits,Event Groups) появились во FreeRTOS 8.
Бит (он же флаг) события - это бит, принимающий значение 0 или 1 и имеющий семантическое значение (ясное программисту).
ОС FreeRTOS не поддерживает механизм отдельных битов, поддерживает наборы битов. Длина одного набора - 8 бит (если константа configUSE_16_BIT_TICKS равна 1) или 24 бита(configUSE_16_BIT_TICKS = 0). Все функции для работы с битами начинаются с xEventGroup...
Функция xEventGroupWaitBits
Итак, создадим группу битов с именем xEventGroupSdOrCC.
EventGroupHandle_t xEventGroupSdOrCC;
Теперь установим в этой группе бит с номером 0
xEventGroupSetBits(xEventGroupSdOrCC, (1<<0));
Теперь можно написать мигалку (на PORTG 2), которая будет мигать только тогда, когда хоть один из битов группы xEventGroupSdOrCC установлен
for( ;; )
{
vTaskDelayUntil(&xLastWakeTime,500);//Выдержка времени 500 тиков (не ms)
xEventGroupWaitBits( xEventGroupSdOrCC, 0b11, pdFALSE, pdFALSE, portMAX_DELAY ); // xClearOnExit, xWaitForAllBits
PORTG ^= (1<<PG2);
}
Мы использовали следующие параметры при вызове xEventGroupWaitBits:
xEventGroupSdOrCC - имя проверяемой группы
0b11 - с чем сравниваем значение в этой группе - сравниваем с 0b11
pdFALSE - после сравнения биты в группе не будут сброшены
pdFALSE - ждём не все биты установленными, а хотя бы один бит
portMAX_DELAY - задержка, если поставим 0 - то проверка произойдёт (результат вернётся в тело xEventGroupSdOrCC ) и следующий за xEventGroupWaitBits оператор (мигалка) начнёт выполнятся. Так как по логике программы мы ждём установку хоть одного бита, чтобы замигать, был выбран вариант portMAX_DELAY - бесконечная задержка.
Функция xEventGroupSync
Свидание нитей.
Свидание нитей (свидание тасков, задач) - необходимость каждой нитью определённого состояние, дальше которого оно двигаться не может без уверенности, что соседи находятся в своих определённых состояниях. Используется xEventGroupSync
Дано:
#define TASK_0_BIT ( 1 << 0 )
#define TASK_1_BIT ( 1 << 1 )
#define TASK_2_BIT ( 1 << 2 )
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
1)таск считывания АЦП,
2)таск записи в SD карту,
3)таск записи в радиоканал.
Таск 2 и 3 ждут состояния 1 - чтение выполнено. Как только получим заветное измерение АЦП unsigned short ADCdata = ADCW, сообщим о сим радостном событии установкой бита 0 в группе xEventGroupSdOrCC и подождём, пока остальные два не запишут каждый себе:
ADCdata = ADCW
EventBits_t uxReturn = xEventGroupSync( xEventGroupSdOrCC ,
TASK_0_BIT,
ALL_SYNC_BITS,
portMAX_DELAY );
xEventGroupSdOrCC - в какой группе ожидаем изменение
TASK_0_BIT - см. дефайн выше - какой бит устанавливаем (нулевой)
ALL_SYNC_BITS - какой комбинации ждём (0b111)
portMAX_DELAY - бесконечная задержка в ожидании, если поставить 0 - пройдёт проверка как будто стоит if, результат вернётся в uxReturn.
RETURN возвращает в тело xEventGroupSync группу событий (тип EventBits_t как и у xEventGroupSdOrCC ). Если время ожидание истекло (не наш случай), то это означает, что xEventGroupSync вернёт комбинацию, состоящую из установленных ею же (uxBitsToSet - второй параметр) битов и (возможно) битов, установленных в xEventGroupSdOrCC из вне. Но установленных битов из вне к этому моменту не хватило, чтобы сработало успешное сравнение с ALL_SYNC_BITS, то есть какие-то ожидаемые биты в этом случае не установлены.
Второй вариант - все ожидаемые биты (uxBitsToSet - второй параметр) были установлены, то xEventGroupSync вернёт значение xEventGroupSdOrCC (до обнуления битов самой xEventGroupSync), сбросит все ALL_SYNC_BITS (параметр uxBitsToWait).
Не вызывайте xEventGroupSync из прерывания (результат непредсказуем)!
Источник: http://www.freertos.org/xEventGroupSync.html |