一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 2137|回复: 0
收起左侧

[操作系统]QEP之init()和dispatch()流程图

[复制链接]
发表于 2018-4-19 10:51 | 显示全部楼层 |阅读模式
本帖最后由 kenson 于 2018-4-19 11:15 编辑 $ t7 F; |0 H: f* _% ?; F! d7 m
/ J0 e1 F5 G5 p: f& N5 |2 A, c
QEP之init()和dispatch()流程图/ Y2 _4 P9 Z; r6 C8 v% i1 q
抽象状态机类QFsm或QHsm有一个函数指针,用于在继承的具体状态机类中指向具体的状态函数,其有两个对外的接口函数init()和dispatch(),其工作原理是理解状态机处理事件过程的关键。
具体状态机类继承自QFsm或QHsm,同时继承了这个函数指针,用于动态指向具体状态机类中的私有状态函数。
具体事件继承于根事件QEvent,并可以自己增加附加的属性。事件是外部与状态机唯一通信的实体,通过dispatch(),把事件送到状态机。状态机对外不可见,具体属性和具体状态函数都是私有的。

! C0 u3 M' ~. E0 W7 H0 d% w: B! Q     图1.QEP总体类结构1.预备知识
(1)声明一个函数指针
具体状态机类继承自QFsm或QHsm,则具体状态机具有了一个指针state,state可以指向任何状态函数,并调用状态函数执行。dispatch()函数可以用空事件探测状态机的结构、可以执行进入和退出动作、可以执行具体的事件处理动作,也可以进行状态转移。

$ y$ v% Y; z* f( V% b: w: O3 Atypedef uint8_t QState;                           
8 t: Q) T# k3 Z, C; G& w% ~3 e
typedef QState (*QStateHandler)(void *me, QEvent const *e);/*函数指针*/3 O# \* F" \3 S
/ z, O* n1 e  q3 v* e
(2)声明一个状态机中的函数指针变量
typedef struct QFsmTag {   

( ?3 ]. ~' W3 K1 V# M% I6 Y* J+ L3 ~QStateHandler state; /*变量(函数指针),指向状态机当前状态(函数)*/
( e: h; \! m/ {0 H$ D3 r1 `$ K} QFsm;: W+ l/ b8 r! G
: ?. C9 d* L5 v# B/ _+ V
typedef struct QFsmTag QHsm;
( [5 b2 t" L, z7 s0 ?+ a* ^; Z6 r: [% n! [; P& D
(3)状态函数处理后的返回结果
每个状态函数中,根据不同的事件处理,处理完后要返回上边的结果之一,供dispatch()了解状态函数对某事件是否忽略、是否处理完、是否转换、是否不能处理而要让父状态函数来处理。
QSUPP(super)中的参数决定了层次状态机的层次结构。
/* 忽略事件 */
8 y) P9 ]4 L, G7 L/ M
#define Q_IGNORED()         (Q_RET_IGNORED); T. t' V4 h( J. c3 j1 Q0 w
/* 已处理事件 */
9 W$ \2 ~$ y9 t  Q  W, |2 D: j: N#define Q_HANDLED()         (Q_RET_HANDLED)7 l/ u. `# c  a. h; E4 X
/* 状态转移 */
/ I/ M) S6 T# M+ L% c8 ?1 F' d3 k#define Q_TRAN(target_)      (((QFsm *)me)->state = (QStateHandler)(target_), Q_RET_TRAN)
9 H9 ^8 p; a0 l, E5 c& _9 H/* 到超状态 */
& J- g3 k; r! C: S& v/ Y$ {$ d0 [3 I#define Q_SUPER(super_)      (((QHsm *)me)->state = (QStateHandler)(super_),  Q_RET_SUPER)
1 R4 O! q6 c+ D' x( z- E  @5 i% _; I: O* }, g, X1 R% M1 g  }
(4)触发动作
dispatch()用于主动去触发具体状态机,以探知状态机的结构、执行进入和退出动作。用QEP_EMPTY_SIG 触发空动作,总是会执行到状态函数的最后一行 QSUPPER(super_),通过触发后的返回结果,可以探知状态机的层次结构。
/* 以sig_信号触发状态机 */
0 W% m# K, G9 g9 _# P
#define QEP_TRIG_(state_, sig_)     ((*(state_))(me, &QEP_reservedEvt_[sig_]))0 D8 g$ b! R- w7 T3 z
/* 触发退出动作,在层次状态机HSM */' H1 [$ E& i0 ]4 E/ U5 }3 Q
#define QEP_EXIT_(state_)       O0 }! L/ y# A
if (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) 9 G( {( K8 d8 S! A) H6 `
{
) R/ }" R; g, e9 H* r! C* D         ...QS     * _5 b" K9 M; F% }8 E/ Z
}
, }$ S* F6 s8 q1 O  P" s
  T# Y5 U2 e, M2 Q( O: ]

7 s3 u# c4 U1 R' i( b/* 触发进入动作,在层次状态机HSM */
- A; B  b2 _: v#define QEP_ENTER_(state_)     3 ], k; E  |% f& c& r7 ?# Q2 c+ [
if (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) ( h5 `, D8 R$ y5 Q2 l" }
{. i% u  H% }  L; M* M
         ...QS     * v. Z  z, t( l
}) u8 U  j: B. F5 h. ^3 u8 i2 s
% Q' H! y: r# X  H* B9 a1 |# b/ ^/ K

8 Y& X! [; @" F/* 触发空动作,在层次状态机HSM (自加)*/( Z8 @4 F, F* Y! w, G! q
#define QEP_EMPTY_(state_)     QEP_TRIG_(state_, QEP_EMPTY_SIG_)  
! s9 R" m  L& O% r" J/ M1 a4 G" K* D, u* {) x( s
2.Fsm状态机init()和dispatch()流程

(1)QFsm_init()流程, s: T3 Y. _  J1 j! G. C3 M* ?% g
815490-20151227210907906-1888535234.png 

   图2.QFsm_init()流程

(2)QFsm_dispatch()流程
8 Y# e8 u' b  y0 K; J0 E 815490-20151227210907999-1694829155.png 

   图3.QFsm_dispatch()流程3.Hsm状态机init()和dispatch()流程

从顶级状态的初始伪状态开始,到本初始伪状态转换的终状态(子状态),执行进入动作。在终状态(子状态)继续检查有没有子初始伪状态,如果有的话,继续进入,执行进入动作,直到最终状态。

(1)QHsm_init()流程
; {0 ^" m( [3 ~0 G; Q 815490-20151227210908374-1012628730.png 

   图4.QHsm_init()流程图与层次状态机

(2)QHsm_dispatch()流程) i& W6 c9 [) u2 {) m
815490-20151227210910999-1369603859.png 

   图5.QHsm_dispatch()流程图
815490-20151227210908343-159821549.png
815490-20151227210907906-1888535234.png
815490-20151227210907999-1694829155.png
815490-20151227210908374-1012628730.png
815490-20151227210910999-1369603859.png

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-4 12:42 , Processed in 0.053203 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表