新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 在MC68HC908GP32上移植μC/OS-II

        在MC68HC908GP32上移植μC/OS-II

        作者: 時間:2016-09-12 來源:網絡 收藏

        4.OS_CPU08.C文件

        本文引用地址:http://www.104case.com/article/201609/305220.htm

        μC/OS-II的移植需要用戶在OS_CPU08.C中定義6個函數:

        OSTaskStkInit()

        OSTaskCreateHook()

        OSTaskDelHook()

        OSTaskSwHook()

        OSTaskStatHook()

        OSTimeTickHook()

        實際需要定義的只有OSTaskStkInit()函數,其他5個函數需要聲明,但不一定有實際內容。這5個函數都是用戶定義,所以OS_CPU08.C中只有定義,沒有給出代碼。如果用戶需要使用這些函數,請將文件OS_CFG.H中的#define constant OS_CPU_HOOKS_EN設為1,設為0表示不使用這些函數。

        OSTaskStkInit()函數由任務創建函數 OSTaskCreate()或OSTaskCreateExt()調用,用來初始化任務的堆棧。初始狀態的堆棧模擬發生一次中斷后的堆棧結構,按照中斷后的進棧次序預留各個寄存器存儲空間;而中斷返回地址指向任務代碼的起始地址。當調用OSTaskCreate()或OSTaskCreateExt()創建一個新任務時,需要傳遞的參數是:任務代碼的起始地址、參數指針(pdata)、任務堆棧頂端的地址、任務的優先級。 OSTaskCreateExt()還需要一些其他參數,但與OSTaskStkinit()沒有關系。OSTaskStkInit()只需要以上提到的 3個參數(task、pdata和ptos)。堆棧初始化工作結束后,OSTaskStkInit()返回新的堆棧棧頂指針,OSTaskCreate()OSTaskCreateExt()將指針保存在任務的OS_TCB中。

        Void*OSTaskStklint(void(*task)(void*pd),void*pdata,void*ptos,INT16U opt)

        {

        INT16U *stk;

        stk=(INT16U*)ptos; /*保存堆棧指針*/

        *--stk=(INT16U)(task); /保存程序計數器內容*/

        *--stk=(INT16U)(0x00); /初始化X和A寄存器內容*/

        --stk=(INT16U)(0x00); /*初始化CCR和H寄存器*/

        return((void*)stk);

        }

        其余的幾個函數:OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskStatHook和OSTimeTickHook()均由用戶自定義。

        四、制作用戶自己的項目

        在為內核編寫了上述與硬件相關的代碼以后,用戶就可以為自己的項目編寫實際的代碼了。在本例中,用戶任務共有兩個。任務1在初始化時鐘中斷以后,就進入了一人死循環。在這個循環里,任務1一方面以1s(秒)為周期改變并行I/O口 PORTA第0個引腳的輸出電壓,另一方面每隔4s便向任務2發送1個信號。而任務2則始終等待任務1發來的信號,一旦收到信號,便改變并行I/O口 PORTA第1個引腳的輸出電壓。具體的代碼如下:

        /*****************************************

        * EXE2.C

        *******************************************/

        #include

        #include includes.h

        Byte PORTA @0x0000; /*并口A地址$0000*/

        Byte DDRA @0x0004; /*并口A方向寄存器地址$0004*/

        Byte T1SC @0x0020; /*定時器控制寄存器地址$0020*/

        Byte T1MODH@0x0023; /*定時器模式寄存器地址$0023*/

        OS_EVENT *Semaphore;

        #define TASK_STK_SIZE 64 /*任務堆棧大小64字節*/

        INT8U Task1Stk[TASK_STK_SIZE]; /*定義任務1堆棧*/

        INT8U Task2Stk[TASK_STK_SIZE]; /*定義任務2堆棧*/

        Void Hardwareinit(void);

        Void Task1(void*pdata)

        {int count=0;

        /*int count=0;

        /*初始化定時器*/

        asm{

        LDA #0x50

        STA T1SC

        LDHX #0x0333 //設定定時器間隔100ms

        STHX T1MODH

        CLI

        }

        for(;;){

        PORTA=0xFE;

        OSTimeDly(5); /*延時0.5s*/

        PORTA|=0x01;

        /*延時0.5s*/

        DSTimeDly(5);

        Count++;

        If(count= =4){

        OSSemPost(Semaphore);

        Count=0;

        }

        }}

        void Task2(void *pdata)

        {

        Byte err;

        For(;;){

        OSSemPend(Semaphore,0,err);

        PORTA=0xFD:

        OSSemPend(Semaphore,0,err);

        PORTA|=0x02;

        }

        }

        void main(void){

        Hardwarelnit(); /*完成硬件的初始化工作*/

        Oslint(); /*初始化多任務環境*/

        Semaphore=OSSemCreate(0);

        OSTaskCreate(Task1,(void*)0,(void*)Task1Stk

        [TASK_STK_SIZE],10);

        OSTaskCreate(Task2,void*)0,(void*)Task2Stk

        [TASK_STK_SIZE],9);

        OSStart();

        }

        在主程序main()中,用戶必須先調用OSInit(),然后創建各個任務和信號量等,最后調用OSStart(),以啟動內核運行,開始正常的任務調度。

        本例中盡量減小了對RAM的需求:假如中斷嵌套層數不超過三層,所需事件只有一個,即只需要一個事件控制塊;應用中對μC/OS-II提供的功能進行最大限度的裁剪,能不用的盡量不用。采用了上述措施后,μC/OS-II的RAM使用情況大致如下:μC/OC-II所使用的全局變量占用22字節,事件控制塊占用12字節。此外,當系統初始化時,還需要最小30字節的系統堆棧用于初始化TCB,并傳遞參數。以上為μC/OS-II中系統所必需的RAM,計64字節。

        假設給每個任務分配64個字節的堆棧空間,其中用于任務控制塊17字節,允許三層中斷嵌套要用18字節,任務切換時的棧結構要用8字節。由于程序是用C語言編寫的,確切的子函數嵌套調用層數是不知道的。如果不使用本身需要緩沖區的C 語言函數,如printf()等,任務中程序調用所產生的嵌套層數不超過10層,則64字節中還能分析給任務局部變量的空間只剩下1字節了。這是能分配任務的最小RAM空間了。

        綜上所述,GP32的512字節RAM可分為8個64字節的RAM塊。如果運行 4個任務,能留給應用程序的RAM也只剩下128字節了。如果在GP32上運行μC/OS-II,且不多于8個任務,則任務調度表可以再簡化,不需要調度 64個任務,只調度8個任務就可以了。


        上一頁 1 2 3 下一頁

        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 玉龙| 黄山市| 鄱阳县| 牡丹江市| 郴州市| 宜良县| 土默特右旗| 伊宁县| 黑山县| 大兴区| 耒阳市| 丹东市| 息烽县| 南靖县| 横山县| 蓝山县| 读书| 安顺市| 潞西市| 桃园市| 铁岭市| 兴业县| 高清| 丹东市| 乐清市| 孝昌县| 揭西县| 思南县| 都匀市| 都江堰市| 元朗区| 迭部县| 太保市| 陆良县| 天长市| 凤山市| 阳江市| 多伦县| 习水县| 交口县| 尖扎县|