⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statemachine.c

📁 嵌入式软件构件:TMR计时器管理、CLK实时时钟、KEY键盘扫描、LED数码显示、LCD显示、COMM串口通信
💻 C
字号:
/*****************************************************************************Filename   : StateMachine.C* Programmer : Haven**Date       : 2007.9.25**DESCRIPTION: 事件分发函数*****************************************************************************/#define FK_SM_GLOBALS#include "..\includes\includes.H"#define MAX_NEST_DEPTH 5/*****************************************************************************void FsmDispatch(FSM *me) 有限状态机事件分发*****************************************************************************/void FsmDispatch(FSM *me) {    STAT_PTR  st = me->StatFunPtr;    (*st)(me);                 if (me->EventSig == (EVENT_SIG)0) {               me->EventSig = (EVENT_SIG)EXIT_SIG;        (*st)(me);               //源状态执行退出动作         me->EventSig = (EVENT_SIG)ENTRY_SIG;        (*me->StatFunPtr)(me);     //目标状态执行进入动作     }}#if HFSM_ENSTAT_PTR HfsmTop(HFSM *me)  {    (void)me;                 return (STAT_PTR)0;               }/******************************************************************void HfsmInit(HFSM *me) 初始状态转换,每一线程在初始化时都需要调用一次本函数。*******************************************************************/void HfsmInit(HFSM *me) {    HFSM_STAT_PTR st;                       //源状态    HFSM_STAT_PTR tt;                       //目标状态    HFSM_STAT_PTR path[MAX_NEST_DEPTH];     //状态层次路径    INT8S ip;        st = &HfsmTop;                      //这个状态机必须在HsmCtor()中被初始化     //REQUIRE(me->StatFunPtr != (HFSM_STAT_PTR)0);        //(void)(*me->StatFunPtr)(me);                    // 在初始伪状态启动转换    //不用初始伪状态设计中省略。    do {                                                 // 穿入目标层次...         tt = me->StatFunPtr;        ip = (INT8S)0;        path[0] = tt;        SIG(me) = (EVENT_SIG)EMPTY_SIG;        tt = (HFSM_STAT_PTR)(*tt)(me);                     // 找出t的超状态        //用于初始转换跨层次的转换,中间层次要找出来,因为每一层都要有进入动作        while (tt != st) {                 ++ip;            path[ip] = tt;            SIG(me) = (EVENT_SIG)EMPTY_SIG;            tt = (HFSM_STAT_PTR)(*tt)(me);                 // 找出t的超状态        }                                                                //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);            // 进入路径不能溢出                 //因为ip是由底层向顶层的查找方式,所以进入动作,是ip--是从顶层到底层        //的一层一层执行进入动作。        do {                    SIG(me) = (EVENT_SIG)ENTRY_SIG;            (void)(*path[ip])(me);                           //执行进入动作            --ip;        } while (ip >= (INT8S)0);        st = me->StatFunPtr;        SIG(me) = (EVENT_SIG)INIT_SIG;    } while ((*st)(me) == (STAT_PTR)0);     // 初始转换句柄,为0是还有初始转换}/****************************************************************************层次状态机事件分发****************************************************************************/void HfsmDispatch(HFSM *me)  {    HFSM_STAT_PTR path[MAX_NEST_DEPTH];    HFSM_STAT_PTR st;    HFSM_STAT_PTR tt;    HFSM_STAT_PTR src;                                        // 转换的源状态     INT8S         ip;                                      // 转换进行路径索引     INT8S         iq;        tt = me->StatFunPtr;    path[1] = tt;                                           // 存储当前状态     do {                                                   // 处理事件层次...         st = tt;                                       //源等于下一条返回状态        tt = (HFSM_STAT_PTR)((*st)(me));                  // 调用状态处理程序     } while (tt != (HFSM_STAT_PTR)0); //如果!=0说明这一层不处理这个信号,返回                                      //上层状态(它的超状态)处理    if (me->EventSig == (EVENT_SIG)0) {                     // 如果是转换请求         src = st;                                             // 转换的源状态         ip = (INT8S)(-1);                                 // 转换进行路径索引         path[0] = me->StatFunPtr;                             // 存储新的状态         me->StatFunPtr = path[1];                             // 恢复当前状态                                               // 退出当前状态,到转换源 src...         //源状态执行退出动作,直到转换源         for (st = path[1]; st != src; ) {            SIG(me) = (EVENT_SIG)EXIT_SIG;            tt = (HFSM_STAT_PTR)(*st)(me);                      // 找到的超状态             if (tt != (HFSM_STAT_PTR)0) {               // 退出动作没有处理程序                 st = tt;                                       // tt 指向超状态             }else{                                            // 退出动作处理了                 SIG(me) = (EVENT_SIG)EMPTY_SIG;                st = (HFSM_STAT_PTR)(*st)(me);                 // 找到ss的超状态             }        }        tt = path[0];                                         // 转换的目标         if (src == tt) {                // (1) 检测 source==target (自转换)             SIG(me) = (EVENT_SIG)EXIT_SIG;            (void)(*src)(me);                                // 退出源状态             ip = (INT8S)0;                                     // 进入目标         }else{            SIG(me) = (EVENT_SIG)EMPTY_SIG;            tt = (HFSM_STAT_PTR)(*tt)(me);               // 找目标的超状态             if (src == tt) {              // (2) 检测 source==target->super                 ip = (INT8S)0;                                 // 进入目标             }else {                SIG(me) = (EVENT_SIG)EMPTY_SIG;                st = (HFSM_STAT_PTR)(*src)(me);          // 找 src的超状态                 if (st == tt) {   // (3) 检测 source->super==target->super                     SIG(me) = (EVENT_SIG)EXIT_SIG;                    (void)(*src)(me);                            // 退出源                     ip = (INT8S)0;                             // 进入目标                 }else {                    if (st == path[0]) {   // (4) 检测 source->super==target                         SIG(me) = (EVENT_SIG)EXIT_SIG;                        (void)(*src)(me);                        // 退出源                     }else { // (5) 检测 rest of source==target->super->super..                                                       // 延着路存储进入路径*/                        iq = (INT8S)0;          // 表明 that LCA not found                         ip = (INT8S)1;             // 进入目标和它的超状态                         path[1] = tt;                   // 存储目标的超状态                         SIG(me) = (EVENT_SIG)EMPTY_SIG;                        tt = (HFSM_STAT_PTR)(*tt)(me);       // 找 tt的超状态                         while (tt != (HFSM_STAT_PTR)0) {                            path[++ip] = tt;                // 存储进入路径                             if (tt == src) {                     // 是源吗?                                 iq = (INT8S)1;      // 表明 that LCA found                                                                                    //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);// 进入路径必须不能溢出                                 --ip;                        // 不能进入源                                 tt = (HFSM_STAT_PTR)0;          // 终止循环                             }else {              // tt不是源, keep going up                                 SIG(me) = (EVENT_SIG)EMPTY_SIG;                                tt = (HFSM_STAT_PTR)(*tt)(me);  // t的超状态                             }                        }                        if (iq == (INT8S)0) {    // the LCA not found yet?                             //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);// 进入路径必须不能溢出                             SIG(me) = (EVENT_SIG)EXIT_SIG;                            (void)(*src)(me);                    // 退出源                              // (6) 检测 the rest of source->super == target->super->super...                                                             iq = ip;                            do {                                if (st == path[iq]) {    // is this the LCA?                                     tt = st;    // 表明 that LCA is found                                     ip = (INT8S)(iq - 1); // do not enter LCA                                    iq = (INT8S)(-1);          // 终止循环                                 }                                else {                                    --iq; // try lower superstate of target                                 }                            } while (iq >= (INT8S)0);                            if (tt == (HFSM_STAT_PTR)0) {  // LCA not found yet?                                     // (7) 检测 每一个 source->super->...                                    // 对每一个 target->super...                                                                     do {                                    SIG(me) = (EVENT_SIG)EXIT_SIG;                                    tt = (HFSM_STAT_PTR)(*st)(me);      // 退出 st                                     if (tt != (HFSM_STAT_PTR)0) { // 如果没有处理?                                         st = tt;                 // tt 指向 ss的源                                     }                                    else {                        // 退出动作执行了                                         SIG(me) = (EVENT_SIG)EMPTY_SIG;                                        st = (HFSM_STAT_PTR)(*st)(me); //ss的超状态                                    }                                    iq = ip;                                    do {                                        if (st == path[iq]) {// is this LCA?                                                         // do not enter LCA                                             ip = (INT8S)(iq - 1);                                            iq = (INT8S)(-1);//终止内部                                             st = (HFSM_STAT_PTR)0; //终止外部                                         }                                        else {                                            --iq;                                        }                                    } while (iq >= (INT8S)0);                                } while (st != (HFSM_STAT_PTR)0);                            }                        }                    }                }            }        }        // 执行进入动作         for (; ip >= (INT8S)0; --ip) {            SIG(me) = (EVENT_SIG)ENTRY_SIG;            (void)(*path[ip])(me);                        // 进入 path[ip]         }        st = path[0];                                  //  粘贴目标到寄存器         me->StatFunPtr = st;                                // 更新当前状态         // 穿过目标层次...         SIG(me) = (EVENT_SIG)INIT_SIG;        while ((*st)(me) == (STAT_PTR)0) {            tt = me->StatFunPtr;            path[0] = tt;            ip = (INT8S)0;            SIG(me) = (EVENT_SIG)EMPTY_SIG;            tt = (HFSM_STAT_PTR)(*tt)(me);                     // 找 tt的超状态             while (tt != st) {                ++ip;                path[ip] = tt;                SIG(me) = (EVENT_SIG)EMPTY_SIG;                tt = (HFSM_STAT_PTR)(*tt)(me);                // 找 tt的超状态             }                        //ASSERT(ip < (INT8S)MAX_NEST_DEPTH);// 进入路径必须不能溢出             do {              // 执行进入动作                  SIG(me) = (EVENT_SIG)ENTRY_SIG;                (void)(*path[ip])(me);                    // 进入 path[ip]                 --ip;            } while (ip >= (INT8S)0);            st = me->StatFunPtr;            SIG(me) = (EVENT_SIG)INIT_SIG;        }    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -