一维状态转移表

发布于 2024-10-26 17:35:25 字数 271 浏览 1 评论 0原文

我正在寻找 C 中一维状态表的一些实现(想法)。转换是一种对象(结构),其中包含:

  • 指向保护函数的指针
  • 下一个状态
  • 指向操作函数的指针列表。

我正在研究 C 状态机设计,但就我而言,我有多个条件来形成事件。 有没有适合嵌入式系统的通用方法或简单的 FSM sw 处理器?

I am looking for some implementation (ideas) of the one-dimensional state table in C. The transition are kind of objects (struct) that contain:

  • Pointer to the guard function
  • Next state
  • List of pointers to action functions.

I am looking at C state-machine design but in my case I have multiple conditions to form an event.
Is there any generic approach or simple FSM sw processor suitable for embedded system?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光沙漏 2024-11-02 17:35:25

通常的方法是存储指向条件函数的指针。
您将这组条件实现为单独的函数,并将指针附加到表中的正确条件。每个功能都会测试给定的一组条件。您迭代列表,直到指向的函数之一返回 true。当然,“当前状态”可以用作条件的一部分,这样就不需要二维数组了。

  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 的计算成本很高,则将花费比必要的更多的 CPU 时间),

这可能会效率低下。在这种情况下,您必须重新映射 condition_set ->将事件列表放入单个决策树中 - 维护起来更困难,但 CPU 效率更高:

   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”除外,它不能为空)。当然,遍历列表需要递归。

The usual approach is to store pointer to a conditional function.
You implement the set of conditions as separate functions, and attach a pointer to the right condition in the table. Each function tests for given set of conditions. You iterate through the list till one of pointed functions returns true. Of course "current state" can be used as part of conditions, which removes the need for 2d array.

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

This may be inefficient if the conditions repeat a lot in a chain like:

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

(most events tests for a separately, if testing for a is computationally expensive it will take much more CPU time than necessary).

In this case you'd have to remap the condition_set -> event list into a single decision tree - much harder to maintain but more CPU-efficient:

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

This of course cannot be a simple 1-dimensional list any more, but requires a tree-like structure instead, say, branched linked list:

  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 on any of the pointers means "no such item" (except on "test" which can't be null). And of course recursion required to traverse the list.

听风念你 2024-11-02 17:35:25

StateMachine 表通常有 2 个维度(我在哪里),(我有什么符号/令牌/源),
两者的交集是单元格(我要去哪里,从哪里出发,何时拥有什么符号/令牌/源)

StateMachine tables usually have 2 dimensions (where I am), (what symbol/token/source I have),
and the intersection of both are cells (where I'll go, from where I am, when what symbol/token/source I have)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文