寫了幾年的代碼,今天試著用C來做一個解釋性語言,一個狀態機,初始化的順序決定執行順序。支持時間和事件觸發兩種方案。現在只是不同匯編,要是會的話也許可以做一個OS,本代碼沒有做驗證,慎用!
- /*
- 事件狀態機,用于處理基于時間和消息
- step by step
- 用戶只需要將需要做的事情按照步驟后條件加入到本函數中即可
- 事件狀態機
- */
- #include"eventStateMachine.H"
- esm_sta esmSta[emsNum];
- event_disc eventDisc[eventNum];
- u32 esmSysTime = 0;
- u8 esmStructInit(event_disc *dat)
- {
- u8 i ;
- for(i =0 ;i != emsNum ; i++)
- {
- if(esmSta[i].usedFlag != 0)
- {
- esmSta[i].dat = dat ;
- return i ;
- }
- }
- return emsNum ;
- }
- /* 用于初始化延時事件
- 0 - 本事件總數
- 1-寫入位置
- 2- 3 延時時間
- */
- void esmTimeInit(u8 *inBuf,u8(*fun)(void))
- {
- u8 totaol ,i ,add;
- totaol = inBuf[0];
- add = inBuf[1];
- u16 time = inBuf[2]<<8|inBuf[3];
- for(i =0 ; i != totaol ; i++)
- {
- if(esmSta[add].dat[i].fun != NULL)
- {
- esmSta[add].dat[i].fun = fun ;
- esmSta[add].dat[i].time = time ;
- esmSta[add].totalNum++;
- }
- }
- }
- /* 事件結構體初始化
- 0 - 本事件總量
- 1- 寫入地址
- */
- void esmEventInit(u8 *inBuf ,u8 (*fun)(void))
- {
- u8 totaol ,i ,add;
- totaol = inBuf[0];
- add = inBuf[1];
- for(i =0 ; i != totaol ; i++)
- {
- if(esmSta[add].dat[i].fun != NULL)
- {
- esmSta[add].dat[i].fun = fun ;
- esmSta[add].dat[i].time = 0xffff ;
- esmSta[add].totalNum++;
- }
- }
- }
- /* 事件狀態機時間鉤子函數
- */
- void esmTimeHookFun(void)
- {
- esmSysTime++;
- }
- void esmTimeCheck(u8 i ,u8 step)
- {
- if( esmSysTime - esmSta[i].dat[step].recordTime >= esmSta[i].dat[step].time)
- {
- esmSta[i].dat[step].fun();
- esmSta[i].nextStepId++; /* 時間順序結構體要求step by step */
- esmSta[i].dat[step].recordTime = 0;
- }
- }
- void esmEventCheck(u8 i ,u8 step)
- {
- u8 next ;
- next =esmSta[i].dat[step].fun();
- if(next != esmWaiteStell)
- {
- esmSta[i].nextStepId = next ;
- }
- }
- void esmEventRunSta(void)
- {
- u8 i ;
- u8 step ;
- for(i = 0 ; i!= emsNum ; i++)
- {
- step = esmSta[i].nextStepId ;
- if(esmSta[i].dat[step].time != 0xffff)
- {
- //啟動延時數秒
- if(esmSta[i].dat[step].recordTime == 0)
- {
- esmSta[i].dat[step].recordTime = esmSysTime ;
- }
- else
- {
- esmTimeCheck(i, step);
- }
- }
- else
- {
- //事件參考執行
- esmEventCheck(i, step);
- }
- //恢復開始從新執行
- if(esmSta[i].totalNum == step)
- {
- esmSta[i].nextStepId = 0;
- }
- }
- }
- //測試驗證
- u8 esmTestFun1(void)
- {
- static u8 ii;
- ii = esmSysTime ;
- return 0;
- }
- u8 esmTestFun2(void)
- {
- if(esmSysTime == 10)
- {
- return esmStepPlus ;
- }
- else
- {
- return esmWaiteStell ;
- }
- }
- //測試驗證
- u8 esmTestFun3(void)
- {
- static u8 iii;
- iii = esmSysTime ;
- return 0;
- }
- /* 初始化順序就是執行的順序 */
- void esmTest(void)
- {
- u8 inBuf[5];
- inBuf[0] = eventNum ;
- inBuf[1] = esmStructInit(eventDisc);
- inBuf[2] = 0x00 ;
- inBuf[3] = 8;
- esmTimeInit( inBuf, &esmTestFun1);
- esmEventInit( inBuf, &esmTestFun2);
- esmTimeInit( inBuf, &esmTestFun3);
- while(1)
- {
- esmEventRunSta();
- esmTimeHookFun();
- }
- }
- #ifndef __eventStateMachine_H
- #define __eventStateMachine_H
- #include "stm32f10x.h"
- /* Scheduler includes. */
- #include "FreeRTOS.h"
- #include "task.h"
- #include"pBase.h"
- #define emsNum 3 /* 申請多個事件狀態機 */
- #define eventNum 4
- typedef struct
- {
- u8 id ;
- u8 (*fun)(void);
- u16 time; /* 延時時間 */
- u16 recordTime ;
- }event_disc;
- typedef struct
- {
- u8 stepId ;
- u8 nextStepId ;
- u8 usedFlag :1; /* 使用標記 */
- u8 totalNum ;
- event_disc *dat;
- }esm_sta;
- #define esmWaiteStell 0xff /* 繼續等待 */
- #define esmStepPlus 0xfe /* 下一步操作 */
- void esmTest(void);
- #endif
復制代碼
|