Выложу в отдельную тему, если не возражаете..
Чутка теории (очень): Конечный Автомат (КА) это такая организация программы, когда она делает нечто строго по своему состоянию (в википедию, за большим). Например "кнопка нажата - делаем это", "кнопка отпущена" - не делаем это или делаем что-то ишо.
Или парсер текста (анализатор компилятора): "пришел такой символ" - о, это начало имени переменной, делаем это. "пришел такой символ" - упс, его не ждали, ошибка.
КА может переходить из одного состояния в другое, в зависимости от тех или иных внешних событий - "нажата кнопка", "нашли очередной символ в строке" и т.д., в т.ч. и по времении "прошло столько-то лет/минут/секунд .. от ..".
В общем, у КА есть "слушатель входного потока событий", который может быть как службой времени (millis), аппаратным событием - "прерывание", программным событием "код выполнил это" (нажата кнопка).. в традиционной реализации, "слушатель" не выделяется из кода КА, и является его частью (прочитать очередной символ из строки, проверить состояние кнопки и т.д., проверить закончился ли интервал времени).
И также есть "матрица состояний" между которыми КА "путешествует" по мере появления входных событий: пока нажата кнопка - повторяем делать это (состояние) или обнаружено нажатие кнопки - сделать это (действие по переходу между состояниями) и перейти в режим ожидания (состояние). Или прочитан символ (перейти в состояние чтения имени переменной)
Состояние - то действие (или бездействие) которое длится существенный промежуток времени МЕЖДУ входными событиями .. часто тупо "ожидание события".
Соответственно, можно различать 2 больших класса КА: автоматы, исполняющие код на переходе между состояниями (Милли) и те, которые исполняют код пока длится состояние (Мура).
Ну и конечно же есть код, исполняющийся в том или ином состоянии - "исполнитель". Также часто пишется вместе с кодом "слушателя" и очень часто в виде switch() оператора:
case "состяние1": "делай это" и "перейди в состояниеN"
...
и часто код КА отличается по наличию "переменной текущего состояния" ..
То есть, все задачи видов:
1. Сделай это, через 5мсек сделай так, а через 100лет сделай тут .. (КА Времени - разного рода "часовые реле" - например "мигалка двоеточием в часах" - включи/выключи каждые 0.5сек);
2. Запусти замер, как закончится (через столько) выведи на экран (вариант предыдущего .. интервал замера существенная трата времени и часто сделан на delay);
3. Если случилось тут, то включи это и покажи тут, потом включи тут и выключи тут ..
4. Пришло прерывание надо принять по SPI кучку байтов, и в коде "пришла команда по SPI - надо сделать это"
и мн. другие классы задач легко решаются как раз программированием в стиле "конечных автоматов".
Более того! У микроконтроллера, принимающего внешние события, управляющего по ним теми или иными устройствами и сигнализирующего об их состоянии на то или иное устройство вывода .. и нет иных "задач", кроме как в виде "конечных автоматов". Он предназначен в общем-то "исключительно для этого".
В стиле КА легко встраиваются и асинхронные обработчики прерываний, т.к. по сути это такой же "слушатель" внешнего потока аппаратного события. Не больше.
Чутка теории (очень): Конечный Автомат (КА) это такая организация программы, когда она делает нечто строго по своему состоянию (в википедию, за большим). Например "кнопка нажата - делаем это", "кнопка отпущена" - не делаем это или делаем что-то ишо.
Или парсер текста (анализатор компилятора): "пришел такой символ" - о, это начало имени переменной, делаем это. "пришел такой символ" - упс, его не ждали, ошибка.
КА может переходить из одного состояния в другое, в зависимости от тех или иных внешних событий - "нажата кнопка", "нашли очередной символ в строке" и т.д., в т.ч. и по времении "прошло столько-то лет/минут/секунд .. от ..".
В общем, у КА есть "слушатель входного потока событий", который может быть как службой времени (millis), аппаратным событием - "прерывание", программным событием "код выполнил это" (нажата кнопка).. в традиционной реализации, "слушатель" не выделяется из кода КА, и является его частью (прочитать очередной символ из строки, проверить состояние кнопки и т.д., проверить закончился ли интервал времени).
И также есть "матрица состояний" между которыми КА "путешествует" по мере появления входных событий: пока нажата кнопка - повторяем делать это (состояние) или обнаружено нажатие кнопки - сделать это (действие по переходу между состояниями) и перейти в режим ожидания (состояние). Или прочитан символ (перейти в состояние чтения имени переменной)
Состояние - то действие (или бездействие) которое длится существенный промежуток времени МЕЖДУ входными событиями .. часто тупо "ожидание события".
Соответственно, можно различать 2 больших класса КА: автоматы, исполняющие код на переходе между состояниями (Милли) и те, которые исполняют код пока длится состояние (Мура).
Ну и конечно же есть код, исполняющийся в том или ином состоянии - "исполнитель". Также часто пишется вместе с кодом "слушателя" и очень часто в виде switch() оператора:
case "состяние1": "делай это" и "перейди в состояниеN"
...
и часто код КА отличается по наличию "переменной текущего состояния" ..
То есть, все задачи видов:
1. Сделай это, через 5мсек сделай так, а через 100лет сделай тут .. (КА Времени - разного рода "часовые реле" - например "мигалка двоеточием в часах" - включи/выключи каждые 0.5сек);
2. Запусти замер, как закончится (через столько) выведи на экран (вариант предыдущего .. интервал замера существенная трата времени и часто сделан на delay);
3. Если случилось тут, то включи это и покажи тут, потом включи тут и выключи тут ..
4. Пришло прерывание надо принять по SPI кучку байтов, и в коде "пришла команда по SPI - надо сделать это"
и мн. другие классы задач легко решаются как раз программированием в стиле "конечных автоматов".
Более того! У микроконтроллера, принимающего внешние события, управляющего по ним теми или иными устройствами и сигнализирующего об их состоянии на то или иное устройство вывода .. и нет иных "задач", кроме как в виде "конечных автоматов". Он предназначен в общем-то "исключительно для этого".
В стиле КА легко встраиваются и асинхронные обработчики прерываний, т.к. по сути это такой же "слушатель" внешнего потока аппаратного события. Не больше.