ucOSII 入門教程好好學_第1頁
ucOSII 入門教程好好學_第2頁
ucOSII 入門教程好好學_第3頁
ucOSII 入門教程好好學_第4頁
ucOSII 入門教程好好學_第5頁
已閱讀5頁,還剩72頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

嵌入式實時操作系統

μC/OS-II講座北華大學任哲2006廣州為什么要學習μC/OS-II一.凡從事嵌入式系統開發工作的人,必須對嵌入式操作系統有足夠的了解。二.對于初學者,從μC/OS-II開始是個明智的選擇。1.μC/OS-II麻雀雖小,卻五臟基本全(它是個微內核)。2.可以學習實時系統的一些編程技巧。3.可以把在學校中學到的操作系統抽象概念具體化。4.具有很強的實用性。5.學習數據結構應用的好例子。講座的主要內容一.計算機操作系統的基本概念二.操作系統中常用的數據結構三.并發操作系統的概念四.任務的要素五.μC/OS-II的任務管理(任務調度)六.μC/OS-II的中斷和時鐘七.μC/OS-II的任務的同步與通信八.μC/OS-II的存儲管理九.硬件抽象層和測試臺操作系統是一種為應用程序提供服務的系統軟件,是一個完整計算機系統的有機組成部分。從層次來看,操作系統位于計算機硬件之上,應用軟件之下。所以也把它叫做應用軟件的運行平臺。什么是計算機操作系統(OperatingSystem,OS)它在計算機應用程序與計算機硬件系統之間,屏蔽了計算機硬件工作的一些細節,并對系統中的資源進行有效的管理。通過提供函數(應用程序接口(API)),從而使應用程序的設計人員得以在一個友好的平臺上進行應用程序的設計和開發,大大地提高了應用程序的開發效率。計算機操作系統的作用從用戶的角度來看,它就是一大堆函數(API和系統函數),用戶可以調用(普通調用或系統調用)它們來對系統資源進行操作。計算機硬件用匯編語言編寫的硬件抽象層高級語言的接口應用軟件操作系統操作系統計算機操作系統的功能處理器的管理存儲管理網絡和通信的管理I/O設備管理文件管理任務管理任務表存儲分配表文件目錄設備表總之,需要一大堆表操作系統中經常使用的數據結構(數組)數組1。同一數據類型數據的集合;2。占用連續內存空間;3。其中的所有元素名稱都相同,但每個元素都有一個編號;4。元素名去掉編號(下標),得到的是數組名,數組名是個指針。inta[10]a[0]a[1]a[2]a[3]a[9]aa+1使用上的特點:1。分類存放;2。檢索速度快且恒定;3。缺點:占用連續空間大……a+2a+3a+9應用:記錄同類事物的表操作系統中經常使用的數據結構(位圖)位圖是數組的一種特殊應用a[10](可以記錄80個事物的狀態)a[0]a[1]a[2]a[3]a[9]aa+1……a+2a+3a+9應用:登記表1/0D7D6D5D4D3D2D1D0操作系統中經常使用的數據結構(結構)1。不同數據類型數據的集合;2。占用連續內存空間;structStudent{intage;char*name;charsex;};使用上的特點:1。不分類存放,但用來描述同一事物;2。檢索速度快且恒定;應用:通訊錄中的一條記錄、工具箱、廚房等等nextnext兩個元素的鏈表操作系統中經常使用的數據結構(鏈表)structStudent{Student*nextintage;char*name;charsex;};1。同數據類型數據的集合;2。不占用連續內存空間。使用上的特點:1。分類存放,但空間上不連續(不需要大量的連續存儲空間);2。檢索速度慢,且耗費的時間不固定;應用:存放大量的較大的表,類似檔案柜操作系統中經經常使用的數據結構((隊列)按照先進先出的規則組織的的數據結構可以用數組也可以用鏈表來實現主要用于對象象的排隊操作系統中經經常使用的數據結構((堆棧)按照先進后出規則組織的數數據結構主要用數組來來實現主要用于程序模塊的嵌嵌套運行什么是多任務務系統簡單地說,就就是能用一個個處理器并發(注意,,不是同時!?。┑剡\行多個程程序的計算機機管理系統。。并發:由同一個處理理器輪換地運行多個程序序?;蛘哒f是是由多個程序輪班地占占用處理器這這個資源。且在占用這個個資源期間,,并不一定能夠把程序序運行完畢。。并發過程示意圖處理器如何進進行程序的切換?程序的切換((兩句話)處理器是個傻傻瓜,PC讓它干啥,它它就干啥。PC是個指路器,,它指向哪兒,處理器就就去哪兒。從此可以知道道,哪個程序序占有了PC,哪個程序就就占有了處理理器。

=PC深刻地理解PC是理解系統進行程序切換換動作的關鍵鍵。所謂切換就是:PC目標地址如何操作PC指令:不同的計算機機類型的指令令是不同的。。數據傳送指令令子程序返回指指令(由堆棧彈出)中斷服務程序序返回指令(由堆棧彈出)小結系統是通過把把待運行程序序的地址賦予予程序計數器器PC來實現程序的的切換的。任務代碼任務堆棧內存處理器PCSP任務運行時與與處理器之間的的關系處理器通過兩兩個指針寄存存器(PC和和SP)來與與任務代碼和和任務堆棧建建立聯系并運運行它寄存器組程序運行環境運行環境包括括了兩部分::處理器中的的運行環境和和內存中的運運行環境任務代碼任務堆棧內存處理器PCSP多任務時的問問題任務代碼任務堆棧內存任務代碼任務堆棧內存?當有多個任務務時,處理器器中的運行環環境應該怎么么辦?寄存器組程序運行環境境程序虛擬處理器PCSP虛擬處理器PCSP虛擬處理器PCSP虛擬處理器PCSP調度器多任務時任務務與處理器之之間關系的的處理程序處理器PCSP在內存中為每每個任務創建建一個虛擬的的處理器(處處理器部分的的運行環境由操作系統的的調度器按某種規則來來進行這兩個個復制工作復制當需要運行某個任務時就把該任務的虛擬處理器復制到實際處理器中復制當需要中止當前任務時,則把任務對應的虛擬處理器復制到內存復制再把另一個需要運行的任務的虛擬處理器復制到實際處理器中寄存器組寄存器組也就是說,任任務的切換是是任務運行環境的切切換虛擬處理器虛擬處理器應應該存儲的主主要信息:1。程序的斷斷點地址(PC)2。任務堆棧棧指針(SP)3。程序狀態態字寄存器((PSW)4。通用寄存存器內容5。函數調用用信息(已存存在于堆棧))另外再用一個個數據結構保保存任務堆棧棧指針(SP)),這個數據據結構叫做任任務控制塊,它除除了保存任務務堆棧指針之之外還要負責保保存任務其他他信息。這些內容通常常保存在任務務堆棧中,這這些內容也常常叫做任務的的上下文。任務控制塊是是由操作系統統另行構造的的一個數據結結構,每個任任務都有一個個。任務控制塊結結構的主要成成員typedefstructos_tcb{OS_STK*OSTCBStkPtr;//指向任務務堆棧棧頂的的指針……INT8UOSTCBStat;//任務的當當前狀態標志志INT8UOSTCBPrio;//任任務的的優先先級別別……}OS_TCB;任務代碼任務堆棧內存任務控制塊其實,,程序序切換換的關關鍵是是把程序序的私有堆堆棧指指針賦予處理理器的的堆棧棧指針針SP實質上上系統統是通通過SP的的切換換來實現現程序序的切切換的的。要建立立一個個概念念:具具有控制塊塊的程程序才才是一一個可以被被系統統所運運行的的任務務。程序代代碼、、私有有堆棧棧、任任務控制制塊是任務務的三三要件件。任務控控制塊塊提供供了運運行環環境的存存儲位位置。。任務的的基本本概念念把一個個大型型任務務分解解成多多個小小任務務,然然后在在計算算機中中通過過運行行這些些小任任務,,最終終達到到完成成大任任務的的目的的。在μC/OS-II中,,與上上述那那些小小任務務對應應的程程序實實體就就叫做做“任任務””(實實質上上是一一個線線程)),μC/OS-II就是是一個個能對對這些些小任任務的的運行行進行行管理理和調調度的的多任任務操操作系系統。。從應用用程序序設計計的角角度來來看,,μC/OS-II的任任務就就是一一個用用戶編編寫的的C函函數和和與之之相關關聯的的一些些數據據結構構而構構成的的一個個實體體。任務代碼任務堆棧內存在內存中應該存有任務的代碼和與該任務配套的堆棧任務切切換過過程獲得待待運行行任務務的任任務控控制塊塊恢復待運行任務的運行環境處理器的PC=任務堆棧中的斷點地址處理器的SP=任務塊中保存的SP如何獲獲得待待運行行任務務的任任務控控制塊塊?小結一個完完整的的任務務應該該有如如下三三部分分:任務代代碼((程序序)任務的的私有有堆棧棧(用用以保保護運運行環環境))任務控控制塊塊(提供供私有有堆棧棧也是是虛擬擬處理理器的的位置置)這些都都是任任務方方應該該提供供的基基本信信息。。μC/OS-II中的任務管管理任務的的狀態態及其其轉換換正在運運行的的任務務,需需要等等待一一段時時間或或需要要等待待一個個事件件發生生再運運行時時,該該任務務就會會把CPU的使使用權權讓給給別的的任務務而使使任務務進入入等待待狀態態。任務在在沒有有被配配備任任務控控制塊塊或被被剝奪奪了任任務控控制塊塊時的的狀態態叫做做任務務的睡睡眠狀狀態系統為為任務務配備備了任任務控控制塊塊且在在任務務就緒緒表中中進行行了就就緒登登記,,這時時任務務的狀狀態叫叫做就就緒狀狀態。。處于就就緒狀狀態的的任務務如果果經調調度器器判斷斷獲得得了CPU的使用用權,,則任任務就就進入入運行行狀態態一個正正在運運行的的任務務一旦旦響應應中斷斷申請請就會會中止止運行行而去去執行行中斷斷服務務程序序,這這時任任務的的狀態態叫做做中斷斷服務務狀態態前面談談到,,一個個任務務的任任務控控制塊塊的主要要作用用就是是保存存該任任務的的虛擬擬處理器器的堆堆棧指指針寄寄存器器SP。其實,,隨著著任務務管理理工作作的復復雜性性的提高高,它它還應應該保保存一一些其其他信信息。任務控控制塊塊———任務在在系統統中的的身份份證由于系系統存存在著著多個個任務務,于于是系統如如何來來識別別并管管理一一個任任務就就是一個需需要解解決的的問題題。識識別一一個任任務的最直直接的的辦法法是為為每一一個任任務起起一個名稱稱。由于μC/OS-II中的的任務務都有有一個個惟一的的優先先級別別,因因此μC/OS-II是是用用任務務的的優優先先級級來來作作為為任任務務的的標標識識的。。所以以,,任任務務控控制制塊塊還還要要來來保存存該該任務務的的優優先先級級別別。另外外,,前前面面也也談談到到,,一一個個任任務務在在不同同的的時時刻刻還還處處于于不不同同的的狀狀態態,,顯然然,,記記錄錄了了任任務務狀態態的數數據據也也應該該保保存存到到任任務務控控制制塊塊中中。。基于于上上述述原原因因,,系系統統必必須須為為每每個個任任務務創創建建一個個保保存存與與該該任任務務有有關關的的相相關關信信息息的的數數據據結構構,,這這個個數數據據結結構構就就叫叫做做該該任任務務的的任任務務控制制塊塊((TCB))。。任務務控控制制塊塊結結構構的的主主要要成成員員typedefstructos_tcb{OS_STK*OSTCBStkPtr;//指指向向任任務務堆堆棧棧棧棧頂頂的的指指針針………INT8UOSTCBStat;//任任務務的的當當前前狀狀態態標標志志INT8UOSTCBPrio;//任任務務的的優優先先級級別別………}OS_TCB;任務務控控制制塊塊是是不不是是像像我們們人人在在一一個個國國家家中中的身份份證證?((其其實實,,系統統中中的的所所有有資資源源都應應該該有有身身份份證證。。))任務務在在內內存存中中的的結結構構用戶戶任任務務代代碼碼的的一般般結結構構voidMyTask(void*pdata){for(;;){可以被中中斷的用用戶代碼碼;OS_ENTER_CRITICAL();//進入入臨界段段(關中中斷)不可以被被中斷的的用戶代代碼;OS_EXIT_CRITICAL();//退出出臨界段段(開中中斷)可以被中中斷的用用戶代碼碼;}}臨界段無限循環環于是可以以這樣說說,μC/OS-II任務的的代碼結構構是一個個可以帶帶有臨界界段的無無限循環環。系統提供供的空閑任務務在多任務務系統運運行時,,系統經經常會在在某個時時間內無無用戶任任務可運運行而處處于所謂謂的空閑閑狀態,,為了使使CPU在沒有有用戶任任務可執執行的時時候有事事可做,,μC/OS-II提供了了一個叫叫做空閑閑任務OSTaskIdle()的系統任任務voidOSTaskIdle(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifpdata=pdata;//防止止某些編編譯器報報錯for(;;){OS_ENTER_CRITICAL();//關閉閉中斷OSdleCtr++;//計數數OS_EXIT_CRITICAL();//開放放中斷}}空閑任務務只是做做了一個個計數工工作注意!空空閑任務務中沒有有調用任任務延時時函數μC/OS-II規定,一一個用戶戶應用程程序必須須使用這這個空閑閑任務,,而且這這個任務務是不能能用軟件件來刪除除的系統提供供的另一一個任務務——統計任務務μC/OS-II提供的的另一個個系統任任務是統統計任務務OSTaskStat()。這個統統計任務務每秒計計算一次次CPU在單位位時間內內被使用用的時間間,并把把計算結結果以百百分比的的形式存存放在變變量OSCPUsage中,,以便應應用程序序通過訪訪問它來來了解CPU的的利用率率,所以以這個系系統任務務OSTaskStat()叫做統計計任務任務的優優先權及優先級級別μC/OS_II把任任務的優優先權分分為64個優先先級別,,每一個個級別都都用一個個數字來來表示。。數字0表示任任務的優優先級別別最高,,數字越大大則表示示任務的的優先級級別越低低用戶可以以根據應應用程序序的需要要,在文文件OS_CFG.H中通過過給表示示最低優優先級別別的常數數OS_LOWEST_PRIO賦值的方方法,來來說明應應用程序序中任務務優先級級別的數數目。該該常數一一旦被定定義,則則意味著著系統中中可供使使用的優優先級別別為:0,1,,2,………,OS_LOWEST_PRIO,共OS_LOWEST_PRIO+1個固定地,,系統總總是把最最低優先先級別OS_LOWEST_PRIO自動賦給給空閑任任務。如如果應用用程序中中還使用用了統計計任務,,系統則則會把優優先級別別OS_LOWEST_PRIO-1自動賦給給統計任任務,因因此用戶戶任務可可以使用用的優先先級別是是:0,,1,2…OS_LOWEST_PRIO-2,,共OS_LOWEST_PRIO-1個個任務務堆堆棧棧保存CPU寄存存器中的的內容及及存儲任任務私有有數據的的需要,,每個任任務都應應該配有有自己的的堆棧,,任務堆堆棧是任任務的重重要的組組成部分分在應用程程序中定定義任務務堆棧的的棧區非非常簡單單,即定定義一個個OS_STK類型的的一個數數組并在在創建一一個任務務時把這這個數組組的地址址賦給該該任務就就可以了了。例如://定義堆棧棧的長度#define TASK_STK_SIZE 512//定義一個個數組來作為為任務堆棧OS_STKTaskStk[TASK_STK_SIZE];typedefunsignedintOS_STK;//這是系統統定義的一個個數據類型voidmain(void){……OSTaskCreate(MyTask,//任務的指指針&MyTaskAgu,//傳遞給任任務的參數&MyTaskStk[MyTaskStkN-1],//任務堆棧棧棧頂地址20//任務的優優先級別);……}在創建用戶任任務時,要傳傳遞任務的堆堆棧指針和任任務優先級別別使用函數OSTaskCreate()創建建任務時,,一定要注注意所使用用的處理器器對堆棧增增長方向的的支持是向向上的還是是向下的任務堆棧的的初始化應用程序在在創建一個個新任務的的時候,必必須把在系系統啟動這這個任務時時CPU各各寄存器所所需要的初初始數據((任務指針針、任務堆堆棧指針、、程序狀態態字等等)),事先存存放在任務務的堆棧中中μC/OS-II在創創建任務函函數OSTaskCreate()中通過調調用任務堆堆棧初始化化函數OSTaskStkInit()來完成任務務堆棧初始始化工作的的它的原型如如下:OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdato,OS_STK*ptos,INT16Uopt);由于各種處處理器的寄寄存器及對對堆棧的操操作方式不不盡相同,,因此該函函數需要用用戶在進行行μC/OS-II的移移植時,按按所使用的的處理器由由用戶來編編寫。實現現這個函數數的具體細細節,將在在本書有關關μC/OS-II移植植的章節中中做進一步的介紹紹其實,任務務堆棧的初初始化就是是對該任務務的虛擬處處理器的初始化(復復位)。任務控制塊塊(OS_TCB)及任務控制制塊鏈表μC/OS-II用來來記錄任務務的堆棧指指針、任務務的當前狀狀態、任務務的優先級級別等一些些與任務管管理有關的的屬性的表表就叫做任務控制塊塊任務控制塊塊就相當于于是一個任任務的身份份證,沒有有任務控制制塊的任務務是不能被被系統承認認和管理的的任務控制塊塊結構的主主要成員typedefstructos_tcb{OS_STK*OSTCBStkPtr;//指向任任務堆棧棧棧頂的指針針……structos_tcb*OSTCBNext;//指向后后一個任務務控制塊的的指針structos_tcb*OSTCBPrev;//指向前前一個任務務控制塊的的指針……INT16UOSTCBDly;//任務等等待的時限限(節拍數數)INT8UOSTCBStat;//任務的的當前狀態態標志INT8UOSTCBPrio;//任務的的優先級別別……}OS_TCB;任務控制塊塊鏈表空任務控制制塊鏈表當應用程序序調用函數數OSTaskCreate()創創建一個任任務時,這這個函數會會調用系統統函數OSTCBInit()來來為任務控控制塊進行行初始化。。這個函數數首先為被被創建任務務從空任務務控制塊鏈鏈表獲取一一個任務控控制塊,然然后用任務務的屬性對對任務控制制塊各個成成員進行賦賦值,最后后再把這個個任務控制制塊鏈入到到任務控制制塊鏈表的的頭部當進行系統統初始化時時,初始化化函數會按按用戶提供供的任務數數為系統創創建具有相相應數量的的任務控制制塊并把它它們鏈接為為一個鏈表表。由于這些任任務控制塊塊還沒有對對應的任務務,故這個個鏈表叫做做空任務塊塊鏈表。即即相當于是是一些空白白的身份證證。任務就緒表表及任務調度多任務操作作系統的核核心工作就就是任務調調度。所謂調度,,就是通過過一個算法法在多個任任務中確定定該運行的的任務,做做這項工作作的函數就就叫做調度度器。μC/OS_II進行任務調調度的思想想是“近似地每時時每刻總是是讓優先級級最高的就就緒任務處處于運行狀狀態”。為了了保證這一一點,它在系統或用用戶任務調調用系統函函數及執行行中斷服務務程序結束束時總是調調用調度器器,來確定定應該運行行的任務并并運行它。μC/OS_II進行行任務調度度的依據就就是任務就緒表表為了能夠使使系統清楚楚地知道,系統中哪些些任務已經經就緒,哪哪些還沒有有就緒,μC/OS_II在RAM中設設立了一個個記錄表,,系統中的每每個任務都都在這個表表中占據一一個位置,,并用這個個位置的狀狀態(1或或者0)來來表示任務務是否處于于就緒狀態態,這個表就就叫做任務務就緒狀態態表,簡稱稱叫任務就就緒表任務就緒表就是一個二維數組OSRdyTbl[]為加快訪問任務就緒表的速度,系統定義了一個變量OSRdyGrp來表明就緒表每行中是否存在就緒任務。OSRdyTbl[]1/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/01/0OSRdyGrpD7D6D5D4D3D2D1D01/01/01/01/01/01/01/01/0任務就緒表表的示意圖圖01234567xy01234567OSRdyGrpD7D6D5D4D3D2D1D011110000prio=29D7D6D5D4D3D2D1D01D7D6D5D4D3D2D1D01OSRdyTbl[3]把prio為29的的任務置為為就緒狀態態YXOSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];在程序中,,可以用類類似下面的的代碼把優優先級別為為prio的任務置置為就緒狀狀態:OSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];如果要使一一個優先級級別為prio的任任務脫離就就緒狀態則則可使用如如下類似代代碼:if((OSRdyTbl[prio>>3]&=~OSMapTbl[prio&0x07])==0)OSRdyGrp&=~OSMapTbl[prio>>3];OSRdyGrpD7D6D5D4D3D2D1D011110000prio=29D7D6D5D4D3D2D1D01D7D6D5D4D3D2D1D01OSRdyTbl[y]x=OSUnMapTal[OSRdyTbl[y]];11000000000000y=OSUnMapTal[OSRdyGrp];圖5-6在在就緒表中查查找最高優先先級別任務的的過程從任務就緒表表中獲取優先先級別最高的的就緒任務可可用如下類似似的代碼:y=OSUnMapTal[OSRdyGrp];//D5、D4、D3位x=OSUnMapTal[OSRdyTbl[y]];//D2、D1、D0位prio=(y<<3)+x;//優先級別別或y=OSUnMapTbl[OSRdyGrp];prio=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]]);優先級判定表表OSUnMapTbl[256](os_core.c)INT8UconstOSUnMapTbl[]={0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};舉例:如OSRdyGrp的值值為00101000B,即0X28,則查得得OSUnMapTbl[OSRdyGrp]的值是3,,它相應于OSRdyGrp中的第第3位置1;;如OSRdyTbl[3]的值是11100100B,即即0XE4,,則查OSUnMapTbl[OSRdyTbl[3]]的值是2,,則進入就緒緒態的最高任任務優先級Prio=3*8+2=26小結系統通過查找找任務就緒表表來獲取待運行任任務的優先級級優先級任務切換過程程獲得待運行任任務的任務控控制塊恢復待運行任務的運行環境處理器的PC=任務堆棧中的斷點地址處理器的SP=任務塊中保存的SP如何獲得待運運行任務的任任務控制塊??根據就緒表獲得待運行任任務的任務控制塊指指針其實,調度器器在進行調度度時,在這個個位置還要進進行一下判斷斷:究竟是待待運行任務是是否為當前任任務,如果是是,則不切換換;如果不是是才切換,而而且還要保存存被中止任務務的運行環境境。1.任務切換宏OS_TASK_SW()任務切換就是是中止正在運運行的任務((當前任務)),轉而去運運行另外一個個任務的操作作,當然這個個任務應該是是就緒任務中中優先級別最最高的那個任任務先保護被中止止任務的斷點點數據后恢復待運行行任務的斷點點數據不要企圖用PUSH和POP指令來來使程序計數數器PC壓棧棧和出棧,因因為沒有這樣樣的指令。只好變通一下下了。中斷動作和過過程調用指令令可以使PC壓棧;中斷返回指令令可以使PC出棧。因此任務切換換OSCtxSw()必定是一一個中斷斷服務程程序。需要由宏宏OS_TASK_SW()來引發一一次中斷斷或者一一次調用用來使OSCtxSw()執行任務務切換工工作調度時機機很容易想想到的調調度時機機就是定時調調度。對于實時時系統來來說,應應該盡可能地實實現即時時調度。。用函數OSTaskCreate()創建任務務應用程序序通過調調用OSTaskCreate()函函數來創創建一個個任務,,OSTaskCreate()函數的的原型如如下:INT8UOSTaskCreate(void(*task)(void*pd),//指向任任務的指指針void*pdata,//傳傳遞給任任務的參參數OS_STK*ptos, //指向任任務堆棧棧棧頂的的指針INT8Uprio //任務的的優先級級)創建任務務的一般方方法一般來說說,任務務可以在在調用函函數OSStart()啟啟動任務務調度之之前來創創建,也也可以在在任務中中來創建建。但是是,μC/OS-II有一個個規定::在調用用啟動任任務函數數OSStart()之前前,必須須已經創創建了至至少一個個任務。。因此,,人們習習慣上在在調用函函數OSStart()之之前先創創建一個個任務,,并賦予予它最高高的優先先級別,,從而使使它成為為起始任任務。然然后在這這個起始始任務中中,再創創建其他他各任務務。如果要使使用系統統提供的的統計任任務,則則統計任任務的初初始化函函數也必必須在這這個起始始任務中中來調用用voidmain(void){ ………OSInit();//對μC/OS-II進行初初始化……OSTaskCreate(TaskStart,………);//創建建任務TaskStartOSStart();//開始始多任務務調度}voidTaskStart(void*pdata){……//在這這個位置置安裝并并啟動μC/OS-II的時鐘鐘OSStatInit();//初始始化統計計任務……//在這這個位置置創建其其他任務務for(;;){起始任務務TaskStart的代碼碼}}μC/OS-II的初始化在使用μC/OS-II的所有有服務之之前,必必須要調調用μC/OS-II的初始始化函數數OSInit()對μC/OS-II自身的的運行環環境進行行初始化化。函數OSInit()將對對μC/OS-II的所有有的全局局變量和和數據結結構進行行初始化化,同時時創建空空閑任務務OSTaskIdle,并并賦之以以最低的的優先級級別和永永遠的就就緒狀態態。如果果用戶應應用程序序還要使使用統計計任務的的話(常常數OS_TASK_STAT_EN=1),則則OSInit()還要以以優先級級別為OS_LOWEST_PRIO-1來創建建統計任任務初始化函函數OSInit()對數數據結構構進行初初始化時時,主要要要創建建包括空空任務控控制塊鏈鏈表在內內的5個個空數據據緩沖區區。同時時,為了了可以快快速地查查詢任務務控制塊塊鏈表中中的各個個元素,,初始化化函數OSInit()還還要創建建一個數數組OSTCBPrioTbl[OS_LOWEST_PRIO+1],在這這個數組組中,按按任務的的優先級級別的順順序把任任務控制制塊的指指針存放放在了對對應的元元素中μC/OS-II的的啟啟動動μC/OS-II進進行行任任務務的的管管理理是是從從調調用用啟啟動動函函數數OSStart()開開始始的的,,當當然然其其前前提提條條件件是是在在調調用用該該函函數數之之前前至至少少創創建建了了一一個個用用戶戶任任務務第3章章μC/OS-ⅡⅡ的中中斷斷和和時時鐘鐘本章章主主要要內內容容::μC/OS-II系系統統響應應中中斷斷的的過過程程μC/OS-II系系統統響響應應中中斷斷的的過過程程為為::系系統統接接收收到到中中斷斷請請求求后后,,這這時時如如果果CPU處處于于中中斷斷允允許許狀狀態態((即即中中斷斷是是開開放放的的)),,系系統統就就會會中中止止正正在在運運行行的的當當前前任任務務,,而而按按照照中中斷斷向向量量的的指指向向轉轉而而去去運運行行中中斷斷服服務務子子程程序序;;當當中中斷斷服服務務子子程程序序的的運運行行結結束束后后,,系系統統將將會會根根據據情情況況返返回回到到被被中中止止的的任任務務繼繼續續運運行行或或者者轉轉向向運運行行另另一一個個具具有有更更高高優優先先級級別別的的就就緒緒任任務務。。注意意??!中斷斷服服務務子子程程序序運運行行結結束束之之后后,,系系統統將將會會根根據據情情況況進進行行一一次次任任務務調調度度去去運運行行優優先先級級別別最最高高的的就就緒緒任任務務,,而而并并不不是是一一定定要要接接續續運運行行被被中中斷斷的的任任務務的的。中斷斷請請求求關閉閉中中斷斷轉到到中中斷斷向向量量保存存CPU寄寄存存器器通知知內內核核退退出出ISRISR給給任任務務發發信信號號中斷斷返返回回恢復復CPU寄寄存存器器中斷斷響響應應中斷斷恢恢復復中斷斷恢恢復復任務務響響應應時時間間任務務響響應應時時間間中斷斷的的響響應應過過程程無新新高高級級任任務務則則返返回回原原任任務務通知內核退出ISR恢復CPU寄存器中斷返回有新高級任務則運行高級任務通知知內內核核進進入入ISRvoidOSIntEnter(void){if(OSRunning==TRUE){if(OSIntNesting<255){OSIntNesting++;//中中斷斷嵌嵌套套層層數數計計數數器器加加一一}}}voidOSIntExit(void){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifif(OSRunning==TRUE){OS_ENTER_CRITICAL();if(OSIntNesting>0){OSIntNesting--;//中中斷斷嵌嵌套套層層數數計計數數器器減減一一}if((OSIntNesting==0)&&(OSLockNesting==0)){OSIntExitY=OSUnMapTbl[OSRdyGrp];OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]);if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;OSIntCtxSw();}}OS_EXIT_CRITICAL();}}在中中斷斷服服務務程程序序中中調調用用的的負負責責任任務務切切換換工工作作的的函函數數OSIntCtxSw()叫做做中中斷斷級級任任務務切切換換函函數數OSIntCtxSw(){OSTCBCur=OSTCBHighRdy;//任任務務控控制制塊塊的的切切換換OSPrioCur=OSPrioHighRdy;SP=OSTCBHighRdy->OSTCBStkPtr;//SP指指向向待待運運行行任任務務堆堆棧棧用出棧棧指令令把R1,R2,………彈彈入CPU的通通用寄寄存器器;RETI;//中中斷返返回,,使PC指指向待待運行行任務務}應用程程序中中的臨界段段在應用用程序序中經經常有有一些些代碼碼段必必須不不受任任何干干擾地地連續續運行行,這這樣的的代碼碼段叫叫做臨臨界段段。因因此,,為了了使臨臨界段段在運運行時時不受受中斷斷所打打斷,,在臨臨界段段代碼碼前必必須用用關中中斷指指令使使CPU屏屏蔽中中斷請請求,,而在在臨界界段代代碼后后必須須用開開中斷斷指令令解除除屏蔽蔽使得得CPU可可以響響應中中斷請請求由于各各廠商商生產產的CPU和C編譯譯器的的關中中斷和和開中中斷的的方法法和指指令不不盡相相同,,為增增強μC/OS-II的可可移植植性((即在在μC/OS-II的各各個C函數數中盡盡可能能地不不出現現匯編編語言言代碼碼),,μC/OS-II用兩兩個宏宏來實實現中中斷的的開放放和關關閉,,而把把與系系統的的硬件件相關關的關關中斷斷和開開中斷斷的指指令分分別封封裝在在這兩兩個宏宏中::OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()第一種種方法法最簡簡單,,即直直接使使用處處理器器的開開中斷斷和關關中斷斷指令令來實實現宏宏,這這時需需要令令常數數OS_CRITICAL_METHOD=1。其其示意意性代代碼為為:#defineOS_ENTER_CRITICAL()\asm(““DI”)\\關關中斷斷#defineOS_EXIT_CRITICAL()\asm(““EI”)\\開開中斷斷第二種種方法法稍微微復雜雜一些些,但但可以以使CPU中斷斷允許許標志志的狀狀態,,在臨臨界段段前和和臨界界段后后不發發生改改變。。在宏宏OS_ENTER_CRITICAL()中,,把CPU的允允許中中斷標標志保保持到到堆棧棧中,,然后后再關關閉中中斷,,這樣樣在臨臨界段段結束束時,,即在在調用用宏OS_EXIT_CRITICAL()時只只要把把堆棧棧中保保存的的CPU允允許中中斷狀狀態恢恢復就就可以以了。。這兩兩個宏宏的示示意性性代碼碼如下下:#defineOS_ENTER_CRITICAL()\asm(““PUSHPSW”)\/*通通過保保存程程序狀狀態字字來保保存中中斷允許許標志志*/asm(““DI”)//關關中斷斷#defineOS_EXIT_CRITICAL()asm(““POPPSW”)//恢恢復中中斷允允許標標志μC/OS-II的系統時時鐘μC/OS-II與大大多數數計算算機系系統一一樣,,用硬硬件定定時器器產生生一個周周期為為ms級的的周期期性中中斷來來實現現系統統時鐘鐘,最小的時鐘單單位就就是兩兩次中中斷之之間相相間隔隔的時時間,,這個個最小小時鐘鐘單位位叫做做時鐘節節拍(TimeTick))。硬件定定時器器以時鐘節節拍為為周期期定時時地產產生中中斷,,該中中斷的的中斷斷服務務程序序叫做做OSTickISR()。中中斷服服務程程序通通過調調用函函數OSTimeTick()來完完成系系統在在每個個時鐘鐘節拍拍時需需要做做的工工作。voidOSTickISR(void){保存CPU寄存存器;;調用OSIntEnter();//記記錄中中斷嵌嵌套層層數if(OSIntNesting==1;{OSTCBCur->OSTCBStkPtr=SP;//保保存堆堆棧指指針}調用OSTimeTick();//節節拍處處理清除中中斷;;開中斷斷;調用OSIntExit();//中中斷嵌嵌套層層數減減一恢復CPU寄存存器;;中斷返返回;;}這是系系統時時鐘中中斷服服務程程序voidOSTimeTick(void){……OSTimeTickHook();……OSTime++;//記記錄節節拍數數……if(OSRunning==TRUE){ptcb=OSTCBList;while(ptcb->OSTCBPrio!=OS_IDLE_PRIO){OS_ENTER_CRITICAL();if(ptcb->OSTCBDly!=0){if(--ptcb->OSTCBDly==0)//任任務的的延時時時間間減一一{if((ptcb->OSTCBStat&OS_STAT_SUSPEND)==OS_STAT_RDY){OSRdyGrp|=ptcb->OSTCBBitY;OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;}else{ptcb->OSTCBDly=1;}}}ptcb=ptcb->OSTCBNext;OS_EXIT_CRITICAL();}}時鐘節節拍服服務函函數函數OSTimeTick()的任任務,,就是是在每個個時鐘鐘節拍拍了解解每個個任務務的延延時狀狀態,,使其其中已已經到到了延延時時時限的的非掛掛起任任務進進入就就緒狀狀態。任務的的延時時由于嵌嵌入式式系統統的任任務是是一個個無限限循環環,并并且μC/OS-II還是一一個搶搶占式式內核核,所所以為為了使使高優優先級級別的的任務務不至至于獨獨占CPU,可以以給其其他任任務優優先級級別較較低的的任務務獲得得CPU使用權權的機機會,,μC/OS-II規定::除了空空閑任任務之之外的的所有有任務務必須須在任任務中中合適適的位位置調調用系系統提提供的的函數數OSTimeDly(),使使當前前任務務的運運行延延時((暫停停)一一段時時間并并進行行一次次任務務調度度,以以讓出出CPU的的使用用權。。voidOSTimeDly(INT16Uticks){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifif(ticks>0){OS_ENTER_CRITICAL();if((OSRdyTbl[OSTCBCur->OSTCBY]&=~OSTCBCur->OSTCBBitX)==0){OSRdyGrp&=~OSTCBCur->OSTCBBitY;//取消當當前任任務的的就緒緒狀態態}OSTCBCur->OSTCBDly=ticks;//延延時節節拍數數存入入任務務控制制塊OS_EXIT_CRITICAL();OS_Sched();//調用調調度函函數}}這是系系統提提供的的延時時函數數其他用用來管管理時時間的的函數數INT8UOSTimeDlyResume(INT8Uprio);INT32UOSTimeGet(void);voidOSTimeSet(INT32Uticks);取消任任務延延時函函數獲得系系統時時間函函數設置系系統時時間函函數第4章章任務的的同步步與通通信系統中中的多多個任任務在在運行行時,,經常常需要要互相相無沖沖突地地訪問問同一一個共共享資資源,,或者者需要要互相相支持持和依依賴,,甚至至有時時還要要互相相加以以必要要的限限制和和制約約,才才保證證任務務的順順利運運行。。因此此,操操作系系統必必須具具有對對任務務的運運行進進行協協調的的能力力,從從而使使任務務之間間可以以無沖沖突、、流暢暢地同同步運運行,,而不不致導導致災災難性性的后后果。。與人們們依靠靠通信信來互互相溝溝通,,從而而使人人際關關系和和諧、、工作作順利利的做做法一一樣,,計算算機系系統是是依靠靠任務務之間間的良良好通通信來來保證證任務務與任任務的的同步步的。。例如,兩個任任務:任務A和任務B,,它們需要通通過訪問同一一個數據緩沖沖區合作完成成一項工作,,任務A負責責向緩沖區寫寫入數據,任任務B負責從從緩沖區讀取取該數據。顯顯然,當任務務A還未向緩緩沖區寫入數數據時(緩沖沖區為空時)),任務B因因不能從緩沖沖區得到有效效數據而應該該處于等待狀狀態,只有等等任務A向緩緩沖區寫入了了數據之后,,才應該通知知任務B去取取數據。例如,任務A和任務B共共享一臺打印印機,如果系系統已經把打打印機分配給給了任務A,,則任務B因因不能獲得打打印機的使用用權而應該處處于等待狀態態,只有當任任務A把打印印機釋放后,,系統才能喚喚醒任務B使使其獲得打印印機的使用權權。如果這兩兩個任務不這這樣做,那么么也會造成極極大的混亂。總之,多個任任務共享同一一資源或有工工作順序要求求時,在正式式工作之前要要互相打招呼呼。黃宏:別走啊?。∷蔚さぃ何易宰约旱耐?,我我愛走就走,,你管不著!!黃宏:腿是你你自己的,但但手是咱倆的的呀!事件任務間的同步步依賴于任務務間的通信。。在μC/OS-II中,是使使用信號量、、郵箱(消息息郵箱)和消消息隊列這些些被稱作事件件的中間環節節來實現任務務之間的通信信的。宋丹丹黃宏一個簡單的信信號量1/0收信方發信方共享資源事件控制塊為了把描述事事件的數據結結構統一起來來,μC/OS-II使用叫做做事件控制塊塊ECB的數數據結構來描描述諸如信號號量、郵箱((消息郵箱))和消息隊列列這些事件。。事件控制塊塊中包含包括括等待任務表表在內的所有有有關事件的的數據typedefstruct{INT8UOSEventType;//事件件的類型INT16UOSEventCnt;//信號量量計數器void*OSEventPtr; //消息或消息息隊列的指針針INT8UOSEventGrp;//等待事件件的任務組INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//任務等等待表}OS_EVENT;把一個任務置置于等待狀態態要調用OS_EventTaskWait()函數。。該函數的原原型為:voidOS_EventTaskWait(OS_EVENT*pevent //事件件控制塊的指指針);函數OS_EventTaskWait(),將在任任務調用函數數OS××××Pend()請求求一個事件時時,被OS××××Pend()所所調用。如果一個正在在等待的任務務具備了可以以運行的條件件,那么就要要使它進入就就緒狀態。這這時要調用OS_EventTaskRdy()函數。。該函數的作作用就是把調調用這個函數數的任務在任任務等待表中中的位置清0(解除等待待狀態)后,,再把任務在在任務就緒表表中對應的位位置1,然后后引發一次任任務調度。OS_EventTaskRdy()函數的的原型為:INT8UOS_EventTaskRdy(OS_EVENT*pevent, //事件控制塊塊的指針void*msg,//未使用INT8Umsk//清除除TCB狀態態標志掩碼);函數OS_EventTaskRdy()將在任務調調用函數OS×××Post()發送一一個事件時,,被函數OS×××Post()所調用。。如果一個正在在等待事件的的任務已經超超過了等待的的時間,卻仍仍因為沒有獲獲取事件等原原因而未具備備可以運行的的條件,卻又又要使它進入入就緒狀態,,這時要調用用OS_EventTO()函數數。OS_EventTO()函數的原型為為:voidOS_EventTO(OS_EVENT*pevent //事件控制塊塊的指針);函數OS_EventTO()將在任務調用用OS×××Pend()請求一個事件件時,被函數數OS×××Pend()所調用??帐录刂茐K塊鏈表在μC/OS-II初始化時時,系統會在在初始化函數數OSInit()中中按應用程序序使用事件的的總數OS_MAX_EVENTS(在文件OS_CFG.H中定義義),創建OS_MAX_EVENTS個空事事件控制塊并并借用成員OSEventPtr作作為鏈接指針針,把這些空空事件控制塊塊鏈接成一個個單向鏈表。。由于鏈表中中的所有控制制塊尚未與具具體事件相關關聯,故該鏈鏈表叫做空事事件控制塊鏈鏈表。以后,,每當應用程程序創建一個個事件時,系系統就會從鏈鏈表中取出一一個空事件控控制塊,并對對它進行初始始化以描述該該事件。而當當應用程序刪刪除一個事件件時,就會將將該事件的控控制塊歸還給給空事件控制制塊鏈表信號量及其操操作在使用信號量量之前,應用用程序必須調調用函數OSSemCreate()來創建建一個信號量量,OSSemCreate()的原型為::OS_EVENT*OSSemCreate(INT16Ucnt//信號號量計數器初初值);函數的返回值值為已創建的的信號量的指指針。任務通過調用用函數OSSemPend()請請求信號量,,函數OSSemPend()的的原型如下::voidOSSemPend(OS_EVENT*pevent,//信號量量的指針INT16Utimeout,//等待待時限INT8U*err); //錯誤信息參數pevent是被請請求信號量的的指針。為防止任務因因得不到信號號量而處于長長期的等待狀狀態,函數OSSemPend允許許用參數timeout設置一個等等待時間的限限制,當任務務等待的時間間超過timeout時時可以結束等等待狀態而進進入就緒狀態態。如果參數數timeout被設置置為0,則表表明任務的等等待時間為無無限長。任務獲得信號號量,并在訪訪問共享資源源結束以后,,必須要釋放放信號量,釋釋放信號量也也叫做發送信信號量,發送送信號量需調調用函數OSSemPost()。OSSemPost()函數在對信信號量的計數數器操作之前前,首先要檢檢查是否還有有等待該信號號量的任務。。如果沒有,,就把信號量量計數器OSEventCnt加一一;如果有,,則調用調度度器OS_Sched()去運行行等待任務中中優先級別最最高的任務。。函數OSSemPost()的的原型為:INT8UOSSemPost (OS_EVENT*pevent //信號號量的指針);調用函數成功功后,函數返返回值為OS_ON_ERR,否則則會根據具體體錯誤返回OS_ERR_EVENT_TYPE、OS_SEM_OVF。應用程序如果果不需要某個個信號量了,,那么可以調調用函數OSSemDel()來來刪除該信號號量,這個函函數的原型為為:OS_EVENT*OSSemDel(OS_EVENT*pevent, //信號量的的指針INT8Uopt,//刪刪除條件選選項INT8U*err//錯誤誤信息);互斥型信號號量和任務務優先級反反轉在可剝奪型型內核中,,當任務以以獨占方式式使用共享享資源時,,會出現低低優先級任任務先于高高優先級任任務而被運運行的現象象,這種現現象叫做任任務優先級級反轉。在一般情情況下是不不允許出現現這種任務務優先級反反轉現象的的,下面就就對優先級級的反轉現現象做一個個詳細的分分析,以期期找出原因因及解決方方法。圖4-15描述了A、B、C三個任務務的運行情情況。其中中,任務A的優先級級別高于任任務B,任任務B的優優先級別高高于任務C。任務A和任務C都要使用用同一個共共享資源S,而用于于保護該資資源的信號號量在同一一時間只能能允許一個個任務以獨獨占的方式式對該資源源進行訪問問,即這個個信號量是是一個互斥斥型信號量量。通過例子可可以發現,,使用信號號量的任務務是否能夠夠運行是受受任務的優優先級別和和是否占用用信號量兩兩個條件約約束的,而而信號量的的約束高于于優先級別別的約束。。于是當出出現低優先先級別的任任務與高優優先級別的的任務使用用同一個信信號量,而而系統中還還存有別的的中等優先先級別的任任務時,如如果低優先先級別的任任務先獲得得了信號量量,就會使使高級別的的任務處于于等待狀態態,而那些些不使用該該信號量的的中等級別別的任務卻卻可以剝奪奪低優先級級別的任務務的CPU使用權而而先于高優優先級別的的任務而運運行了。解決問題的的辦法之一一,是使獲獲得信號量量任務的優優先級別在在使用共享享資源期間間暫時提升升到所有任任務最高優優先級的高高一個級別別上,以使使該任務不不被其他的的任務所打打斷,從而而能盡快地地使用完共共

溫馨提示

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

評論

0/150

提交評論