【问题标题】:Document C code containing state machines包含状态机的文档 C 代码
【发布时间】:2020-05-26 04:00:33
【问题描述】:

我编写了包含状态机1 的C 代码。现在我正在寻找一种方法来生成一个 html 文件来记录该状态机,如 [2]。

我看过 doxygen [3]。它可以提取文本、调用图等,但不能生成状态机图。 我看过 Graphviz [4]。它可以生成状态机图,但不能将文本和图合并到一个 html 文件中。 我找到了一个 Doxygen 预处理器 [5],它声称能够记录状态机,但最后一次更新是从 2009 年开始

是否有人知道可以从源代码或代码中特制的 cmets 中提取文本和图表的系统,并且正在积极开发?

编辑 1 我没有像我应该表达的那样清楚地表达我的问题。我想找出一个工作流程,使我能够记录和验证我为基于微控制器的产品制作的 C 代码。

我希望让我的用户能够理解我将要在 C 代码中实现的内容,因此我制作的 C 代码实际上是用户想要的更有可能。

到目前为止,我想出了这个工作流程:

1) 我和用户坐下来讨论所有可能发生的故障情况,以及我的程序应该如何应对这些情况。这存储在电子表格中。

2) 我将步骤 1 中的电子表格转换为一个或多个状态机。这可以通过笔和纸来完成。完成后,我让用户检查状态机是否与电子表格一致。

3) 我以机器可理解的形式编写状态机,并让程序生成状态机的图形表示。我让用户检查这是否与步骤 2 的版本相同。

4) 我采用状态机的机器可理解形式,并使用它为状态机的每个状态和转换编写单元测试。我让具有编程技能的同事检查单元测试是否与状态机一致。

5) 我编写 C 代码,并对其进行调整以使其通过所有单元测试。

6) 根据步骤 1 中的场景测试成品。

在写下这篇文章时,我意识到在这个过程中有很多手动工作可能会自动完成。你知道可以做到这一点的工具吗?

Fiddling Bits 建议的 SMC [6] 看起来很有希望,但我不确定它是否可以生成像 1 下发布的那样的 C 文件。我也不确定是否可以进行这样的往返:我将状态机写入 .sm 文件,让 SMC 生成 C 文件。我编辑 C 文件,我让 SMC 更新 .sm 文件,我编辑 .sm 文件,然后让 SMC 再次更新 C 文件。

编辑 2 我已经按照 Marc 的建议查看了 plantuml,但这增加了生成 html 页面所需的工具的额外复杂性。

我已经通过使用 \dot 命令 [7] 在 doxygen 命令块中嵌入 graphvid 图表解决了这个问题。 C代码见[8]。

1C 代码

typedef enum
{
    stIDLE=0,
    stDONE
} TRXSTATES;

TRXSTATES theState = stIDLE;

void execute (void)
{
    switch (theState)
    {
        case stIDLE:
        {
            theState = stDONE
            break;
        }
        case stDONE:
        {
            break;
        }
    }
}

[2] 所需的 html 页面

Some smart text about this state machine
+--------+       +--------+
+ stIDLE + ----> + stDONE +
+--------+       +--------+

[3]http://www.doxygen.nl/index.html

[4]http://graphviz.org/

[5]https://sites.google.com/site/abudden/doxygen-preprocessor

[6]http://smc.sourceforge.net/

[7]http://www.doxygen.nl/manual/commands.html#cmddot

[8] 更新后的 C 代码

/** \mainpage
 * Some smart text about this state machine
 * \dot
 * digraph statemachine {
 *      rankdir=LR
 *      node [shape=record, fontname=Helvetica, fontsize=10];
 *      stIdle [ label="Idle" ];
 *      stDone [ label="Done" ];
 *      stIdle -> stDone [ label ="Finished", arrowhead="open", style="solid" ];
 *  }
 *  \enddot
*/
typedef enum
{
    stIDLE=0,
    stDONE
} TRXSTATES;

TRXSTATES theState = stIDLE;

void execute (void)
{
    switch (theState)
    {
        case stIDLE:
        {
            theState = stDONE
            break;
        }
        case stDONE:
        {
            break;
        }
    }
}  

【问题讨论】:

  • 如果您自己编写 C 代码(而不是为您生成),听起来您需要自定义实现。
  • 你可以看看这个:smc.sourceforge.net
  • 你通常会在编码之前设计你的状态机。从图表自动生成(和往返)代码比将任意手写代码逆向工程简单得多,因为实现状态机和各种编码风格的方法不止一种应付。

标签: c doxygen graphviz state-machine fsm


【解决方案1】:

一种可能的方法是使用plantumldoxygen 中以文本形式对图表进行编码。

图表示例:

https://dev.mysql.com/doc/dev/mysql-server/latest/structpfs__lock.html

它的源码,看@startuml/@enduml

https://github.com/mysql/mysql-server/blob/8.0/storage/perfschema/pfs_lock.h

图表是手动维护的,还允许在生成的文档中添加注释、cmets 等。

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 2010-11-27
    • 1970-01-01
    • 2012-10-16
    • 2022-11-02
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多