Использование автоматного програмирования на примере Quantum Leaps. Вступление.


Года три назад устроился я програмистом микроконтроллеров на одну фирму, и там мне мой руководитель предложил разобраться с так называемым автоматным программированием. Но не просто с методом, а поставил задачу освоить framework Quantum Leaps.

С данной задачей я справился, но этот фреймворк мне настолько понравился, что я решил поделится своим опытом использования с общественностью.
Итак, что же такое Quantum Leaps. Это набор из трёх фреймворков с открытым исходным кодом, позволяющий быстро написать готовый продукт. Почему набор? Потому как есть реализация на С (QP/C), на С++ (QP/C++), и отдельная очень компактная реализация на С(QP-nano). Каждый из этих фреймворков представляет из себя платформо-компиляторо-независимый код, так называемый QP™ Baseline Code.
Для адаптации под конкретную архитектуру и компилятор используются различные QP™ Development Kits(QDK). На этой страничке доступны для скачивания как базовый код всех трёх вариантов фреймворка, так и большой набор Development Kits под различные архитектуры и компиляторы.
На этой же страничке можно скачать QP Modeler(QM), очень полезная програмка! Я ждал её с тех пор, как разобрался с QP. Позволяет графически нарисовать диаграмму состояний и по ней сгенерировать код, это если кратко.
Ну и отдельный плюс данного фреймворка — это большая книга по автоматному программированию на C/C++ на примере QP от его создателя, доступная для скачивания здесь(.pdf 4МБ).

Приятной особеностью QP является возможность работать поверх любой операционки, от Windows до какой-то экзотики для AVR. Но этот вопрос оставим на потом, когда будем с QP на «ты».

Итак, с чего же начать. А начнём пожалуй с попытки объяснить как это всё работает.

Скажу сразу, так как я в основном пишу на С++, то и все примеры я буду приводить на «плюсах».

Как и любая реализация многозадачности QP имеет в своём составе диспетчер задач, либо вытесняющий(QK) либо нет(Vanilla). По своей сути это бесконечный цикл, в котором проверяется наличие событий для определённого автомата, которые ему необходимо обработать. Если событий нет, можно уйти в спячку до возникновения оного.

Событие(QEvent) и конечный автомат — это ключевые понятия в QP.

QP поддерживат два типа конечных автоматов — простой(QFSm) и иерархический(QHSm). Любой из этих типов автоматов — это набор определённых состояний(QState), в которых автомат можен находится и набор правил, по которым автомат может изменять своё состояние. Различие между ними состоит в том, что состояние автомата типа QHSm, фактичеки может содержать в себе ещё один автомат хоть QFSm, хоть QHSm типа. Уровень вложености настраиватся и по умолчанию равен 10.

Событие.

struct QEvent{
  QSignal sig;
  uint8_t dynamic_;
}

Это основной механизм взаимодействия автоматов с внешним миром и между собой. Событие обязательно состоит из сигнала(QSignal sig) и поля служебной информации(uint8_t dynamic_), а так же может содержать не обязательные поля определяемые пользователем. Именно реакция на сигналы описана в состояниях.
Существуют динамические и статические события. Статические события — это не изменяемые события, которые существуют всегда. У статических событий поле dynamic_ всегда равно нулю.
Динамические события — это события, которые создаются в области динамической памяти, и существуют до тех пор, пока не будут обработаны всеми автоматами, которым они предназначены.

Сигналы.

enum QSignal{Q_EMPTY_SIG = 0, Q_ENTRY_SIG, Q_INIT_SIG, Q_EXIT_SIG, Q_USER_SIG};
enum QSignal{Q_EMPTY_SIG = 0, Q_ENTRY_SIG, Q_INIT_SIG, Q_EXIT_SIG, Q_TOUT_SIG, Q_USER_SIG};// для QP-nano

В QP есть 4 сигнала зарезирвированых системой Q_EMPTY_SIG, Q_ENTRY_SIG, Q_INIT_SIG и Q_EXIT_SIG а в QP-nano ещё и Q_TOUT_SIG об их назначении поговоримпозже.

Состояние(QState) — по своей сути это функция, которая должна обработать событие. Результатом работы данной функции является либо переход в другое состояние, либо какое-то действие без смены состояния.
Для наглядности рассмотрим абстрактную функцию-состояние:

QState AbstractState(QFSm * me, QEvent const * e){
  switch(e->sig){
    case Q_ENTRY_SIG:{
      return Q_HANDLED();
    }

    case Q_INIT_SIG:{
      return Q_HANDLED();
    }

    case Q_USER_SIG:{
      return Q_TRAN(&AnotheAbstractState);
    }

    case Q_EXIT_SIG:{
      return Q_HANDLED();
    }
  }
  return Q_SUPER(QFSm::top);  
}

Как видим возможны 3 варианта «ответа» обработано — Q_HANDLED(), перейти в другое состояние — Q_TRAN(), и «что делать не знаю, спросите выше» — Q_SUPER(). Для QFSm — Q_SUPER() равносильно Q_HANDLED(), хотя если поковыряться в исходниках мы увидим, что там реально Q_IGNORED(), но идейный смысл тот же.
Теперь пройдёмся по сигналам, которые обрабатывает данное состояние.
Q_ENTRY — этот сигнал framework автоматически дает на обработку состоянию каждый раз, когда в него входят.
Q_INIT — очень актуально для QHSm — тоже генерируется автоматически, когда состояние является конечной точкой назначения перехода.
Q_EXIT — автоматически генерируется при выходе из состояния.
Обработка этих трёх сигналов должна присутствовать в каждом состоянии.

На этом пока всё, если у уважаемого сообщества будет интерес к данной теме — с удовольствием продолжу.
З.Ы. Извините за орфографию и некоторую сумбурность изложения, русский язык не изучал, да и статья эта первая в моей жизни. Буду рад конструктивной критике.

UPD: Прикрепил полную версию книги
  • +2
  • 04 октября 2011, 23:21
  • kovz
  • 1
Файлы в топике: practical-uml-statecharts-in-c-c-second-.pdf

Комментарии (19)

RSS свернуть / развернуть
… а какие есть аналоги этой программы и чем они хуже/лучше?
PS… ваша фирма купила этот софт или пока триалите?
PPS… однако прихватили они доменчик www.state-machine.com
0
Ждем продолжения.
0
  • avatar
  • foxit
  • 05 октября 2011, 00:07
А чем это лучше обычных конечных автоматов?
0
  • avatar
  • a9d
  • 05 октября 2011, 00:12
Тем что ничего не надо изобретать, все софттаймеры евенты и прочее часто юзаемое мясо уже есть.
0
И чем это лучше? Ведь это уже все есть готовое.
Зачем платить за этот продукт? Чем он такой блатной?
0
Ну как минимум тем, что он под GPL. И всё уже есть готовое — это что например?
0
Еще тем, что это единая система котороую юзают многие. А значит будут и библиотеки, да и собственный код структурируется и систематизируется.
0
Очень хороший, продуманный и оптимизированный framework. Действительно помогает структуировать и систематизировать собственный код. Кроме того занимет мало места при достаточно большом наборе возможностей. Я пока использовал только QP-nano. О нем у меня только положительные впечатления. С появлением QM процесс разработки автомата очень сильно упростился. Появилась возможность быстро вносить изменения в структуру автомата, причем довольно значительные изменения вносятся путем простого перетаскивания объектов.
0
  • avatar
  • kvm
  • 05 октября 2011, 13:42
Единственное, что не очень понравилось, это, с моей точки зрения, несколько сумбурное повествование в книге по framework. Читается довольно тяжело, но полезной информации содержит в себе много.
0
Кстати, по приведенной ссылке лежит только часть книги (90 листов из 721). Если кого-то заинтересует, могу выложить полный вариант.
0
Зачем спрашивать? Выкладывай сразу)
0
Прошу прощения! Сейчас на работе, книжка 10 метров в упакованном виде, так что такой объем на работе выложить, к сожалению, не могу. Вечером обязательно выложу!
0
Прикрепил полную книгу к топику
0
хотя странно раньше по той ссылке полная версия лежала
0
а продолжение статьи будет?
0
столько лет прошло, но помним я и ты…
А можно продолжение запилить? Там уже автогенерация кода появилась по слухам :)
0
Слухи правильные! :) Появилась и давно! State machine делается в визуальном редакторе QM, который уже генерирует код. На данный момент уже используется 3 версия этого редектора.
К сожалению поддержка некоторых старых микроконтроллеров прекращена, на практически все новые типы поддержка есть. Даже на Arduino можно использовать, что довольно таки сильно расширяет возможности последней. :)
0
Поглядел по-диагонали, имхо оверкил… Имею опыт работы с visualSTATE, Matlab Stateflow, как-то поинтуитивнее выходит. Я хочу просто автомат нарисовать, сгенерировать код и вставить в проект, а тут подсадить хотят полностью на qp
0
автомат нарисовать, сгенерировать код и вставить в проект
Так код-то тоже генерируется по каким-то правилам! Эти правила устанавливает тот кто пишет софт. Вот и «Quantum Leaps» тоже генерирует код по своим «правилам». :) И тоже просто рисуется автомат, генерируется код по этому автомату и вставляется в проект. Только вдобавок можно ещё воспользоваться их же ядром для обработки этого кода. А вообще каждый выбирает инструменты по себе, для своей конкретной задачи. :)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.