View Categories

Организация программы

Информации из предыдущих уроков уже достаточно для того, чтобы начать писать простенькие программы, которые работают в реальном времени - опрашивать кнопки, переключать реле по датчику, мигать светодиодами и так далее. Для полного счастья не хватает только принципов написания сложной программы с большим количеством логики, тем более - многозадачной. В этом уроке коротко рассмотрим разные подходы к организации программы для Arduino, чтобы они были в одном месте, а затем некоторые из них более подробно разберём в отдельных уроках.

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

Суперцикл #

Самым простым способом организации программы является суперцикл (superloop) - вся программа помещается в бесконечный цикл, который выполняется раз за разом с максимальной скоростью, на которую способен процессор. В этом цикле могут опрашиваться кнопки, читаться датчики, отправляться данные по условию и так далее, всё это происходит линейно друг за другом в порядке написания:

while (1) {
    if (клик_по_кнопке()) отправить_данные();
    читать_датчик();
    мигать_светодиодом();
}

Знакомо? Всё верно, в Arduino фреймворке нам предлагается работать именно таким образом - в функции loop. Этот подход "родной" для чистого C/C++ и широко используется во встраиваемых системах и на слабых МК - это буквально самый легковесный способ, не требующий ни байта лишнего кода. В цикле мы вручную проверяем датчики, кнопки и так далее, этот опрос называется polling.

Суперцикл - это не буквально "цикл", а подход к организации программы. В реализации это может быть как непосредственно цикл, так и функция, которая вызывается всё время на протяжении работы программы

Написать многозадачную программу в таком формате непросто, подробнее - в этом уроке.

События и обработчики #

Следующий подход характерен для языков более высокого уровня, например JavaScript и C#. Вместо того, чтобы вручную опрашивать что-то в цикле, мы просим программу вызвать указанную функцию, когда наступит нужное событие:

// функция-обработчик
обработчик() {
    // попали сюда после клика по кнопке
}

// подключение обработчика
на_клик_кнопки(обработчик);

В C/C++ тоже можно писать в таком стиле, но polling придётся делать вручную (в суперцикле или прерываниях) и самому вызывать для себя функцию-обработчик. Тем не менее, этим очень удобно пользоваться и писать многозадачные программы, когда оно хорошо реализовано в рамках "библиотеки". Подробнее в этом уроке.

Прерывания #

При разработке под МК доступен такой инструмент, как прерывания. По сути это событийный подход, в котором события вызываются периферией МК в автоматическом режиме - их не нужно оправшивать вручную. Например можно подключить функцию, которая будет вызываться при поступлении байта по интерфейсу связи UART. Прерывания позволяют реализовать некоторые задачи так, чтобы они выполнялись "на фоне" основной программы, например отправку данных из буфера без ожидания для каждого байта, или нажатие кнопки.

Подробнее в этом уроке.

Диспетчер задач #

Для организации крупного проекта, в котором выполняется множество задач с разными периодами времени и/или режимами энергосбережения, можно использовать простой диспетчер задач, который будет вызывать функции-задачи. Это уже некая "библиотека", которая поможет более лаконично организовать программу, избегать дублирования кода и иметь возможность удобно управлять задачами из одной "точки входа". Примеры:

  • GyverOS - простой диспетчер задач, вызывает функции с указанным для них периодом
  • Looper - очень мощный диспетчер-фреймворк с автоматической регистрацией задач, поддержкой событий и корутин без стека. Подробная документация есть по ссылке

Операционная система #

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

В рамках данного раздела уроков мы не рассматриваем популярные ОС (например FreeRTOS), т.к. они довольно тяжёлые для слабых МК, требуют знания дополнительной сложной теории многопоточных систем и обладания навыками работы с суперциклом и событиями - так что первым делом нужно всё равно освоить их.

Полезные страницы #

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх