新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II的任務管理

        μC/OS-II的任務管理

        作者: 時間:2016-10-08 來源:網絡 收藏

        INT16Ui;

        OS_STK*pfill;

        if(prio>OS_LOWEST_PRIO){(1)

        return(OS_PRIO_INVALID);

        }

        OS_ENTER_CRITICAL();

        if(OSTCBPrioTbl[prio]==(OS_TCB*)0){(2)

        OSTCBPrioTbl[prio]=(OS_TCB*)1;(3)

        OS_EXIT_CRITICAL();(4)

        if(optOS_TASK_OPT_STK_CHK){(5)

        if(optOS_TASK_OPT_STK_CLR){

        Pfill=pbos;

        for(i=0;i

        #ifOS_STK_GROWTH==1

        *pfill++=(OS_STK)0;

        #else

        *pfill--=(OS_STK)0;

        #endif

        }

        }

        }

        psp=(void*)OSTaskStkInit(task,pdata,ptos,opt);(6)

        err=OSTCBInit(prio,psp,pbos,id,stk_size,pext,opt);(7)

        if(err==OS_NO_ERR){(8)

        OS_ENTER_CRITICAL;

        OSTaskCtr++;(9)

        OSTaskCreateHook(OSTCBPrioTbl[prio]);(10)

        OS_EXIT_CRITICAL();

        if(OSRunning){(11)

        OSSched();(12)

        }

        }else{

        OS_ENTER_CRITICAL();

        OSTCBPrioTbl[prio]=(OS_TCB*)0;(13)

        OS_EXIT_CRITICAL();

        }

        return(err);

        }else{

        OS_EXIT_CRITICAL();

        return(OS_PRIO_EXIST);

        }

        }

        OSTaskCreateExt()一開始先檢測分配給任務的優先級是否有效[L4.3(1)]。 任務的優先級必須在0到OS_LOWEST_PRIO之間。接著,OSTaskCreateExt()要確保在規定的優先級上還沒有建立任務[L4.3(2)]。在使用μC/OS-Ⅱ時,每個任務都有特定的優先級。如果某個優先級是空閑的,μC/OS-Ⅱ通過放置一個非空指針在OSTCBPrioTbl[]中來保留該優先級[L4.3(3)]。這就使得OSTaskCreateExt()在設置任務數據結構的其他部分時能重新允許中斷[L4.3(4)]。

        為了對任務的堆棧進行檢驗[參看4.03,堆棧檢驗,OSTaskStkChk()],用戶必須在opt參數中設置OS_TASK_OPT_STK_CHK標志。 堆棧檢驗還要求在任務建立時堆棧的存儲內容都是0(即堆棧已被清零)。為了在任務建立的時候將堆棧清零,需要在opt參數中設置OS_TASK_OPT_STK_CLR。當以上兩個標志都被設置好后,OSTaskCreateExt()才能將堆棧清零[L4.3(5)]。

        接著,OSTaskCreateExt()調用OSTaskStkInit()[L4.3(6)],它負責建立任務的堆棧。該函數是與處理器的硬件體系相關的函數,可以在OS_CPU_C.C文件中找到。有關實現OSTaskStkInit()的細節可參看第八章——移植μC/OS-Ⅱ。如果已經有人在你用的處理器上成功地移植了μC/OS-Ⅱ,而你又得到了他的代碼,就不必考慮該函數的實現細節了。

        OSTaskStkInit()函數返回新的堆棧棧頂(psp),并被保存在任務的0S_TCB中。

        μC/OS-Ⅱ支持的處理器的堆棧既可以從上(高地址)往下(低地址)遞減也可以從下往上遞增(參看4.02,任務堆棧)。用戶在調用OSTaskCreateExt()的時候必須知道堆棧是遞增的還是遞減的(參看用戶所用處理器的OS_CPU.H中的OS_STACK_GROWTH),因為用戶必須得把堆棧的棧頂傳遞給OSTaskCreateExt(),而棧頂可能是堆棧的最低地址(當OS_STK_GROWTH

        為0時),也可能是最高地址(當OS_STK_GROWTH為1時)。

        一旦OSTaskStkInit()函數完成了建立堆棧的任務,OSTaskCreateExt()就調用

        OSTCBInit()[L4.3(7)], 從空閑的OS_TCB緩沖池中獲得并初始化一個OS_TCB。 OSTCBInit()

        的代碼在OSTaskCreate()中曾描述過(參看4.00節),從OSTCBInit()返回后,

        OSTaskCreateExt()要檢驗返回代碼[L4.3(8)],如果成功,就增加OSTaskCtr[L4.3(9)],

        OSTaskCtr用于保存產生的任務數目。 如果OSTCBInit()返回失敗, 就置OSTCBPrioTbl[prio]

        的入口為0[L4.3(13)]以放棄對該任務優先級的占用。然后,OSTaskCreateExt()調用

        OSTaskCreateHook()[L4.3(10)],OSTaskCreateHook()是用戶自己定義的函數,用來擴展

        OSTaskCreateExt()的功能。OSTaskCreateHook()可以在OS_CPU_C.C中定義(如果

        OS_CPU_HOOKS_EN置1),也可以在其它地方定義(如果OS_CPU_HOOKS_EN置0)。注意,

        OSTaskCreateExt()在調用OSTaskCreateHook()時,中斷是關掉的,所以用戶應該使

        OSTaskCreateHook()函數中的代碼盡量簡化,因為這將直接影響中斷的響應時間。

        OSTaskCreateHook()被調用時會收到指向任務被建立時的OS_TCB的指針。這意味著該函數可以訪問OS_TCB數據結構中的所有成員。

        如果OSTaskCreateExt()函數是在某個任務的執行過程中被調用的(即OSRunning置為

        True[L4.3(11)]),以任務調度函數會被調用[L4.3(12)]來判斷是否新建立的任務比原來的任務有更高的優先級。如果新任務的優先級更高,內核會進行一次從舊任務到新任務的任務切換。如果在多任務調度開始之前(即用戶還沒有調用OSStart()),新任務就已經建立了,則任務調度函數不會被調用。

        4.2任務堆棧

        每個任務都有自己的堆棧空間。堆棧必須聲明為OS_STK類型,并且由連續的內存空間組成。用戶可以靜態分配堆棧空間(在編譯的時候分配)也可以動態地分配堆棧空間(在運行的時候分配)。靜態堆棧聲明如程序清單L4.4和4.5所示,這兩種聲明應放置在函數的外面。

        程序清單 L4.4 靜態堆棧

        staticOS_STKMyTaskStack[stack_size];

        程序清單 L4.5 靜態堆棧

        OS_STKMyTaskStack[stack_size];

        用戶可以用C編譯器提供的malloc()函數來動態地分配堆棧空間,如程序清單L4.6所示。在動態分配中,用戶要時刻注意內存碎片問題。特別是當用戶反復地建立和刪除任務時,內存堆中可能會出現大量的內存碎片,導致沒有足夠大的一塊連續內存區域可用作任務堆棧,這時malloc()便無法成功地為任務分配堆棧空間。

        程序清單 LL4.6 用malloc()為任務分配堆棧空間

        OS_STK*pstk;

        pstk=(OS_STK*)malloc(stack_size);

        if(pstk!=(OS_STK*)0){/* 確認malloc()能得到足夠地內存空間 */

        Createthetask;

        }

        圖4.1表示了一塊能被malloc()動態分配的3K字節的內存堆[F4.1(1)]。為了討論問題方便,假定用戶要建立三個任務(任務A,B和C),每個任務需要1K字節的空間。設第一個1K字節給任務A,第二個1K字節給任務B,第三個1K字節給任務C[F4.1(2)]。然后,用戶的應用程序刪除任務A和任務C,用free()函數釋放內存到內存堆中[F4.1(3)]。現在,用戶的內存堆雖有2K字節的自由內存空間,但它是不連續的,所以用戶不能建立另一個需要2K字節內存的任務(即任務D)。如果用戶并不會去刪除任務,使用malloc()是非常可行的。



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 南丹县| 淮南市| 平顺县| 沅江市| 无极县| 呼伦贝尔市| 牟定县| 东兴市| 永修县| 肥乡县| 鸡泽县| 富源县| 临海市| 江孜县| 韶山市| 视频| 辽源市| 福贡县| 浮山县| 香河县| 密山市| 永丰县| 泌阳县| 邮箱| 瑞金市| 海盐县| 灵宝市| 安阳市| 湖口县| 灯塔市| 彰武县| 任丘市| 高雄市| 财经| 麻江县| 许昌县| 晋州市| 西华县| 沙湾县| 衡阳县| 东乡族自治县|