實驗二 UCOS-II任務管理_第1頁
實驗二 UCOS-II任務管理_第2頁
實驗二 UCOS-II任務管理_第3頁
實驗二 UCOS-II任務管理_第4頁
實驗二 UCOS-II任務管理_第5頁
已閱讀5頁,還剩4頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、班 級 學號 姓 名 同組人 實驗日期 室溫 大氣壓 成 績 實驗二 UCOS-II任務管理一、實驗目的1、掌握UCOS-II中任務管理的函數的應用。2、掌握UCOS-II在STM32平臺下對硬件的控制。3、掌握開發UCOS-II應用的程序結構。二、實驗步驟1、UCOSII工作原理UCOSII提供系統時鐘節拍,實現任務切換和任務延時等功能。這個時鐘節拍由OS_TICKS_PER_SEC(在os_cfg.h中定義)設置,一般我們設置UCOSII的系統時鐘節拍為1ms100ms。本次實驗利用STM32的SYSTICK定時器來提供UCOSII時鐘節拍。UCOSII的任何任務都是通過一個叫任務控制塊(

2、TCB)的東西來控制的,每個任務管理塊有3個最重要的參數:(1)任務函數指針;(2)任務堆棧指針;(3)任務優先級。 在UCOSII中,使用CPU的時候,優先級高(數值小)的任務比優先級低的任務具有優先使用權,即任務就緒表中總是優先級最高的任務獲得CPU使用權,只有高優先級的任務讓出CPU使用權(比如延時)時,低優先級的任務才能獲得CPU使用權。UCOSII不支持多個任務優先級相同,也就是每個任務的優先級必須不一樣。任務的調度其實就是CPU運行環境的切換,即:PC指針、SP指針和寄存器組等內容的存取過程 UCOSII的每個任務都是一個死循環。每個任務都處在以下5種狀態之一的狀態下,這5種狀態是

3、:睡眠狀態、就緒狀態、運行狀態、等待狀態(等待某一事件發生)和中斷服務狀態。 睡眠狀態,任務在沒有被配備任務控制塊或被剝奪了任務控制塊時的狀態。就緒狀態,系統為任務配備了任務控制塊且在任務就緒表中進行了就緒登記,任務已經準備好了,但由于該任務的優先級比正在運行的任務的優先級低,還暫時不能運行,這時任務的狀態叫做就緒狀態。 運行狀態,該任務獲得CPU使用權,并正在運行中,此時的任務狀態叫做運行狀態等待狀態,正在運行的任務,需要等待一段時間或需要等待一個事件發生再運行時,該任務就會把CPU的使用權讓給別的任務而使任務進入等待狀態。中斷服務狀態,一個正在運行的任務一旦響應中斷申請就會中止運行而去執行

4、中斷服務程序,這時任務的狀態叫做中斷服務狀態。UCOSII任務的5個狀態轉換關系如圖所示: 與任務相關的幾個函數:1)建立任務函數UCOSII提供了我們2個建立任務的函數:OSTaskCreat和OSTaskCreatExt,我們一般用OSTaskCreat函數來創建任務,該函數原型為:OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INTU prio) 該函數包括4個參數:task:是指向任務代碼的指針;pdata:是任務開始執行時,傳遞給任務的參數的指針;ptos:是分配給任務的堆棧的棧頂指針;prio是分配給任務的優先級。

5、 每個任務都有自己的堆棧,堆棧必須申明為OS_STK類型,并且由連續的內存空間組成??梢造o態分配堆??臻g,也可以動態分配堆棧空間。OSTaskCreatExt也可以用來創建任務。2)任務刪除函數任務刪除,就是把任務置于睡眠狀態,并不是把任務代碼給刪除了。UCOSII提供的任務刪除函數原型為:INT8U OSTaskDel(INT8U prio) 其中參數prio就是我們要刪除的任務的優先級。故該函數是通過任務優先級來實現任務刪除的。3)請求任務刪除函數 必須確保被刪除任務的資源被釋放的前提下才能將其刪除,所以我們通過向被刪除任務發送刪除請求,來實現任務釋放自身占用資源后再刪除。UCOSII提供

6、的請求刪除任務函數原型為:INT8U OSTaskDelReq(INT8U prio)同樣還是通過優先級來確定被請求刪除任務。4)改變任務的優先級函數 UCOSII在建立任務時,會分配給任務一個優先級,但是這個優先級并不是一成不變的,而是可以通過調用UCOSII提供的函數修改。UCOSII提供的任務優先級修改函數原型為:INT8U OSTaskChangePrio(INT8U oldprio,INT8U newprio)。5)任務掛起函數任務掛起和任務刪除有點類似,但是又有區別,任務掛起只是將被掛起任務的就緒標志刪除,并做任務掛起記錄,并沒有將任務控制塊任務控制塊鏈表里面刪除,也不需要釋放其資

7、源,而任務刪除則必須先釋放被刪除任務的資源,并將被刪除任務的任務控制塊也給刪了。被掛起的任務,在恢復(解掛)后可以繼續運行。UCOSII提供的任務掛起函數原型為:INT8U OSTaskSuspend(INT8U prio) 6)任務恢復函數有任務掛起函數,就有任務恢復函數,通過該函數將被掛起的任務恢復,讓調度器能夠重新調度該函數。UCOSII提供的任務恢復函數原型為:INT8U OSTaskResume(INT8U prio)三、實驗內容在UCOSII里面創建3個任務:開始任務、LED0任務和LED1任務,開始任務用于創建其他(LED0和LED1)任務,之后掛起;LED0任務用于控制DS0

8、的亮滅,DS0每秒鐘亮80ms;LED1任務用于控制DS1的亮滅,DS1亮300ms,滅300ms,依次循環。所要用到的硬件資源如下:1)指示燈DS0 、DS1 的硬件電路圖如圖 其中PWR是系統電源指示燈,為藍色。LED0和LED1分別接在PB5和PE5上。為了方便大家判斷,我們選擇了DS0為紅色的LED,DS1為綠色的LED。2)軟件參數設置 在os_cfg.h里面定義OS_TICKS_PER_SEC=200,也就是設置UCOSII的時鐘節拍為5ms。OS_MAX_TASKS = 10,也就是最多10個任務(包括空閑任務和統計任務在內)。前面提到,我們需要在sys.h里面設置SYSTEM_

9、SUPPORT_UCOS為1,以支持UCOSII,通過這個設置,不僅可以實現利用delay_init來初始化SYSTICK,產生UCOSII的系統時鐘節拍,還可以讓delay_us和delay_ms函數在UCOSII下能夠正常使用,這使得我們之前的代碼可以十分方便的移植到UCOSII下。雖然UCOSII也提供了延時函數:OSTimeDly和OSTimeDLyHMSM,但是這兩個函數的最少延時單位只能是1個UCOSII時鐘節拍,在本次實驗中,即5ms,顯然不能實現us級的延時,而us級的延時在很多時候非常有用:比如IIC模擬時序,DS18B20等單總線器件操作等。而通過delay_us和dela

10、y_ms,則可以方便的提供us和ms的延時服務,這比UCOSII本身提供的延時函數更好用。在設置SYSTEM_SUPPORT_UCOS為1之后,UCOSII的時鐘節拍由SYSTICK的中斷服務函數提供,該部分代碼如下:systick中斷服務函數,使用ucos時用到void SysTick_Handler(void) OSIntEnter();/進入中斷OSTimeTick(); /調用ucos的時鐘服務程序OSIntExit(); /觸發任務切換軟中斷 以上代碼,其中OSIntEnter是進入中斷服務函數,用來記錄中斷嵌套層數(OSIntNesting增加1);OSTimeTick是系統時鐘節

11、拍服務函數,在每個時鐘節拍了解每個任務的延時狀態,使已經到達延時時限的非掛起任務進入就緒狀態;OSIntExit是退出中斷服務函數,該函數可能觸發一次任務切換(當OSIntNesting=0&&調度器未上鎖&&就緒表最高優先級任務!=被中斷的任務優先級時),否則繼續返回原來的任務執行代碼(如果OSIntNesting不為0,則減1)。 事實上,任何中斷服務函數,都應該加上OSIntEnter和OSIntExit函數,這是因為UCOSII是一個可剝奪型的內核,中斷服務子程序運行之后,系統會根據情況進行一次任務調度去運行優先級別最高的就緒任務,而并不一定接著運行被中

12、斷的任務! 最后,打開test.c,輸入如下代碼: #include "sys.h" #include "usart.h" #include "delay.h" #include "led.h" #include "includes.h" /UCOSII任務設/ /START 任務 /設置任務優先級 #define START_TASK_PRIO 10 /開始任務的優先級設置為最低 /設置任務堆棧大小 #define START_STK_SIZE 64 /任務堆棧 OS_STK START_TA

13、SK_STKSTART_STK_SIZE; /任務函數 void start_task(void *pdata); /LED0任務 /設置任務優先級 #define LED0_TASK_PRIO 7 /設置任務堆棧大小 #define LED0_STK_SIZE 64 /任務堆棧 OS_STK LED0_TASK_STKLED0_STK_SIZE; /任務函數 void led0_task(void *pdata); /LED1任務 /設置任務優先級 #define LED1_TASK_PRIO 6 /設置任務堆棧大小 #define LED1_STK_SIZE 64 /任務堆棧 OS_STK

14、 LED1_TASK_STKLED1_STK_SIZE; /任務函數 void led1_task(void *pdata); int main(void) Stm32_Clock_Init(9); /系統時鐘設置 delay_init(72); /延時初始化 LED_Init(); LED_Init(); /初始化與LED連接的硬件接口 OSInit(); OSTaskCreate(start_task, (void *)0, (OS_STK *)&START_TASK_STKSTART_STK_SIZE-1, START_TASK_PRIO );/創建起始任務 OSStart();

15、 /開始任務 void start_task(void *pdata) OS_CPU_SR cpu_sr=0; pdata = pdata; OS_ENTER_CRITICAL(); /進入臨界區(無法被中斷打斷) OSTaskCreate(led0_task, (void *)0, (OS_STK*)&LED0_TASK_STKLED0_STK_SIZE-1, LED0_TASK_PRIO); OSTaskCreate(led1_task, (void *)0, (OS_STK*)&LED1_TASK_STKLED1_STK_SIZE-1, LED1_TASK_PRIO);

16、OSTaskSuspend(START_TASK_PRIO); /掛起起始任務. OS_EXIT_CRITICAL(); /退出臨界區(可以被中斷打斷) /LED0任務 void led0_task(void *pdata) while(1) LED0=0; delay_ms(80); LED0=1; delay_ms(920); ; /LED1任務 void led1_task(void *pdata) while(1) LED1=0; delay_ms(300); LED1=1; delay_ms(300); ; 該部分代碼我們創建了3個任務:start_task、led0_task和le

17、d1_task,優先級分別是10、7和6,堆棧大小都是64(注意OS_STK為32位數據)。我們在main函數只創建了start_task一個任務,然后在start_task再創建另外兩個任務,在創建之后將自身(start_task)掛起。這里,我們單獨創建start_task,是為了提供一個單一任務,實現應用程序開始運行之前的準備工作。 在應用程序中經常有一些代碼段必須不受任何干擾地連續運行,這樣的代碼段叫做臨界段。因此,為了使臨界段在運行時不受中斷所打斷,在臨界段代碼前必須用關中斷指令使CPU屏蔽中斷請求,而在臨界段代碼后必須用開中斷指令解除屏蔽使得CPU可以響應中斷請求。UCOSII提供OS_ENTER_CRITICAL和OS_EXIT_CRITICAL兩個宏來實現,這兩個宏需要在移植UCOSII的時候實現,采用OS_CRITICAL_METHOD為3來實現這兩個宏。因為臨界段代碼不能被中斷,將嚴重影響系統的實時性,所以臨界段代碼越短越好!在start_task任務中,我們在創建led0_task和led1_task的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論