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

下載本文檔

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

文檔簡介

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

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

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

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

什么是可重入代碼可重入的代碼指的是一段代碼(比如:一個函數(shù))可以被多個任務(wù)同時調(diào)用,而不必擔(dān)心會破壞數(shù)據(jù)。也就是說,可重入型函數(shù)在任何時候都可以被中斷執(zhí)行,過一段時間以后又可以繼續(xù)運行,而不會因為在函數(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)動后再開中斷。用信號量禁止該函數(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)生定時中斷

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

COS-II進行任務(wù)調(diào)度的時候,會把當前任務(wù)的CPU寄存器存放到此任務(wù)的堆棧中,然后,再從另一個任務(wù)的堆棧中恢復(fù)原來的工作寄存器,繼續(xù)運行另一個任務(wù)。所以,寄存器的入棧和出棧是

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

由于移植時需要對CPU的寄存器進行操作,所以需要C交叉編譯器能夠支持匯編語言程序。嵌入式C編譯器一般都包括匯編器、鏈接器和定位器。鏈接器是用來將不同的模塊(編譯或匯編過的文件)鏈接成目標文件;定位器則允許將代碼和數(shù)據(jù)放置在目標處理器的指定內(nèi)存空間中。移植μC/OS-II要點(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中被映射到了兩個異常中斷中——FIQ和IRQ。通過控制CPSR中的對應(yīng)數(shù)據(jù)位,可以開啟或者關(guān)閉中斷。為了方便和統(tǒng)一μC/OS-II系統(tǒng)中斷的處理,只使用了IRQ模式的中斷。移植μC/OS-II要點(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)的保護模式。中止模式(abt)

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

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

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

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

R15可以直接訪問。R0到

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

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

(PC)。CPSR:當前程序狀態(tài)寄存器,包括代碼標志狀態(tài)和當前模式位。5個SPSR(程序狀態(tài)保存寄存器):當異常發(fā)生時保存CPSR狀態(tài)。μC/OS-II在ARM上的任務(wù)切換任務(wù)級的任務(wù)切換;中斷級的任務(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實現(xiàn)中斷級的任務(wù)切換ARM在棧指針調(diào)整過程中的優(yōu)勢移植μC/OS-II要點(3)——Thumb帶來的問題很多ARM內(nèi)核集成了16位thumb指令集。Thumb可以在一定程度上節(jié)省代碼空間,提高系統(tǒng)效率。Thumb會給中斷級的任務(wù)切換帶來麻煩。CPSR中的T位不能直接操作。Thumb狀態(tài)將導(dǎo)致CPSR恢復(fù)以后的指令不能運行。解決辦法:對Thumb的使用必須保證原子操作。專門對任務(wù)切換中Thumb的情況作處理。建議,小心使用C編譯器,盡量不使用Thumb。移植μC/OS-II的要點(4)—何時啟動系統(tǒng)定時器如果在OSStart之前啟動定時器,則系統(tǒng)可能無法正確執(zhí)行完OSStartHighRdy。OSStart函數(shù)直接調(diào)用OSStartHighRdy去執(zhí)行最高優(yōu)先級的任務(wù),OSStart不返回。系統(tǒng)定時器應(yīng)該在系統(tǒng)的最高優(yōu)先級任務(wù)中啟動。使用OSRunning變量來控制操作系統(tǒng)的運行。在我們的移植版本中,使用了μC/OS-II中的保留任務(wù)1作為系統(tǒng)任務(wù),負責(zé)啟動定時器。例:C/OS-II在S3C44B0X上的移植設(shè)置OS_CPU.H中與處理器和編譯器相關(guān)的代碼。用C語言編寫六個操作系統(tǒng)相關(guān)的函數(shù)(OS_CPU_C.C)。用匯編語言編寫四個與處理器相關(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è)置堆棧的增長方向:堆棧由高地址向低地址增長。設(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é)果為負,0-結(jié)果為正或0Z=1-結(jié)果為0,0-結(jié)果不為0C=1-進位,0-借位V=1-結(jié)果溢出,0結(jié)果沒溢出Q位:僅ARM5TE/J架構(gòu)支持指示增強型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ù)的微處理器和微控制器的堆棧是從上往下長的。但是某些處理器是用另外一種方式工作的。

C/OS-Ⅱ被設(shè)計成兩種情況都可以處理,只要在結(jié)構(gòu)常量OS_STK_GROWTH中指定堆棧的生長方式就可以了。置OS_STK_GROWTH為0表示堆棧從下往上長。置OS_STK_GROWTH為1表示堆棧從上往下長。用C語言編寫六個操作系統(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個函數(shù)為接口函數(shù),可以不加代碼。OSTaskStkInitOSTaskCreate()和OSTaskCreateExt()通過調(diào)用OSTaskStkInit()來初始化任務(wù)的堆棧結(jié)構(gòu)。因此堆??雌饋砭拖駝偘l(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。這里我們定義了堆棧是從上往下長的。在用戶建立任務(wù)時,用戶傳遞任務(wù)的地址、pdata指針、任務(wù)的堆棧棧頂和任務(wù)的優(yōu)先級給OSTaskCreate()和OSTaskCreateExt()。一旦用戶初始化了堆棧,OSTaskStkInit()就需要返回堆棧指針所指的地址。OSTaskCreate()和OSTaskCreateExt()會獲得該地址并將它保存到任務(wù)控制塊(OS_TCB)中。堆棧初始化低地址內(nèi)存存儲的處理器寄存器值中斷返回地址處理器狀態(tài)字任務(wù)起始地址pdata高地址內(nèi)存堆棧指針堆棧增長方向ARM系統(tǒng)的堆棧初始化堆棧指針SP堆棧增長方向低端內(nèi)存?zhèn)浞莩绦驙顟B(tài)寄存器SPSR當前程序狀態(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當用OSTaskCreate()和OSTaskCreateExt()建立任務(wù)的時候就會調(diào)用OSTaskCreateHook()。該函數(shù)允許用戶或使用移植實例的用戶擴展

C/OS-Ⅱ功能。當

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

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

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

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

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

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

voidOSCtxSw(void){

保存處理器寄存器;

將當前任務(wù)的堆棧指針保存到當前任務(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ù)級的任務(wù)切換函數(shù)(1)

OS_TASK_SW STMFD sp!,{lr} ;保存pc STMFD sp!,{lr} ;保存lr STMFD sp!,{r0-r12} ;保存寄存器和返回地址 MRS r4,CPSR STMFD sp!,{r4} ;保存當前的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ù)級的任務(wù)切換函數(shù)(2)

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

voidOSIntCtxSw(void){

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

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

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

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

堆棧指針=OSTCBHighRdy->OSTCBStkPtr;

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

執(zhí)行中斷返回指令;}OSIntCtxSW();中斷級的任務(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;當前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();中斷級的任務(wù)切換函數(shù)(2)

;在任務(wù)堆棧上保存PSR和任務(wù)PSRMRS r4,CPSRbicr4,r4,#0xC0;使中斷位處于使能態(tài)STMFD sp!,{r4} ;保存任務(wù)當前PSRMRS r4,SPSRSTMFD sp!,{r4} ;SPSR;OSPrioCur=OSPrioHighRdy//改變當前程序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();中斷級的任務(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等.壓縮文件請下載最新的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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論