嵌入式實(shí)時(shí)操作系統(tǒng)的移植講義教材_第1頁
嵌入式實(shí)時(shí)操作系統(tǒng)的移植講義教材_第2頁
嵌入式實(shí)時(shí)操作系統(tǒng)的移植講義教材_第3頁
嵌入式實(shí)時(shí)操作系統(tǒng)的移植講義教材_第4頁
嵌入式實(shí)時(shí)操作系統(tǒng)的移植講義教材_第5頁
已閱讀5頁,還剩88頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

嵌入式系統(tǒng)設(shè)計(jì)與實(shí)例開發(fā)——ARM與C/OS-Ⅱ第五講C/OS-Ⅱ移植分析和系統(tǒng)初始化北京航空航天大學(xué)嵌入式機(jī)電控制研究室提要12嵌入式系統(tǒng)的初始化C/OS-Ⅱ移植分析初始化程序的下載執(zhí)行目標(biāo)機(jī)宿主機(jī)1)通過編程器將可執(zhí)行目標(biāo)文件燒寫到BootROM(ROM、EPROM、FLASH)等;2)通過串行口和網(wǎng)口下載執(zhí)行目標(biāo)文件,要求宿主機(jī)系統(tǒng)上有數(shù)據(jù)傳輸工具程序、目標(biāo)機(jī)裝載器、嵌入式監(jiān)視器或目標(biāo)機(jī)系統(tǒng)上的調(diào)試代理;3)通過JTAG或BDM接口下載。嵌入式系統(tǒng)的初始化過程硬件初始化階段1.復(fù)位向量

ENTRYbResetHandler;fordebugbHandlerUndef;handlerUndefbHandlerSWI;SWIinterrupthandlerbHandlerPabort;handlerPAbortbHandlerDabort;handlerDAbortb. ;handlerReservedbHandlerIRQbHandlerFIQ嵌入式系統(tǒng)的初始化過程(2)硬件初始化階段2.最小硬件初始化1)設(shè)置適當(dāng)?shù)募拇嫫?,使嵌入式處理器處于一個(gè)已知的狀態(tài):獲得CPU的類型。獲得或設(shè)置CPU的時(shí)鐘頻率。2)禁止中斷和高速緩存。3)初始化內(nèi)存控制器、內(nèi)存芯片和高速緩存單元,包括:得到內(nèi)存的開始地址。得到內(nèi)存的大小。如果有要求,則還需要進(jìn)行主存測(cè)試嵌入式系統(tǒng)的初始化過程(3)硬件初始化階段3.其余硬件初始化引導(dǎo)代碼調(diào)用合適的函數(shù)對(duì)目標(biāo)機(jī)系統(tǒng)上的全部硬件部件進(jìn)行初始化,包括:建立執(zhí)行處理程序。初始化中斷處理程序。初始化總線接口。初始化板級(jí)外設(shè)得到內(nèi)存的開始地址。嵌入式系統(tǒng)的初始化過程(4)RTOS初始化階段4.RTOS初始化1)RTOS初始化2)RTOS對(duì)象和服務(wù)初始化任務(wù)信號(hào)量定時(shí)器中斷內(nèi)存管理3)RTOS任務(wù)堆棧初始化4)RTOS擴(kuò)展部件初始化5)啟動(dòng)RTOS嵌入式系統(tǒng)的初始化過程(5)應(yīng)用程序初始化階段5.應(yīng)用程序初始化ARM7TDMI系統(tǒng)初始化的一般過程啟動(dòng)(系統(tǒng)上電/復(fù)位)從程序入口點(diǎn)關(guān)閉中斷初始化時(shí)鐘等硬件相關(guān)寄存器初始化存儲(chǔ)器系統(tǒng)初始化C所需要的存儲(chǔ)器空間調(diào)用C入口函數(shù)一、設(shè)置程序入口指針上電復(fù)位后直接到程序入口點(diǎn)執(zhí)行,入口點(diǎn)一般為一個(gè)跳轉(zhuǎn)表,跳轉(zhuǎn)到復(fù)位處理程序處開始執(zhí)行ARM7TDMI系統(tǒng)的初始化。啟動(dòng)程序首先必須定義入口指針,而且整個(gè)應(yīng)用程序只有一個(gè)入口指針。例:AREABoot,CODE,READONLYENTRY/*設(shè)置程序入口指針*/二、設(shè)置中斷向量ARM要求中斷向量必須設(shè)置在從OX00000000地址開始,連續(xù)8*4字節(jié)的地址空間。向量表包含一系列跳轉(zhuǎn)指令,跳轉(zhuǎn)到相應(yīng)的中斷服務(wù)程序。對(duì)各未用中斷,使其指向一個(gè)含返回指令的啞函數(shù),以防止錯(cuò)誤中斷引起系統(tǒng)的混亂。中斷向量表FIQ0x1C外部快速中斷IRQ0x18一般外部中斷(Reserved)0x14保留DataAbort0x10數(shù)據(jù)異常FrefetchAbort0x0C預(yù)取指異常Softwareint0x08軟件中斷Undef0x04未定義指令中斷Reset0x00復(fù)位中斷中斷向量表的程序AREABoot,CODE,READONLYENTRYBReset_handlerBUndef_HandlerBSWI_HandlerBPreAbort_HandlerB.;forreservedinterrupt,stophereBIRQ_handlerBFIQ_handler三、初始化時(shí)鐘和設(shè)置相關(guān)的寄存器通過設(shè)置時(shí)鐘控制器來確定CPU的工作頻率,設(shè)置中斷控制寄存器屏蔽中斷。四、初始化存儲(chǔ)器系統(tǒng)參考芯片手冊(cè),設(shè)置與內(nèi)存映射相關(guān)的寄存器。五、初始化堆棧ARM處理器有好幾種運(yùn)行狀態(tài)(模式),各種狀態(tài)都需要有自己的堆棧,所以需要分別為這些堆棧分配空間并設(shè)置好各自的堆棧指針。如果系統(tǒng)使用了DRAM或其他外設(shè),需要設(shè)置一些寄存器,以確定其刷新頻率、數(shù)據(jù)總線寬度等信息。有的系統(tǒng)還需設(shè)置一些寄存器來控制SDRAM、USB、網(wǎng)絡(luò)接口等。六、初始化C環(huán)境在目標(biāo)文件中,代碼、數(shù)據(jù)放在不同的段中。源文件編譯鏈接生成含.data、.text段的目標(biāo)文件,且鏈接器生成的.data段是以系統(tǒng)RAM為參考地址。故在系統(tǒng)啟動(dòng)時(shí)需要復(fù)制ROM或FLASH中的.data段到RAM,以完成對(duì)RAM的初始化。在初始化期間應(yīng)將系統(tǒng)需要讀寫的數(shù)據(jù)和變量從ROM復(fù)制到RAM里運(yùn)行。鏈接器產(chǎn)生的符號(hào)表符號(hào)由鏈接器自動(dòng)產(chǎn)生,只讀段(read-onlyRO)就是代碼段,讀寫段(read-writeRW)是已經(jīng)初始化的全局變量,而零初始化段(zero-initializedsectionZI)中存放未初始化的全局變量。初始化C環(huán)境(2)C環(huán)境初始化,就是利用上述符號(hào)初始化RW和ZI段以使后面使用的全局變量的C程序正常運(yùn)行。這里有兩個(gè)循環(huán),第一個(gè)循環(huán)把預(yù)初始化的數(shù)據(jù)段(位于代碼段的后面)復(fù)制到RAM中,另一個(gè)循環(huán)把未初始化的數(shù)據(jù)段ZI初始化為0,也就是實(shí)現(xiàn)把從ROM中的.data段復(fù)制到RAM,對(duì)ZI段內(nèi)的數(shù)據(jù)初始化為0,以完成對(duì)C環(huán)境的初始化。ROM地址的重映射(remap)0x0200(bootcode)0x0100(Reset_handler)……BReset_Handler0x0000Flash(remap)0x0204(bootcode)0x0200(Reset_handler)BReset_Handler0x0000RAM初始化C環(huán)境(3)七、呼叫C程序?qū)ain函數(shù)的調(diào)用進(jìn)入μC/OS的入口,通過這個(gè)入口就進(jìn)入μC/OS的主函數(shù),啟動(dòng)對(duì)μC/OS的初始化。例IMPORTMainbMain;CEntryμC/OS系統(tǒng)的初始化完成了前面的硬件初始化和運(yùn)行環(huán)境的相關(guān)設(shè)置后,進(jìn)入Main(),Main()是μC/OS的入口函數(shù),啟動(dòng)對(duì)μC/OS的初始化。ARM7的硬件抽象層——uHALμC/OSARM公司為操作系統(tǒng)的開發(fā)提供了一個(gè)硬件抽象層HAL,稱為uHAL。從結(jié)構(gòu)上看,uHAL是一組庫程序,需要說明的是,uHAL并不是專門為μC/OS準(zhǔn)備的,甚至也不是專為操作系統(tǒng)內(nèi)核準(zhǔn)備的。uHAL只是個(gè)針對(duì)ARM核的函數(shù)庫。μC/OS是建立在uHAL的基礎(chǔ)之上的。μC/OS系統(tǒng)的初始化(2)ARMTargetInit()函數(shù)結(jié)構(gòu)ARMTargetInit()調(diào)uHAL打印接口打印系統(tǒng)信息調(diào)用uHAL函數(shù)禁止所有中斷調(diào)用uHAL函數(shù)對(duì)中斷初始化uHAL函數(shù)對(duì)ARM計(jì)數(shù)器初始化結(jié)束uHAL的功能uHAL的作用之一是在操作系統(tǒng)本身進(jìn)入正常運(yùn)行之前,為系統(tǒng)提供基本的輸入輸出手段,例如uHALr_printf()等。uHAL還要為操作系統(tǒng)的運(yùn)行準(zhǔn)備一個(gè)基本的運(yùn)行環(huán)境,具體包括下列各種初始化:通過uHAL_ResetMMU(),將MMU設(shè)置在一個(gè)確定的初始狀態(tài)。通過ARMDisable()關(guān)閉中斷。通過uHAL_InitInterrupts()設(shè)置中斷向量處理程序。通過uHAL_InitTimer()對(duì)系統(tǒng)使用的計(jì)數(shù)器進(jìn)行初始化。ARMTargetStart()的分析創(chuàng)建了任務(wù)之后,ARMTargetStart()調(diào)用uHALr_InstallSystemTimer()創(chuàng)建一個(gè)系統(tǒng)時(shí)鐘,為時(shí)鐘中斷做好準(zhǔn)備。提要12嵌入式系統(tǒng)的初始化C/OS-Ⅱ移植分析操作系統(tǒng)移植的概念所謂操作系統(tǒng)的移植,是指使一個(gè)實(shí)時(shí)操作系統(tǒng)能夠在某個(gè)微處理器平臺(tái)上運(yùn)行。

COS-II的主要代碼都是由標(biāo)準(zhǔn)的C語言寫成的,移植方便。移植的主要工作是修改部分與處理器硬件相關(guān)的代碼。移植的層次操作系統(tǒng)的移植大體可以分為兩個(gè)層次:跨體系結(jié)構(gòu)的移植。針對(duì)特定處理器的移植。移植

COS-II滿足的條件處理器的C編譯器能產(chǎn)生可重入代碼。在程序中可以打開或者關(guān)閉中斷。處理器支持中斷,并且能產(chǎn)生定時(shí)中斷(通常在10-100Hz之間)。處理器支持能夠容納一定量數(shù)據(jù)的硬件堆棧。處理器有將堆棧指針和其他CPU寄存器存儲(chǔ)和讀出到堆棧(或者內(nèi)存)的指令。

什么是可重入代碼可重入的代碼指的是一段代碼(比如:一個(gè)函數(shù))可以被多個(gè)任務(wù)同時(shí)調(diào)用,而不必?fù)?dān)心會(huì)破壞數(shù)據(jù)。也就是說,可重入型函數(shù)在任何時(shí)候都可以被中斷執(zhí)行,過一段時(shí)間以后又可以繼續(xù)運(yùn)行,而不會(huì)因?yàn)樵诤瘮?shù)中斷的時(shí)候被其他的任務(wù)重新調(diào)用,影響函數(shù)中的數(shù)據(jù)??芍厝氪a舉例 程序1:可重入型函數(shù) voidswap(int*x,int*y) { inttemp; temp=*x; *x=*y; *y=temp; }非可重入代碼舉例程序2:非可重入型函數(shù) inttemp; voidswap(int*x,int*y) { temp=*x; *x=*y; *y=temp; }返回不可重入函數(shù)被中斷破壞如何使函數(shù)具有可重入性使Swap()函數(shù)具有可重入性:把Temp定義為局部變量。調(diào)用Swap()函數(shù)之前關(guān)中斷,調(diào)動(dòng)后再開中斷。用信號(hào)量禁止該函數(shù)在使用過程中被再次調(diào)用。打開/關(guān)閉中斷在

COS-II中,可以通過:OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()宏來控制系統(tǒng)關(guān)閉或者打開中斷。這需要處理器的支持。在ARM7TDMI的處理器上,可以設(shè)置相應(yīng)的寄存器來關(guān)閉或者打開系統(tǒng)的所有中斷。處理器支持中斷并且能產(chǎn)生定時(shí)中斷

COS-II是通過處理器產(chǎn)生的定時(shí)器的中斷來實(shí)現(xiàn)多任務(wù)之間的調(diào)度的。ARM7TDMI的處理器上可以產(chǎn)生定時(shí)器中斷。處理器支持硬件堆棧

COS-II進(jìn)行任務(wù)調(diào)度的時(shí)候,會(huì)把當(dāng)前任務(wù)的CPU寄存器存放到此任務(wù)的堆棧中,然后,再?gòu)牧硪粋€(gè)任務(wù)的堆棧中恢復(fù)原來的工作寄存器,繼續(xù)運(yùn)行另一個(gè)任務(wù)。所以,寄存器的入棧和出棧是

COS-II多任務(wù)調(diào)度的基礎(chǔ)。ARM7處理器中有專門的指令處理堆棧,可以靈活的使用堆棧。移植對(duì)開發(fā)工具的要求移植COS-II需要一個(gè)標(biāo)準(zhǔn)的C交叉編譯器。

由于移植時(shí)需要對(duì)CPU的寄存器進(jìn)行操作,所以需要C交叉編譯器能夠支持匯編語言程序。嵌入式C編譯器一般都包括匯編器、鏈接器和定位器。鏈接器是用來將不同的模塊(編譯或匯編過的文件)鏈接成目標(biāo)文件;定位器則允許將代碼和數(shù)據(jù)放置在目標(biāo)處理器的指定內(nèi)存空間中。移植μC/OS-II要點(diǎn)(1)開關(guān)中斷的方式。推薦使用method3{#ifOS_CRITICAL_METHOD==3 OS_CPU_SRcpu_sr;#endif… OS_ENTER_CRITICAL();… OS_EXIT_CRITICAL();}使用method3方式的開關(guān)中斷#defineOS_ENTER_CRITICAL() {cpu_sr=INTS_OFF();}#defineOS_EXIT_CRITICAL() {if(cpu_sr==0)INTS_ON();}ARM的中斷模式設(shè)備的中斷在ARM中被映射到了兩個(gè)異常中斷中——FIQ和IRQ。通過控制CPSR中的對(duì)應(yīng)數(shù)據(jù)位,可以開啟或者關(guān)閉中斷。為了方便和統(tǒng)一μC/OS-II系統(tǒng)中斷的處理,只使用了IRQ模式的中斷。移植μC/OS-II要點(diǎn)(2)——系統(tǒng)中斷的處理所有中斷的調(diào)用都需要經(jīng)過系統(tǒng)的接管。中斷處理函數(shù)調(diào)用前后需要通知系統(tǒng)。例如: OSIntEnter(); yourInterruptFun(); OSIntExit();OSIntExit的意義ARM的工作模式ARM處理器有7種操作模式:用戶模式(usr)正常的程序執(zhí)行模式??焖僦袛嗄J?fiq)

支持高速數(shù)據(jù)傳輸或通道處理。中斷模式(irq)

用于通用中斷處理。管理員模式(svc)

操作系統(tǒng)的保護(hù)模式。中止模式(abt)

支持虛擬內(nèi)存和/或內(nèi)存保護(hù)等異常。系統(tǒng)模式(sys)

支持操作系統(tǒng)的特殊用戶模式(運(yùn)行操作系統(tǒng)任務(wù))。未定義模式(und)

支持硬件協(xié)處理器的軟件仿真。除了用戶模式外,其他模式均可視為特權(quán)模式ARM的寄存器(1)37個(gè)寄存器:31個(gè)通用32位寄存器,包括程序計(jì)數(shù)器PC。6個(gè)狀態(tài)寄存器。15個(gè)通用寄存器

(R0toR14),以及2個(gè)狀態(tài)寄存器和程序計(jì)數(shù)器(PC)在任何時(shí)候都中可見的??梢姷募拇嫫魅Q于處理器的模式,不同的模式映射了不同的工作寄存器。ARM寄存器的組織注:表明用戶或系統(tǒng)模式使用的正常寄存器已經(jīng)被異常模式指定的另一個(gè)寄存器取代ARM的寄存器(2)R0到

R15可以直接訪問。R0到

R14是通用寄存器。R13:堆棧指針

(sp)(通常)。每種處理器模式都有單獨(dú)的堆棧。R14:鏈接寄存器(lr)。R15:程序計(jì)數(shù)器

(PC)。CPSR:當(dāng)前程序狀態(tài)寄存器,包括代碼標(biāo)志狀態(tài)和當(dāng)前模式位。5個(gè)SPSR(程序狀態(tài)保存寄存器):當(dāng)異常發(fā)生時(shí)保存CPSR狀態(tài)。μC/OS-II在ARM上的任務(wù)切換任務(wù)級(jí)的任務(wù)切換;中斷級(jí)的任務(wù)切換。中斷處理過程OSIntExit()voidOSIntExit(void){OS_ENTER_CRITICAL(); (1)if((--OSIntNesting|OSLockNesting)==0){(2)OSIntExitY=OSUnMapTbl[OSRdyGrp];(3)OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]);if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;OSIntCtxSw(); (4)}}OS_EXIT_CRITICAL();}OSIntExit的關(guān)鍵——OSIntCtxSw實(shí)現(xiàn)中斷級(jí)的任務(wù)切換ARM在棧指針調(diào)整過程中的優(yōu)勢(shì)移植μC/OS-II要點(diǎn)(3)——Thumb帶來的問題很多ARM內(nèi)核集成了16位thumb指令集。Thumb可以在一定程度上節(jié)省代碼空間,提高系統(tǒng)效率。Thumb會(huì)給中斷級(jí)的任務(wù)切換帶來麻煩。CPSR中的T位不能直接操作。Thumb狀態(tài)將導(dǎo)致CPSR恢復(fù)以后的指令不能運(yùn)行。解決辦法:對(duì)Thumb的使用必須保證原子操作。專門對(duì)任務(wù)切換中Thumb的情況作處理。建議,小心使用C編譯器,盡量不使用Thumb。移植μC/OS-II的要點(diǎn)(4)—何時(shí)啟動(dòng)系統(tǒng)定時(shí)器如果在OSStart之前啟動(dòng)定時(shí)器,則系統(tǒng)可能無法正確執(zhí)行完OSStartHighRdy。OSStart函數(shù)直接調(diào)用OSStartHighRdy去執(zhí)行最高優(yōu)先級(jí)的任務(wù),OSStart不返回。系統(tǒng)定時(shí)器應(yīng)該在系統(tǒng)的最高優(yōu)先級(jí)任務(wù)中啟動(dòng)。使用OSRunning變量來控制操作系統(tǒng)的運(yùn)行。在我們的移植版本中,使用了μC/OS-II中的保留任務(wù)1作為系統(tǒng)任務(wù),負(fù)責(zé)啟動(dòng)定時(shí)器。例:C/OS-II在S3C44B0X上的移植設(shè)置OS_CPU.H中與處理器和編譯器相關(guān)的代碼。用C語言編寫六個(gè)操作系統(tǒng)相關(guān)的函數(shù)(OS_CPU_C.C)。用匯編語言編寫四個(gè)與處理器相關(guān)的函數(shù)(OS_CPU.ASM)。設(shè)置與處理器和編譯器相關(guān)的代碼OS_CPU.H中定義了與編譯器相關(guān)的數(shù)據(jù)類型。比如:INT8U、INT8S等。與ARM處理器相關(guān)的代碼,使用OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()宏開啟/關(guān)閉中斷。設(shè)置堆棧的增長(zhǎng)方向:堆棧由高地址向低地址增長(zhǎng)。設(shè)置includes.htypedefunsignedcharBOOLEAN;typedefunsignedcharINT8U;typedefsignedcharINT8S;typedefunsignedintINT16U;typedefsignedintINT16S;typedefunsignedlongINT32U;typedefsignedlongINT32S;typedeffloatFP32;typedefdoubleFP64;typedefunsignedlongOS_STK;typedefunsignedlongOS_CPU_SR;externintINTS_OFF(void);externvoidINTS_ON(void);#defineOS_ENTER_CRITICAL(){cpu_sr=INTS_OFF();}#defineOS_EXIT_CRITICAL(){if(cpu_sr==0)INTS_ON();}#defineOS_STK_GROWTH1 /*從高向低*/程序狀態(tài)寄存器條件位:N=1-結(jié)果為負(fù),0-結(jié)果為正或0Z=1-結(jié)果為0,0-結(jié)果不為0C=1-進(jìn)位,0-借位V=1-結(jié)果溢出,0結(jié)果沒溢出Q位:僅ARM5TE/J架構(gòu)支持指示增強(qiáng)型DSP指令是否溢出J位僅ARM5TE/J架構(gòu)支持J=1:處理器處于Jazelle狀態(tài)中斷禁止位:I=1:禁止IRQF=1:禁止FIQTBit僅ARMxT架構(gòu)支持T=0:處理器處于ARM狀態(tài)T=1:處理器處于Thumb狀態(tài)Mode位(處理器模式位):0b10000 User0b10001 FIQ0b10010 IRQ0b10011 Supervisor0b10111 Abort0b11011 Undefined0b11111 System2731NZCVQ2867IFTmode1623

815

54024fsxc

UndefinedJ打開/關(guān)閉中斷 EXPORTINTS_OFF EXPORTINTS_ONINTS_OFFmrsr0,cpsr;currentCSRmovr1,r0;makeacopyformaskingorrr1,r1,#0xC0;maskoffintbitsmsrCPSR_cxsf,r1;disableintsandr0,r0,#0x80;returnIRQbitmovpc,lr;returnINTS_ONmrsr0,cpsr;currentCSRbicr0,r0,#0x80;maskonintsmsrCPSR_cxsf,r0;enableintsmovpc,lr;return…110000007031…100000007031…IFTMode7031設(shè)置OS_STK_GROWTH絕大多數(shù)的微處理器和微控制器的堆棧是從上往下長(zhǎng)的。但是某些處理器是用另外一種方式工作的。

C/OS-Ⅱ被設(shè)計(jì)成兩種情況都可以處理,只要在結(jié)構(gòu)常量OS_STK_GROWTH中指定堆棧的生長(zhǎng)方式就可以了。置OS_STK_GROWTH為0表示堆棧從下往上長(zhǎng)。置OS_STK_GROWTH為1表示堆棧從上往下長(zhǎng)。用C語言編寫六個(gè)操作系統(tǒng)相關(guān)的函數(shù)void*OSTaskStkInit(void(*task)(void*pd),void*pdata,void*ptos,INT16Uopt)voidOSTaskCreateHook(OS_TCB*ptcb)voidOSTaskDelHook(OS_TCB*ptcb)voidOSTaskSwHook(void)voidOSTaskStatHook(void)voidOSTimeTickHook(void)后5個(gè)函數(shù)為接口函數(shù),可以不加代碼。OSTaskStkInitOSTaskCreate()和OSTaskCreateExt()通過調(diào)用OSTaskStkInit()來初始化任務(wù)的堆棧結(jié)構(gòu)。因此堆棧看起來就像剛發(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。這里我們定義了堆棧是從上往下長(zhǎng)的。在用戶建立任務(wù)時(shí),用戶傳遞任務(wù)的地址、pdata指針、任務(wù)的堆棧棧頂和任務(wù)的優(yōu)先級(jí)給OSTaskCreate()和OSTaskCreateExt()。一旦用戶初始化了堆棧,OSTaskStkInit()就需要返回堆棧指針?biāo)傅牡刂贰STaskCreate()和OSTaskCreateExt()會(huì)獲得該地址并將它保存到任務(wù)控制塊(OS_TCB)中。堆棧初始化低地址內(nèi)存存儲(chǔ)的處理器寄存器值中斷返回地址處理器狀態(tài)字任務(wù)起始地址pdata高地址內(nèi)存堆棧指針堆棧增長(zhǎng)方向ARM系統(tǒng)的堆棧初始化堆棧指針SP堆棧增長(zhǎng)方向低端內(nèi)存?zhèn)浞莩绦驙顟B(tài)寄存器SPSR當(dāng)前程序狀態(tài)寄存器CPSR任務(wù)傳遞參數(shù)R0(pdata)R1……R11R12中斷返回地址LR任務(wù)起始地址ptos(PC)高端內(nèi)存OSTaskStkInitOS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt){unsignedint*stk;stk=(unsignedint*)ptos;/*Loadstackpointer*///USE_ARG(opt);opt++;/*buildastackforthenewtask*/*--stk=(unsignedint)task;/*pc*/*--stk=(unsignedint)task;/*lr*/*--stk=12;/*r12*/*--stk=11;/*r11*/*--stk=10;/*r10*/*--stk=9;/*r9*/*--stk=8;/*r8*/*--stk=7;/*r7*/*--stk=6;/*r6*/*--stk=5;/*r5*/*--stk=4;/*r4*/*--stk=3;/*r3*/*--stk=2;/*r2*/*--stk=1;/*r1*/*--stk=(unsignedint)pdata;/*r0*/*--stk=(SUPMODE); /*cpsr*/*--stk=(SUPMODE); /*spsr*/return((OS_STK*)stk);}OSTaskCreateHook當(dāng)用OSTaskCreate()和OSTaskCreateExt()建立任務(wù)的時(shí)候就會(huì)調(diào)用OSTaskCreateHook()。該函數(shù)允許用戶或使用移植實(shí)例的用戶擴(kuò)展

C/OS-Ⅱ功能。當(dāng)

C/OS-Ⅱ設(shè)置完了自己的內(nèi)部結(jié)構(gòu)后,會(huì)在調(diào)用任務(wù)調(diào)度程序之前調(diào)用OSTaskCreateHook()。該函數(shù)被調(diào)用的時(shí)候中斷是禁止的。因此用戶應(yīng)盡量減少該函數(shù)中的代碼以縮短中斷的響應(yīng)時(shí)間。當(dāng)OSTaskCreateHook()被調(diào)用的時(shí)候,它會(huì)收到指向已建立任務(wù)的OS_TCB的指針,這樣它就可以訪問所有的結(jié)構(gòu)成員了。函數(shù)原型:voidOSTaskCreateHook(OS_TCB*ptcb){ptcb=ptcb;}OSTaskDelHook

當(dāng)任務(wù)被刪除的時(shí)候,就會(huì)調(diào)用OSTaskDelHook()函數(shù)。該函數(shù)在把任務(wù)從

C/OS-Ⅱ的內(nèi)部任務(wù)鏈表中刪除之前被調(diào)用。當(dāng)該函數(shù)被調(diào)用的時(shí)候,它會(huì)收到指向正被刪除任務(wù)的OS_TCB的指針,這樣它就可以訪問所有的結(jié)構(gòu)成員了。OSTaskDelHook()可以來檢驗(yàn)TCB擴(kuò)展是否被建立(一個(gè)非空指針),并進(jìn)行一些清除操作。函數(shù)原型:voidOSTaskDelHook(OS_TCB*ptcb){ptcb=ptcb;}OSTaskSwHook當(dāng)發(fā)生任務(wù)切換的時(shí)候就會(huì)調(diào)用OSTaskSwHook()。OSTaskSwHook()可以直接訪問OSTCBCur和OSTCBHighRdy,因?yàn)樗鼈兪侨肿兞?。OSTCBCur指向被切換出去的任務(wù)OS_TCB,而OSTCBHighRdy指向新任務(wù)OS_TCB。注意在調(diào)用OSTaskSwHook()期間中斷一直是被禁止的。因此用戶應(yīng)盡量減少該函數(shù)中的代碼以縮短中斷的響應(yīng)時(shí)間。函數(shù)原型:voidOSTaskSwHook(void){#if0if(OSRunning==TRUE){/*保存擬被掛起任務(wù)的寄存器;}/*恢復(fù)擬被運(yùn)行任務(wù)的寄存器;#endif}OSTaskStatHookOSTaskStatHook()每秒鐘都會(huì)被OSTaskStat()調(diào)用一次。用戶可以用OSTaskStatHook()來擴(kuò)展統(tǒng)計(jì)功能。例如,用戶可以保持并顯示每個(gè)任務(wù)的執(zhí)行時(shí)間,每個(gè)任務(wù)所用的CPU份額,以及每個(gè)任務(wù)執(zhí)行的頻率等。函數(shù)原型:voidOSTaskStatHook(void)OSTimeTickHookOSTimeTickHook()在每個(gè)時(shí)鐘節(jié)拍都會(huì)被OSTaskTick()調(diào)用。實(shí)際上,OSTimeTickHook()是在節(jié)拍被

C/OS-Ⅱ真正處理,并通知用戶的移植實(shí)例或應(yīng)用程序之前被調(diào)用的。函數(shù)原型:voidOSTimeTickHook(void)用匯編語言編寫四個(gè)

與處理器相關(guān)的函數(shù)OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()OSStartHighRdy():運(yùn)行優(yōu)先級(jí)最高的就緒任務(wù)

OSStartHighRdy LDR r4,addr_OSTCBCur ;得到當(dāng)前任務(wù)TCB地址 LDR r5,addr_OSTCBHighRdy ;得到最高優(yōu)先級(jí)任務(wù)TCB地址 LDR r5,[r5] ;獲得堆棧指針 LDR sp,[r5] ;轉(zhuǎn)移到新的堆棧中 STR r5,[r4] ;設(shè)置新的當(dāng)前任務(wù)TCB地址 LDMFD sp!,{r4} ; MSR SPSR,r4 LDMFD sp!,{r4} ;從棧頂獲得新的狀態(tài) MSR CPSR,r4 ;CPSR處于SVC32Mode摸式 LDMFD sp!,{r0-r12,lr,pc} ;運(yùn)行新的任務(wù)OSCtxSw()的原型

voidOSCtxSw(void){

保存處理器寄存器;

將當(dāng)前任務(wù)的堆棧指針保存到當(dāng)前任務(wù)的OS_TCB中:OSTCBCur->OSTCBStkPtr=Stackpointer;

調(diào)用用戶定義的OSTaskSwHook();OSTCBCur=OSTCBHighRdy;OSPrioCur=OSPrioHighRdy;

得到需要恢復(fù)的任務(wù)的堆棧指針:Stackpointer=OSTCBHighRdy->OSTCBStkPtr;

將所有處理器寄存器從新任務(wù)的堆棧中恢復(fù)出來;

執(zhí)行中斷返回指令;}OS_TASK_SW();任務(wù)級(jí)的任務(wù)切換函數(shù)(1)

OS_TASK_SW STMFD sp!,{lr} ;保存pc STMFD sp!,{lr} ;保存lr STMFD sp!,{r0-r12} ;保存寄存器和返回地址 MRS r4,CPSR STMFD sp!,{r4} ;保存當(dāng)前的PSR MRS r4,SPSR STMFD sp!,{r4} ;保存SPSR ;OSPrioCur=OSPrioHighRdy LDR r4,addr_OSPrioCur LDR r5,addr_OSPrioHighRdy

LDRB r6,[r5] STRB r6,[r4]

OS_TASK_SW():任務(wù)級(jí)的任務(wù)切換函數(shù)(2)

;得到當(dāng)前任務(wù)TCB地址 LDR r4,addr_OSTCBCur LDR r5,[r4] STR sp,[r5] ;保存sp在被占先的任務(wù)的TCB ;得到最高優(yōu)先級(jí)任務(wù)TCB地址 LDR r6,addr_OSTCBHighRdy LDR r6,[r6] LDR sp,[r6] ;得到新任務(wù)堆棧指針 ;OSTCBCur=OSTCBHighRdy STR r6,[r4] ;設(shè)置新的當(dāng)前任務(wù)的TCB地址;保存任務(wù)方式寄存器 LDMFD sp!,{r4} MSR SPSR,r4 LDMFD sp!,{r4} MSR CPSR,r4;返回到新任務(wù)的上下文 LDMFD sp!,{r0-r12,lr,pc}中斷服務(wù)關(guān)于棧指針調(diào)整棧指針調(diào)整調(diào)整堆棧指針(加一個(gè)數(shù)在堆棧指針上)來完成的。加在堆棧指針上的數(shù)必須是明確的,而這個(gè)數(shù)主要依賴于移植的目標(biāo)處理器(地址空間可能是16,32或64位),所用的編譯器,編譯器選項(xiàng),內(nèi)存模式等等。另外,處理器狀態(tài)字可能是8,16,32甚至64位寬,并且OSIntExit()可能會(huì)分配局部變量。有些處理器允許用戶直接增加常量到堆棧指針中,而有些則不允許。在后一種情況下,可以通過簡(jiǎn)單的執(zhí)行一定數(shù)量的pop(出棧)指令來實(shí)現(xiàn)相同的功能。一旦堆棧指針完成調(diào)整,新的堆棧指針會(huì)被保存到被切換出去的任務(wù)的OS_TCB中。OSIntCtxSW的實(shí)現(xiàn)OSIntCtxSw()的原型

voidOSIntCtxSw(void){

調(diào)整堆棧指針來去掉在調(diào)用:OSIntExit(),OSIntCtxSw()過程中壓入堆棧的多余內(nèi)容;

將當(dāng)前任務(wù)堆棧指針保存到當(dāng)前任務(wù)的OS_TCB中:OSTCBCur->OSTCBStkPtr=堆棧指針;

調(diào)用用戶定義的OSTaskSwHook();OSTCBCur=OSTCBHighRdy;OSPrioCur=OSPrioHighRdy;

得到需要恢復(fù)的任務(wù)的堆棧指針:

堆棧指針=OSTCBHighRdy->OSTCBStkPtr;

將所有處理器寄存器從新任務(wù)的堆棧中恢復(fù)出來;

執(zhí)行中斷返回指令;}OSIntCtxSW();中斷級(jí)的任務(wù)切換函數(shù)(1)

OSIntCtxSwaddr7,sp,#16;保存寄存器指針LDR sp,=IRQStack ;FIQ_STACKmrsr1,SPSR;得到暫停的PSRorrr1,r1,#0xC0;關(guān)閉IRQ,FIQ.msrCPSR_cxsf,r1;轉(zhuǎn)換模式(應(yīng)該是SVC_MODE)ldrr0,[r7,#52];從IRQ堆棧中得到IRQ'sLR(任務(wù)PC)subr0,r0,#4;當(dāng)前PC地址是(saved_LR-4)STMFD sp!,{r0} ;保存任務(wù)PCSTMFD sp!,{lr} ;保存LRmovlr,r7;保存FIQ堆棧ptrinLR(轉(zhuǎn)到nuker7)ldmfdlr!,{r0-r12};從FIQ堆棧中得到保存的寄存器STMFD sp!,{r0-r12} ;在任務(wù)堆棧中保存寄存器 OSIntCtxSW();中斷級(jí)的任務(wù)切換函數(shù)(2)

;在任務(wù)堆棧上保存PSR和任務(wù)PSRMRS r4,CPSRbicr4,r4,#0xC0;使中斷位處于使能態(tài)STMFD sp!,{r4} ;保存任務(wù)當(dāng)前PSRMRS r4,SPSRSTMFD sp!,{r4} ;SPSR;OSPrioCur=OSPrioHighRdy//改變當(dāng)前程序LDR r4,addr_OSPrioCurLDR r5,addr_OSPrioHighRdyLDRB r6,[r5]STRB r6,[r4];得到被占先的任務(wù)TCBLDR r4,addr_OSTCBCurLDR r5,[r4]STR sp,[r5] ;保存sp在被占先的任務(wù)的TCBOSIntCtxSW();中斷級(jí)的任務(wù)切換函數(shù)(3)

;得到新任務(wù)TCB地址LDR r6,addr_OSTCBHighRdyLDR r6,[r6]LDR sp,[r6] ;得到新任務(wù)堆棧指針;OSTCBCur=OSTCBH

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論