首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C FSM状态的一种热编码

C FSM状态的一种热编码
EN

Stack Overflow用户
提问于 2015-08-26 07:31:18
回答 1查看 564关注 0票数 3

基本上,我只想知道这是否是一个好主意手动一个热编码状态的C FSM。我实现它是为了编写一个简单的状态转换验证器:

代码语言:javascript
运行
复制
typedef enum
{
    FSM_State1 = (1 << 0),
    FSM_State2 = (1 << 1),
    FSM_State3 = (1 << 2),
    FSM_StateError = (1 << 3)
} states_t;

然后是验证:

代码语言:javascript
运行
复制
states_t nextState, requestedState;
uint32_t validDestStates = 0;

// Compute requested state
requestedState = FSM_State1;

// Define valid transitions
validDestStates |= FSM_State2;
validDestStates |= FSM_State3;

// Check transition
if (validDestStates & requestedState)
{
    // Valid transition
    nextState = requestedState;
}
else
{
    // Illegal transition
    nextState = FSM_StateError;
}

我知道我被限制在我可以使用的整数的最大大小。但我没有那么多州。所以这不是问题

还有比这种编码更好的东西吗?我还没看出有什么缺点吗?

谢谢你的帮忙!

编辑:根据user3386109注释更改验证测试

最后的思想

最后,我所做的是:

[1]国家枚举是一个“经典”枚举:

代码语言:javascript
运行
复制
typedef enum
{
    FSM_State1,
    FSM_State2,
    FSM_State3,
    FSM_StateError
} states_t;

有效转换的2/位字段:

代码语言:javascript
运行
复制
struct s_fsm_stateValidation
{
    bool State1IsValid: 1;
    bool State2Valid: 1;
    bool State3IsValid: 1;
    bool StateErrorIsValid: 1;

    /// Reserved space for 32bit reserved in the union
    uint32_t reserved: 28;
};

3/为验证创建一个联合。

代码语言:javascript
运行
复制
typedef union FSM_stateValidation_u
{
    /// The bit field of critical system errors
    struct s_fsm_stateValidation state;
    /// Access the bit field as a whole
    uint32_t all;
} u_FSM_stateValidation;

4我更改了验证:

代码语言:javascript
运行
复制
u_FSM_stateValidation validDestStates;

// Set valid states
validDestStates.state.State1 = true;

// Compute requestedState
requestedState = FSM_State2;

if ((validDestStates.all & ((uint32_t) (1 << requestedState)) ))
{
    // Next state is legal
    return requestedState;
}
else
{
    return FSM_StateError;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-26 07:52:56

从一个快速的谷歌,“一个热编码”意味着每一个有效的代码有准确的一个位集,这似乎是你正在做的。搜索结果表明这是一种硬件设计模式。

我能想到的缺点是..。

  1. 正如您所建议的,您正在极大地限制有效代码的数量--对于32位,您的最大代码/状态为32码/状态,而不是超过40亿。
  2. 对于查找表来说,这并不理想,因为查找表是switch语句的常见实现。通常有一个内部可用来确定哪一个是最低位集,但我不会打赌编译器会自动使用它。

不过,这些并不是什么大问题,只要州数很少。

因此,国际海事组织的问题是,是否有理由证明这一成本是合理的。它不需要一个巨大的优势,但必须有某种意义。

我想出的最好方法是,您可以使用按位方式来指定状态集,这样就可以有效地测试当前状态是否处于给定的集合中--如果您有一些需要在状态(1<<0)(1<<3)中执行的操作,例如,您可以测试if (state & 0x9)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32220507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档