Одномерная таблица переходов состояний - PullRequest
0 голосов
/ 25 марта 2011

Я ищу некоторые реализации (идеи) одномерной таблицы состояний в C. Переход - это вид объектов (структура), которые содержат:

  • Указатель на функцию защиты
  • Следующее состояние
  • Список указателей на функции действий.

Я смотрю на Дизайн конечного автомата C , но в моем случае у меня несколькоусловия для формирования события.Есть ли какой-либо общий подход или простой процессор FSM SW, подходящий для встроенной системы?

Ответы [ 2 ]

0 голосов
/ 01 апреля 2011

Обычный подход - хранить указатель на условную функцию. Вы реализуете набор условий как отдельные функции и прикрепляете указатель к нужному условию в таблице. Каждая функция тестирует для заданного набора условий. Вы перебираете список, пока одна из указанных функций не вернет true. Конечно, «текущее состояние» может использоваться как часть условий, что устраняет необходимость в 2d массиве.

  struct {
       bool(*test)();           //the condition
       void(*onsuccess)();      //event
  } condition;

Это может быть неэффективно, если условия многократно повторяются в цепочке, например:

  ev1: (a && b && c)
  ev2: (a && !b && c)
  ev3: (a && b && d)
  ev4: (a && !b && !c)
  ev5: (!a)

(большинство событий тестируется для a отдельно, если тестирование для a требует больших вычислительных ресурсов, это потребует гораздо больше времени процессора, чем необходимо).

В этом случае вам придется переназначить список condition_set -> event в одно дерево решений - гораздо сложнее поддерживать, но более эффективно использовать процессор:

   a:
       b:
           c: ev1
           d: ev3
      !b:
           c: ev2
          !c: ev4
  !a: ev5

Это, конечно, больше не может быть простым одномерным списком, но вместо него требуется древовидная структура, скажем, разветвленный связанный список:

  struct {
       bool(*test)();           //the condition
       void(*onsuccess)();      //event (if any)
       condition* next_sibling; //other conditions dependent on parent but independent from this one,
       condition* first_child;  //other conditions dependent on this one,
  } condition;

NULL на любом из указателей означает «нет такого элемента» (кроме «test», который не может быть нулевым). И, конечно, рекурсия необходима для обхода списка.

0 голосов
/ 25 марта 2011

Таблицы StateMachine обычно имеют 2 измерения (где я), (какой символ / токен / источник у меня есть), и пересечение обоих ячеек (куда я пойду, откуда я, когда какой символ / токен / источник у меня есть)

...