1. 程式人生 > >嵌入式應用程式碼框架(C 語言訊號量 或狀態機)ZosPost

嵌入式應用程式碼框架(C 語言訊號量 或狀態機)ZosPost

應用場景:

               在嵌入式工作中 ,大的專案通常是多人配合完成。每個人程式碼風格,命名習慣,工作思路 都可能不一樣。那程式碼在整個合過程中或後期維護都 是一件很頭痛的事情為此我整理了這個開源庫,希望能對有這方面困擾的朋友有一定幫助。

 在專案開發過程中,經常遇到以下情況:

 1、某個方法在操作某個硬體時,需要等待一段時間硬體才響應。

 2、某個方法在操作某個硬體時,不知道硬體什麼時候才響應。

 3、在專案整合過程中,發現同事某些無用功能功,因為不瞭解同事程式碼邏輯和風格無法去除。

 4、得到同事一大堆結口函式,使用時無從下手。

為解決這些問題下面就來看一下我認為可行的辦法:

先來看一段程式碼:

 ButtonClass_t *ButtonThis=NULL;

 ButtonThis=CreateButtonClassMallocNew();  ButtonThis->ButtonDownEvent=ButtonDownEvent;//按下事件回撥  ButtonThis->ButtonUpEvent=ButtonUpEvent;    //擡起事件回撥  ButtonThis->ButtonGet=ButtonGet;            //輸入模擬讀取  ButtonThis->ButtonSetMode(ButtonThis,TriggerChickOne_e);//按下一次觸發一次

用高階語言的人一個 這個是不是很面熟。沒錯 這特別像C++中的類,但是這個並不是類,而是C的結構體封裝。很多人會覺得奇怪,為什麼用C這樣子來寫程式碼,你不如直接用C++好了,C和C++這個問題我這裡不作討論。

這樣子使用有什麼好處能解決什麼問題:

      這樣子書寫,可以很好的解決程式碼整合過程中新功能的增加和刪除。

      為什麼這麼說呢:1、刪除無用功能(假如整合過程中ButtonThis 這個按鈕沒有作用,只需要將ButtonThis出現過的地方刪除                                           即可,無需關心其它程式碼邏輯)

                                   2、增加功能(如果專案中要用到按鈕這個功能 ,只需要建立一個按鈕指標並給他對應的回撥即可)

                                   3、這樣子書寫 留給使用者的所有介面全在這一個ButtonThis結構體指標裡,不用整個工程尋找各個介面。

至此3和4 問題基本得到解決。

接下來我們解決1和2這就要用到我標題提到的ZosPost了 :

同樣先來看一段程式碼

void *ZosThis=NULL;

ButtonClass_t *ButtonThis=NULL;

//按鍵掃描模擬 int  ButtonActionTask(int arg,char *argv[]) {     ButtonClass_t *Button=(    ButtonClass_t *)GetUserThis(argv);     TaskStart(GetSystem(argv));     while(1)     {      Button->Loop(Button);      ZosPostDelayedAction(GetThis(argv),10,ButtonActionTask,GetUserThis(argv));      TaskSleep(GetSystem(argv));     }     TaskStop(System);

}

//延時模擬 unsigned int i=1; int  ActionTask(int arg,char *argv[]) {

    void *Argc=(ZosPostClass_t*)argv[0];     ZosPostDelayedAction_t *System=(ZosPostDelayedAction_t*)argv[1];

    TaskStart(System);

    while(1)     {     if(i==0)i=1;     i=i*2;     ZosPostSetInterruptSignalAction(Argc,TASK_DEMO_E,GetSystem(argv)->Action,GetUserThis(argv));//放下一個斷訊號     ZosPostDelayedAction(Argc,i,GetSystem(argv)->Action,GetUserThis(argv));                     //啟動一個延時訊號     TaskSleep(System);                                                                          //放下一個斷點暫時退出本函式     printf("1hello:%d\r\n",i);

    i=i*2;     ZosPostSetInterruptSignalAction(Argc,TASK_DEMO_E,GetSystem(argv)->Action,GetUserThis(argv));     ZosPostDelayedAction(Argc,i,GetSystem(argv)->Action,GetUserThis(argv));     TaskSleep(System);     printf("2hello:%d\r\n",i);

    i=i*2;     ZosPostSetInterruptSignalAction(Argc,TASK_DEMO_E,GetSystem(argv)->Action,GetUserThis(argv));     ZosPostDelayedAction(Argc,i,GetSystem(argv)->Action,GetUserThis(argv));     TaskSleep(System);

    //i=i*2;     //ZosPostDelayedAction(Argc,i,Action,NULL); //讓系統鎖定在這裡執行     //TaskEnd();     }     TaskStop(System);

}

int main() {      printf("   純C演示 模擬執行緒   \r\n");      ButtonThis=CreateButtonClassMallocNew();      ButtonThis->ButtonDownEvent=ButtonDownEvent;//按下事件回撥      ButtonThis->ButtonUpEvent=ButtonUpEvent;    //擡起事件回撥      ButtonThis->ButtonGet=ButtonGet;            //輸入模擬讀取      ButtonThis->ButtonSetMode(ButtonThis,TriggerChickOne_e);      ZosThis=CreateZosPostDelayedActionClassMalloc(200); // 可能 以使用動態記憶體分配     // ZosThis=CreateZosPostDelayedActionClassUser(ZosThis,uZosBuff,10); //可以手動指定最大協同數量      ZosPostDelayedAction(ZosThis,1,ActionTask,NULL);      ZosPostDelayedAction(ZosThis,10,ButtonActionTask,ButtonThis);//模擬檢測按鍵

    // ZosPostSetPriorityEvel(ZosThis,ActionTask,66536);//放慢執行ActtionTask們(可以理解為優先順序)      while(1)      {      ZosPostDelayedActionLoop(ZosThis);      ZosPostDelayedActionClock(ZosThis);      }

}

看到這麼多程式碼 是否有點蒙了 ,但仔細看 你會發現這玩意是否特別像作業系統中的執行緒?

比如: ButtonActionTask這個函式還特別奇怪裡面居然有一個while(1)  這不是死迴圈了麼??呵呵 這個問題以後解釋

先說上面這段程式碼是怎麼解決 前面提到的1 和2 的問題的。

前面說到這玩意像一個執行緒,沒錯 甚至可以理解為它就是一個執行緒(其實不是執行緒只是寫法不一樣而已)上面這段程式碼實現了 在檢測按鍵(ButtonActionTask)的同時也執行了ActionTask中的邏輯處理,在ActionTask 中我們用到了 延時等待 和訊號等待完美解決了

 1、某個方法在操作某個硬體時,需要等待一段時間硬體才響應。

 2、某個方法在操作某個硬體時,不知道硬體什麼時候才響應。

這2個問題。驗證程式碼稍後我會放入我的GITBUB 希望能對相關人員有所幫助