C-FSM状态的一种热编码
基本上,我只是想知道手动对C FSM的状态进行热编码是否是个好主意。 我实现了这一点,以编写一个简单的状态转换验证器:C-FSM状态的一种热编码,c,state,state-machine,C,State,State Machine,基本上,我只是想知道手动对C FSM的状态进行热编码是否是个好主意。 我实现了这一点,以编写一个简单的状态转换验证器: typedef enum { FSM_State1 = (1 << 0), FSM_State2 = (1 << 1), FSM_State3 = (1 << 2), FSM_StateError = (1 << 3) } states_t; 我知道我只能使用整数的最大大小。但我没有那么多州。因此
typedef enum
{
FSM_State1 = (1 << 0),
FSM_State2 = (1 << 1),
FSM_State3 = (1 << 2),
FSM_StateError = (1 << 3)
} states_t;
我知道我只能使用整数的最大大小。但我没有那么多州。因此,这不是一个问题
还有比这种编码更好的吗? 是否有一些缺点我还没有看到 谢谢你的帮助 编辑:根据用户3386109注释更改验证测试
最后的想法 最后我做的是: 1/状态枚举是“经典”枚举: 有效转换的2/位字段:
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/为验证创建一个联合体
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/我更改了验证:
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;
}
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;
}
u_FSM_状态验证有效状态;
//设置有效状态
ValidTestState.state.State1=真;
//计算请求状态
requestedState=FSM_State2;
如果((validdestates.all&((uint32_t)(1)来自快速谷歌,“一个热编码”意味着每个有效代码都有一个精确的位集,这似乎就是您正在做的。搜索结果表明这是一种硬件设计模式
我能想到的缺点是
正如您所建议的,您极大地限制了有效代码的数量-对于32位,您最多有32个代码/状态,而不是超过40亿个
它对于查找表并不理想,因为查找表是switch
语句的常见实现。通常有一个内在函数可用于确定哪一个是最低位集,但我不希望编译器自动使用它
不过,如果州的数量不多,这些问题就不是什么大问题
因此,国际海事组织的问题是,是否有优势来证明这一成本。这不一定是一个巨大的优势,但必须有某种意义
我能想到的最好办法是,您可以使用位技巧来指定状态集,这样您就可以有效地测试当前状态是否在给定的集中-如果您需要在状态中执行某些操作(1)只要您知道这些限制,我看不出这样的系统有任何问题。事实上,我认为它应该非常适合非常小的嵌入式环境中的小型状态机,因为空间非常宝贵。我认为这是一个@means matters的问题,您需要&
而不是
,例如如果(ValidTestState&requestedState)nextState=requestedState;
“还有比这种编码更好的吗?”更好地定义。更快、更安全、更少的内存消耗?首先使用位的原因是什么?如果是因为需要快速评估有效状态转换,则此方法比使用状态的向上计数整数稍快。如果需要快速调用实际状态,则此方法稍慢,因为不能使用基于函数指针的查找表,编译器也不能将swich语句转换为函数指针的查找表。(有关查找表,请参阅)是的,我有硬件设计师的背景。这是我在状态机中学习一个热编码的地方。我不知道你提到的第二个缺点。这就是我想要的评论。你的最后一点也很有趣。我不确定我是否需要这个技巧。但我会记住它。谢谢你的回答!
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;
}