rtos_queue — две задачи FreeRTOS и очередь
Задача-датчик раз в секунду меряет температуру кристалла (встроенный датчик DTS) и кладёт измерение в очередь. Задача-обработчик забирает измерения и раз в 5 штук печатает среднее. Так обычно и делят работу в прошивке: кто добывает данные, не ждёт того, кто их обрабатывает.
Включить
Заголовок раздела «Включить»cmake --preset Release -DH723_RECIPES="rtos_queue"Вывод на плате
Заголовок раздела «Вывод на плате»rtos_queue: started, period 1000 msrtos_queue: #5 t=7475 ms, die 58 C (avg of 5), queued 0rtos_queue: #10 t=12475 ms, die 59 C (avg of 5), queued 0rtos_queue: #15 t=17475 ms, die 59 C (avg of 5), queued 0queued 0 — обработчик успевает, очередь не копится. t растёт ровно на 5000 мс.
Как это работает
Заголовок раздела «Как это работает»- Очередь копирует данные.
xQueueSendкладёт в очередь копию структурыrtosQueueSample, а не указатель — после отправки датчик может спокойно менять свою переменную. - Обработчик не тратит процессор, пока ждёт.
xQueueReceiveс таймаутом усыпляет задачу до прихода данных. Таймаут (2 периода) нужен, чтобы заметить, что датчик замолчал. - Датчик не ждёт обработчика.
xQueueSend(..., 0): если очередь полна, измерение теряется с предупреждением, а не стопорит датчик. Для данных, которые терять нельзя, ставят таймаут илиportMAX_DELAY. - Ровный период.
vTaskDelayUntilотсчитывает от прошлого пробуждения, а не от конца работы, поэтому период не «плывёт» из-за времени измерения. - Приоритеты. Обработчик на уровень выше датчика: как только в очереди что-то появилось, планировщик сразу переключается на него.
- Статическая память. Очередь (
xQueueCreateStatic) и задачи (xTaskCreateStatic) — в статических массивах, их размер виден при сборке.
Переделать под себя
Заголовок раздела «Переделать под себя»- Своё измерение — поля в
rtosQueueSampleи код вsensorTask. - Частота и усреднение —
RTOS_QUEUE_PERIOD_MS,RTOS_QUEUE_BATCH. - Если обработчик делает долгую работу (запись на SD, отправка по сети), стоит увеличить
RTOS_QUEUE_LENGTH, чтобы очередь пережила паузы. - Стек:
uxTaskGetStackHighWaterMark(NULL)внутри задачи покажет, сколько слов стека ни разу не использовалось.
Исходники рецепта: recipes/rtos_queue
