基本上,我只想知道这是否是一个好主意手动一个热编码状态的C FSM。我实现它是为了编写一个简单的状态转换验证器:
typedef enum
{
FSM_State1 = (1 << 0),
FSM_State2 = (1 << 1),
FSM_State3 = (1 << 2),
FSM_StateError = (1 << 3)
} states_t;然后是验证:
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]国家枚举是一个“经典”枚举:
typedef enum
{
FSM_State1,
FSM_State2,
FSM_State3,
FSM_StateError
} states_t;有效转换的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我更改了验证:
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;
}发布于 2015-08-26 07:52:56
从一个快速的谷歌,“一个热编码”意味着每一个有效的代码有准确的一个位集,这似乎是你正在做的。搜索结果表明这是一种硬件设计模式。
我能想到的缺点是..。
switch语句的常见实现。通常有一个内部可用来确定哪一个是最低位集,但我不会打赌编译器会自动使用它。不过,这些并不是什么大问题,只要州数很少。
因此,国际海事组织的问题是,是否有理由证明这一成本是合理的。它不需要一个巨大的优势,但必须有某种意义。
我想出的最好方法是,您可以使用按位方式来指定状态集,这样就可以有效地测试当前状态是否处于给定的集合中--如果您有一些需要在状态(1<<0)和(1<<3)中执行的操作,例如,您可以测试if (state & 0x9)。
https://stackoverflow.com/questions/32220507
复制相似问题