量子编程详解之一: QP-nano代码大餐之状态机函数详细注释

先把内容贴上来再说,下一步接着来

这个是量子编程的学习心得的第一篇

先是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 */

    原文作者:lyqdy1
    原文地址: https://blog.csdn.net/lyqdy1/article/details/7085959
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞