一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

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

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

[复制链接]
发表于 2018-4-19 10:51 | 显示全部楼层 |阅读模式
本帖最后由 kenson 于 2018-4-19 11:15 编辑 0 I/ A1 o1 D5 m, J3 S, {
) p8 g8 _+ \& C2 h2 t) D
QEP之init()和dispatch()流程图
$ u& ^8 C4 E" B
抽象状态机类QFsm或QHsm有一个函数指针,用于在继承的具体状态机类中指向具体的状态函数,其有两个对外的接口函数init()和dispatch(),其工作原理是理解状态机处理事件过程的关键。
具体状态机类继承自QFsm或QHsm,同时继承了这个函数指针,用于动态指向具体状态机类中的私有状态函数。
具体事件继承于根事件QEvent,并可以自己增加附加的属性。事件是外部与状态机唯一通信的实体,通过dispatch(),把事件送到状态机。状态机对外不可见,具体属性和具体状态函数都是私有的。
0 L7 Y" l! n8 ~* n
     图1.QEP总体类结构1.预备知识
(1)声明一个函数指针
具体状态机类继承自QFsm或QHsm,则具体状态机具有了一个指针state,state可以指向任何状态函数,并调用状态函数执行。dispatch()函数可以用空事件探测状态机的结构、可以执行进入和退出动作、可以执行具体的事件处理动作,也可以进行状态转移。
* X2 h% \3 {& V% F9 k, C+ A* [
typedef uint8_t QState;                           
" N% J2 x. l5 Q: ~
typedef QState (*QStateHandler)(void *me, QEvent const *e);/*函数指针*/
3 E$ n! I0 e! a2 m" [3 d& N( G
+ l* T2 U, M6 t" p) b9 Y
(2)声明一个状态机中的函数指针变量
typedef struct QFsmTag {   

( b+ @. `1 G9 g& ]% ZQStateHandler state; /*变量(函数指针),指向状态机当前状态(函数)*/" ?! D2 }2 C0 I; b2 o! |* W$ `5 O
} QFsm;
9 {  l4 }4 {7 P: W* C; v4 J8 v
. s4 u7 X9 z$ {& D$ P
typedef struct QFsmTag QHsm;
3 ]$ }2 c3 _' i# D- b0 Q" X2 K* U' r" G6 z& ]. @
(3)状态函数处理后的返回结果
每个状态函数中,根据不同的事件处理,处理完后要返回上边的结果之一,供dispatch()了解状态函数对某事件是否忽略、是否处理完、是否转换、是否不能处理而要让父状态函数来处理。
QSUPP(super)中的参数决定了层次状态机的层次结构。
/* 忽略事件 */

/ ^; K! h* Q3 O; O' q#define Q_IGNORED()         (Q_RET_IGNORED); J: C- G7 u! L5 i# F
/* 已处理事件 */
! h$ a, z' P& U% Q) w9 y#define Q_HANDLED()         (Q_RET_HANDLED)
; R4 ^3 s6 T' ~/* 状态转移 */
5 O. E5 Y/ }4 M: T/ C; Y#define Q_TRAN(target_)      (((QFsm *)me)->state = (QStateHandler)(target_), Q_RET_TRAN)" N" T6 l$ W! E: ~6 U
/* 到超状态 */
/ D2 f( J8 q  v4 {+ q2 y" Y#define Q_SUPER(super_)      (((QHsm *)me)->state = (QStateHandler)(super_),  Q_RET_SUPER)
4 x8 Z; X% c4 |
3 l# ?; m) V# k1 K+ z& ^
(4)触发动作
dispatch()用于主动去触发具体状态机,以探知状态机的结构、执行进入和退出动作。用QEP_EMPTY_SIG 触发空动作,总是会执行到状态函数的最后一行 QSUPPER(super_),通过触发后的返回结果,可以探知状态机的层次结构。
/* 以sig_信号触发状态机 */
% q" p! Q. d' @+ q0 t9 E% w
#define QEP_TRIG_(state_, sig_)     ((*(state_))(me, &QEP_reservedEvt_[sig_]))
7 c& a  t% X: X& B5 P/* 触发退出动作,在层次状态机HSM */
9 j" A+ G4 S2 L; w0 U" t#define QEP_EXIT_(state_)     
" W9 }8 O  M* w: V# Dif (QEP_TRIG_(state_, Q_EXIT_SIG) == Q_RET_HANDLED) - @+ N+ W. j) w
{
- y8 W7 \, g9 j! F  W, C2 h# x         ...QS     + W) Y! h2 t3 s9 q$ `
}
9 ^. `$ c/ B: w* C, k
' t  q, R/ K0 T* T+ X3 l

& y" c# C/ O1 Z- A2 ]/* 触发进入动作,在层次状态机HSM */
5 V4 e5 B5 u+ T* Y' O#define QEP_ENTER_(state_)     
, C9 c# u" y. eif (QEP_TRIG_(state_, Q_ENTRY_SIG) == Q_RET_HANDLED) " M: V$ x4 q; b, D
{
3 ^- W- v0 _* i! Q# G, `. {. s         ...QS     
) r5 f" ~( b  u# ^4 Z) G8 {  v5 o}
$ D: s6 U; K4 N! o3 z) Z: o1 _* ?
, `( H( {- [' w( z+ W7 Y
* o: p' M0 o( n1 R
/* 触发空动作,在层次状态机HSM (自加)*/
! o/ u/ ~$ @& N/ Z+ c* W/ w#define QEP_EMPTY_(state_)     QEP_TRIG_(state_, QEP_EMPTY_SIG_)  9 q3 P' \( X8 C+ K& t# O4 o% d

/ g' U# K: X8 v% s2.Fsm状态机init()和dispatch()流程

(1)QFsm_init()流程! W2 Q: L& Z6 h) y& ?& D* g
815490-20151227210907906-1888535234.png 

   图2.QFsm_init()流程

(2)QFsm_dispatch()流程2 C5 F+ z5 L6 i, A9 {
815490-20151227210907999-1694829155.png 

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

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

(1)QHsm_init()流程4 p" G0 n& a' N
815490-20151227210908374-1012628730.png 

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

(2)QHsm_dispatch()流程9 }6 Z) T/ T% k& P# |6 [
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, 2025-4-28 08:47 , Processed in 0.065067 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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