新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II的內核結構

        μC/OS-II的內核結構

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

        盡的解釋。

        OSSched()的所有代碼都屬臨界段代碼。在尋找進入就緒態的優先級最高的任務過程

        中,為防止中斷服務子程序把一個或幾個任務的就緒位置位,中斷是被關掉的。為縮短切

        換時間,OSSched()全部代碼都可以用匯編語言寫。為增加可讀性,可移植性和將匯編語言

        代碼最少化,OSSched()是用C寫的。

        3.6 給調度器上鎖和開鎖(LockingandUnLockingtheScheduler)

        給調度器上鎖函數OSSchedlock()(程序清單L3.9)用于禁止任務調度,直到任務完

        成后調用給調度器開鎖函數OSSchedUnlock()為止,(程序清單L3.10)。調用

        OSSchedlock()的任務保持對CPU的控制權,盡管有個優先級更高的任務進入了就緒態。然

        而,此時中斷是可以被識別的,中斷服務也能得到(假設中斷是開著的)。OSSchedlock()

        和OSSchedUnlock()必須成對使用。變量OSLockNesting跟蹤OSSchedLock()函數被調用的

        次數,以允許嵌套的函數包含臨界段代碼,這段代碼其它任務不得干預。μC/OS-Ⅱ允許嵌

        套深度達255層。當OSLockNesting等于零時,調度重新得到允許。函數OSSchedLock()和

        OSSchedUnlock()的使用要非常謹慎,因為它們影響μC/OS-Ⅱ對任務的正常管理。

        當OSLockNesting減到零的時候,OSSchedUnlock()調用OSSched[L3.10(2)]。

        OSSchedUnlock()是被某任務調用的,在調度器上鎖的期間,可能有什么事件發生了并使一

        個更高優先級的任務進入就緒態。

        調用OSSchedLock()以后,用戶的應用程序不得使用任何能將現行任務掛起的系統調用。也就是說,用戶程序不得調用OSMboxPend()、OSQPend()、OSSemPend()、OSTaskSuspend

        (OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMSM(),直到OSLockNesting回零為止。因為調度器上了鎖,用戶就鎖住了系統,任何其它任務都不能運行。

        當低優先級的任務要發消息給多任務的郵箱、消息隊列、信號量時(見第6章任務間通訊和同步),用戶不希望高優先級的任務在郵箱、隊列和信號量沒有得到消息之前就取得了CPU的控制權,此時,用戶可以使用禁止調度器函數。

        程序清單 L3.9 給調度器上鎖

        voidOSSchedLock(void)

        {

        if(OSRunning==TRUE){

        OS_ENTER_CRITICAL();

        OSLockNesting++;

        OS_EXIT_CRITICAL();

        }

        }

        程序清單L3.10給調度器開鎖.

        voidOSSchedUnlock(void)

        {

        if(OSRunning==TRUE){

        OS_ENTER_CRITICAL();

        if(OSLockNesting>0){

        OSLockNesting--;

        if((OSLockNesting|OSIntNesting)==0){(1)

        OS_EXIT_CRITICAL();

        OSSched();(2)

        }else{

        OS_EXIT_CRITICAL();

        }

        }else{

        OS_EXIT_CRITICAL();

        }

        }

        }

        3.7 空閑任務(IdleTask)

        μC/OS-Ⅱ總是建立一個空閑任務,這個任務在沒有其它任務進入就緒態時投入運行。這個空閑任務[OSTaskIdle()]永遠設為最低優先級,即OS_LOWEST_PRI0。空閑任務OSTaskIdle()什么也不做,只是在不停地給一個32位的名叫OSIdleCtr的計數器加1,統計任務(見3.08節,統計任務)使用這個計數器以確定現行應用軟件實際消耗的CPU時間。程序清單L3.11是空閑任務的代碼。在計數器加1前后,中斷是先關掉再開啟的,因為8位以及大多數16位微處理器的32位加1需要多條指令,要防止高優先級的任務或中斷服務子程序從中打入。空閑任務不可能被應用軟件刪除。

        程序清單L3.11μC/OS-Ⅱ的空閑任務.

        voidOSTaskIdle(void*pdata)

        {

        pdata=pdata;

        for(;;){

        OS_ENTER_CRITICAL();

        OSIdleCtr++;

        OS_EXIT_CRITICAL();

        }

        }

        3.8 統計任務

        μC/OS-Ⅱ有一個提供運行時間統計的任務。這個任務叫做OSTaskStat(),如果用戶將系統定義常數OS_TASK_STAT_EN(見文件OS_CFG.H)設為1,這個任務就會建立。一旦得到了允許,OSTaskStat()每秒鐘運行一次(見文件OS_CORE.C),計算當前的CPU利用率。換句話說,OSTaskStat()告訴用戶應用程序使用了多少CPU時間,用百分比表示,這個值放在一個有符號8位整數OSCPUsage中,精讀度是1個百分點。

        如果用戶應用程序打算使用統計任務,用戶必須在初始化時建立一個唯一的任務,在這個任務中調用OSStatInit()(見文件OS_CORE.C)。換句話說,在調用系統啟動函數OSStart()之前,用戶初始代碼必須先建立一個任務,在這個任務中調用系統統計初始化函數OSStatInit(),然后再建立應用程序中的其它任務。程序清單L3.12是統計任務的示意性代碼。

        程序清單L3.12初始化統計任務.

        voidmain(void)

        {

        OSInit();/* 初始化uC/OS-II(1)*/

        /* 安裝uC/OS-II的任務切換向量 */

        /* 創建用戶起始任務(為了方便討論,這里以TaskStart()作為起始任務)(2)*/

        OSStart();/* 開始多任務調度 (3)*/

        }

        voidTaskStart(void*pdata)

        {

        /* 安裝并啟動uC/OS-II的時鐘節拍 (4)*/

        OSStatInit();/* 初始化統計任務 (5)*/

        /* 創建用戶應用程序任務 */

        for(;;){

        /* 這里是TaskStart()的代碼!*/

        }

        }

        因為用戶的應用程序必須先建立一個起始任務[TaskStart()],當主程序main()調用系統啟動函數OSStcnt()的時候,μC/OS-Ⅱ只有3個要管理的任務:TaskStart()、OSTaskIdle()和OSTaskStat()。請注意,任務TaskStart()的名稱是無所謂的,叫什么名字都可以。因為μC/OS-Ⅱ已經將空閑任務的優先級設為最低,即OS_LOWEST_PR10,統計任務的優先級設為次低,OS_LOWEST_PR10-1。啟動任務TaskStart()總是優先級最高的任務。

        圖F3.4解釋初始化統計任務時的流程。用戶必須首先調用的是μC/OS-Ⅱ中的系統初始化函數OSInit(),該函數初始化μC/OS-Ⅱ[圖F3.4(2)]。有的處理器(例如Motorola的MC68HC11),不需要“設置”中斷向量,中斷向量已經在ROM中有了。用戶必須調用OSTaskCreat()或者OSTaskCreatExt()以建立TaskStart()[圖F3.4(3)]。進入多任務的條件準備好了以后,調用系統啟動函數OSStart()。這個函數將使 TaskStart()開始執行,因為TaskStart()是優先級最高的任務[圖F3.4(4)]]。



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 车致| 广灵县| 百色市| 永州市| 江北区| 建水县| 临清市| 绥中县| 淅川县| 巴塘县| 江北区| 吉首市| 樟树市| 同德县| 大余县| 巴塘县| 宜阳县| 莱芜市| 怀仁县| 买车| 达州市| 邹城市| 宣化县| 石渠县| 咸宁市| 竹北市| 类乌齐县| 太和县| 观塘区| 永嘉县| 大埔县| 宁晋县| 抚远县| 博爱县| 岚皋县| 玉溪市| 富蕴县| 城步| 左云县| 临海市| 黄浦区|