Черга (Queue) у FreeRTOS — це потокобезпечний (thread-safe) буфер типу FIFO (First-In, First-Out — першим прийшов, першим пішов). Вона слугує основним механізмом для передачі даних та синхронізації між різними задачами (Tasks) або між обробниками переривань (ISR) та задачами.
Копіювання за значенням (Pass by Value): Коли ви надсилаєте дані в чергу, вони фізично копіюються байт-за-байтом у буфер черги.
Блокування задач (Blocking):
Якщо задача намагається прочитати з порожньої черги, вона переходить у стан очікування (не споживає CPU) до появи даних або закінчення таймауту.
Якщо задача намагається записати у повну чергу, вона блокується до звільнення місця або закінчення таймауту.
Потокобезпечність: Кілька задач можуть одночасно читати та писати в одну чергу без ризику пошкодити дані (FreeRTOS внутрішньо використовує м'ютекси/критичні секції).
1. Створення та видалення черги
xQueueCreate Створює нову чергу і виділяє під неї пам'ять у купі (Heap).
C
QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
uxQueueLength — максимальна кількість елементів у черзі.
uxItemSize — розмір одного елемента в байтах (зазвичай використовують sizeof(тип)).
Повертає: QueueHandle_t (вказівник на чергу) або NULL, якщо бракує пам'яті.
vQueueDelete Видаляє чергу та звільняє виділену під неї пам'ять.
C
void vQueueDelete(QueueHandle_t xQueue);
2. Відправка даних у чергу (Звичайний контекст задач)
xQueueSend / xQueueSendToBack Додає елемент у кінець черги (стандартний FIFO).
C
BaseType_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);
pvItemToQueue — вказівник на дані, які будуть скопійовані в чергу.
xTicksToWait — час очікування (у тіках FreeRTOS), якщо черга повна.
0 — не чекати взагалі.
pdMS_TO_TICKS(100) — чекати 100 мс.
portMAX_DELAY — чекати нескінченно, поки не з'явиться місце.
Повертає: pdPASS (успішно) або errQUEUE_FULL (черга повна).
xQueueSendToFront Додає елемент у початок черги (використовується для термінових/пріоритетних повідомлень).
C
BaseType_t xQueueSendToFront(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);
xQueueOverwrite Записує дані у чергу розміром в 1 елемент. Якщо черга вже повна, вона перезаписує існуюче значення.
C
BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void *pvItemToQueue);
3. Читання та перегляд даних з черги
xQueueReceive Вичитати (злити) елемент з черги. Зчитаний елемент видаляється з черги.
C
BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
pvBuffer — буфер (змінна), куди будуть скопійовані дані.
xTicksToWait — час очікування, якщо черга порожня.
Повертає: pdPASS або pdFAIL.
xQueuePeek Скопіювати елемент з черги без його видалення.
C
BaseType_t xQueuePeek(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
4. Функції для використання всередині переривань (ISR)
Функції із суфіксом FromISR є неблокуючими (не мають аргументу xTicksToWait) та безпечними для виклику в контексті переривань.
xQueueSendFromISR / xQueueSendToBackFromISR
C
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
pxHigherPriorityTaskWoken — прапорець, який встановлюється у pdTRUE, якщо відправка розблокувала задачу з вищим пріоритетом. Якщо pdTRUE, наприкінці ISR викликають portYIELD_FROM_ISR().
xQueueSendToFrontFromISR — Додати в початок черги з ISR.
xQueueReceiveFromISR — Зчитати з черги з ISR.
5. Допоміжні функції стану черги
uxQueueMessagesWaiting — повертає кількість елементів, що зараз знаходяться в черзі.
uxQueueSpacesAvailable — повертає кількість вільних місць у черзі.
xQueueReset — повністю очищає чергу (повертає її до порожнього стану).