先把内容贴上来再说,下一步接着来
这个是量子编程的学习心得的第一篇
先是qepn.c
格式还弄不好
研究好了重发一篇
/*****************************************************************************
* Product: QEP-nano implemenation
* Last Updated for Version: 4.1.05
* Date of the Last Update: Oct 27, 2010
*
* Q u a n t u m L e a P s
* —————————
* innovating embedded systems
*
* Copyright (C) 2002-2010 Quantum Leaps, LLC. All rights reserved.
*
* This software may be distributed and modified under the terms of the GNU
* General Public License version 2 (GPL) as published by the Free Software
* Foundation and appearing in the file GPL.TXT included in the packaging of
* this file. Please note that GPL Section 2[b] requires that all works based
* on this software must also be made publicly available under the terms of
* the GPL (“Copyleft”).
*
* Alternatively, this software may be distributed and modified under the
* terms of Quantum Leaps commercial licenses, which expressly supersede
* the GPL and are specifically designed for licensees interested in
* retaining the proprietary status of their code.
*
* Contact information:
* Quantum Leaps Web site: http://www.quantum-leaps.com
* e-mail: info@quantum-leaps.com
*****************************************************************************/
#include “qpn_port.h” /* QP-nano port */
#ifndef Q_NHSM
Q_DEFINE_THIS_MODULE(qepn)
#endif
/**
* \file
* \ingroup qepn qfn
* QEP-nano implementation.
*/
/** empty signal for internal use only */
#define QEP_EMPTY_SIG_ 0
/** maximum depth of state nesting (including the top level), must be >= 2 */
#define QEP_MAX_NEST_DEPTH_ 5
/*………………………………………………………………..*/
/*lint -e970 -e971 */ /* ignore MISRA rules 13 and 14 in this function */
char const Q_ROM * Q_ROM_VAR QP_getVersion(void) {
static char const Q_ROM Q_ROM_VAR version[] = {
((QP_VERSION >> 12) & 0xF) + ‘0’,
‘.’,
((QP_VERSION >> 8) & 0xF) + ‘0’,
‘.’,
((QP_VERSION >> 4) & 0xF) + ‘0’,
(QP_VERSION & 0xF) + ‘0’,
‘\0’
};
return version;
}
#ifndef Q_NFSM
/*………………………………………………………………..*/
void QFsm_init(QFsm *me) {
(void)(*me->state)(me); /* execute the top-most initial transition */
Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
(void)(*me->state)(me); /* enter the target */
}
/*………………………………………………………………..*/
#ifndef QK_PREEMPTIVE
void QFsm_dispatch(QFsm *me) {
#else
void QFsm_dispatch(QFsm *me) Q_REENTRANT {
#endif
QStateHandler s = me->state;
if ((*s)(me) == Q_RET_TRAN) { /* transition taken? */
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
(void)(*s)(me); /* exit the source */
Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
(void)(*me->state)(me); /* enter the target */
}
}
#endif /* Q_NFSM */
#ifndef Q_NHSM
/*………………………………………………………………..*/
QState QHsm_top(QHsm *me) {
(void)me; /* supress the “unused argument” compiler warning */
return Q_IGNORED(); /* the top state ignores all events */
}
/*………………………………………………………………..*/
void QHsm_init(QHsm *me) {
QStateHandler t;
/* 初始化状态机时必须转换到一个明确的状态 */
Q_ALLEGE((*me->state)(me) == Q_RET_TRAN);/* initial tran. must be taken */
/*从顶层状态开始,执行递归的进入操作
* 此时me->state已经为初始化后的目标状态
*/
t = (QStateHandler)&QHsm_top; /* an HSM starts in the top state */
do { /* drill into the target hierarchy… */
QStateHandler path[QEP_MAX_NEST_DEPTH_];
int8_t ip = (int8_t)0;
/*利用QEP_EMPTY_SIG_信号,从目标状态回溯到顶状态,
* QEP_EMPTY_SIG_信号除把状态转换到超状态,不做任何操作
* 保存回溯的路径到ip数组中,保存为逆序
* 即第一个数组元素为目标状态,上层状态其后
* 顶层状态并不包括在路径中
*/
path[0] = me->state;
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
(void)(*me->state)(me);
while (me->state != t) {
++ip;
path[ip] = me->state;
(void)(*me->state)(me);
}
/* 回到目标状态 */
me->state = path[0];
/* 确保深度在预定内 */
/* entry path must not overflow */
Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
/* 从进入路径执行Q_ENTRY_SIG信号事件 */
Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
do { /* retrace the entry path in reverse (correct) order… */
(void)(*path[ip])(me); /* enter path[ip] */
–ip;
} while (ip >= (int8_t)0);
/* 在目标状态上执行初始化 */
t = path[0];
Q_SIG(me) = (QSignal)Q_INIT_SIG;
/*在目标状态上执行初始化操作
* 如果目标状态的初始化导致状态转换,则重复上述过程
* 直到进入一个状态在执行初始化后不再转换
*/
} while ((*t)(me) == Q_RET_TRAN); /* initial transition handled? */
me->state = t;
}
/*………………………………………………………………..*/
#ifndef QK_PREEMPTIVE
void QHsm_dispatch(QHsm *me) {
#else
void QHsm_dispatch(QHsm *me) Q_REENTRANT {
#endif
QStateHandler path[QEP_MAX_NEST_DEPTH_];
QStateHandler s;
QStateHandler t;
QState r;
t = me->state; /* save the current state */
/*事件处理,直到被当前状态或层次上的超状态处理
* 因为在被处理前一直返回 Q_RET_SUPER
* 所以此循环退出时,事件肯定已经被处理了
* s 保存的是处理事件的超状态!
* 当前的me->state则为在处理事件的超状态中转换的目标状态
*/
do { /* process the event hierarchically… */
s = me->state;
r = (*s)(me); /* invoke state handler s */
} while (r == Q_RET_SUPER);
if (r == Q_RET_TRAN) { /* transition taken? */
/*
* 在事件处理时,发生了状态转换
* 这个转换要么发生在分发事件的初始状态(入口参数me->state),
* 要么就在初始状态的超状态
* s就保存了这个发生转换的状态
*/
int8_t ip = (int8_t)(-1); /* transition entry path index */
int8_t iq; /* helper transition entry path index */
/* 把转换的目标状态保存到path[0] */
path[0] = me->state; /* save the target of the transition */
/* 把转换的起源状态保存到path[1],
* 起源状态为入口参数me->state,先前存放在t中
*/
path[1] = t;
/*如果转换发生在超状态中,则执行从起源状态到超状态的退出操作
* 注意,最后的超状态是不会执行退出操作的
*/
while (t != s) { /* exit current state to transition source s… */
/*
* 执行退出事件不能有转换,除非返回超状态
*/
Q_SIG(me) = (QSignal)Q_EXIT_SIG; /* find superstate of t */
if ((*t)(me) == Q_RET_HANDLED) { /* exit action handled? */
/*
* 退出被处理则要执行空信号,强迫返回超状态
*/
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
(void)(*t)(me); /* find superstate of t */
}
/*
* me->state必定已变为超状态!
*/
t = me->state; /* me->state holds the superstate */
}
/* 现在,me->state回到了执行转换状态的超状态 */
/* 提出目标状态 */
t = path[0]; /* target of the transition */
/*t已经为目标状态,
* s为执行状态转换的那个状态,即实际执行处理被分发的事件的那个状态
* 这个状态要么是分发事件的初始状态(入口参数me->state),
* 要么是初始状态的超状态
*/
if (s == t) { /* (a) check source==target (transition to self) */
/*转换的目标状态与转换操作发生的状态相同
* 执行一个自转换,即退出操作
*/
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
(void)(*s)(me); /* exit the source */
/* 准备进入目标状态, path[0]就是目标状态 */
ip = (int8_t)0; /* enter the target */
}
else {
/*
* 目标状态与转换源状态不同,
* 即从处理事件的那个状态转换到了一个新状态
* 此时,并不知道目标状态在状态树中的哪个位置
* 麻烦即将来临!
*
* s: 执行转换的起源状态 t: 目标状态
*/
/* 求得目标状态的超状态 */
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
(void)(*t)(me); /* find superstate of target */
t = me->state;
/* t: 已变成目标状态的超状态 */
/* 目标状态是否起源状态的子状态? */
/* 目标状态的超状态就是起源状态么? */
if (s == t) { /* (b) check source==target->super */
/*
* 目标状态的超状态就是起源状态
*/
/* 准备进入目标状态, path[0]就是目标状态 */
ip = (int8_t)0; /* enter the target */
}
else {
/*
* 目标状态的超状态不是起源状态
*/
/* 求得起源状态的超状态 */
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
(void)(*s)(me); /* find superstate of source */
/* 是否兄弟状态?*/
/* 即起源状态的超状态和目标状态的超状态相同么 ? */
/* (c) check source->super==target->super */
if (me->state == t) {
/*
* 起源状态的超状态和目标状态的超状态相同,
* 这个超状态就是LCA(最小公共超状态)
*/
/* 退出起源状态,准备进入目标状态, path[0]就是目标状态 */
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
(void)(*s)(me); /* exit the source */
ip = (int8_t)0; /* enter the target */
}
else {
/*
* 不是兄弟状态,那么是目标状态是起源状态的父亲么 ?
* me->state已经是起源状态的超状态
*/
/* (d) check source->super==target */
if (me->state == path[0]) {
/*
* 目标状态确实是父状态
* 退出起源状态
* 转换到父状态不需要执行进入操作
* 因为源状态本身就在父状态之中
* 故ip=-1,没有ip=0这句
*/
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
(void)(*s)(me); /* exit the source */
}
else { /* (e) check rest of source==target->super->super..
* and store the entry path along the way
*/
/*
* 彻底看看源状态是不是目标状态的超状态
* 即目标状态是否在源状态的状态树上
*/
/* iq指示是否找到LCA */
iq = (int8_t)0; /* indicate that LCA not found */
/* path[0]已经是目标状态 */
ip = (int8_t)1; /* enter target and its superstate */
/* path[1]存放目标状态的超状态 */
path[1] = t; /* save the superstate of target */
/* 至此,me->state是神马玩意了呢 ? */
/* OK,它已经是起源状态的超状态了 */
t = me->state; /* save source->super */
/*
* 现在,从目标状态的超状态往上走
* 目标状态的超状态在path[1]里
*/
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
r = (*path[1])(me); /* find target->super->super */
/* Go up! */
/*
* 到顶或者
* 从超状态链中找到起源状态
*/
while (r == Q_RET_SUPER) {
/*
* 保存路径
*/
path[++ip] = me->state; /* store the entry path */
if (me->state == s) { /* is it the source? */
/*
* 找到了,那个找我麻烦的状态:-)
* 设置标志
*/
iq = (int8_t)1; /* indicate that LCA found */
/* entry path must not overflow */
Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
/* 扣除目标状态 */
–ip; /* do not enter the source */
/*
* r还有用么,舍不得用break?
* 结构化真他妈的那么重要?
*/
r = Q_RET_HANDLED; /* terminate the loop */
}
else { /* it is not the source, keep going up */
/*
* Go up continue!
* 对QEP_EMPTY_SIG_,
* 只要有超状态就会返回Q_RET_SUPER
* 否则就是到顶了
*/
r = (*me->state)(me); /* superstate of t */
}
}
/*
* 在目标状态的超状态中找到源状态了么?
* 实际上是看目标状态与源状态是否在同一条树枝路径上
*/
if (iq == (int8_t)0) { /* the LCA not found yet? */
/*
* 悲剧啊,不在一条树枝上!
* LCA自然是还没找到
*/
/* entry path must not overflow */
Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
/*
* 没办法,LCA肯定在源状态的某个超状态上了
* 来,现在沿着源状态的超状态往上走
* 去找与目标状态的共同祖先LCA
* path已经记录了目标状态的超状态链
*/
/*
* 毫无疑问,这次需要从源状态一路退出到LCA
*/
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
(void)(*s)(me); /* exit the source */
/* 注意,俺开始退出了 */
/*
* iq的作用变了,用于辅助跟踪状态链
*/
/* (f) check the rest of source->super
* == target->super->super…
*/
iq = ip;
r = Q_RET_IGNORED; /* indicate LCA NOT found */
/* 此时,t为起源状态的父状态,即第一层超状态 */
do {
/*
* 从目标状态超状态链的最上面开始
*/
s = path[iq];
if (t == s) { /* is this the LCA? */
/*
* 这么容易就找到了?真没劲啊
*/
r = Q_RET_HANDLED;/* indicate LCA found */
/*
* 目标状态的超状态链不包括LCA
* 注意:如果iq=0,
* 即目标状态就是超源状态的父状态
* ip=0-1=-1,此后不会执行父状态的进入
* 因为此时源状态本身就在目标状态中!
*/
ip = (int8_t)(iq – 1);/*do not enter LCA*/
/*
* 结束循环的标志,我日,还是不用break!
*/
iq = (int8_t)(-1);/* terminate the loop */
}
else {
/*
* 向目标状态的超状态链向下辗个位置
*/
–iq; /* try lower superstate of target */
}
} while (iq >= (int8_t)0);
/* 源状态的父状态也不是LCA? */
if (r != Q_RET_HANDLED) { /* LCA not found yet? */
/* (g) check each source->super->…
* for each target->super…
*/
/*
* 确实不是,还得继续找,肏他妈的真累啊
* 这下该怎么找啊,好晕
* 这些变量都变成什么玩意儿了?
* t:还是为起源状态的父状态
*/
r = Q_RET_IGNORED; /* keep looping */
do {
/*
* 唉,从源状态的父状态往上一层层地退吧!
* 兄弟,听过“王霞”的故事么?见附录
*/
/* exit t unhandled? */
Q_SIG(me) = (QSignal)Q_EXIT_SIG;
if ((*t)(me) == Q_RET_HANDLED) {
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
(void)(*t)(me); /* find super of t */
}
t = me->state; /* set to super of t */
/*
* 一边执行退出一边往上走
*/
/*
* path为目标状态的超状态链
* 这个链中开始找LCA
* 就是每得到一个源状态的超状态
* 就在目标状态的超状态中找
* 找到的第一个就是LCA
* 不信?你可以画个图看看
*/
iq = ip;
do {
s = path[iq];
if (t == s) { /* is this LCA? */
/*
* 终于找到了,我的妈呀
*/
/* do not enter LCA */
ip = (int8_t)(iq – 1);
iq = (int8_t)(-1);/*break inner */
r = Q_RET_HANDLED;/*break outer */
}
else {
–iq;
}
} while (iq >= (int8_t)0);
} while (r != Q_RET_HANDLED);
}
}
}
}
}
}
/*
* 在上述过程中,退出操作已经干了
* 进入链也保存在path中了
* 开始进入吧,慢点哦^_^
*/
/* retrace the entry path in reverse (desired) order… */
Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
for (; ip >= (int8_t)0; –ip) {
(void)(*path[ip])(me); /* enter path[ip] */
}
/* 目标状态提取出来 */
t = path[0]; /* stick the target into register */
/* 更新状态机的目标状态 */
me->state = t; /* update the current state */
/*
* 最后一件事,在目标状态上执行初始化
* 这个过程真他妈的应该和QHsm_init好好地复用一下代码
* 这两个地方类似的递归初始化的代码没有复用相当挫
* 注:初始化转换只能在引起初始化状态的状态树枝里
*/
/* drill into the target hierarchy… */
Q_SIG(me) = (QSignal)Q_INIT_SIG;
while ((*t)(me) == Q_RET_TRAN) {
ip = (int8_t)0;
/*
* 初始化时如果状态转换则生成超状态链
*/
path[0] = me->state;
Q_SIG(me) = (QSignal)QEP_EMPTY_SIG_;
(void)(*me->state)(me); /* find the superstate */
while (me->state != t) {
++ip;
path[ip] = me->state;
(void)(*me->state)(me); /* find the superstate */
}
me->state = path[0];
/* entry path must not overflow */
Q_ASSERT(ip < (int8_t)QEP_MAX_NEST_DEPTH_);
/* 在状态链上执行进入 */
Q_SIG(me) = (QSignal)Q_ENTRY_SIG;
do { /* retrace the entry path in reverse (correct) order… */
(void)(*path[ip])(me); /* enter path[ip] */
–ip;
} while (ip >= (int8_t)0);
/*
* 在目标状态上继续执行初始化
* 最后,没有状态转换的初始化操作的状态为最后的状态
* 这个最后的状态为最终的目标状态,放在t中
*/
t = path[0];
Q_SIG(me) = (QSignal)Q_INIT_SIG;
}
}
/* 目标状态终于确定,俺洗洗睡了 */
me->state = t; /* set new state or restore the current state */
}
#endif /* Q_NHSM */