uC/OS-II的特殊任務包括空閑任務和統計任務,又稱操作系統的系統任務。雖然統計任務不是必需的,但是卻二十默認的系統任務。這兩個任務在操作系統初始化時被創建,在多任務啟動后被執行。那么,這兩個任務都具有什么功能,又使用了哪些重要的數據結構呢?
空閑任務OS_TaskIdle是uC/OS-II的系統任務因為它占據了最低優先級63,所以只有在其他的任務都因為等待事件的發生而被阻塞的時候才能得到運行。
空閑任務的代碼在os_core.c內核中,代碼如下所示:
50.png (13.86 KB, 下載次數: 109)
下載附件
2013-7-26 02:03 上傳
由空閑任務的代碼可知,空閑任務除了不停地將空閑計數器OSIdleCtr的值加1之外,幾乎什么都不做。當沒有任何其他任務能夠運行的時候,操作系統就會執行這段代碼。而OSTaskIdleHook默認情況下也只是一個空函數,如沒有特殊需要我們不需要去填寫它,該函數的另一個作用就是占據一點時間,給系統足夠的時間響應中斷。
統計任務OS_TaskStat是uC/OS-II的另一個重要的系統任務,我們可以通過宏設置取消統計任務,但一般情況下不這么做,因為統計任務執行的統計工作時比較重要的。統計任務的主要功能是計算CPU的利用率。如果沒有統計任務,就不知道多任務環境下系統的運行情況是否良好。
CPU的利用率使用全局變量OSCPUUsage表示,這里涉及的幾個全局變量如下所示:
51.png (9.05 KB, 下載次數: 100)
下載附件
2013-7-26 02:03 上傳
分析一下統計任務的代碼。首先是統計任務的初始化,該初始化任務的主要目的是獲得系統空閑計數的最大值,代碼如下所示:
52.png (35.04 KB, 下載次數: 91)
下載附件
2013-7-26 02:03 上傳
該統計任務初始化函數在用戶任務中被調用,這個函數在移植過程中被App_TaskStart調用,App_TaskStart的優先級設置為1。代碼如下所示:
53.png (17.04 KB, 下載次數: 96)
下載附件
2013-7-26 02:03 上傳
這時系統沒有運行其他的任務。系統任務初始化函數首先將自己阻塞兩個時鐘周期,在系統時鐘中斷2次后,由調度器進行任務調度而恢復運行,目的是與時鐘同步。接著,統計任務初始化函數清空空閑計數器OSIdleCtr,訪問全局變量OSIdleCtr必須關中斷,訪問完后再開中斷。接下來調用OSTimeDly(OS_TICKS_PER_SEC/10u)又把自己阻塞100ms,100ms后才恢復運行。在這100ms之內,運行的任務只有空閑任務。空閑任務會拼命將空閑計數器OSIdleCtr的值往上加,加到多大就要看CPU的速度。延時結束后,用OSIdleCtrMax接納OSIdleCtr的值,因此OSIdleCtrMax表示空閑狀態100ms內OSIdleCtr的計數值,稱為空閑計數最大值。那么,在系統運行了其他用戶任務的情況下,每100ms內OSIdleCtr的計數值肯定小于這個數值的。獲得了這個數值,統計任務就有了統計的基礎了,因此統計任務就準備好了,可以設置OSStatRdy的值為真。
54.png (41.75 KB, 下載次數: 102)
下載附件
2013-7-26 02:03 上傳
統計任務優先級僅僅比空閑任務高,空閑任務的優先級是63,統計任務的優先級是62,這個數值越小優先級越高。因此,統計任務優先于空閑任務運行。在操作系統初始化過程中,初始化OSStatRdy為假,并創建了統計任務和空閑任務。初始化后又創建了一個名為App_TaskStart的優先級為1的任務。在多任務啟動后,如果沒有其他的任務就緒,那么首先要運行App_TaskStart,App_TaskStart中運行OSStatInit。在OSStatInit沒有結束前,由于OSStatRdy的值一直是假,所以
55.png (4.86 KB, 下載次數: 113)
下載附件
2013-7-26 02:03 上傳
此處的循環不能結束,統計任務OS_TaskStat就把自己延時,等待,把CPU留給空閑任務用于做空閑計數。
OSStatInit結束時,100ms過后,OSStatRdy為真,統計任務OS_TaskStat經過200ms的延時時間后被喚醒,發現OSStatRdy為真就離開循環,為方便以后的計算,將空閑計數的最大值OSIdleCrMax除以100,商仍放在OSIdleCtrMax中。如果這時OSIdleCtrMax的值是0,說明空閑計數的值太少了(不到100),系統狀況很差,統計任務干脆講自己掛起來不再進行統計。
如果一切正常,那么統計任務進入死循環進行統計工作。首先將100ms內空閑計數值OSIdleCtr存到OSIdleCtrRun中,然后將OSIdleCtr清0以初始化下一個100ms的計數,然后進行CPU利用率的計算,公式為:OSCPUUsage = 100uL - OSIdleCtrRun/OSIdleCtrMax 。
因為OSIdleCtrMax的值是在前面除過100的,因此還原為:
OSCPUUsage = 100*(1-OSIdleCtrRun/OSIdleCtrMax)
OSIdleCtrRun是100ms內空閑任務對OSIdleCtr的計數值,OSIdleCtrMax是系統空閑的時候最大的計數值。OSIdleCtrRun/OSIdleCtrMax就是系統的空閑度了,但系統完全空閑的時候這個值就是1,而當系統繁忙的時候空閑任務可能得不到運行,這個值就是0。OSCPUUsage反映了系統的繁忙程度,也就是CPU的利用率。
接下來再延遲100ms來讓空閑任務統計下一個100ms的計數值,循環繼續進行下一次的統計。
|