有限状态机在学习和工作中经常能够遇到,前面的文章也有使用到。但是对于层次状态机网上的学习资源却很少,导致一直不理解这个工作机制,后面偶然在GitHub看到一篇文章,深入学习后发现层次状态机太实用了,如果将其在项目上结合,肯定能够创造出一个比较好的代码框架。
一、HSM状态调度机制
HSM状态间是存在等级关系,状态间至少存在2个等级,并且除根状态外至少存在ENTER和EXTI事件,我认为HSM的状态机结构类似树状结构,HSM状态如图所示:

很明显这里存在四个等级,CAMERA为d0,其余为d1,d2,d3。 CAMERA为根状态(根状态不做任何处理),其余的六种状态,有些的父状态为根状态,有些则作为其他的父状;
1.切换状态-等级不同
例如从CAMERA_StateOnDispPlay状态(d3)切换到CAMERA_StateOnShoot(d2)状态;
首先函数调度会先找到他们共同的父状态,这里即为CAMERA_StateOn,然后依次调用CAMERA_StateOnDispPlay和CAMERA_StateOnDisp状态的EXTI事件,再调用CAMERA_StateOnShoot的ENTER事件,即可切换到目标状态,方向如图:

2.切换状态-等级相同
例如从CAMERA_StateOnDisp状态(d2)切换到CAMERA_StateOnShoot(d2)状态;
他们父状态是相同的,所以只需要调用当前状态的EXTI事件后,再进入目标状态的ENTER事件即可。
状态调度函数源码如下
// Func: void HSM_Tran(HSM *This, HSM_STATE *nextState, void *param, void (*method)(HSM *This, void *param))
// Desc: Transition to another HSM STATE
// This: Pointer to HSM instance
// nextState: Pointer to next HSM STATE
// param: Optional Parameter associated with HSME_ENTRY and HSME_EXIT event
// method: Optional function hook between the HSME_ENTRY and HSME_EXIT event handling
void HSM_Tran(HSM *This, HSM_STATE *nextState, void *param, void (*method)(HSM *This, void *param))
{
#if HSM_FEATURE_SAFETY_CHECK
// [optional] Check for illegal call to HSM_Tran in HSME_ENTRY or HSME_EXIT
if (This->hsmTran)
{
HSM_DEBUG("!!!!Illegal call of HSM_Tran[%s -> %s] in HSME_ENTRY or HSME_EXIT Handler!!!!",
This->curState->name, nextState->name);
return;
}
// Guard HSM_Tran() from certain recursive calls
This->hsmTran = 1;
#endif // HSM_FEATURE_SAFETY_CHECK
HSM_STATE *list_exit[HSM_MAX_DEPTH];
HSM_STATE *list_entry[HSM_MAX_DEPTH];
uint8_t cnt_exit = 0;
uint8_t cnt_entry = 0;
uint8_t idx;
// This per

文章详细介绍了HSM(HierarchicalStateMachine)层次状态机的工作机制,包括状态调度和事件调度。在状态调度中,重点阐述了不同等级状态间的切换逻辑,而事件调度则讲解了如何处理不同状态下的事件。HSM的应用在于其能有效管理复杂的状态流程,文章提供了一种清晰的理解和实现HSM的方法。
最低0.47元/天 解锁文章
1464

被折叠的 条评论
为什么被折叠?



