版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1實(shí)時(shí)操作系統(tǒng)
μC/OS-Ⅱ分析和應(yīng)用
12第一章:μC/OS-II概述μμC/OS-II概述任務(wù)管理中斷和時(shí)間管理2Co存儲(chǔ)管理任務(wù)之間的通信與同步SII3操作系統(tǒng)綜述一、操作系統(tǒng)綜述1、通用操作系統(tǒng)2、嵌入式操作系統(tǒng)二、為什么需要嵌入式操作系統(tǒng)三、μC/OS-II34一、操作系統(tǒng)綜述:通用操作系統(tǒng)操作系統(tǒng)是計(jì)算機(jī)系統(tǒng)中的一個(gè)軟件系統(tǒng),它是這樣一些程序模塊的集合:它們能有效地組織和管理計(jì)算機(jī)中的硬件以及軟件資源,合理地組織計(jì)算機(jī)工作流程,控制程序的執(zhí)行,并向用戶提供各種服務(wù)功能,使得用戶能夠靈活、方便和有效地使用計(jì)算機(jī),使整個(gè)計(jì)算機(jī)系統(tǒng)能高效地運(yùn)行。45非嵌入式操作系統(tǒng)-桌面操作系統(tǒng):
MSDOS:基于Intelx86系列的PC機(jī)上的最早的操作系統(tǒng),微軟公司產(chǎn)品,只能管理運(yùn)行一個(gè)程序,只提供字符顯示界面。
WindowsXX:是現(xiàn)在基于Intelx86系列的PC機(jī)上的主要操作系統(tǒng)。提供GUI支持??梢赃\(yùn)行多個(gè)程序,為面向桌面、面向個(gè)人用戶的多任務(wù)操作系統(tǒng)。5一、操作系統(tǒng)綜述:通用操作系統(tǒng)6操作系統(tǒng)綜述-多任務(wù)操作系統(tǒng)WindowsX67非嵌入式操作系統(tǒng)-服務(wù)器操作系統(tǒng):
UNIX:一個(gè)真正穩(wěn)健、實(shí)用、強(qiáng)大的服務(wù)器操作系統(tǒng),是一個(gè)多用戶操作系統(tǒng)。廣泛應(yīng)用于科研、通訊、金融等關(guān)鍵領(lǐng)域。LINUX:是一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng)。
Windows2000Server:利用Windows的友好的用戶界面的優(yōu)勢打進(jìn)服務(wù)器操作系統(tǒng)市場。但其在整體性能、效率、穩(wěn)定性上都與UNIX有一定差距,所以現(xiàn)在主要應(yīng)用于中小企業(yè)市場。7一、操作系統(tǒng)綜述:通用操作系統(tǒng)8操作系統(tǒng)綜述-多用戶操作系統(tǒng)UNIX8UNIX主機(jī)終端1終端2終端n網(wǎng)絡(luò)TCP/IP網(wǎng)絡(luò)終端服務(wù)器終端。。。主機(jī)m主機(jī)nRS2322RS2322RS2322RS2322RS2322RS232299一、操作系統(tǒng)綜述:嵌入式操作系統(tǒng)在我們的現(xiàn)實(shí)生活和工作中,除了廣泛使用計(jì)算機(jī)外,還有比計(jì)算機(jī)更多的IT產(chǎn)品應(yīng)用于各個(gè)領(lǐng)域。1010
這些產(chǎn)品大都是“類計(jì)算機(jī)”產(chǎn)品,但是,在這些產(chǎn)品上,受資源限制和“個(gè)性”要求,不可能也沒有必要運(yùn)行完整的Windows、Linux等操作系統(tǒng)來管理系統(tǒng)的運(yùn)行,因此,派生出了所謂的嵌入式實(shí)時(shí)操作系統(tǒng)(RTOS)和嵌入式應(yīng)用系統(tǒng):
嵌入式系統(tǒng)的一般定義:“以應(yīng)用為中心,以計(jì)算機(jī)技術(shù)為基礎(chǔ),軟硬件可裁剪,適應(yīng)應(yīng)用系統(tǒng)對(duì)功能、可靠性、成本、體積、功耗等嚴(yán)格要求的專用計(jì)算機(jī)系統(tǒng)”。一、操作系統(tǒng)綜述:嵌入式操作系統(tǒng)1111嵌入式(實(shí)時(shí))操作系統(tǒng):用于嵌入式設(shè)備的操作系統(tǒng),具有通用操作系統(tǒng)的基本特點(diǎn),又具有系統(tǒng)實(shí)時(shí)性、硬件的相關(guān)依賴性、軟件固態(tài)化以及應(yīng)用的專用性等特點(diǎn),操作系統(tǒng)、應(yīng)用軟件等與硬件融為一體,不可分離;嵌入式(實(shí)時(shí))操作系統(tǒng)通常包括與硬件相關(guān)的底層驅(qū)動(dòng)軟件、系統(tǒng)內(nèi)核、設(shè)備驅(qū)動(dòng)接口、通信協(xié)議、圖形用戶界面(GUI)等;嵌入式(實(shí)時(shí))操作系統(tǒng)的重要指標(biāo):實(shí)時(shí)性(中斷響應(yīng)時(shí)間、任務(wù)切換時(shí)間等)、尺寸(可裁剪性)、可擴(kuò)展性(內(nèi)核、中間件);一、操作系統(tǒng)綜述:嵌入式操作系統(tǒng)12常見的嵌入式操作系統(tǒng)
12嵌入式操作系統(tǒng)的種類繁多,大體上可分為兩種,商用型和免費(fèi)型。商用型的嵌入式操作系統(tǒng)功能穩(wěn)定、可靠,有完善的技術(shù)支持和售后服務(wù),但往往價(jià)格昂貴,如Vxworks、QNX、WinCE、PalmOS等。免費(fèi)型的實(shí)時(shí)操作系統(tǒng),如:
Linux,μC/OS-II等是一種源碼開放的RTOS;
還有一個(gè)大家耳熟能詳?shù)南到y(tǒng)....13常見的嵌入式操作系統(tǒng)13嵌入式系統(tǒng)的特點(diǎn):專用性為特定應(yīng)用定制的產(chǎn)品。裁減性軟、硬件小而精,夠用即可。實(shí)時(shí)性程序和數(shù)據(jù)都在存儲(chǔ)器中,既滿足邏
輯正確性,也要滿足時(shí)間正確性??煽啃詿o人值守、自動(dòng)化設(shè)備的使用要求。低功耗便攜式應(yīng)用的要求。高性價(jià)家用的應(yīng)用要求。14其它組件
TCP/IP
設(shè)備I/ORTOS在嵌入式系統(tǒng)中的位置RTOS
KERNEL
調(diào)試工具
FS C/C++設(shè)備驅(qū)動(dòng)BSP嵌入式硬件平臺(tái)
應(yīng)用系統(tǒng)RTOS在嵌入式系統(tǒng)中的位置1415二、為什么需要嵌入式操作系統(tǒng)在早期的一些嵌入式系統(tǒng)中沒有操作系統(tǒng)的概念,程序員直接針對(duì)裸機(jī)及裸設(shè)備編寫嵌入式產(chǎn)品的程序。在這種情況下,通常把嵌入式程序分成兩部分:前臺(tái)程序和后臺(tái)程序。151616前后臺(tái)系統(tǒng)運(yùn)行流程二、為什么需要嵌入式操作系統(tǒng)17
17二、為什么需要嵌入式操作系統(tǒng)18intmain(void){for(;;){while(Computer()) //計(jì)算機(jī)通訊數(shù)據(jù)ProcessHost();if(BarCode()) //條碼槍處理 ProcessReader();if(BalanceWeight()) //電子秤處理 ProcessWeight();if(KeyInput()) //鍵盤處理 ProcessKey();}}18二、為什么需要嵌入式操作系統(tǒng)1919這樣的系統(tǒng)我們稱之為前后臺(tái)系統(tǒng):
應(yīng)用程序是一個(gè)無限的循環(huán),循環(huán)中調(diào)用相應(yīng)的函數(shù)完成相應(yīng)的操作,這部分可以看成后臺(tái)(background)。也可以叫做任務(wù)級(jí)。
時(shí)間相關(guān)性很強(qiáng)的關(guān)鍵操作(Criticaloperation)采用中斷服務(wù)來完成,這部分可以看成前臺(tái)(foreground)。前臺(tái)也叫中斷級(jí)。
因?yàn)橹袛喾?wù)提供的信息一直要等到后臺(tái)程序走到該處理這個(gè)信息這一步時(shí)才能得到處理,這種系統(tǒng)在處理信息的及時(shí)性上,比實(shí)際可以做到的要差。這個(gè)指標(biāo)稱作任務(wù)級(jí)響應(yīng)時(shí)間。最壞情況下的任務(wù)級(jí)響應(yīng)時(shí)間取決于整個(gè)循環(huán)的執(zhí)行時(shí)間。因?yàn)檠h(huán)的執(zhí)行時(shí)間不是常數(shù),程序經(jīng)過某一特定部分的準(zhǔn)確時(shí)間也是不能確定的。進(jìn)而,如果程序修改了,循環(huán)的時(shí)序也會(huì)受到影響。二、為什么需要嵌入式操作系統(tǒng)20前后臺(tái)系統(tǒng)的實(shí)時(shí)性比預(yù)計(jì)的要差:
1.前后臺(tái)系統(tǒng)中的所有任務(wù)依次序順序處理,無優(yōu)先級(jí)別,對(duì)那些實(shí)時(shí)性要求高的任務(wù)不可能立刻得到處理。
2.后臺(tái)程序是一個(gè)無限循環(huán)的結(jié)構(gòu),一旦在這個(gè)循環(huán)體中正在處理的任務(wù)崩潰,將會(huì)導(dǎo)致整個(gè)任務(wù)序列中的其他任務(wù)得不到處理,從而造成整個(gè)系統(tǒng)的崩潰。
3.這類系統(tǒng)結(jié)構(gòu)簡單,每個(gè)任務(wù)幾乎不需要額外的RAM/ROM開銷,可以節(jié)約寶貴的存儲(chǔ)資源,因而在簡單的嵌入式應(yīng)用被廣泛使用.20二、為什么需要嵌入式操作系統(tǒng)21#include<stdio.h>intmain(void){FILE*in;if((in=fopen("TEST.DAT","rt"))==NULL) return1;while(!feof(in))
putch(fgetc(in));
fclose(in);return0;}使用編程平臺(tái)編寫應(yīng)用程序讀寫文件數(shù)據(jù)在屏幕上顯示內(nèi)容與其它程序通信….磁盤顯示器其它程序21由操作系統(tǒng)負(fù)責(zé)完成由硬件驅(qū)動(dòng)負(fù)責(zé)二、為什么需要嵌入式操作系統(tǒng)22微處理器(MCU)
ROMSDRAMA/DI/OD/A實(shí)時(shí)操作系統(tǒng)(RTOS)圖形用戶接口(GUI)BSP板極支持包/HAL硬件抽象層/ 通用接口任務(wù)管理文件系統(tǒng)(FAT)應(yīng)用程序硬件層軟件層中間層功能層嵌入式計(jì)算機(jī)系統(tǒng)22二、為什么需要嵌入式操作系統(tǒng)23三、μC/OS簡介1、μC/OS——MicroControllerOS,微控制器操作系統(tǒng)2、μC/OS簡介lllll美國人JeanLabrosse1992年完成應(yīng)用面覆蓋了諸多領(lǐng)域,如照相機(jī)、醫(yī)療器械、音響設(shè)備、發(fā)動(dòng)機(jī)控制、高速公路電話系統(tǒng)、自動(dòng)提款機(jī)等1998年μC/OS-II,目前μC/OS-III版本也已經(jīng)發(fā)布2000年,得到美國航空管理局(FAA)的認(rèn)證,可以用于飛行器中網(wǎng)站www.ucos-II.com()2324uuuu公開源代碼可移植性(Portable)絕大部分μ
C/OS-II的源碼是用移植性很強(qiáng)的ANSIC寫的。和微處理器硬件相關(guān)的那部分是用匯編語言寫的。匯編語言寫的部分已經(jīng)壓到最低限度,使得μ
C/OS-II便于移植到其他微處理器上。μ
C/OS-II可以在絕大多數(shù)8位、16位、32位以至64位微處理器、微控制器、數(shù)字信號(hào)處理器(DSP)上運(yùn)行??晒袒≧OMable)μ
C/OS-II是為嵌入式應(yīng)用而設(shè)計(jì)的,這就意味著,只要讀者有固化手段(C編譯、連接、下載和固化),μ
C/OS-II可以嵌入到讀者的產(chǎn)品中成為產(chǎn)品的一部分??刹眉簦⊿calable)μC/OS的性能特點(diǎn)(一)
可以只使用μ
C/OS-II中應(yīng)用程序需要的那些系統(tǒng)服務(wù)。也就是說某產(chǎn) 品可以只使用很少幾個(gè)μ
C/OS-II調(diào)用,而另一個(gè)產(chǎn)品則使用了幾乎所 有μ
C/OS-II的功能,這樣可以減少產(chǎn)品中的μ
C/OS-II所需的存儲(chǔ)器空 間(RAM和ROM)。這種可剪裁性是靠條件編譯實(shí)現(xiàn)的。可擴(kuò)展(Extendable)
可以增補(bǔ)uC/OS中未包含的其他功能2425uuuuuuu
占先式(Preemptive) 多任務(wù)
μC/OS-II可以管理64個(gè)任務(wù),然而,目前這一版本保留8個(gè)給系統(tǒng)。
可確定性全部μ
C/OS-II的函數(shù)調(diào)用與服務(wù)的執(zhí)行時(shí)間具有可確定性。
任務(wù)棧每個(gè)任務(wù)有自己單獨(dú)的棧,μ
C/OS-II允許每個(gè)任務(wù)有不同的棧空間,以便壓低應(yīng) 用程序?qū)AM的需求。
系統(tǒng)服務(wù)
μC/OS-II提供很多系統(tǒng)服務(wù),例如郵箱、消息隊(duì)列、信號(hào)量、塊大小固定的內(nèi)存 的申請(qǐng)與釋放、時(shí)間相關(guān)函數(shù)等。
中斷管理中斷可以使正在執(zhí)行的任務(wù)暫時(shí)掛起,如果優(yōu)先級(jí)更高的任務(wù)被該中斷喚醒,則 高優(yōu)先級(jí)的任務(wù)在中斷嵌套全部退出后立即執(zhí)行,中斷嵌套層數(shù)可達(dá)255層。
穩(wěn)定性與可靠性μC/OS的性能特點(diǎn)(二)2526μC/OS-II提供的系統(tǒng)服務(wù)ll信號(hào)量(OSSemPend(),使用共享資源,OSSemPost())帶互斥機(jī)制的信號(hào)量n使用互斥信號(hào)量減少優(yōu)先級(jí)倒置的問題llllll事件標(biāo)志消息信箱消息隊(duì)列內(nèi)存管理時(shí)鐘管理任務(wù)管理2627μC/GUI與μC/FSlμC/GUIlllll嵌入式的用戶界面用ANSIC書寫支持任何8,16,32-bitsCPU彩色,灰、度,等級(jí)或黑白顯示代碼尺寸小lμC/FSllll嵌入式的文件系統(tǒng)WritteninANSIC用ANSIC書寫支持任何8,16,32-bitsCPU支持SMC,MMC,SD,CF,IDE,Flash,RAM其他介質(zhì)2728可移植的數(shù)據(jù)類型typedefunsignedcharBOOLEAN;typedefunsignedcharINT8U;typedefsignedcharINT8S;typedefunsignedintINT16U;typedefsignedintINT16S;typedefunsignedlongINT32U;typedefsignedlongINT32S;typedeffloatFP32;typedefdoubleFP64;
2829μC/OS-II的組成文件結(jié)構(gòu)
293030μμC/OS-II概述任務(wù)管理中斷和時(shí)間管理Co存儲(chǔ)管理任務(wù)之間的通信與同步SII第二章:μC/OS-II任務(wù)管理31RTOS在嵌入式系統(tǒng)中的位置μC/OS-II:任務(wù)管理 之前我們介紹過簡單的收款機(jī)程序,其實(shí)也可以稱之為一個(gè)任務(wù),只是在這樣簡單的前后臺(tái)編程方式下,MCU(MicroControlUnit)僅僅運(yùn)行一個(gè)單一任務(wù)而已。但是,此任務(wù)是可以被中斷服務(wù)程序所打斷,當(dāng)中斷服務(wù)程序運(yùn)行完畢后,MCU又會(huì)絲毫不差地返回到被中斷位置繼續(xù)執(zhí)行處理收款機(jī)業(yè)務(wù)功能的“任務(wù)”程序。之所以能夠做到這一點(diǎn),是因?yàn)檫M(jìn)入中斷服務(wù)程序時(shí),及時(shí)將斷點(diǎn)位置的有關(guān)信息壓入堆棧進(jìn)行保存,這些信息包括:PC、程序狀態(tài)字PSW等。這些工作由MCU的中斷響應(yīng)機(jī)制或者中斷指令完成。3132RTOS在嵌入式系統(tǒng)中的位置μC/OS-II:任務(wù)管理以下示例為一個(gè)時(shí)鐘中斷服務(wù)匯編語言程序,當(dāng)時(shí)鐘計(jì)數(shù)器減到0時(shí),會(huì)產(chǎn)生中斷,并運(yùn)行此中斷服務(wù)程序:TIME_A4_ISR: pushmr0,r1,r2,r3,a0,a1 ;savegeneralregisters mov.b PRN_FISRSB,r0l ; mov.b r0l,a0 ; shl.w #1,a0 ......... popm r0,r1,r2,r3,a0,a1 ;restoreregisters reit ;returnfrominterrupt32進(jìn)入TIME_A4_ISR前,中斷處理機(jī)制會(huì)將PC和PSW自動(dòng)存入堆棧中斷服務(wù)程序再把自己要用到的寄存器壓入堆棧,以免破壞被中斷程序所使用到的寄存器中的內(nèi)容中斷服務(wù)程序運(yùn)行完畢,從堆棧中恢復(fù)被保護(hù)的寄存器內(nèi)容執(zhí)行中斷返回指令,完成兩個(gè)操作:1。從堆棧中把PSW彈出并存入PSW寄存器;2。從堆棧中將斷點(diǎn)地址彈出并存入到PC中,使MCU到回到斷點(diǎn)處繼續(xù)執(zhí)行33一個(gè)從鍵盤輸入字符串的小程序(任務(wù)).voidGetAString(intiLen,char*iBuf){inti;for(i=0;i<iLen;){if(kbhit())iBuf[i++]=getch();}}//------------------------------------------------------------//intmain(intargc,char*argv[]){charstr[100];while(1){
GetAString(90,str);}}33
Main在調(diào)用GetAString時(shí)要做的幾件事情:1.
將執(zhí)行完GetAString后的返回地址壓入堆棧;2.
將GetAString的兩個(gè)參數(shù)iLen和iBuf壓入堆棧;3.
GetAString在堆棧中為自己的內(nèi)部變量i分配空間.34程序代碼程序堆棧內(nèi)存處理器PCSP寄存器組程序運(yùn)行時(shí)與處理器之間的關(guān)系處理器通過兩個(gè)指針寄存器(PC和SP)來與任務(wù)代碼和任務(wù)堆棧建立聯(lián)系并運(yùn)行它處理器通過兩個(gè)指針寄存器(PC和SP)來與任務(wù)代碼和任務(wù)堆棧建立聯(lián)系并運(yùn)行它運(yùn)行環(huán)境包括了兩部分:處理器中的運(yùn)行環(huán)境和內(nèi)存中的運(yùn)行環(huán)境運(yùn)行環(huán)境包括了兩部分:處理器中的運(yùn)行環(huán)境和內(nèi)存中的運(yùn)行環(huán)境35一個(gè)從鍵盤輸入字符串的小程序(任務(wù))voidGetAString(intiLen,char*iBuf){inti;for(i=0;i<iLen;){if(kbhit())iBuf[i++]=getch();}}//------------------------------------------------------------//intmain(intargc,char*argv[]){charstr[100];while(1){
GetAString(90,str);}}實(shí)際應(yīng)用要求:運(yùn)行此程序的設(shè)備突然斷電了,重新開機(jī)后,需要從斷電時(shí)的程序斷點(diǎn)位置繼續(xù)運(yùn)行,怎么辦?3536一個(gè)從鍵盤輸入字符串的小程序(任務(wù))掉電時(shí)進(jìn)行如下處理:掉電時(shí),產(chǎn)生系統(tǒng)中斷,進(jìn)入掉電中斷服務(wù)程序;將程序斷點(diǎn)(PC)存入非易失存儲(chǔ)器將所有寄存器的值存入非易失存儲(chǔ)器將堆棧中的數(shù)據(jù)存入非易失存儲(chǔ)器開機(jī)時(shí)進(jìn)行如下處理:判斷是否有被保護(hù)的現(xiàn)場數(shù)據(jù);恢復(fù)堆棧數(shù)據(jù)恢復(fù)寄存器數(shù)據(jù)恢復(fù)PC中的數(shù)據(jù)3637任務(wù)代碼任務(wù)堆棧內(nèi)存處理器PCSP任務(wù)代碼任務(wù)堆棧內(nèi)存任務(wù)代碼任務(wù)堆棧內(nèi)存?當(dāng)有多個(gè)任務(wù)時(shí),處理器中的運(yùn)行環(huán)境應(yīng)該怎么辦?寄存器組程序運(yùn)行環(huán)境多任務(wù)運(yùn)行時(shí)與處理器之間的關(guān)系38程序
虛擬處理器PCSP
虛擬處理器PCSP
虛擬處理器PCSP
虛擬處理器PCSP調(diào)度器程序處理器PCSP在內(nèi)存中為每個(gè)任務(wù)創(chuàng)建一個(gè)虛擬的處理器(處理器部分的運(yùn)行環(huán)境由操作系統(tǒng)的調(diào)度器按某種規(guī)則來進(jìn)行這兩個(gè)復(fù)制工作復(fù)制當(dāng)需要運(yùn)行某個(gè)任務(wù)時(shí)就把該任務(wù)的虛擬處理器復(fù)制到實(shí)際處理器中復(fù)制當(dāng)需要中止當(dāng)前任務(wù)時(shí),則把任務(wù)對(duì)應(yīng)的虛擬處理器復(fù)制到內(nèi)存復(fù)制再把另一個(gè)需要運(yùn)行的任務(wù)的虛擬處理器復(fù)制到實(shí)際處理器中寄存器組寄存器組也就是說,任務(wù)的切換實(shí)際上是任務(wù)運(yùn)行環(huán)境的切換多任務(wù)運(yùn)行時(shí)與處理器之間的關(guān)系39虛擬處理器應(yīng)該存儲(chǔ)的主要信息:1。程序的斷點(diǎn)地址(PC)2。任務(wù)堆棧指針(SP)3。程序狀態(tài)字寄存器(PSW)4。通用寄存器內(nèi)容5。函數(shù)調(diào)用信息(已存在于堆棧)另外再用一個(gè)數(shù)據(jù)結(jié)構(gòu)保存任務(wù)堆棧指針(SP),這個(gè)數(shù)據(jù)結(jié)構(gòu)叫做任務(wù)控制塊,它除了保存任務(wù)堆棧指針之外還要負(fù)責(zé)保存任務(wù)其他信息。這些內(nèi)容通常保存在任務(wù)堆棧中,這些內(nèi)容也常叫做任務(wù)的上下文。任務(wù)控制塊是由操作系統(tǒng)另行構(gòu)造的一個(gè)數(shù)據(jù)結(jié)構(gòu),每個(gè)任務(wù)都有一個(gè)。任務(wù)代碼任務(wù)堆棧內(nèi)存任務(wù)控制塊多任務(wù)運(yùn)行時(shí)虛擬處理器40程序切換的關(guān)鍵是把程序的私有堆棧指針賦予處理器的堆棧指針SP,實(shí)質(zhì)上系統(tǒng)是通過SP的切換來實(shí)現(xiàn)任務(wù)的切換的。要建立一個(gè)概念:具有控制塊的程序才是一個(gè)可以被系統(tǒng)所運(yùn)行的任務(wù)。程序代碼、私有堆棧、任務(wù)控制塊是任務(wù)的三大要素。任務(wù)控制塊提供了運(yùn)行環(huán)境的存儲(chǔ)位置。多任務(wù)運(yùn)行時(shí)虛擬處理器41
在多任務(wù)環(huán)境下,把一個(gè)大型軟件分解成多個(gè)小任務(wù),然后在計(jì)算機(jī)中通過運(yùn)行這些小任務(wù),最終達(dá)到完成軟件所要實(shí)現(xiàn)的功能的目的。
在μC/OS-II中,與上述那些小任務(wù)對(duì)應(yīng)的程序?qū)嶓w就叫做“任務(wù)”(實(shí)質(zhì)上是一個(gè)線程),μC/OS-II就是一個(gè)能對(duì)這些小任務(wù)的運(yùn)行進(jìn)行管理和調(diào)度的多任務(wù)操作系統(tǒng)。
任務(wù)的概念421.
一個(gè)任務(wù),也稱作一個(gè)線程,是完成某一特定功能的程序,該程序認(rèn)為CPU完全屬于自己;2.
應(yīng)用程序的設(shè)計(jì)過程,就是如何把復(fù)雜的功能分割成多個(gè)任務(wù)來實(shí)現(xiàn),每個(gè)任務(wù)被賦予一定的優(yōu)先級(jí),有它自己的一套CPU寄存器和自己的棧空間;3.
典型地、每個(gè)任務(wù)都是一個(gè)無限的循環(huán)。每個(gè)任務(wù)都處在5種狀態(tài)之一的狀態(tài)下:休眠態(tài),就緒態(tài)、運(yùn)行態(tài)、掛起態(tài)(等待某一事件發(fā)生)和被中斷態(tài);42任務(wù)的概念4343任務(wù)的概念44從應(yīng)用程序設(shè)計(jì)的角度來看,μ/OS-II的任務(wù)就是一個(gè)用戶編寫的C函數(shù)和與之相關(guān)聯(lián)的一些數(shù)據(jù)結(jié)構(gòu)而構(gòu)成的一個(gè)實(shí)體。
任務(wù)代碼任務(wù)堆棧內(nèi)存在內(nèi)存中應(yīng)該存有任務(wù)的代碼和與該任務(wù)配套的堆棧任務(wù)的概念任務(wù)控制塊在內(nèi)存中還必須保存任務(wù)控制塊45μC/OS-II所管理的任務(wù)一般結(jié)構(gòu):voidMyTask(void*pdata) { for(;;) { {可以被中斷的任務(wù)代碼;}
OS_ENTER_CRITICAL();//進(jìn)入臨界段(關(guān)中斷)
{不可以被中斷的任務(wù)代碼;}
OS_EXIT_CRITICAL(); //退出臨界段(開中斷) {可以被中斷的任務(wù)代碼;}
OSTimeDly(10); //引起任務(wù)調(diào)度 }}pdata參數(shù)為任務(wù)所需要的參數(shù),在創(chuàng)建任務(wù)時(shí)指定為了有效的對(duì)中斷進(jìn)行控制,在任務(wù)的代碼里可使用UC/OS-II定義的宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()來控制何時(shí)響應(yīng)中斷,何時(shí)屏蔽中斷。在運(yùn)行這兩個(gè)宏之間的代碼時(shí)是不會(huì)響應(yīng)中斷的,這種受保護(hù)的代碼段叫臨界段。μC/OS-II的任務(wù)45根據(jù)嵌入式系統(tǒng)任務(wù)的工作特點(diǎn),任務(wù)的執(zhí)行代碼通常是一個(gè)無限循環(huán)結(jié)構(gòu),并且在這個(gè)循環(huán)中可以響應(yīng)中斷,這種結(jié)構(gòu)也叫超循環(huán)結(jié)構(gòu)。并非每個(gè)任務(wù)都要pdata,當(dāng)多個(gè)任務(wù)完成相同的功能,僅僅是其使用的數(shù)據(jù)不同時(shí),可以通過提供不同的pdata參數(shù)來用同一個(gè)函數(shù)創(chuàng)建多個(gè)任務(wù),如:可以將四個(gè)串口安排成每個(gè)串口都是一個(gè)單獨(dú)的任務(wù),而每個(gè)任務(wù)的代碼實(shí)際上是相同的。不同的僅僅是串口的參數(shù)(波特率、I/O口地址、中斷向量號(hào)、數(shù)據(jù)收發(fā)區(qū)等)。46μC/OS-II的任務(wù)voidTask1(void*pdata) //定義用戶任務(wù)1{ for(;;){ …… }}voidTask2(void*pdata) //定義用戶任務(wù)2{ for(;;){ …… }}voidmain(){ ……OSInit(); //初始化uC/OS-IIOSTaskCreate(Task1,……); //創(chuàng)建用戶任務(wù)1 OSTaskCreate(Task2,……); //創(chuàng)建用戶任務(wù)2OSStart(); //啟動(dòng)任務(wù)} Task1是一個(gè)任務(wù)。因此它不是被主函數(shù)或其它函數(shù)調(diào)用的,主函數(shù)main()只負(fù)責(zé)創(chuàng)建和啟動(dòng)它們,而由操作系統(tǒng)負(fù)責(zé)來調(diào)度運(yùn)行它們。OSInit()在main()函數(shù)中首先被調(diào)用,是uC/OS運(yùn)行的第一個(gè)函數(shù)。它完成uC/OS的初始化,建立任務(wù)空閑鍵表OSTCBFreeList,建立事件空閑鍵表OSEventFreeList.創(chuàng)建空閑任務(wù)OS_TaskIdle等。
使用函數(shù)OSStart()啟動(dòng)任務(wù)之后,任務(wù)就交由操作系統(tǒng)管理和調(diào)度了。46創(chuàng)建任務(wù)。建立此任務(wù)的TCB,為任務(wù)分配堆棧,,設(shè)定任務(wù)的優(yōu)先級(jí),將任務(wù)置為就緒狀態(tài)47μC/OS-II的任務(wù)OSInit函數(shù)原型:voidOSInit(void){OS_InitMisc();//完成一般變量初始化OS_InitRdyList();//就緒列表初始化OS_InitTCBList();//空閑任務(wù)鍵表OSTCBFreeList建立OS_InitEventList();//事件空閑鍵表OSEventFreeList建立。OS_FlagInit();//其它相關(guān)功能參數(shù)初始化。OS_MemInit();//內(nèi)存管理初始化函數(shù)OS_QInit();//消息隊(duì)列初始化函數(shù)OS_InitTaskIdle();//創(chuàng)建空閑任務(wù)OS_TaskIdle.OS_InitTaskStat();OSInitHookEnd();}
4748voidMyTask(void*pdata){ /*對(duì)參數(shù)pdata進(jìn)行操作,例如pdata=pdata*/for(;;){/*任務(wù)函數(shù)體.為無限循環(huán)結(jié)構(gòu)*/ . .
/*任務(wù)中必須調(diào)用如下的函數(shù)之一:*/ /*OSMboxPend()*/ /*OSQPend()*/ /*OSSemPend()*/ /*OSTimeDly()*/ /*OSTimeDlyHMSM()*/ /*OSTaskSuspend()(掛起任務(wù)自身)*/ /*OSTaskDel()(刪除任務(wù)自身)*/ .}}
μC/OS-II的任務(wù)48任務(wù)中必須調(diào)用如下的函數(shù)之一,其目的是能夠引起任務(wù)調(diào)度49lμC/OS-Ⅱ可以管理多達(dá)64個(gè)任務(wù);lll每個(gè)任務(wù)被賦以不同的優(yōu)先級(jí),取值從0到OS_LOWEST_PRIO-2,數(shù)值越小,優(yōu)先級(jí)越高;系統(tǒng)保留了優(yōu)先級(jí)為0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及OS_LOWEST_PRI0這8個(gè)任務(wù)以被將來使用,用戶可以有56個(gè)應(yīng)用任務(wù);任務(wù)的優(yōu)先級(jí)同樣也是它的標(biāo)識(shí)號(hào)ID。μC/OS-II的任務(wù)4950uC/OS-II的任務(wù)有兩種,用戶任務(wù)和系統(tǒng)任務(wù):由應(yīng)用程序設(shè)計(jì)者編寫的任務(wù)叫做用戶任務(wù),由系統(tǒng)提供的任務(wù)叫做系統(tǒng)任務(wù)。用戶任務(wù)是為解決應(yīng)用問題而編寫的,系統(tǒng)任務(wù)是為應(yīng)用程序來提供某種服務(wù)的。μC/OS-II的任務(wù)5051系統(tǒng)任務(wù)之:空閑任務(wù)(IdleTask)
μC/OS-Ⅱ總要建立一個(gè)空閑任務(wù),這個(gè)任務(wù)在沒有其它任務(wù)進(jìn)入就緒態(tài)時(shí)投入運(yùn)行。這個(gè)空閑任務(wù)OSTaskIdle()永遠(yuǎn)設(shè)為最低優(yōu)先級(jí),即OS_LOWEST_PRI0??臻e任務(wù)OSTaskIdle()什么也不做,只是在不停地給一個(gè)32位的名叫OSIdleCtr的計(jì)數(shù)器加1,統(tǒng)計(jì)任務(wù)使用這個(gè)計(jì)數(shù)器以確定現(xiàn)行應(yīng)用軟件實(shí)際消耗的CPU時(shí)間??臻e任務(wù)不能被應(yīng)用軟件刪除。5152系統(tǒng)任務(wù)之:
統(tǒng)計(jì)任務(wù)OSTaskStat()任務(wù)OSTaskStat()是負(fù)責(zé)統(tǒng)計(jì)運(yùn)行時(shí)間的任務(wù),如果用戶將系統(tǒng)定義常數(shù)OS_TASK_STAT_EN(見文件OS_CFG.H)設(shè)為1,這個(gè)任務(wù)就會(huì)建立。一旦得到允許,統(tǒng)計(jì)任務(wù)每秒運(yùn)行一次(OS_CORE.C)以計(jì)算當(dāng)前的CPU利用率。也即計(jì)算應(yīng)用程序使用了多少CPU時(shí)間,用百分比表示,這個(gè)值放在一個(gè)有符號(hào)8位整數(shù)OSCPUsage中,精確度是1個(gè)百分點(diǎn)。5253任務(wù)的實(shí)現(xiàn)μC/OS-II任務(wù)創(chuàng)建功能函數(shù)之一:53INT8UOSTaskCreate( void(*task)(void*pd),//是指向任務(wù)代碼的指針 void*pdata,
//指向任務(wù)傳遞參數(shù)的一個(gè)數(shù)據(jù)結(jié)構(gòu) OS_STK*ptos,
//指向任務(wù)堆棧棧頂?shù)闹羔?INT8Uprio
//為任務(wù)的優(yōu)先級(jí));54任務(wù)的實(shí)現(xiàn)lOSTaskCreateExt()μC/OS-II中的任務(wù)是進(jìn)程還是線程?μC/OS-II任務(wù)創(chuàng)建功能函數(shù)之二:INT8UOSTaskCreateExt( void(*task)(void*pd),//是指向任務(wù)代碼的指針 void*pdata,//指針指向向任務(wù)傳遞參數(shù)的一個(gè)數(shù)據(jù)結(jié)構(gòu) OS_STK*ptos,//指向任務(wù)堆棧棧頂?shù)闹羔?INT8Uprio,//為任務(wù)的優(yōu)先級(jí) INT16Uid,//是任務(wù)的標(biāo)識(shí)(保留) OS_STK*pbos,//指向堆棧底端的指針 INT32Ustk_size,//指定任務(wù)堆棧的大小 void*pext,//個(gè)用戶定義數(shù)據(jù)結(jié)構(gòu)的指針,可作為TCB的擴(kuò)展 INT16Uopt//存放與任務(wù)相關(guān)的操作信息);54當(dāng)前的μC/OS版本的Opt支持下列操作:OS_TASK_OPT_STK_CHK:決定是否進(jìn)行任務(wù)堆棧檢查。OS_TASK_OPT_STK_CLR:決定是否清空堆棧。OS_TASK_OPT_SAVE_FP:決定是否保存浮點(diǎn)寄存器的數(shù)值。此項(xiàng)操作僅當(dāng)處理器有浮點(diǎn)硬件時(shí)有效。保存操作由硬件相關(guān)的代碼完成。55任務(wù)也可以自我刪除(并非真的刪除,只是內(nèi)核不再知道該任務(wù))voidMyTask(void*pdata){....../*任務(wù)代碼*/OSTaskDel(OS_PRIO_SELF);}
55任務(wù)的實(shí)現(xiàn)56
μC/OS-II多任務(wù)的啟動(dòng)是用戶通過調(diào)用OSStart()實(shí)現(xiàn)的。然而,啟動(dòng)μC/OS-Ⅱ之前,用戶至少要建立一個(gè)應(yīng)用任務(wù)。OSStart函數(shù)直接調(diào)用OSStartHighRdy去執(zhí)行最高優(yōu)先級(jí)的任務(wù),OSStart不返回.OSInit();/*初始化uC/OS-II*/
...通過調(diào)用OSTaskCreate()或OSTaskCreateExt()創(chuàng)建至少一個(gè)任務(wù);
...OSStart();/*開始多任務(wù)調(diào)度!永不返回*/}56
voidmain(void) {任務(wù)的實(shí)現(xiàn)任務(wù)創(chuàng)建示例#defineTASK_STK_SIZE512//定義堆棧大小#defineTaskStart_ID5//定義任務(wù)的ID,優(yōu)先級(jí)voidTaskStart(void*data)
//定義任務(wù){(diào)
WORDkey;data=data;/*避免編譯警告*/
PC_DispStr(16,0,"uC/OS-II,TheReal-TimeKernel",DISP_BGND_RED);
PC_DispStr(17,1,"JeanJ.Labrosse",DISP_FGND_WHITE);
PC_DispStr(18,3,"EXAMPLE#1",DISP_FGND_WHITE);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
for(;;){
if(PC_GetKey(&key)==TRUE){
/*是否有按鍵*/
if(key==0x1B)/*有按鍵,且為ESC*/
PC_DOSReturn();/*退出系統(tǒng)*/
}
OSTimeDlyHMSM(0,0,1,0);/*延遲等待1秒*/
}//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<}OS_STKTaskStartStk[TASK_STK_SIZE];
//定義堆棧任務(wù)創(chuàng)建示例voidmain(void){
PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);/*清除屏幕*/
OSInit();/*初始化uC/OS-II*/
PC_DOSSaveReturn();/*保護(hù)用于返回DOS的系統(tǒng)環(huán)境*/
PC_VectSet(uCOS,OSCtxSw);/*初始化uC/OS-II的中斷向量*/
OSTaskCreate(TaskStart,//要?jiǎng)?chuàng)建的任務(wù)名稱(void*)0,//傳遞給任務(wù)的參數(shù)&TaskStartStk[TASK_STK_SIZE-1],//任務(wù)要用到的堆棧
TaskStart_ID//任務(wù)優(yōu)先級(jí)
);/*創(chuàng)建任務(wù)*/
OSStart();/*啟動(dòng)任務(wù)*/}59μC/OS-II系統(tǒng)的初始化與啟動(dòng)lll在調(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)先級(jí)一般被設(shè)成最低,即OS_LOWEST_PRIO;如果需要,OSInit()還建立統(tǒng)計(jì)任務(wù)OSTaskStat(),并讓其進(jìn)入就緒狀態(tài);OSInit()還初始化了4個(gè)空數(shù)據(jù)結(jié)構(gòu)緩沖區(qū):空閑
TCB鏈表OSTCBFreeList、空閑事件鏈表
OSEventFreeList、空閑隊(duì)列鏈表OSQFreeList和 空閑存儲(chǔ)鏈表OSMemFreeList。
5960μC/OS-II系統(tǒng)初始化后的狀態(tài)
60調(diào)用OSInit()之后的數(shù)據(jù)結(jié)構(gòu)61
OSStart()voidOSStart(void){ INT8UY; INT8UX; if(OSRunning==FALSE){yx=OSUnMapTbl[OSRdyGrp];=OSUnMapTbl[OSRdyTbl[y]];OSPrioHighRdy=(INT8U)((Y<<3)+X);OSPrioCurOSTCBHighRdy=OSPrioHighRdy;=OSTCBPrioTbl[OSPrioHighRdy];OSTCBCur=OSTCBHighRdy;
OSStartHighRdy();//啟動(dòng)最高優(yōu)先級(jí)任務(wù) } }6162系統(tǒng)啟動(dòng)后的狀態(tài)
62調(diào)用OSStart()以后的變量與數(shù)據(jù)結(jié)構(gòu)假設(shè)用戶創(chuàng)建的任務(wù)優(yōu)先級(jí)為663任務(wù)控制塊TCBll任務(wù)控制塊OS_TCB是描述一個(gè)任務(wù)的核心數(shù)據(jù)結(jié)構(gòu),存放了它的各種管理信息,包括任務(wù)堆棧指針,任務(wù)的狀態(tài)、優(yōu)先級(jí),任務(wù)鏈表指針等;一旦任務(wù)建立了,任務(wù)控制塊OS_TCB將被賦值。記住:μC/OS-Ⅱ管理任務(wù)的核心是任務(wù)控制塊TCB!6364任務(wù)堆棧voidmytask(){…..for(;;){…..}}任務(wù)代碼任務(wù)控制塊指向前一個(gè)任務(wù)控制塊的指針指向后一個(gè)任務(wù)控制塊的指針指向任務(wù)的指針指向任務(wù)堆棧的指針任務(wù)的優(yōu)先級(jí)別……任務(wù)任務(wù)控制塊TCB
:任務(wù)的存儲(chǔ)結(jié)構(gòu)從任務(wù)的存儲(chǔ)結(jié)構(gòu)看,任務(wù)由三個(gè)部分組成:任務(wù)控制塊、任務(wù)代碼與任務(wù)堆棧6465任務(wù)控制塊TCB
:任務(wù)的存儲(chǔ)結(jié)構(gòu)任務(wù)控制塊任務(wù)代碼任務(wù)堆棧任務(wù)1任務(wù)控制塊任務(wù)代碼任務(wù)堆棧任務(wù)2任務(wù)控制塊任務(wù)代碼任務(wù)堆棧任務(wù)n……任務(wù)控制塊鏈表系統(tǒng)在調(diào)用函數(shù)OSInit()對(duì)uC/OS-II系統(tǒng)進(jìn)行初始化時(shí),先在RAM中建立一個(gè)OS_TCB結(jié)構(gòu)類型的數(shù)組OSTCBTbl[],每個(gè)數(shù)組元素就是一個(gè)任務(wù)控制塊,然后把這些控制塊鏈接成一個(gè)如圖所示的鏈表。由于鏈表中的這些控制塊還沒有與具體任務(wù)相關(guān)聯(lián),因此這個(gè)鏈表叫做空任務(wù)塊鏈表。每當(dāng)應(yīng)用程序調(diào)用系統(tǒng)函數(shù)OSTaskCreate()創(chuàng)建一個(gè)任務(wù)時(shí),系統(tǒng)就會(huì)將任務(wù)控制塊鏈表頭指針OSTCBFreeList指向的任務(wù)控制塊分配給該任務(wù)。在給任務(wù)控制塊中的各成員賦值后,就按任務(wù)控制塊鏈表的頭指針OSTCBList將其加入到任務(wù)控制塊鏈表中。6566任務(wù)控制塊TCB
:任務(wù)的存儲(chǔ)結(jié)構(gòu)一旦任務(wù)建立,uCOS就會(huì)為此任務(wù)創(chuàng)建一個(gè)任務(wù)控制塊OS_TCB。任務(wù)控制塊是一個(gè)數(shù)據(jù)結(jié)構(gòu),保存該任務(wù)的相關(guān)參數(shù),包括任務(wù)堆棧指針,任務(wù)的當(dāng)前狀態(tài),任務(wù)的優(yōu)先級(jí)等。任務(wù)CPU使用權(quán)被剝奪時(shí),OS_TCB保存該時(shí)刻任務(wù)狀態(tài);任務(wù)重新得到CPU控制權(quán)時(shí),OS_TCB可確保任務(wù)從此前被中斷的那一點(diǎn)絲毫不差地繼續(xù)執(zhí)行。OS_TCB全部駐留在RAM中。任務(wù)控制塊就相當(dāng)于一個(gè)任務(wù)的身份證,沒有任務(wù)控制塊的任務(wù)是不能被系統(tǒng)承認(rèn)和管理的。
6667任務(wù)控制塊TCBtypedef
struct
os_tcb
{OS_STK*OSTCBStkPtr;//指向任務(wù)堆棧棧頂?shù)闹羔?/p>
INT16UOSTCBOpt; //任務(wù)選擇項(xiàng)
INT16UOSTCBId;
//任務(wù)的ID
……
structos_tcb*OSTCBNext;//指向后一個(gè)任務(wù)控制塊的指針
structos_tcb*OSTCBPrev;//指向前一個(gè)任務(wù)控制塊的指針OS_EVENT*OSTCBEventPtr;//事件指針void*OSTCBMsg;//消息指針
……INT16U OSTCBDly;//任務(wù)等待的時(shí)限(節(jié)拍數(shù))
INT8U OSTCBStat;//任務(wù)的當(dāng)前狀態(tài)標(biāo)志
INT8U OSTCBPrio;//任務(wù)的優(yōu)先級(jí)別
……}OS_TCB;6768任務(wù)控制塊TCB:棧指針
OSTCBStkPtr:指向當(dāng)前任務(wù)棧頂?shù)闹羔槪總€(gè)任務(wù)可以有自己的棧,棧的容量可以是任意的;
OSTCBStkBottom:執(zhí)行任務(wù)棧底的指針;。如果微處理器的棧指針是遞減的,即棧存儲(chǔ)器從高地址向低地址方向分配,則OSTCBStkBottom指向任務(wù)使用的??臻g的最低地址。類似地,如果微處理器的棧是從低地址向高地址遞增型的,則OSTCBStkBottom指向任務(wù)可以使用的??臻g的最高地址。函數(shù)OSTaskStkChk()要用到變量OSTCBStkBottom,在運(yùn)行中檢驗(yàn)??臻g的使用情況。用戶可以用它來確定任務(wù)實(shí)際需要的??臻g
OSTCBStkSize:棧的容量,用可容納的指針數(shù)目而不是字節(jié)數(shù)(Byte)來表示。在函數(shù)OSStakChk()中要使用OSTCBStkSize。6869任務(wù)控制塊TCB:棧指針
任務(wù)所需的堆棧的容量是在創(chuàng)建任務(wù)時(shí)指定的。在指定堆棧大小的時(shí)候必須考慮此任務(wù)所調(diào)用的所有函數(shù)的嵌套情況,任務(wù)所調(diào)用的所有函數(shù)會(huì)分配的局部變量的數(shù)目,以及所有可能的中斷服務(wù)例程嵌套的堆棧需求。另外,為任務(wù)分配的堆棧必須能儲(chǔ)存所有的CPU寄存器。由于嵌入式硬件平臺(tái)的RAM資源很寶貴,因此我們應(yīng)該給每個(gè)任務(wù)分配夠用的堆棧!用戶如何確定一個(gè)任務(wù)所需要的堆棧大小呢?6970任務(wù)控制塊TCB:棧檢測
OSTCBOpt:為使用OSTaskCreateExt()創(chuàng)建任務(wù)時(shí)的選擇項(xiàng)。
OS_TASK_OTP_STK_CHK用于告知TaskCreateExt(),在任務(wù)建立的時(shí)候可以進(jìn)行任務(wù)棧檢驗(yàn)功能;OS_TASK_OPT_STK_CLR表示任務(wù)建立的時(shí)候任務(wù)棧要清零。如果要進(jìn)行棧檢測,創(chuàng)建任務(wù)時(shí)必須將棧清0;OS_TASK_OPT_SAVE_FP通知TaskCreateExt(),任務(wù)要做浮點(diǎn)運(yùn)算。如果微處理器有硬件的浮點(diǎn)協(xié)處理器,則所建立的任務(wù)在做任務(wù)調(diào)度切換時(shí),浮點(diǎn)寄存器的內(nèi)容要保存7071任務(wù)控制塊TCB:棧檢測7172任務(wù)控制塊TCB:棧檢測μC/OS-Ⅱ提供的OSTaskStkChk()函數(shù)可以為用戶確定任務(wù)做需要的堆棧大小,要使用此功能,用戶必須要做以下幾件事情:在OS_CFG.H文件中設(shè)OS_TASK_CREATE_EXT為1。用OSTaskCreateExt()建立任務(wù),并給予任務(wù)比實(shí)際需要更多的內(nèi)存空間。在OSTaskCreateExt()中,將參數(shù)opt設(shè)置為OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR。注意如果用戶的程序啟動(dòng)代碼清除了所有的RAM,并且從未刪除過已建立了的任務(wù),那么用戶就不必設(shè)置選項(xiàng)OS_TASK_OPT_STK_CLR了。這樣就會(huì)減少OSTaskCreateExt()的執(zhí)行時(shí)間。將用戶想檢驗(yàn)的任務(wù)的優(yōu)先級(jí)作為OSTaskStkChk()的參數(shù)并調(diào)用之。
72用戶應(yīng)該使自己的應(yīng)用程序運(yùn)行足夠長的時(shí)間,并且經(jīng)歷最壞的堆棧使用情況,這樣才能得到正確的數(shù)。一旦OSTaskStkChk()提供給用戶最壞情況下堆棧的需求,用戶就可以重新設(shè)置堆棧的最后容量了。為了適應(yīng)系統(tǒng)以后的升級(jí)和擴(kuò)展,用戶應(yīng)該多分配10%-100%的堆??臻g。在堆棧檢驗(yàn)中,用戶所得到的只是一個(gè)大致的堆棧使用情況,并不能說明堆棧使用的全部實(shí)際情況。73任務(wù)控制塊TCB:鏈表指針
OSTCBNext、OSTCBPrev:用于任務(wù)控制塊OS_TCBs的雙重鏈接,該鏈表在時(shí)鐘節(jié)拍函數(shù)OSTimeTick()中使用,用于刷新各個(gè)任務(wù)的任務(wù)延遲變量.OSTCBDly,每個(gè)任務(wù)的任務(wù)控制塊OS_TCB在任務(wù)建立的時(shí)候被鏈接到鏈表中,在任務(wù)刪除的時(shí)候從鏈表中被刪除。雙重連接的鏈表使得任一成員都能被快速插入或刪除。所有的任務(wù)控制塊分屬于兩條不同的鏈表,單向的空閑鏈表(頭指針為OSTCBFreeList)和雙向的使用鏈表(頭指針為OSTCBList);7374任務(wù)控制塊TCB:空閑TCB鏈表l所有的任務(wù)控制塊都被放置在任務(wù)控制塊列表數(shù)組
OSTCBTbl[]中,系統(tǒng)初始化時(shí),所有TCB被鏈接成空閑的 單向鏈表,頭指針為OSTCBFreeList。當(dāng)創(chuàng)建一個(gè)任務(wù)后, 就把OSTCBFreeList所指向的TCB賦給了該任務(wù),并將它加 入到使用鏈表中,然后把OSTCBFreeList指向空閑鏈表中的 下一個(gè)結(jié)點(diǎn)。7475任務(wù)控制塊TCB:延遲/狀態(tài)/優(yōu)先級(jí)
OSTCBDly:保存的是任務(wù)允許等待事件發(fā)生的最多時(shí)鐘節(jié)拍數(shù)。如果這個(gè)變量為0,表示任務(wù)不延時(shí),或者表示等待事件發(fā)生的時(shí)間沒有限制。當(dāng)需要把任務(wù)延時(shí)若干時(shí)鐘節(jié)拍時(shí)要用到這個(gè)變量,或者需要把任務(wù)掛起一段時(shí)間以等待某事件的發(fā)生,這種等待是有超時(shí)限制的。OSTCBStat:任務(wù)的狀態(tài)字。為0時(shí),任務(wù)進(jìn)入就緒態(tài)。在uCOS_II.H中有這個(gè)值的其它狀態(tài)定義:等待信號(hào)量、等待郵箱、掛起等。OSTCBPrio:是任務(wù)優(yōu)先級(jí)。任務(wù)優(yōu)先級(jí)越高,.OSTCBPrio的值越小。7576任務(wù)控制塊TCB:系統(tǒng)初始化后…指針數(shù)組,指向相應(yīng)TCB76總結(jié):任務(wù)控制塊是一個(gè)數(shù)據(jù)結(jié)構(gòu),當(dāng)任務(wù)的CPU使用權(quán)被剝奪時(shí),μC/OS-Ⅱ用它來保存該任務(wù)的狀態(tài)。當(dāng)任務(wù)重新得到CPU使用權(quán)時(shí),任務(wù)控制塊能確保任務(wù)從當(dāng)時(shí)被中斷的指令位置絲毫不差地繼續(xù)執(zhí)行。77任務(wù)的狀態(tài)-就緒lll就緒狀態(tài)(Ready):萬事具備,只欠CPU;在所有的就緒任務(wù)當(dāng)中,具有最高優(yōu)先級(jí)的任務(wù)被選中去運(yùn)行;如果任務(wù)在運(yùn)行的時(shí)候被搶占了CPU,則
又回到就緒狀態(tài)。7778任務(wù)的狀態(tài)-運(yùn)行l(wèi)ll運(yùn)行狀態(tài)(Running):任務(wù)在CPU上運(yùn)行;當(dāng)一個(gè)任務(wù)在運(yùn)行時(shí),如果沒有關(guān)閉中斷,則有可能被中斷所打斷;當(dāng)一個(gè)任務(wù)在運(yùn)行時(shí),可能因?yàn)楦鞣N原因進(jìn)入阻塞狀態(tài)。–OSMBoxPend(),OSQPend(),OSSemPend()
OSTaskSuspend(),OSTimeDly()7879任務(wù)的狀態(tài)-休眠ll休眠狀態(tài)(Dormant):任務(wù)存在于內(nèi)存空間中,但內(nèi)核不可見;可以通過以下函數(shù)通知內(nèi)核,使之變?yōu)榫途w狀態(tài):–OSTaskCreate()或OSTaskCreateExt()l可以通過以下函數(shù)返回到休眠狀態(tài):–OSTaskDel()7980任務(wù)的狀態(tài)-ISRll中斷服務(wù)狀態(tài)(ISR):該任務(wù)原來在CPU上運(yùn)行,后來被中斷所打斷,由中斷服務(wù)程序ISR接管了CPU;當(dāng)中斷服務(wù)程序運(yùn)行完畢后,內(nèi)核要判斷是
否有新的、更高優(yōu)先級(jí)的任務(wù)就緒,如果有 ,則原有的任務(wù)被搶占;如果沒有,則原有 的任務(wù)重新運(yùn)行。8081任務(wù)的狀態(tài)-阻塞ll阻塞/等待狀態(tài)(Waiting):任務(wù)由于正在等待某個(gè)事件(信號(hào)量、郵箱或隊(duì)列)而被掛起;當(dāng)任務(wù)等待的事件發(fā)生時(shí),回到就緒狀態(tài)。–OSMBoxpost(),OSQPost(),
OSSemPost(),OSTaskResume(), OSTimeDlyResume()或OSTimeTick()8182狀態(tài)的轉(zhuǎn)換正在運(yùn)行的任務(wù),需要等待一段時(shí)間或需要等待一個(gè)事件發(fā)生再運(yùn)行時(shí),該任務(wù)就會(huì)把CPU的使用權(quán)讓給別的任務(wù)而使任務(wù)進(jìn)入等待狀態(tài)。任務(wù)在沒有被配備任務(wù)控制塊或被剝奪了任務(wù)控制塊時(shí)的狀態(tài)叫做任務(wù)的睡眠狀態(tài)
系統(tǒng)為任務(wù)配備了任務(wù)控制塊且在任務(wù)就緒表中進(jìn)行了就緒登記,這時(shí)任務(wù)的狀態(tài)叫做就緒狀態(tài)。
處于就緒狀態(tài)的任務(wù)如果經(jīng)調(diào)度器判斷獲得了CPU的使用權(quán),則任務(wù)就進(jìn)入運(yùn)行狀態(tài)
一個(gè)正在運(yùn)行的任務(wù)一旦響應(yīng)中斷申請(qǐng)就會(huì)中止運(yùn)行而去執(zhí)行中斷服務(wù)程序,這時(shí)任務(wù)的狀態(tài)叫做中斷服務(wù)狀態(tài)
83狀態(tài)的轉(zhuǎn)換83刪除任務(wù)創(chuàng)建任務(wù)掛起時(shí)間到收到等待的消息等待消息掛起中斷結(jié)束任務(wù)調(diào)度刪除任務(wù)自我刪除84狀態(tài)的轉(zhuǎn)換84OSTaskDel()OSTaskCreate()OSTaskCreateExt()OSIntExitOSStart()OSIntExit()OSTASKSW()OSTaskDel()OSTaskDel()OSMBoxPost()OSQPost()OSQPostFront()OSSemPost()OSTaskResume()OSTaskDlyResume()OSTimeTick()OSMBoxPend()OSQPend()OSSemPend()OSTaskSuspend()OSTaskDly()OSTimeDlyHMSM()中斷85任務(wù)就緒表ll每個(gè)任務(wù)的就緒態(tài)標(biāo)志存放在就緒表中,就緒表中有兩個(gè)變量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任務(wù)按優(yōu)先級(jí)分組,8個(gè)任
務(wù)為一組。OSRdyGrp中的每一位表示8組任 務(wù)中每一組中是否有進(jìn)入就緒態(tài)的任務(wù)。 任務(wù)進(jìn)入就緒態(tài)時(shí),就緒表OSRdyTbl[]中 的相應(yīng)元素的相應(yīng)位也置位。8586任務(wù)就緒表
OSRdyGrp7
6
5
4
3
2
1
000YYYXXX任務(wù)優(yōu)先級(jí)
21018
0 816
1 917
71523
61422
51321
41220
3111926344250582432404856253341495731394755633038465462293745536128364452602735435159[0][1][2][3][4][5][6][7]OSRdyTbl[8]
XY優(yōu)先級(jí)最低任務(wù)(空閑任務(wù))優(yōu)先級(jí)最高任務(wù)任務(wù)優(yōu)先級(jí)號(hào)
對(duì)于整數(shù)OSRdyTbl[i],若它的某一位為1,則OSRdyGrp的第i位為1。 任務(wù)的優(yōu)先級(jí)由X和Y確定
86為加快訪問任務(wù)就緒表的速度,系統(tǒng)定義了一個(gè)變量OSRdyGrp來表明就緒表每行中是否存在就緒任務(wù)。87根據(jù)優(yōu)先級(jí)確定就緒表(1)n假設(shè)優(yōu)先級(jí)為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;87881
OSRdyTbl[]1OSRdyGrp
D7D6D5D4D3D2D1D0
任務(wù)就緒表的示意圖01234567xy0123456789根據(jù)優(yōu)先級(jí)確定就緒表(2)n由以上計(jì)算可知:若要將OSRdyGrp及OSRdyBbl[]
的第n位置1,則應(yīng)該把OSRdyGrp及OSRdyBbl[]
的值與2n相或。uC/OS中,把2n的n=0-7的8個(gè) 值先計(jì)算好存在數(shù)組OSMapTbl[7]中,也就是:
OSMapTbl[0]=20=0x01(00000001)
OSMapTbl[1]=21=0x02(00000010)
……
OSMapTbl[7]=27=0x80(10000000)8990使任務(wù)進(jìn)入就緒態(tài)n如果prio是任務(wù)的優(yōu)先級(jí),即任務(wù)的標(biāo)識(shí)號(hào),則將任務(wù)放入就緒表,即使任務(wù)進(jìn)入就緒態(tài)的方法是:OSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];n假設(shè)優(yōu)先級(jí)為29——11101bOSRdyGrpOSRdyTbl[3]|=OSMapTbl[29>>3](0x04);|=0x20;9091OSRdyGrp
D7D6D5D4D3D2D1D0
11110000prio=29D7D6D5D4D3D2D1D0
1D7D6D5D4D3D2D1D0
1OSRdyTbl[3]把prio為29的任務(wù)置為就緒狀態(tài)YXOSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];使任務(wù)進(jìn)入就緒態(tài)92使任務(wù)脫離就緒態(tài)n將任務(wù)就緒表OSRdyTbl[prio>>3]相應(yīng)元素的相應(yīng)
位清零,而且當(dāng)OSRdyTbl[prio>>3]中的所有位都 為零時(shí),即該任務(wù)所在組的所有任務(wù)中沒有一個(gè) 進(jìn)入就緒態(tài)時(shí),OSRdyGrp的相應(yīng)位才為零。
if((OSRdyTbl[prio>>3]&=
~OSMapTbl[prio&0x07])==0) OSRdyGrp&=~OSMapTbl[prio>>3];9293
OSRdyTbl[8]
OSRdyGrp
D7D6D5D4D3D2D1D0
01234567xy01234567當(dāng)要把任務(wù)優(yōu)先級(jí)為34的任務(wù)加入到任務(wù)就緒表中時(shí),要進(jìn)行以下操作:1.將任務(wù)優(yōu)先級(jí)號(hào)34>>8,確定任務(wù)在就續(xù)表中的行42.將任務(wù)優(yōu)先級(jí)號(hào)34%8,確定任務(wù)在就續(xù)表中的列2,將此位置1113.再將任務(wù)組管理單元位置194任務(wù)的調(diào)度lllμC/OS是可搶占實(shí)時(shí)多任務(wù)內(nèi)核,它總是運(yùn)行就緒任務(wù)中優(yōu)先級(jí)最高的那一個(gè)。μC/OS中不支持時(shí)間片輪轉(zhuǎn)法,每個(gè)任務(wù)的優(yōu)先級(jí)要求不一樣且是唯一的,所以任務(wù)調(diào)度的工作就是:查找準(zhǔn)備就緒的最高優(yōu)先級(jí)的任務(wù)并進(jìn)行任務(wù)調(diào)度。μC/OS任務(wù)調(diào)度所花的時(shí)間為常數(shù),與應(yīng)用程
序中建立的任務(wù)數(shù)無關(guān)。
9495l確定哪個(gè)任務(wù)的優(yōu)先級(jí)最高,應(yīng)該選擇哪個(gè)任務(wù)去運(yùn)行,這部分的工作是由調(diào)度器(Scheduler)來完成的。ww任務(wù)級(jí)的調(diào)度是由函數(shù)OSSched()完成的;中斷級(jí)的調(diào)度是由另一個(gè)函數(shù)OSIntExt()完成的。95任務(wù)的調(diào)度96根據(jù)就緒表確定最高優(yōu)先級(jí)9697根據(jù)就緒表確定最高優(yōu)先級(jí)97intRdyTask(){ inti,j,k=0; for(i=0;i<8;i++) { for(j=0;j<8;j++) { if(ODRdyTbl[i]&(1<<j))//判斷是否就緒
returnk;//返回就緒任務(wù)優(yōu)先級(jí)(任務(wù)ID) k++;} } return-1;//無就緒任務(wù)}此程序的缺陷?98
根據(jù)就緒表確定最高優(yōu)先級(jí)兩個(gè)關(guān)鍵:ll將優(yōu)先級(jí)數(shù)分解為高三位和低三位分別確定;高優(yōu)先級(jí)對(duì)應(yīng)的優(yōu)先級(jí)編號(hào)值?。?899根據(jù)就緒表確定最高優(yōu)先級(jí)ll通過OSRdyGrp值確定高3位,假設(shè)OSRdyGrp=0x08=0x00001000,第3位為1,因此優(yōu)先級(jí)的高3位為011([3]);通過OSRdyTbl[3]的值來確定低3位,假設(shè)OSRdyTbl[3]
=0x3a,第2位為1,因此優(yōu)先級(jí)的低3位為010,3*8+2=2699如何確定一個(gè)字節(jié)中第一個(gè)為1的位序號(hào)?此位在OSRdyTbl[3]中的位編號(hào)為1,而在整個(gè)OSRdyTbl表中的總編號(hào)為26.任務(wù)優(yōu)先級(jí)=26
00011
010100根據(jù)就緒表確定最高優(yōu)先級(jí)100為了加快處理速度,uC/OS-II采用查表法,來獲得計(jì)算優(yōu)先級(jí)的數(shù)據(jù),為此定義了優(yōu)先級(jí)參數(shù)表: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};OSUnMapTbl中存放了一個(gè)字節(jié)中第一個(gè)位為1的位序號(hào)(0~7).如:值10010100B(十進(jìn)制為148)中的第二位為1,在OSUnMapTbl中找到148位置的值,為2.101源代碼中使用了查表法n查表法具有確定的時(shí)間,增加了系統(tǒng)的可預(yù)測性,uC/OS中所有的系統(tǒng)調(diào)用時(shí)間都是確定的參見OS_CORE.C
Y=OSUnMapTbl[OSRdyGrp]; X=OSUnMapTbl[OSRdyTbl[Y]]; Prio=(Y<<3)+X;
101102INT8UconstOSUnMapTbl[]={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,它相應(yīng)于OSRdyGrp中的第3位置1;如OSRdyTbl[3]的值是11100100B,即0XE4,則查OSUnMapTbl[OSRdyTbl[3]]的值是2,則進(jìn)入就緒態(tài)的最高任務(wù)優(yōu)先級(jí)
Prio=3*8+2=26
優(yōu)先級(jí)判定表OSUnMapTbl[256]103
任務(wù)調(diào)度器voidOSSched(void){INT8
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 孔乙己學(xué)習(xí)課件
- 第17課《昆明的雨》八年級(jí)語文上冊精講同步課堂(統(tǒng)編版)
- 愛車講堂 課件
- 西南林業(yè)大學(xué)《材料化學(xué)》2022-2023學(xué)年第一學(xué)期期末試卷
- 西南林業(yè)大學(xué)《地理信息系統(tǒng)原理》2023-2024學(xué)年第一學(xué)期期末試卷
- 應(yīng)對(duì)挫折課件
- 西京學(xué)院《機(jī)械制造工藝》2023-2024學(xué)年第一學(xué)期期末試卷
- 幼兒園小班兒歌《鈴兒響叮當(dāng)》課件
- 西京學(xué)院《電機(jī)學(xué)》2021-2022學(xué)年期末試卷
- 醫(yī)保課件 模板
- 2023年8月26日事業(yè)單位聯(lián)考C類《職業(yè)能力傾向測驗(yàn)》試題
- 2023年天津公務(wù)員已出天津公務(wù)員考試真題
- 施工現(xiàn)場臨水施工方案
- 2022年公務(wù)員多省聯(lián)考《申論》真題(四川縣鄉(xiāng)卷)及答案解析
- 艾滋病職業(yè)防護(hù)培訓(xùn)
- 2025年高考數(shù)學(xué)專項(xiàng)題型點(diǎn)撥訓(xùn)練之初等數(shù)論
- 上海市浦東新區(qū)2024-2025學(xué)年六年級(jí)上學(xué)期11月期中數(shù)學(xué)試題(無答案)
- 教科版三年級(jí)科學(xué)上冊《第1單元第1課時(shí) 水到哪里去了》教學(xué)課件
- 通信技術(shù)工程師招聘筆試題與參考答案(某世界500強(qiáng)集團(tuán))2024年
- 國際貿(mào)易術(shù)語2020
- 國網(wǎng)新安規(guī)培訓(xùn)考試題及答案
評(píng)論
0/150
提交評(píng)論