量子编程详解之一: 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:                  [email protected]
*****************************************************************************/
#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 */

你可能感兴趣的:(量子编程详解之一: QP-nano代码大餐之状态机函数详细注释)