嵌入式實時操作系統(tǒng)分析課件_第1頁
嵌入式實時操作系統(tǒng)分析課件_第2頁
嵌入式實時操作系統(tǒng)分析課件_第3頁
嵌入式實時操作系統(tǒng)分析課件_第4頁
嵌入式實時操作系統(tǒng)分析課件_第5頁
已閱讀5頁,還剩319頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

嵌入式系統(tǒng)設(shè)計與實例開發(fā)—基于32位微處理器與實時操作系統(tǒng)實時操作系統(tǒng)C/OS-Ⅱ分析2009.4嵌入式系統(tǒng)設(shè)計與實例開發(fā)實時操作系統(tǒng)C/OS-II1324C/OS-II概述任務(wù)管理中斷和時間管理任務(wù)之間的通信與同步5存儲管理實時操作系統(tǒng)C/OS-II1324C/OS-II概述任務(wù)通用操作系統(tǒng)和嵌入式(實時)操作系統(tǒng)通用操作系統(tǒng):Windows/NT/XP、Linux、UNIX等,用于PC機(jī)、服務(wù)器,嵌入式(實時)操作系統(tǒng):用于嵌入式設(shè)備的操作系統(tǒng),具有通用操作系統(tǒng)的基本特點,又具有系統(tǒng)實時性、硬件的相關(guān)依賴性、軟件固態(tài)化以及應(yīng)用的專用性等特點;嵌入式(實時)操作系統(tǒng)通常包括與硬件相關(guān)的底層驅(qū)動軟件、系統(tǒng)內(nèi)核、設(shè)備驅(qū)動接口、通信協(xié)議、圖形界面、標(biāo)準(zhǔn)化瀏覽器Browser等;嵌入式(實時)操作系統(tǒng)的重要指標(biāo):實時性(中斷響應(yīng)時間、任務(wù)切換時間等)、尺寸(可裁剪性)、可擴(kuò)展性(內(nèi)核、中間件);通用操作系統(tǒng)和嵌入式(實時)操作系統(tǒng)通用操作系統(tǒng):Windo嵌入式操作系統(tǒng)的發(fā)展操作系統(tǒng)內(nèi)核應(yīng)用程序驅(qū)動程序和固件操作系統(tǒng)內(nèi)核文件系統(tǒng)驅(qū)動程序和固件APIGUI應(yīng)用程序操作系統(tǒng)內(nèi)核文件系統(tǒng)驅(qū)動程序和固件APIGUI應(yīng)用程序通信協(xié)議庫函數(shù)80年代初期80年代中期-90年代中期90年代末期-21世紀(jì)嵌入式操作系統(tǒng)的發(fā)展操作系統(tǒng)內(nèi)核應(yīng)用程序驅(qū)動程序和固件操作系常見的嵌入式操作系統(tǒng)實時嵌入式操作系統(tǒng)的種類繁多,大體上可分為兩種,商用型和免費(fèi)型。商用型的實操作系統(tǒng)功能穩(wěn)定、可靠,有完善的技術(shù)支持和售后服務(wù),但往往價格昂貴,如Vxworks、QNX、WinCE、PalmOS等。免費(fèi)型的實時操作系統(tǒng)在價格方面具有優(yōu)勢,目前主要有Linux,μC/OS是一種源碼開放的商業(yè)RTOS;μC/OS是商業(yè)操作系統(tǒng)常見的嵌入式操作系統(tǒng)實時嵌入式操作系統(tǒng)的種類繁多,大體上學(xué)習(xí)嵌入式操作系統(tǒng)

學(xué)習(xí)一種實時操作系統(tǒng)RTOS,如uc/OS,掌握實時系統(tǒng)的概念和設(shè)計方法;嵌入式系統(tǒng)以應(yīng)用為中心,應(yīng)用時選擇“適用”的操作系統(tǒng);嵌入式Linux;自己“寫”RTOS——一種學(xué)習(xí)態(tài)度;學(xué)習(xí)嵌入式操作系統(tǒng)RTOS在嵌入式系統(tǒng)中的位置嵌入式硬件平臺BSPKERNELFSTCP/IP設(shè)備驅(qū)動設(shè)備I/O調(diào)試工具其它組件應(yīng)用RTOSC/C++RTOS在嵌入式系統(tǒng)中的位置嵌入式硬件平臺BSPKERNELC/OS簡介

1、C/OS——MicroControllerOS,微控制器操作系統(tǒng)2、C/OS簡介美國人JeanLabrosse1992年完成應(yīng)用面覆蓋了諸多領(lǐng)域,如照相機(jī)、醫(yī)療器械、音響設(shè)備、發(fā)動機(jī)控制、高速公路電話系統(tǒng)、自動提款機(jī)等1998年C/OS-II,目前的版本C/OS-IIV2.61,2.722000年,得到美國航空管理局(FAA)的認(rèn)證,可以用于飛行器中網(wǎng)站www.ucos-II.com()C/OS簡介

1、C/OS——MicroControl公開源代碼可移植性(Portable)

絕大部分C/OS-II的源碼是用移植性很強(qiáng)的ANSIC寫的。和微處理器硬件相關(guān)的那部分是用匯編語言寫的。匯編語言寫的部分已經(jīng)壓到最低限度,使得C/OS-II便于移植到其他微處理器上。C/OS-II可以在絕大多數(shù)8位、16位、32位以至64位微處理器、微控制器、數(shù)字信號處理器(DSP)上運(yùn)行??晒袒≧OMable)

C/OS-II是為嵌入式應(yīng)用而設(shè)計的,這就意味著,只要讀者有固化手段(C編譯、連接、下載和固化),C/OS-II可以嵌入到讀者的產(chǎn)品中成為產(chǎn)品的一部分。可裁剪(Scalable)

可以只使用C/OS-II中應(yīng)用程序需要的那些系統(tǒng)服務(wù)。也就是說某產(chǎn)品可以只使用很少幾個C/OS-II調(diào)用,而另一個產(chǎn)品則使用了幾乎所有C/OS-II的功能,這樣可以減少產(chǎn)品中的C/OS-II所需的存儲器空間(RAM和ROM)。這種可剪裁性是靠條件編譯實現(xiàn)的。C/OS的性能特點(一)公開源代碼C/OS的性能特點(一)占先式(Preemptive)總是運(yùn)行就緒條件下優(yōu)先級最高的任務(wù)。多任務(wù)

C/OS-II可以管理64個任務(wù),然而,目前這一版本保留8個給系統(tǒng)。應(yīng)用程序最多可以有56個任務(wù)。可確定性

全部C/OS-II的函數(shù)調(diào)用與服務(wù)的執(zhí)行時間具有可確定性。任務(wù)棧

每個任務(wù)有自己單獨的棧,C/OS-II允許每個任務(wù)有不同的??臻g,以便壓低應(yīng)用程序?qū)AM的需求。系統(tǒng)服務(wù)

C/OS-II提供很多系統(tǒng)服務(wù),例如郵箱、消息隊列、信號量、塊大小固定的內(nèi)存的申請與釋放、時間相關(guān)函數(shù)等。中斷管理

中斷可以使正在執(zhí)行的任務(wù)暫時掛起,如果優(yōu)先級更高的任務(wù)被該中斷喚醒,則高優(yōu)先級的任務(wù)在中斷嵌套全部退出后立即執(zhí)行,中斷嵌套層數(shù)可達(dá)255層。穩(wěn)定性與可靠性C/OS的性能特點(二)占先式(Preemptive)C/OS的性能特點(二)μC/OS-II圖書描述了μC/OS-II內(nèi)部的工作原理隨書的CD中包含了源代碼工業(yè)界最清晰的源代碼除英文版外,有中文和韓文版ChineseKoreanEnglishISBN1-57820-103-9美國CMPBOOKISBN7-81077-290-2北京航空航天大學(xué)出版社ISBN89-951540-5-5μC/OS-II圖書描述了μC/OS-II內(nèi)部的工作原理ChμC/OS-II的各種商業(yè)應(yīng)用全世界有數(shù)百種產(chǎn)品在應(yīng)用:AvionicsMedicalCellphonesRoutersandswitchesHigh-endaudioequipmentWashingmachinesanddryersUPS(UninterruptiblePowerSupplies)IndustrialcontrollersGPSNavigationSystemsMicrowaveRadiosInstrumentationPoint-of-saleterminals更多μC/OS-II的各種商業(yè)應(yīng)用全世界有數(shù)百種產(chǎn)品在應(yīng)用:μC/OS-II提供的系統(tǒng)服務(wù)信號量帶互斥機(jī)制的信號量減少優(yōu)先級倒置的問題事件標(biāo)志消息信箱消息隊列內(nèi)存管理時鐘管理任務(wù)管理μC/OS-II提供的系統(tǒng)服務(wù)信號量μC/GUIandμC/FSμC/GUI嵌入式的用戶界面用ANSIC書寫支持任何8,16,32-bitsCPU彩色,灰、度,等級或黑白顯示代碼尺寸小μC/FS嵌入式的文件系統(tǒng)WritteninANSIC用ANSIC書寫支持任何8,16,32-bitsCPU支持SMC,MMC,SD,CF,IDE,Flash,RAM其他介質(zhì)μC/GUIandμC/FSμC/GUI可移植的數(shù)據(jù)類型typedefunsignedcharBOOLEAN;typedefunsignedcharINT8U;typedefsignedcharINT8S;typedefunsignedintINT16U;typedefsignedintINT16S;typedefunsignedlongINT32U;typedefsignedlongINT32S;typedeffloatFP32;typedefdoubleFP64;可移植的數(shù)據(jù)類型typedefunsignedcharC/OS-II的文件結(jié)構(gòu)C/OS-II的文件結(jié)構(gòu)1324C/OS-II概述任務(wù)管理中斷和時間管理任務(wù)之間的通信與同步5存儲管理1324C/OS-II概述任務(wù)管理中斷和時間管理任務(wù)之間的任務(wù)的實現(xiàn)創(chuàng)建任務(wù)的系統(tǒng)服務(wù)OSTaskCreate()INT8UOSTaskCreate(

void(*task)(void*pd),//任務(wù)代碼指針

void*pdata,//任務(wù)參數(shù)指針

OS_STK*ptos,//任務(wù)棧的棧頂指針

INT8Uprio//任務(wù)的優(yōu)先級

);OSTaskCreateExt()任務(wù)的實現(xiàn)創(chuàng)建任務(wù)的系統(tǒng)服務(wù)任務(wù)主函數(shù)一個任務(wù)通常是一個無限循環(huán)(返回值類型void)voidMyTask(void*pdata){while(1){dosomething;waiting; dosomething; }}任務(wù)主函數(shù)一個任務(wù)通常是一個無限循環(huán)(返回值類型void)任務(wù)也可以自我刪除(并非真的刪除,只是內(nèi)核不再知道該任務(wù))voidMyTask(void*pdata){....../*用戶代碼*/OSTaskDel(OS_PRIO_SELF);}任務(wù)也可以自我刪除(并非真的刪除,只是內(nèi)核不再知道該任務(wù))μC/OS-Ⅱ可以管理多達(dá)64個任務(wù);每個任務(wù)被賦以不同的優(yōu)先級,取值從0到OS_LOWEST_PRIO-2,數(shù)值越小,優(yōu)先級越高;系統(tǒng)保留了優(yōu)先級為0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及OS_LOWEST_PRI0這8個任務(wù)以被將來使用,用戶可以有56個應(yīng)用任務(wù);任務(wù)的優(yōu)先級同樣也是它的標(biāo)識號ID。OS_CFG.H

中定義=61μC/OS-Ⅱ可以管理多達(dá)64個任務(wù);OS_CFG.H

中定空閑任務(wù)和統(tǒng)計任務(wù)內(nèi)核總是創(chuàng)建一個空閑任務(wù)OSTaskIdle();總是設(shè)置為最低優(yōu)先級,OS_LOWEST_PRIO;當(dāng)所有其他任務(wù)都未在執(zhí)行時,空閑任務(wù)開始執(zhí)行;應(yīng)用程序不能刪除該任務(wù);空閑任務(wù)的工作就是把32位計數(shù)器OSIdleCtr加1,該計數(shù)器被統(tǒng)計任務(wù)所使用;統(tǒng)計任務(wù)OSTaskStat(),提供運(yùn)行時間統(tǒng)計。每秒鐘運(yùn)行一次,計算當(dāng)前的CPU利用率。其優(yōu)先級是OS_LOWEST_PRIO-1,可選??臻e任務(wù)和統(tǒng)計任務(wù)內(nèi)核總是創(chuàng)建一個空閑任務(wù)OSTaskIdl任務(wù)控制塊TCB任務(wù)控制塊OS_TCB是描述一個任務(wù)的核心數(shù)據(jù)結(jié)構(gòu),存放了它的各種管理信息,包括任務(wù)堆棧指針,任務(wù)的狀態(tài)、優(yōu)先級,任務(wù)鏈表指針等;一旦任務(wù)建立了,任務(wù)控制塊OS_TCB將被賦值。任務(wù)控制塊TCB任務(wù)控制塊OS_TCB是描述一個任務(wù)的核心任務(wù)控制塊TCBtypedefstructos_tcb{棧指針;INT16UOSTCBId;/*任務(wù)的ID*/鏈表指針;OS_EVENT*OSTCBEventPtr;/*事件指針*/void*OSTCBMsg;/*消息指針*/INT8UOSTCBStat;/*任務(wù)的狀態(tài)*/INT8UOSTCBPrio;/*任務(wù)的優(yōu)先級*/其他……}OS_TCB;任務(wù)控制塊TCBtypedefstructos_tcb棧指針OSTCBStkPtr:指向當(dāng)前任務(wù)棧頂?shù)闹羔?,每個任務(wù)可以有自己的棧,棧的容量可以是任意的;OSTCBStkBottom:指向任務(wù)棧底的指針;OSTCBStkSize:棧的容量,用可容納的指針數(shù)目而不是字節(jié)數(shù)(Byte)來表示。棧指針OSTCBStkPtr:指向當(dāng)前任務(wù)棧頂?shù)闹羔?,每個任嵌入式實時操作系統(tǒng)分析課件鏈表指針?biāo)械娜蝿?wù)控制塊分屬于兩條不同的鏈表,單向的空閑鏈表(頭指針為OSTCBFreeList)和雙向的使用鏈表(頭指針為OSTCBList);OSTCBNext、OSTCBPrev:用于將任務(wù)控制塊插入到空閑鏈表或使用鏈表中。每個任務(wù)的任務(wù)控制塊在任務(wù)創(chuàng)建的時候被鏈接到使用鏈表中,在任務(wù)刪除的時候從鏈表中被刪除。雙向連接的鏈表使得任一成員都能快速插入或刪除。鏈表指針?biāo)械娜蝿?wù)控制塊分屬于兩條不同的鏈表,單向的空閑鏈表空閑TCB鏈表所有的任務(wù)控制塊都被放置在任務(wù)控制塊列表數(shù)組OSTCBTbl[]中,系統(tǒng)初始化時,所有TCB被鏈接成空閑的單向鏈表,頭指針為OSTCBFreeList。當(dāng)創(chuàng)建一個任務(wù)后,就把OSTCBFreeList所指向的TCB賦給了該任務(wù),并將它加入到使用鏈表中,然后把OSTCBFreeList指向空閑鏈表中的下一個結(jié)點??臻eTCB鏈表所有的任務(wù)控制塊都被放置在任務(wù)控制塊列表數(shù)組O系統(tǒng)初始化后…指針數(shù)組,指向相應(yīng)TCB系統(tǒng)初始化后…指針數(shù)組,指向相應(yīng)TCB任務(wù)的狀態(tài)-休眠休眠狀態(tài)(Dormant):任務(wù)存在于內(nèi)存空間中,但內(nèi)核不可見;可以通過以下函數(shù)通知內(nèi)核,使之變?yōu)榫途w狀態(tài):OSTaskCreate()或OSTaskCreateExt()可以通過以下函數(shù)返回到休眠狀態(tài):OSTaskDel()

任務(wù)的狀態(tài)-休眠休眠狀態(tài)(Dormant):任務(wù)存在于內(nèi)存空任務(wù)的狀態(tài)-就緒就緒狀態(tài)(Ready):萬事具備,只欠CPU;在所有的就緒任務(wù)當(dāng)中,具有最高優(yōu)先級的任務(wù)被選中去運(yùn)行;如果任務(wù)在運(yùn)行的時候被搶占了CPU,則又回到就緒狀態(tài)。任務(wù)的狀態(tài)-就緒就緒狀態(tài)(Ready):萬事具備,只欠CPU任務(wù)的狀態(tài)-運(yùn)行運(yùn)行狀態(tài)(Running):任務(wù)在CPU上運(yùn)行;當(dāng)一個任務(wù)在運(yùn)行時,如果沒有關(guān)閉中斷,則有可能被中斷所打斷;當(dāng)一個任務(wù)在運(yùn)行時,可能因為各種原因進(jìn)入阻塞狀態(tài)。OSMBoxPend(),OSQPend(),OSSemPend()OSTaskSuspend(),OSTimeDly()任務(wù)的狀態(tài)-運(yùn)行運(yùn)行狀態(tài)(Running):任務(wù)在CPU上運(yùn)任務(wù)的狀態(tài)-ISR中斷服務(wù)狀態(tài)(ISR):該任務(wù)原來在CPU上運(yùn)行,后來被中斷所打斷,由中斷服務(wù)程序ISR接管了CPU;當(dāng)中斷服務(wù)程序運(yùn)行完畢后,內(nèi)核要判斷是否有新的、更高優(yōu)先級的任務(wù)就緒,如果有,則原有的任務(wù)被搶占;如果沒有,則原有的任務(wù)重新運(yùn)行。任務(wù)的狀態(tài)-ISR中斷服務(wù)狀態(tài)(ISR):該任務(wù)原來在CPU任務(wù)的狀態(tài)-阻塞阻塞/等待狀態(tài)(Waiting):任務(wù)由于正在等待某個事件(信號量、郵箱或隊列)而被掛起;當(dāng)任務(wù)等待的事件發(fā)生時,回到就緒狀態(tài)。OSMBoxpost(),OSQPost(),OSSemPost(),OSTaskResume(),OSTimeDlyResume()或OSTimeTick()任務(wù)的狀態(tài)-阻塞阻塞/等待狀態(tài)(Waiting):任務(wù)由于正狀態(tài)的轉(zhuǎn)換刪除任務(wù)狀態(tài)的轉(zhuǎn)換刪除任務(wù)任務(wù)就緒表每個任務(wù)的就緒態(tài)標(biāo)志放入在就緒表中,就緒表中有兩個變量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任務(wù)按優(yōu)先級分組,8個任務(wù)為一組。OSRdyGrp中的每一位表示8組任務(wù)中每一組中是否有進(jìn)入就緒態(tài)的任務(wù)。任務(wù)進(jìn)入就緒態(tài)時,就緒表OSRdyTbl[]中的相應(yīng)元素的相應(yīng)位也置位。任務(wù)就緒表每個任務(wù)的就緒態(tài)標(biāo)志放入在就緒表中,就緒表中有兩個任務(wù)就緒表OSRdyGrp1207654300XXXYYY任務(wù)優(yōu)先級2017654310891514131211181617232221201926242531302928273432333938373635424041474645444350484955545352515856576362616059[0][1][2][3][4][5][6][7]OSRdyTbl[8]XY優(yōu)先級最低任務(wù)(空閑任務(wù))優(yōu)先級最高任務(wù)任務(wù)優(yōu)先級號對于整數(shù)OSRdyTbl[i](0i7),若它的某一位

為1,則OSRdyGrp的第i位為1。任務(wù)的優(yōu)先級由X和Y確定任務(wù)就緒表OSRdyGrp1207654300XXXYYY根據(jù)優(yōu)先級確定就緒表(1)假設(shè)優(yōu)先級為12的任務(wù)進(jìn)入就緒狀態(tài),12=1100b,則OSRdyTbl[1]的第4位置1,且OSRdyGrp的第1位置1,相應(yīng)的數(shù)學(xué)表達(dá)式為:

OSRdyGrp|=0x02;OSRdyTbl[1]|=0x10;而優(yōu)先級為21的任務(wù)就緒21=10101b,則OSRdyTbl[2]的第5位置1,且OSRdyGrp的第2位置1,相應(yīng)的數(shù)學(xué)表達(dá)式為:

OSRdyGrp|=0x04;OSRdyTbl[2]|=0x20;根據(jù)優(yōu)先級確定就緒表(1)假設(shè)優(yōu)先級為12的任務(wù)進(jìn)入就緒狀態(tài)根據(jù)優(yōu)先級確定就緒表(2)從上面的計算可知:若OSRdyGrp及OSRdyBbl[]的第n位置1,則應(yīng)該把OSRdyGrp及OSRdyBbl[]的值與2n相或。uC/OS中,把2n的n=0-7的8個值先計算好存在數(shù)組OSMapTbl[7]中,也就是:

OSMapTbl[0]=20=0x01(00000001)OSMapTbl[1]=21=0x02(00000010)

……OSMapTbl[7]=27=0x80(10000000)根據(jù)優(yōu)先級確定就緒表(2)從上面的計算可知:若OSRdyGr使任務(wù)進(jìn)入就緒態(tài)如果prio是任務(wù)的優(yōu)先級,即任務(wù)的標(biāo)識號,則將任務(wù)放入就緒表,即使任務(wù)進(jìn)入就緒態(tài)的方法是:OSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];假設(shè)優(yōu)先級為12——1100bOSRdyGrp|=OSMapTbl[12>>3](0x02);OSRdyTbl[1]|=0x10;使任務(wù)進(jìn)入就緒態(tài)如果prio是任務(wù)的優(yōu)先級,即任務(wù)的標(biāo)識號,使任務(wù)脫離就緒態(tài)將任務(wù)就緒表OSRdyTbl[prio>>3]相應(yīng)元素的相應(yīng)位清零,而且當(dāng)OSRdyTbl[prio>>3]中的所有位都為零時,即該任務(wù)所在組的所有任務(wù)中沒有一個進(jìn)入就緒態(tài)時,OSRdyGrp的相應(yīng)位才為零。if((OSRdyTbl[prio>>3]&=

OSMapTbl[prio&0x07])==0)OSRdyGrp&=OSMapTbl[prio>>3];使任務(wù)脫離就緒態(tài)將任務(wù)就緒表OSRdyTbl[prio>>3任務(wù)的調(diào)度C/OS是可搶占實時多任務(wù)內(nèi)核,它總是運(yùn)行就緒任務(wù)中優(yōu)先級最高的那一個。C/OS中不支持時間片輪轉(zhuǎn)法,每個任務(wù)的優(yōu)先級要求不一樣且是唯一的,所以任務(wù)調(diào)度的工作就是:查找準(zhǔn)備就緒的最高優(yōu)先級的任務(wù)并進(jìn)行上下文切換。C/OS任務(wù)調(diào)度所花的時間為常數(shù),與應(yīng)用程序中建立的任務(wù)數(shù)無關(guān)。任務(wù)的調(diào)度C/OS是可搶占實時多任務(wù)內(nèi)核,它總是運(yùn)行就緒任確定哪個任務(wù)的優(yōu)先級最高,應(yīng)該選擇哪個任務(wù)去運(yùn)行,這部分的工作是由調(diào)度器(Scheduler)來完成的。任務(wù)級的調(diào)度是由函數(shù)OSSched()完成的;中斷級的調(diào)度是由另一個函數(shù)OSIntExt()完成的。確定哪個任務(wù)的優(yōu)先級最高,應(yīng)該選擇哪個任務(wù)去運(yùn)行,這部分的工根據(jù)就緒表確定最高優(yōu)先級兩個關(guān)鍵:將優(yōu)先級數(shù)分解為高三位和低三位分別確定;高優(yōu)先級有著小的優(yōu)先級號;根據(jù)就緒表確定最高優(yōu)先級兩個關(guān)鍵:根據(jù)就緒表確定最高優(yōu)先級通過OSRdyGrp值確定高3位,假設(shè)OSRdyGrp=0x08=

0x00001000,第3位為1,優(yōu)先級的高3位為011;通過OSRdyTbl[3]的值來確定低3位,假設(shè)OSRdyTbl[3]=0x3a,第1位為1,優(yōu)先級的低3位為001,3*8+1=2500011001任務(wù)優(yōu)先級根據(jù)就緒表確定最高優(yōu)先級通過OSRdyGrp值確定高3位,假任務(wù)調(diào)度器voidOSSched(void){INT8Uy;

OS_ENTER_CRITICAL();if((OSLockNesting|OSIntNesting)==0){ y=OSUnMapTbl[OSRdyGrp];OSPrioHighRdy=(INT8U)((y<<3)+ OSUnMapTbl[OSRdyTbl[y]]); if(OSPrioHighRdy!=OSPrioCur){ OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;OS_TASK_SW();}}OS_EXIT_CRITICAL();}檢查是否中斷調(diào)用和允許任務(wù)調(diào)用找到優(yōu)先級最高的任務(wù)該任務(wù)是否正在運(yùn)行任務(wù)調(diào)度器voidOSSched(void)檢查是否中斷源代碼中使用了查表法查表法具有確定的時間,增加了系統(tǒng)的可預(yù)測性,uC/OS中所有的系統(tǒng)調(diào)用時間都是確定的Y=OSUnMapTbl[OSRdyGrp];X=OSUnMapTbl[OSRdyTbl[Y]];Prio=(Y<<3)+X;參見OS_CORE.C源代碼中使用了查表法查表法具有確定的時間,增加了系統(tǒng)的可預(yù)測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};優(yōu)先級判定表OSUnMapTbl[256]舉例:

如OSRdyGrp的值為01101000B,即0X68,則查得OSUnMapTbl[OSRdyGrp]的值是3,它相應(yīng)于OSRdyGrp中的第3位置1;如OSRdyTbl[3]的值是11100100B,即0XE4,則查OSUnMapTbl[OSRdyTbl[3]]的值是2,則進(jìn)入就緒態(tài)的最高任務(wù)優(yōu)先級Prio=3*8+2=26

INT8UconstOSUnMapTbl[]={優(yōu)先任務(wù)切換將被掛起任務(wù)的寄存器內(nèi)容入棧;將較高優(yōu)先級任務(wù)的寄存器內(nèi)容出棧,恢復(fù)到硬件寄存器中。任務(wù)切換將被掛起任務(wù)的寄存器內(nèi)容入棧;任務(wù)級的任務(wù)切換OS_TASK_SW()通過sc系統(tǒng)調(diào)用指令完成保護(hù)當(dāng)前任務(wù)的現(xiàn)場恢復(fù)新任務(wù)的現(xiàn)場執(zhí)行中斷返回指令開始執(zhí)行新的任務(wù)任務(wù)級的任務(wù)切換OS_TASK_SW()通過sc系統(tǒng)調(diào)用指令調(diào)用OS_TASK_SW()前的數(shù)據(jù)結(jié)構(gòu)低優(yōu)先級任務(wù)OS_TCBOSTCBCur(1)存貯器低地址存貯器高地址堆棧方向SPR1R2R3R4PCPSW存貯器低地址存貯器高地址高優(yōu)先級任務(wù)OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)調(diào)用OS_TASK_SW()前的數(shù)據(jù)結(jié)構(gòu)低優(yōu)先級任務(wù)OSTC保存當(dāng)前CPU寄存器的值低優(yōu)先級任務(wù)OS_TCBOSTCBCurPSWPCR1R2R3R4存貯器低地址存貯器高地址堆棧方向SPR1R2R3R4PCPSW存貯器低地址存貯器高地址高優(yōu)先級任務(wù)OS_TCBOSTCBHighRdy(3)(2)CPU(4)(5)(1)(3)保存當(dāng)前CPU寄存器的值低優(yōu)先級任務(wù)OSTCBCurPSWP重新裝入要運(yùn)行的任務(wù)低優(yōu)先級任務(wù)OS_TCBOSTCBCurPSWPCR1R2R3R4存貯器低地址存貯器高地址堆棧方向SPR1R2R3R4PCPSWPSWPCR1R2R3R4存貯器低地址存貯器高地址高優(yōu)先級任務(wù)OS_TCBOSTCBHighRdyOSTCBCur(1)(2)CPU(4)(4)(1)(3)(3)(4)重新裝入要運(yùn)行的任務(wù)低優(yōu)先級任務(wù)OSTCBCurPSWPCR任務(wù)切換OS_TASK_SW()的代碼VoidOSCtxSw(void){將R1,R2,R3及R4推入當(dāng)前堆棧;OSTCBCurOSTCBStkPtr=SP;OSTCBCur=OSTCBHighRdy;SP=OSTCBHighRdyOSTCBSTKPtr;將R4,R3,R2及R1從新堆棧中彈出;執(zhí)行中斷返回指令;}任務(wù)切換OS_TASK_SW()的代碼VoidOSCtxS給調(diào)度器上鎖OSSchedlock():給調(diào)度器上鎖函數(shù),用于禁止任務(wù)調(diào)度,保持對CPU的控制權(quán)(即使有優(yōu)先級更高的任務(wù)進(jìn)入了就緒態(tài));OSSchedUnlock():給調(diào)度器開鎖函數(shù),當(dāng)任務(wù)完成后調(diào)用此函數(shù),調(diào)度重新得到允許;當(dāng)?shù)蛢?yōu)先級的任務(wù)要發(fā)消息給多任務(wù)的郵箱、消息隊列、信號量時,它不希望高優(yōu)先級的任務(wù)在郵箱、隊列和信號量還沒有得到消息之前就取得了CPU的控制權(quán),此時,可以使用調(diào)度器上鎖函數(shù)。給調(diào)度器上鎖OSSchedlock():給調(diào)度器上鎖函數(shù),用任務(wù)管理的系統(tǒng)服務(wù)創(chuàng)建任務(wù)刪除任務(wù)修改任務(wù)的優(yōu)先級掛起和恢復(fù)任務(wù)獲得一個任務(wù)的有關(guān)信息任務(wù)管理的系統(tǒng)服務(wù)創(chuàng)建任務(wù)創(chuàng)建任務(wù)創(chuàng)建任務(wù)的函數(shù)OSTaskCreate();OSTaskCreateExt();OSTaskCreateExt()是OSTaskCreate()的擴(kuò)展版本,提供了一些附加的功能;任務(wù)可以在多任務(wù)調(diào)度開始(即調(diào)用OSStart())之前創(chuàng)建,也可以在其它任務(wù)的執(zhí)行過程中被創(chuàng)建。但在OSStart()被調(diào)用之前,用戶必須創(chuàng)建至少一個任務(wù);不能在中斷服務(wù)程序(ISR)中創(chuàng)建新任務(wù)。創(chuàng)建任務(wù)創(chuàng)建任務(wù)的函數(shù)OSTaskCreate()INT8UOSTaskCreate(

void(*task)(void*pd),//任務(wù)代碼指針

void*pdata,//任務(wù)參數(shù)指針

OS_STK*ptos,//任務(wù)棧的棧頂指針

INT8Uprio//任務(wù)的優(yōu)先級

);返回值 OS_NO_ERR:函數(shù)調(diào)用成功;

OS_PRIO_EXIT:任務(wù)優(yōu)先級已經(jīng)存在;

OS_PRIO_INVALID:任務(wù)優(yōu)先級無效。OSTaskCreate()INT8UOSTaskCreaOSTaskCreate()的實現(xiàn)過程任務(wù)優(yōu)先級檢查該優(yōu)先級是否在0到OS_LOWSEST_PRIO之間?該優(yōu)先級是否空閑?調(diào)用OSTaskStkInit(),創(chuàng)建任務(wù)的棧幀;調(diào)用OSTCBInit(),從空閑的OS_TCB池(即OSTCBFreeList鏈表)中獲得一個TCB并初始化其內(nèi)容,然后把它加入到OSTCBList鏈表的開頭,并把它設(shè)定為就緒狀態(tài);任務(wù)個數(shù)OSTaskCtr加1;調(diào)用用戶自定義的函數(shù)OSTaskCreateHook();判斷是否需要調(diào)度(調(diào)用者是正在執(zhí)行的任務(wù))OSTaskCreate()的實現(xiàn)過程任務(wù)優(yōu)先級檢查OSTaskCreateExt()INT8UOSTaskCreateExt(

前四個參數(shù)與OSTaskCreate相同,

INT16Uid,//任務(wù)的ID

OS_STK*pbos,//指向任務(wù)棧底的指針

INT32Ustk_size,//棧能容納的成員數(shù)目

void*pext,//指向用戶附加數(shù)據(jù)域的指針

INT16Uopt//一些選項信息

);返回值:與OSTaskCreate()相同。OSTaskCreateExt()INT8UOSTaskC任務(wù)的??臻g每個任務(wù)都有自己的??臻g(Stack),棧必須聲明為OS_STK類型,并且由連續(xù)的內(nèi)存空間組成;??臻g的分配方法靜態(tài)分配:在編譯的時候分配,例如:

staticOS_STKMyTaskStack[stack_size];

OS_STKMyTaskStack[stack_size];動態(tài)分配:在任務(wù)運(yùn)行的時候使用malloc()函數(shù)來動態(tài)申請內(nèi)存空間;任務(wù)的棧空間每個任務(wù)都有自己的??臻g(Stack),棧必須聲OS_STK*pstk;

pstk=(OS_STK*)malloc(stack_size);/*確認(rèn)malloc()能得到足夠的內(nèi)存空間*/

if(pstk!=(OS_STK*)0){Createthetask;}

動態(tài)分配OS_STK*pstk;動態(tài)分配內(nèi)存碎片問題在動態(tài)分配中,可能存在內(nèi)存碎片問題。特別是當(dāng)用戶反復(fù)地建立和刪除任務(wù)時,內(nèi)存堆中可能會出現(xiàn)大量的碎片,導(dǎo)致沒有足夠大的一塊連續(xù)內(nèi)存區(qū)域可用作任務(wù)棧,這時malloc()便無法成功地為任務(wù)分配??臻g。3Kb堆初始狀態(tài)A(1Kb)B(1Kb)C(1Kb)3個任務(wù)1KbB(1Kb)1Kb刪除A,C內(nèi)碎片/

外碎片?內(nèi)存碎片問題在動態(tài)分配中,可能存在內(nèi)存碎片問題。特別是當(dāng)用戶棧的增長方向棧的增長方向的設(shè)置從低地址到高地址:在OS_CPU.H中,將常量OS_STK_GROWTH設(shè)定為0;從高地址到低地址:在OS_CPU.H中,將常量OS_STK_GROWTH設(shè)定為1;OS_STKTaskStack[TASK_STACK_SIZE];OSTaskCreate(task,pdata,

&TaskStack[TASK_STACK_SIZE-1],

prio);棧的增長方向棧的增長方向的設(shè)置刪除任務(wù)OSTaskDel():刪除一個任務(wù),其TCB會從所有可能的系統(tǒng)數(shù)據(jù)結(jié)構(gòu)中移除。任務(wù)將返回并處于休眠狀態(tài)(任務(wù)的代碼還在)。如果任務(wù)正處于就緒狀態(tài),把它從就緒表中移出,這樣以后就不會再被調(diào)度執(zhí)行了;如果任務(wù)正處于郵箱、消息隊列或信號量的等待隊列中,也把它移出;將任務(wù)的OS_TCB從OSTCBList鏈表當(dāng)中移動到OSTCBFreeList。刪除任務(wù)OSTaskDel():刪除一個任務(wù),其TCB會從所OSTaskChangePrio():在程序運(yùn)行期間,用戶可以通過調(diào)用本函數(shù)來改變某個任務(wù)的優(yōu)先級。 INT8UOSTaskChangePrio(INT8Uoldprio,

INT8Unewprio)OSTaskQuery():獲得一個任務(wù)的有關(guān)信息獲得的是對應(yīng)任務(wù)的OS_TCB中內(nèi)容的拷貝。OSTaskChangePrio():在程序運(yùn)行期間,用戶可OSTaskSuspend():掛起一個任務(wù)如果任務(wù)處于就緒態(tài),把它從就緒表中移出;在任務(wù)的TCB中設(shè)置OS_STAT_SUSPEND標(biāo)志,表明該任務(wù)正在被掛起。OSTaskResume():恢復(fù)一個任務(wù)恢復(fù)被OSTaskSuspend()掛起的任務(wù);清除TCB中OSTCBStat字段的OS_STAT_SUSPEND位掛起和恢復(fù)任務(wù)OSTaskSuspend():掛起一個任務(wù)掛起和恢復(fù)任務(wù)第三章、實時操作系統(tǒng)C/OS-II1324C/OS-II概述任務(wù)管理中斷和時間管理任務(wù)之間的通信與同步5存儲管理6C/OS-II的移植第三章、實時操作系統(tǒng)C/OS-II1324C/OS-II中斷處理中斷:由于某種事件的發(fā)生而導(dǎo)致程序流程的改變。產(chǎn)生中斷的事件稱為中斷源。CPU響應(yīng)中斷的條件:至少有一個中斷源向CPU發(fā)出中斷信號;系統(tǒng)允許中斷,且對此中斷信號未予屏蔽。中斷處理中斷:由于某種事件的發(fā)生而導(dǎo)致程序流程的改變。產(chǎn)生中中斷服務(wù)程序ISR中斷一旦被識別,CPU會保存部分(或全部)運(yùn)行上下文(context,即寄存器的值),然后跳轉(zhuǎn)到專門的子程序去處理此次事件,稱為中斷服務(wù)子程序(ISR)。μC/OS-Ⅱ中,中斷服務(wù)子程序要用匯編語言來編寫,然而,如果用戶使用的C語言編譯器支持在線匯編語言的話,用戶可以直接將中斷服務(wù)子程序代碼放在C語言的程序文件中。中斷服務(wù)程序ISR中斷一旦被識別,CPU會保存部分(或全部)(1)保存全部CPU寄存器的值;(2)調(diào)用OSIntEnter(),或直接把全局變量OSIntNesting(中斷嵌套層次)加1;(3)執(zhí)行用戶代碼做中斷服務(wù);(4)調(diào)用OSIntExit();(5)恢復(fù)所有CPU寄存器;(6)執(zhí)行中斷返回指令。用戶ISR的框架(1)保存全部CPU寄存器的值;用戶ISR的框架嵌入式實時操作系統(tǒng)分析課件OSIntEnter()/*在調(diào)用本函數(shù)之前必須先將中斷關(guān)閉*/voidOSIntEnter(void){if(OSRunning==TRUE){if(OSIntNesting<255){OSIntNesting++;}}}OSIntEnter()/*在調(diào)用本函數(shù)之前必須先將中斷關(guān)OSIntExit的意義OSIntExit的意義OSIntExit()voidOSIntExit(void){OS_ENTER_CRITICAL();//關(guān)中斷if((--OSIntNesting|OSLockNesting)==0)//判斷嵌套是否為零{//把高優(yōu)先級任務(wù)裝入OSIntExitY=OSUnMapTbl[OSRdyGrp];OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]);if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=

OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;

OSIntCtxSw();}}OS_EXIT_CRITICAL();//開中斷返回}OSIntExit()voidOSIntExit(voiOSIntCtxSw()在任務(wù)切換時,為什么使用OSIntCtxSw()而不是調(diào)度函數(shù)中的OS_TASK_SW()?原因有二點一半的任務(wù)切換工作,即CPU寄存器入棧,已經(jīng)在前面做完了;需要保證所有被掛起任務(wù)的棧結(jié)構(gòu)是一樣的。OSIntCtxSw()在任務(wù)切換時,為什么使用OSIntCOSIntExit的關(guān)鍵——OSIntCtxSw實現(xiàn)中斷級的任務(wù)切換ARM在棧指針調(diào)整過程中的優(yōu)勢OSIntExit的關(guān)鍵——OSIntCtxSw實現(xiàn)中斷級的調(diào)用中斷切換函數(shù)OSIntCtxSw()后的堆棧情況調(diào)用中斷切換函數(shù)OSIntCtxSw()后的堆棧情況時鐘節(jié)拍時鐘節(jié)拍是一種特殊的中斷,相當(dāng)于操作系統(tǒng)的心臟起搏器;μC/OS需要用戶提供周期性信號源,用于實現(xiàn)時間延時和確認(rèn)超時。節(jié)拍率應(yīng)在10到100Hz之間,時鐘節(jié)拍率越高,系統(tǒng)的額外負(fù)荷就越重;時鐘節(jié)拍的實際頻率取決于用戶應(yīng)用程序的精度。時鐘節(jié)拍源可以是專門的硬件定時器,或是來自50/60Hz交流電源的信號。時鐘節(jié)拍時鐘節(jié)拍是一種特殊的中斷,相當(dāng)于操作系統(tǒng)的心臟起搏器時鐘節(jié)拍ISRvoidOSTickISR(void){

(1)保存處理器寄存器的值;

(2)調(diào)用OSIntEnter()或?qū)SIntNesting加1;

(3)調(diào)用OSTimeTick();/*檢查每個任務(wù)的時間延時*/

(4)調(diào)用OSIntExit();

(5)恢復(fù)處理器寄存器的值;

(6)執(zhí)行中斷返回指令;}時鐘節(jié)拍ISRvoidOSTickISR(void)時鐘節(jié)拍函數(shù)OSTimtick()voidOSTimeTick(void){OS_TCB*ptcb;OSTimeTickHook(); (1)ptcb=OSTCBList; (2)while(ptcb->OSTCBPrio!=OS_IDLE_PRIO){ (3)OS_ENTER_CRITICAL();if(ptcb->OSTCBDly!=0){if(--ptcb->OSTCBDly==0){If(!(ptcb->OSTCBStat&OS_STAT_SUSPEND)){ (4)OSRdyGrp|=ptcb->OSTCBBitY; (5)OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;}else{ptcb->OSTCBDly=1;}}}ptcb=ptcb->OSTCBNext;OS_EXIT_CRITICAL();}OS_ENTER_CRITICAL(); (6)OSTime++; (7)OS_EXIT_CRITICAL();}時鐘節(jié)拍函數(shù)OSTimtick()voidOSTime時間管理與時間管理相關(guān)的系統(tǒng)服務(wù):OSTimeDLY()OSTimeDLYHMSM()OSTimeDlyResmue()OStimeGet()OSTimeSet()時間管理與時間管理相關(guān)的系統(tǒng)服務(wù):OSTimeDLY()OSTimeDLY():任務(wù)延時函數(shù),申請該服務(wù)的任務(wù)可以延時一段時間;調(diào)用OSTimeDLY后,任務(wù)進(jìn)入等待狀態(tài);使用方法voidOSTimeDly(INT16Uticks);ticks表示需要延時的時間長度,用時鐘節(jié)拍的個數(shù)來表示。OSTimeDLY()OSTimeDLY():任務(wù)延時函數(shù),OSTimeDLY()voidOSTimeDly(INT16Uticks){if(ticks>0){OS_ENTER_CRITICAL();if((OSRdyTbl[OSTCBCur->OSTCBY]&=~OSTCBCur->OSTCBBitX)==0){OSRdyGrp&=~OSTCBCur->OSTCBBitY;}OSTCBCur->OSTCBDly=ticks;OS_EXIT_CRITICAL();OSSched();}}OSTimeDLY()voidOSTimeDly(INTOSTimeDLY(1)的問題OSTimeDLY(1)的問題OSTimeDlyHMSM()OSTimeDlyHMSM():OSTimeDly()的另一個版本,即按時分秒延時函數(shù);使用方法INT8UOSTimeDlyHMSM(

INT8Uhours,//小時

INT8Uminutes,//分鐘

INT8Useconds,//秒

INT16Umilli//毫秒

);OSTimeDlyHMSM()OSTimeDlyHMSM()OSTimeDlyResume()OSTimeDlyResume():讓處在延時期的任務(wù)提前結(jié)束延時,進(jìn)入就緒狀態(tài);使用方法INT8UOSTimeDlyResume(INT8U

prio);prio表示需要提前結(jié)束延時的任務(wù)的優(yōu)先級/任務(wù)ID。OSTimeDlyResume()OSTimeDlyResu系統(tǒng)時間每隔一個時鐘節(jié)拍,發(fā)生一個時鐘中斷,將一個32位的計數(shù)器OSTime加1;該計數(shù)器在用戶調(diào)用OSStart()初始化多任務(wù)和4,294,967,295個節(jié)拍執(zhí)行完一遍的時候從0開始計數(shù)。若時鐘節(jié)拍的頻率等于100Hz,該計數(shù)器每隔497天就重新開始計數(shù);OSTimeGet():獲得該計數(shù)器的當(dāng)前值;INT32UOSTimeGet(void);OSTimeSet():設(shè)置該計數(shù)器的值。voidOSTimeSet(INT32Uticks);系統(tǒng)時間每隔一個時鐘節(jié)拍,發(fā)生一個時鐘中斷,將一個32位的計何時啟動系統(tǒng)定時器如果在OSStart之前啟動定時器,則系統(tǒng)可能無法正確執(zhí)行完OSStartHighRdyOSStart函數(shù)直接調(diào)用OSStartHighRdy去執(zhí)行最高優(yōu)先級的任務(wù),OSStart不返回。系統(tǒng)定時器應(yīng)該在系統(tǒng)的最高優(yōu)先級任務(wù)中啟動使用OSRunning變量來控制操作系統(tǒng)的運(yùn)行在我們的移植版本中,使用了uCOS-II中的保留任務(wù)1作為系統(tǒng)任務(wù)。負(fù)責(zé)啟動定時器何時啟動系統(tǒng)定時器如果在OSStart之前啟動定時器,則系統(tǒng)時鐘節(jié)拍的啟動用戶必須在多任務(wù)系統(tǒng)啟動以后再開啟時鐘節(jié)拍器,也就是在調(diào)用OSStart()之后;在調(diào)用OSStart()之后做的第一件事是初始化定時器中斷。voidmain(void){...OSInit();/*初始化uC/OS-II*//*應(yīng)用程序初始化代碼...*//*調(diào)用OSTaskCreate()創(chuàng)建至少一個任務(wù)*/

允許時鐘節(jié)拍中斷;/*錯誤!可能crash!*/OSStart();/*開始多任務(wù)調(diào)度*/}時鐘節(jié)拍的啟動用戶必須在多任務(wù)系統(tǒng)啟動以后再開啟時鐘節(jié)拍器,系統(tǒng)的初始化與啟動在調(diào)用C/OS-II的任何其它服務(wù)之前,用戶必須首先調(diào)用系統(tǒng)初始化函數(shù)OSInit()來初始化C/OS的所有變量和數(shù)據(jù)結(jié)構(gòu);OSInit()建立空閑任務(wù)OSTaskIdle(),該任務(wù)總是處于就緒狀態(tài),其優(yōu)先級一般被設(shè)成最低,即OS_LOWEST_PRIO;如果需要,OSInit()還建立統(tǒng)計任務(wù)OSTaskStat(),并讓其進(jìn)入就緒狀態(tài);OSInit()還初始化了4個空數(shù)據(jù)結(jié)構(gòu)緩沖區(qū):空閑TCB鏈表OSTCBFreeList、空閑事件鏈表OSEventFreeList、空閑隊列鏈表OSQFreeList和空閑存儲鏈表OSMemFreeList。系統(tǒng)的初始化與啟動在調(diào)用C/OS-II的任何其它服務(wù)之前,系統(tǒng)初始化后的狀態(tài)系統(tǒng)初始化后的狀態(tài)C/OS-II的啟動多任務(wù)的啟動是用戶通過調(diào)用OSStart()實現(xiàn)的。然而,啟動μC/OS-Ⅱ之前,用戶至少要建立一個應(yīng)用任務(wù)。voidmain(void){OSInit();/*初始化uC/OS-II*/...

通過調(diào)用OSTaskCreate()或OSTaskCreateExt()

創(chuàng)建至少一個任務(wù);...

OSStart();

/*開始多任務(wù)調(diào)度!永不返回*/

}C/OS-II的啟動多任務(wù)的啟動是用戶通過調(diào)用OSStarOSStart()voidOSStart(void){INT8UY;INT8UX;if(OSRunning==FALSE){y=OSUnMapTbl[OSRdyGrp];x=OSUnMapTbl[OSRdyTbl[y]];OSPrioHighRdy=(INT8U)((Y<<3)+X);OSPrioCur=OSPrioHighRdy;OSTCBHighRdy=

OSTCBPrioTbl[OSPrioHighRdy];OSTCBCur=OSTCBHighRdy;OSStartHighRdy();}}OSStart()voidOSStart(void)統(tǒng)計任務(wù)初始化函數(shù)OSStatInit(void)voidOSStatInit(void){OSTimeDly(2);OS_ENTER_CRITICAL();OSIdleCtr=0L;OS_EXIT_CRITICAL();OSTimeDly(OS_TICKS_PER_SEC);OS_ENTER_CRITICAL();OSIdleCtrMax=OSIdleCtr;OSStatRdy=TRUE;OS_EXIT_CRITICAL();}統(tǒng)計任務(wù)初始化函數(shù)OSStatInit(void)void統(tǒng)計任務(wù)初始化統(tǒng)計任務(wù)初始化系統(tǒng)啟動后的狀態(tài)假設(shè)用戶創(chuàng)建的任務(wù)優(yōu)先級為6系統(tǒng)啟動后的狀態(tài)假設(shè)用戶創(chuàng)建的第三章、實時操作系統(tǒng)C/OS-II1324C/OS-II概述任務(wù)管理中斷和時間管理任務(wù)之間的通信與同步5存儲管理第三章、實時操作系統(tǒng)C/OS-II1324C/OS-II任務(wù)間通信與同步任務(wù)間通信的管理:事件控制塊ECB;同步與互斥臨界區(qū)(CriticalSections);信號量(Semaphores);任務(wù)間通信郵箱(MessageMailboxes);消息隊列(MessageQueues)。任務(wù)間通信與同步任務(wù)間通信的管理:事件控制塊ECB;事件控制塊ECBECB數(shù)據(jù)結(jié)構(gòu)typedefstruct{void*OSEventPtr;/*指向消息或消息隊列的指針*/INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//等待任務(wù)列表INT16UOSEventCnt;/*計數(shù)器(當(dāng)事件是信號量時)*/INT8UOSEventType;/*事件類型:信號量、郵箱等*/INT8UOSEventGrp;/*等待任務(wù)組*/}OS_EVENT;

與TCB類似的結(jié)構(gòu),使用兩個鏈表,空閑鏈表與使用鏈表所有的通信信號都被看成是事件(event),C/OS-II通過事件控制塊(ECB)來管理每一個具體事件。事件控制塊ECBECB數(shù)據(jù)結(jié)構(gòu)所有的通信信號都被看成是事件(事件控制塊ECB數(shù)據(jù)結(jié)構(gòu)2017654310891514131211181617232221201926242531302928273432333938373635424041474645444350484955545352515856576362616059·OSRdyTbl[8]·OSEventGrp·OSEventPtr·OSEventCnt·OSEventTypepreventOS_Event事件控制塊ECB數(shù)據(jù)結(jié)構(gòu)201765431089151413任務(wù)和ISR之間的通信方式一個任務(wù)或ISR可以通過事件控制塊ECB(信號量、郵箱或消息隊列)向另外的任務(wù)發(fā)信號;一個任務(wù)還可以等待另一個任務(wù)或中斷服務(wù)子程序給它發(fā)送信號。對于處于等待狀態(tài)的任務(wù),還可以給它指定一個最長等待時間;多個任務(wù)可以同時等待同一個事件的發(fā)生。當(dāng)該事件發(fā)生后,在所有等待該事件的任務(wù)中,優(yōu)先級最高的任務(wù)得到了該事件并進(jìn)入就緒狀態(tài),準(zhǔn)備執(zhí)行。任務(wù)和ISR之間的通信方式一個任務(wù)或ISR可以通過事件控制塊任務(wù)和ISR之間的通信方式ECBISRTaskSignalSignalWaitWaitTaskTaskAISRTaskSignalSignalWaitWaitTaskTaskBTaskTaskWait/SignalCECBECBECBWait/SignalTimeOut任務(wù)和ISR之間的通信方式ECBISRTaskSignalS等待任務(wù)列表每個正在等待某個事件的任務(wù)被加入到該事件的ECB的等待任務(wù)列表中,該列表包含兩個變量OSEventGrp和OSEventTbl[]。在OSEventGrp中,任務(wù)按優(yōu)先級分組,8個任務(wù)為一組,共8組,分別對應(yīng)OSEventGrp當(dāng)中的8位。當(dāng)某組中有任務(wù)處于等待該事件的狀態(tài)時,對應(yīng)的位就被置位。同時,OSEventTbl[]中的相應(yīng)位也被置位。等待任務(wù)列表每個正在等待某個事件的任務(wù)被加入到該事件的ECB最低優(yōu)先級任務(wù)(即空閑任務(wù),不可能處于等待狀態(tài))565758596061626348495051525354554041424344454647323334353637383924252627282930311617181920212223891011121314150123456701234567[0][1][2][3][4][5][6][7].OSEventGrpOSEventTbl[OS_LOWEST_PRIO/8+1]XY最高優(yōu)先級任務(wù)正在等待該事件的任務(wù)的優(yōu)先級XXXYYY00任務(wù)的優(yōu)先級.OSEventTbl[]中相應(yīng)位的位置.OSEventGrp中相應(yīng)位的位置及.OSEventTbl[]中的數(shù)組下標(biāo)最低優(yōu)先級任務(wù)(即空閑任務(wù),不可能處于等待狀態(tài))565758使任務(wù)進(jìn)入/脫離等待狀態(tài)將一個任務(wù)插入到事件的等待任務(wù)列表中pevent->OSEventGrp|=OSMapTbl[prio>>3];pevent->OSEventTbl[prio>>3]|=OSMapTbl[prio&0x07];從等待任務(wù)列表中刪除一個任務(wù)if((pevent->OSEventTbl[prio>>3]&=~OSMapTbl[prio&0x07])==0){pevent->OSEventGrp&=~OSMapTbl[prio>>3];}使任務(wù)進(jìn)入/脫離等待狀態(tài)將一個任務(wù)插入到事件的等待任務(wù)列表中在等待事件的任務(wù)列表中查找優(yōu)先級最高的任務(wù)在等待任務(wù)列表中查找最高優(yōu)先級的任務(wù)y=OSUnMapTbl[pevent->OSEventGrp];x=OSUnMapTbl[pevent->OSEventTbl[y]];prio=(y<<3)+x;在等待事件的任務(wù)列表中查找優(yōu)先級最高的任務(wù)在等待任務(wù)列表中查空閑ECB的管理ECB的總數(shù)由用戶所需要的信號量、郵箱和消息隊列的總數(shù)決定,由OS_CFG.H中的#defineOS_MAX_EVENTS定義。在調(diào)用OSInit()初始化系統(tǒng)時,所有的ECB被鏈接成一個單向鏈表——空閑事件控制塊鏈表;每當(dāng)建立一個信號量、郵箱或消息隊列時,就從該鏈表中取出一個空閑事件控制塊,并對它進(jìn)行初始化。0OS_MAX_EVENTSOSEventFreeListOS_EVENT空閑ECB的管理ECB的總數(shù)由用戶所需要的信號量、郵箱和消息ECB的基本操作OSEventWaitListInit()初始化一個事件控制塊。當(dāng)創(chuàng)建一個信號量、郵箱或消息隊列時,相應(yīng)的創(chuàng)建函數(shù)會調(diào)用本函數(shù)對ECB的內(nèi)容進(jìn)行初始化,將OSEventGrp和OSEventTbl[]數(shù)組清零;OSEventWaitListInit(OS_EVENT*pevent);prevent:指向需要初始化的事件控制塊的指針。OSEventTaskRdy()。使一個任務(wù)進(jìn)入就緒態(tài)。當(dāng)一個事件發(fā)生時,需要將其等待任務(wù)列表中的最高優(yōu)先級任務(wù)置為就緒態(tài);OSEventTaskRdy(OS_EVENT*pevent,

void*msg,INT8Umsk);msg:指向消息的指針;msk:用于設(shè)置TCB的狀態(tài)。ECB的基本操作OSEventWaitListInit()ECB的基本操作(續(xù))OSEventTaskWait()使一個任務(wù)進(jìn)入等待狀態(tài)。當(dāng)某個任務(wù)要等待一個事件的發(fā)生時,需要調(diào)用本函數(shù)將該任務(wù)從就緒任務(wù)表中刪除,并放到相應(yīng)事件的等待任務(wù)表中;OSEventTaskWait(OS_EVENT*pevent);OSEventTO()由于等待超時而將任務(wù)置為就緒態(tài)。如果一個任務(wù)等待的事件在預(yù)先指定的時間內(nèi)沒有發(fā)生,需要調(diào)用本函數(shù)將該任務(wù)從等待列表中刪除,并把它置為就緒狀態(tài);OSEventTO(OS_EVENT*pevent);ECB的基本操作(續(xù))OSEventTaskWait()同步與互斥為了實現(xiàn)資源共享,一個操作系統(tǒng)必須提供臨界區(qū)操作的功能;μC/OS采用關(guān)閉/打開中斷的方式來處理臨界區(qū)代碼,從而避免競爭條件,實現(xiàn)任務(wù)間的互斥;

μC/OS定義兩個宏(macros)來開關(guān)中斷,即:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL();這兩個宏的定義取決于所用的微處理器,每種微處理器都有自己的OS_CPU.H文件。

同步與互斥為了實現(xiàn)資源共享,一個操作系統(tǒng)必須提供臨界區(qū)操作的...

OS_ENTER_CRITICAL();任務(wù)1的臨界區(qū)代碼;OS_EXIT_CRITICAL();...任務(wù)1任務(wù)2...

OS_ENTER_CRITICAL();任務(wù)2的臨界區(qū)代碼;OS_EXIT_CRITICAL();...臨界資源...

OS_ENTER_CRITICAL();任務(wù)1任務(wù)當(dāng)處理臨界段代碼時,需要關(guān)中斷,處理完畢后,再開中斷;關(guān)中斷時間是實時內(nèi)核最重要的指標(biāo)之一;在實際應(yīng)用中,關(guān)中斷的時間很大程度中取決于微處理器的結(jié)構(gòu)和編譯器生成的代碼質(zhì)量;C/OS-II定義兩個宏開關(guān)中斷:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL();C/OS-II中開關(guān)中斷的方法當(dāng)處理臨界段代碼時,需要關(guān)中斷,處理完畢后,再開中斷;C/OS_CRITICAL_METHOD==1用處理器指令關(guān)中斷,執(zhí)行OS_ENTER_CRITICAL(),開中斷執(zhí)行OS_EXIT_CRITICAL();OS_CRITICAL_METHOD==2實現(xiàn)OS_ENTER_CRITICAL()時,先在堆棧中保存中斷的開/關(guān)狀態(tài),然后再關(guān)中斷;實現(xiàn)OS_EXIT_CRITICAL()時,從堆棧中彈出原來中斷的開/關(guān)狀態(tài);OS_CRITICAL_METHOD==3把當(dāng)前處理器的狀態(tài)字保存在局部變量中(如OS_CPU_SR,關(guān)中斷時保存,開中斷時恢復(fù)C/OS-II中采用了3種開關(guān)中斷的方法OS_CRITICAL_METHOD==1C/OS-II中Intel80x86實模式下中斷的打開與關(guān)閉;方法1#defineOS_ENTER_CRITICAL()asmCLI#defineOS_EXIT_CRITICAL()asmSTI方法2#defineOS_ENTER_CRITICAL()asm{PUSHF;CLI}#defineOS_EXIT_CRITICAL()asmPOPFIntel80x86實模式下中斷的打開與關(guān)閉;信號量信號量在多任務(wù)系統(tǒng)中的功能實現(xiàn)對共享資源的互斥訪問(包括單個共享資源或多個相同的資源);實現(xiàn)任務(wù)之間的行為同步;必須在OS_CFG.H中將OS_SEM_EN開關(guān)常量置為1,這樣μC/OS才能支持信號量。信號量信號量在多任務(wù)系統(tǒng)中的功能uC/OS中信號量由兩部分組成:信號量的計數(shù)值(16位無符號整數(shù))和等待該信號量的任務(wù)所組成的等待任務(wù)表;信號量系統(tǒng)服務(wù)OSSemCreate()OSSemPend(),OSSemPost()OSSemAccept(),OSSemQuery()uC/OS中信號量由兩部分組成:信號量的計數(shù)值(16位無符號任務(wù)、ISR和信號量的關(guān)系或任務(wù)任務(wù)ISROSSemAccept()OSSemPend()OSSemQuery()OSSemPost()OSSemPost()OSSemAccept()OSSemCreate()NN任務(wù)、ISR和信號量的關(guān)系或任務(wù)任務(wù)ISROSSemAc創(chuàng)建一個信號量OSSemCreate()創(chuàng)建一個信號量,并對信號量的初始計數(shù)值賦值,該初始值為0到65,535之間的一個數(shù);OS_EVENT*OSSemCreate(INT16Ucnt);cnt:信號量的初始值。執(zhí)行步驟從空閑事件控制塊鏈表中得到一個ECB;初始化ECB,包括設(shè)置信號量的初始值、把等待任務(wù)列表清零、設(shè)置ECB的事件類型等;返回一個指向該事件控制塊的指針。創(chuàng)建一個信號量OSSemCreate()等待一個信號量OSSemPend()等待一個信號量,即操作系統(tǒng)中的P操作,將信號量的值減1;OSSemPend(OS_EVENT*pevent,

INT16Utimeout,INT8U*err);執(zhí)行步驟如果信號量的計數(shù)值大于0,將它減1并返回;如果信號量的值等于0,則調(diào)用本函數(shù)的任務(wù)將被阻塞起來,等待另一個任務(wù)把它喚醒;調(diào)用OSSched()函數(shù),調(diào)度下一個最高優(yōu)先級的任務(wù)運(yùn)行。等待一個信號量OSSemPend()發(fā)送一個信號量OSSemPost()發(fā)送一個信號量,即操作系統(tǒng)中的V操作,將信號量的值加1;OSSemPost(OS_EVENT*pevent);執(zhí)行步驟檢查是否有任務(wù)在等待該信號量,如果沒有,將信號量的計數(shù)值加1并返回;如果有,將優(yōu)先級最高的任務(wù)從等待任務(wù)列表中刪除,并使它進(jìn)入就緒狀態(tài);調(diào)用OSSched(),判斷是否需要進(jìn)行任務(wù)切換。發(fā)送一個信號量OSSemPost()無等待地請求一個信號量OSSemAccept()當(dāng)一個任務(wù)請求一個信號量時,如果該信號量暫時無效,則讓該任務(wù)簡單地返回,而不是進(jìn)入等待狀態(tài);INT16UOSSemAccept(OS_EVENT*pevent);執(zhí)行步驟如果該信號量的計數(shù)值大于0,則將它減1,然后將信號量的原有值返回;如果該信號量的值等于0,直接返回該值(0)。無等待地請求一個信號量OSSemAccept()查詢一個信號量的當(dāng)前狀態(tài)OSSemQuery()查詢一個信號量的當(dāng)前狀態(tài);INT8UOSSemQuery(OS_EVENT*pevent,

OS_SEM_DATA*pdata);將指向信號量對應(yīng)事件控制塊的指針pevent所指向的ECB的內(nèi)容拷貝到指向用于記錄信號量信息的數(shù)據(jù)結(jié)構(gòu)OS_SEM_DATA數(shù)據(jù)結(jié)構(gòu)的指針pdata所指向的緩沖區(qū)當(dāng)中。查詢一個信號量的當(dāng)前狀態(tài)OSSemQuery()任務(wù)間通信低級通信只能傳遞狀態(tài)和整數(shù)值等控制信息,傳送的信息量小;例如:信號量高級通信能夠傳送任意數(shù)量的數(shù)據(jù);例如:共享內(nèi)存、郵箱、消息隊列任務(wù)間通信低級通信共享內(nèi)存在C/OS-II中如何實現(xiàn)共享內(nèi)存?內(nèi)存地址空間只有一個,為所有的任務(wù)所共享!為了避免競爭狀態(tài),需要使用信號量來實現(xiàn)互斥訪問。共享內(nèi)存在C/OS-II中如何實現(xiàn)共享內(nèi)存?消息郵箱郵箱(MailBox)

溫馨提示

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

評論

0/150

提交評論