Найти в Дзене

Планировщик на таймере - порядок во времени

Следующий шаг к структурированию - Планировщик на таймере (Timer-Based Scheduler). Это эволюция суперлупа, где системный таймер периодически генерирует прерывание (тик), которое проверяет, каким задачам пора выполняться, и выставляет флаги. Основной цикл проверяет эти флаги и запускает соответствующие задачи. volatile uint32_t tick_count = 0; #define TASK1_PERIOD 100 // Выполнять каждые 100 мс #define TASK2_PERIOD 500 // Выполнять каждые 500 мс void systick_isr(void) { tick_count++; } int main(void) { uint32_t last_task1 = 0, last_task2 = 0; setup_timer(); enable_interrupts(); while(1) { uint32_t now = tick_count; // Задача 1: каждые 100 тиков if((now - last_task1) >= TASK1_PERIOD) { last_task1 = now; read_sensors(); } // Задача 2: каждые 500 тиков if((now - last_task2) >= TASK2_PERIOD) { last_task2 = now; update_display(); } idle_task(); } } Как это работает на практике? 🔴Системный таймер генерирует регулярные прерывания (например, каждую 1 мс - системный тик). 🔴Каждый тик и

Планировщик на таймере - порядок во времени

Следующий шаг к структурированию - Планировщик на таймере (Timer-Based Scheduler).

Это эволюция суперлупа, где системный таймер периодически генерирует прерывание (тик), которое проверяет, каким задачам пора выполняться, и выставляет флаги.

Основной цикл проверяет эти флаги и запускает соответствующие задачи.

volatile uint32_t tick_count = 0;

#define TASK1_PERIOD 100 // Выполнять каждые 100 мс

#define TASK2_PERIOD 500 // Выполнять каждые 500 мс

void systick_isr(void) {

tick_count++;

}

int main(void) {

uint32_t last_task1 = 0, last_task2 = 0;

setup_timer();

enable_interrupts();

while(1) {

uint32_t now = tick_count;

// Задача 1: каждые 100 тиков

if((now - last_task1) >= TASK1_PERIOD) {

last_task1 = now;

read_sensors();

}

// Задача 2: каждые 500 тиков

if((now - last_task2) >= TASK2_PERIOD) {

last_task2 = now;

update_display();

}

idle_task();

}

}

Как это работает на практике?

🔴Системный таймер генерирует регулярные прерывания (например, каждую 1 мс - системный тик).

🔴Каждый тик инкрементирует счетчик времени.

🔴Основной цикл постоянно проверяет, не наступило ли время для выполнения очередной задачи, сравнивая текущее время с временем последнего запуска и заданным периодом.

Когда выбирать планировщик на таймере?

🟡Нужна ли предсказуемая периодичность? (Опрос датчиков раз в 100 мс)

🟡Требуется ли лучшее структурирование, чем у суперлупа?

🟡Можно ли допустить задержку реакции до следующего тика?

🟡Хватит ли ресурсов МК для системного таймера и флагов?

Идеальные кандидаты: Системы управления с четкими циклами (термостаты, регуляторы), устройства с периодическим опросом датчиков, информационные дисплеи, мигалки с разными периодами.

Сильные стороны:

➕Детерминированность. Задачи выполняются с фиксированной периодичностью

➕Лучшая модульность. Задачи изолированы, их проще добавлять и модифицировать

➕Контроль времени. Можно замерять длительность выполнения каждой задачи

➕Эффективность. Нет переключения контекста как в RTOS

Слабые стороны:

😀Кооперативная модель. Долгая задача блокирует всю систему

😀Задержка реакции. Событие обработается только в следующем "тике"

😀Статическое планирование. Периоды задач жестко заданы при компиляции

😀Накопление задержек. Если задача выполняется дольше, сдвигается весь график

Планировщик на таймере - это идеальный баланс между простотой суперлупа и сложностью RTOS. Он отлично подходит для циклических систем с четкими временными интервалами, где важна предсказуемость, но нет требований к мгновенной реакции или сложной многозадачности.

#планировщик #scheduler #таймер #архитектурапрошивки #embedded #встраиваемыесистемы #кооперативнаямногозадачность