|
清單 L 1.8
建立其它任務的任務。
void TaskStart (void *data)
{
Prevent compiler warning by assigning ‗data‘ to itself;
Display banner identifying this as EXAMPLE #1; (1)
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); (2)
PC_SetTickRate(200); (3)
OS_EXIT_CRITICAL();
Initialize the statistic task by calling ‗OSStatInit()‘; (4)
μ /C OS-II:源碼公開的實時嵌入式操作系統
12
Create 10 identical tasks; (5)
for (;;) {
Display the number of tasks created;
Display the % of CPU used;
Display the number of task switches in 1 second;
Display uC/OS-II‘s version number
If (key was pressed) {
if (key pressed was the ESCAPE key) {
PC_DOSReturn();
}
}
Delay for 1 Second;
}
}
在建立其他任務之前,必須調用 OSStatInit()[L1.8(4)]來確定用戶的 PC 有多快,如 程序清單 L1.9 所示。在一開始,OSStatInit()就將自身延時了兩個時鐘節拍,這樣它就可 以與時鐘節拍中斷同步[L1.9(1)]。因此,OSStatInit()必須在時鐘節拍啟動之后調用;否 則,用戶的應用程序就會崩潰。當 μC/OS-II 調用 OSStatInit()時,一個 32 位的計數器 OSIdleCtr 被清為 0 [L1.9(2)],并產生另一個延時,這個延時使 OSStatInit()掛起。此 時,uCOS-II 沒有別的任務可以執行,它只能執行空閑任務(μC/OS-II 的內部任務)。空閑 任務是一個無線的循環,它不斷的遞增 OSIdleCtr[L1.9(3)]。1 秒以后,uCOS-II 重新開始 OSStatInit(),并且將 OSIdleCtr 保存在 OSIdleMax 中[L1.9(4)。所以 OSIdleMax 是 OSIdleCtr 所能達到的最大值。而當用戶再增加其他應用代碼時,空閑任務就不會占用那樣 多的 CPU 時間。OSIdleCtr 不可能達到那樣多的記數,(如果擁護程序每秒復位一次 OSIdleCtr)CPU 利用率的計算由 μC/OS-II 中的 OSStatTask()函數來完成,這個任務每秒 執行一次。而當 OSStatRdy 置為 TRUE[L1.9(5)],表示 μC/OS-II 將統計 CPU 的利用率。
程序清單 L 1.9
測試 CPU 速度。
void OSStatInit (void)
{
OSTimeDly(2); (1)
OS_ENTER_CRITICAL();
OSIdleCtr = 0L; (2)
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC); (3)
μ /C OS-II:源碼公開的實時嵌入式操作系統
13
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr; (4)
OSStatRdy = TRUE; (5)
OS_EXIT_CRITICAL();
}
1.07.03 TaskN()
OSStatInit()將返回到 TaskStart()。現在,用戶可以建立 10 個同樣的任務(所有任 務共享同一段代碼)。所有任務都由 TaskStart()中建立,由于 TaskStart()的優先級為 0(最 高),新任務建立后不進行任務調度。當所有任務都建立完成后,TaskStart()將進入無限循 環之中,在屏幕上顯示統計信息,并檢測是否有 ESC 鍵按下,如果沒有按鍵輸入,則延時一 秒開始下一次循環;如果在這期間用戶按下了 ESC 鍵,TaskStart()將調用 PC_DOSReturn() 返回 DOS 系統。 程序清單 L1.10 給出了任務的代碼。任務一開始,調用 OSSemPend()獲取信號量 RandomSem [程序清單 L1.10(1)](也就是禁止其他任務運行這段代碼—譯者注),然后調用 Borland C/C++的庫函數 random()來獲得一個隨機數[程序清單 L1.10(2)],此處設 random ()函數是不可重入的,所以 10 個任務將輪流獲得信號量,并調用該函數。當計算出 x 和 y 坐標后[程序清單 L1.10(3)],任務釋放信號量。隨后任務在計算的坐標處顯示其任務號 (0-9,任務建立時的標識)[程序清單 L1.10(4)]。最后,任務延時一個時鐘節拍[程序清 單 L1.10(5)],等待進入下一次循環。系統中每個任務每秒執行 200 次,10 個任務每秒鐘將 切換 2000 次。
程序清單 L 1.10
在屏幕上顯示隨機位置顯示數字的任務。
void Task (void *data)
{
UBYTE x;
UBYTE y;
UBYTE err;
for (;;) {
OSSemPend(RandomSem, 0, &err); (1)
x = random(80); (2)
y = random(16);
μ /C OS-II:源碼公開的實時嵌入式操作系統
14
OSSemPost(RandomSem); (3)
PC_DispChar(x, y + 5, *(char *)data, DISP_FGND_LIGHT_GRAY); (4)
OSTimeDly(1); (5)
}
}
1.08 例2
例 2 使用了帶擴展功能的任務建立函數 OSTaskCreateExt()和 uCOS-II 的堆棧檢查操 作(要使用堆棧檢查操作必須用 OSTaskCreateExt()建立任務—譯者注)。當用戶不知道應 該給任務分配多少堆棧空間時,堆棧檢查功能是很有用的。在這個例子里,先分配足夠的堆 棧空間給任務,然后用堆棧檢查操作看看任務到底需要多少堆棧空間。顯然,任務要運行足 夠長時間,并要考慮各種情況才能得到正確數據。最后決定的堆棧大小還要考慮系統今后的 擴展,一般多分配 10%,25%或者更多。如果系統對穩定性要求高,則應該多一倍以上。 uCOS-II 的堆棧檢查功能要求任務建立時堆棧清零。OSTaskCreateExt()可以執行此項 操作(設置選項 OS_TASK_OPT_STK_CHK 和 OS_TASK_OPT_STK_CLR 打開此項操作)。如果任務 運行過程中要進行建立、刪除任務的操作,應該設置好上述的選項,確保任務建立后堆棧是 清空的。同時要意識到 OSTaskCreateExt()進行堆棧清零操作是一項很費時的工作,而且取 決于堆棧的大小。執行堆棧檢查操作的時候,uCOS-II 從棧底向棧頂搜索非 0 元素(參看圖 F 1.1),同時用一個計數器記錄 0 元素的個數。 例 2 的磁盤文件為\SOFTWARE\uCOS-II\EX2_x86L,它包含 9 個任務。加上 uCOS-II 本身 的兩個任務:空閑任務(idle task)和統計任務。與例 1 一樣 TaskStart()由 main() 函數建立,其功能是建立其他任務并在屏幕上顯示如下的統計數據:
|
-
-
嵌入式UCOSII學習.pdf
2018-10-29 16:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
3.51 MB, 下載次數: 2, 下載積分: 黑幣 -5
|