毫無保留ucoslwip穩(wěn)定版2我移植的ucos參考ver_第1頁
毫無保留ucoslwip穩(wěn)定版2我移植的ucos參考ver_第2頁
毫無保留ucoslwip穩(wěn)定版2我移植的ucos參考ver_第3頁
毫無保留ucoslwip穩(wěn)定版2我移植的ucos參考ver_第4頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、uc/OS 移植參考任務切換中的部分代碼是和 CPU 相關的,該部分包括:OS_ENTER_CRITICAL(其原身為 void ARMDisable(void))進入臨界區(qū),關閉中斷OS_EXIT_CRITICAL(其原身為void ARMEnable(void))退出臨界區(qū),打開中斷OSStartHighRdy;從系統(tǒng)中切換到第一個任務OS_TASK_SW;從任務中切換到任務OSCtxSw;任務被中斷,從中斷中切換到任務OSTaskStkInit;初始化任務中斷,在構造任務時調用。首先,先來一些公共的內容:一、任務系統(tǒng)(除了中斷)運行在 SYS 模式下,該模式沒有SPSR二、所有希望在中斷

2、中實現(xiàn)任務調度的處理程序必須使用 IRQ 中斷同時使用 OSEnter 和OSExit,這是因為 OSExit 中執(zhí)行切換的 OSCtxSw 直接操作 IRQ 的堆棧來實現(xiàn)了被中斷現(xiàn)場的數(shù)據保護(詳情見下)。系統(tǒng)開始時不Fiq 中斷打開,但是,不可以在其中使用 OSCtxSw(即不可調用OSEnter 和OSExit),簡單的不涉及到任務狀態(tài)的代碼可以使用。IRQ 中斷不支持 IRQ 嵌套,但支持 FIQ 的嵌套。三、ARM 的 c 編譯器對子函數(shù)調用的匯編處理也是值得注意的部分。調用函數(shù)一般使用 bl,但也有時用 b。請看下面的圖例,自己去理解。圖一的函數(shù)關系a;void fun1(void

3、); void fun2(void); main() a+;fun1(); a+;void fun1(void) a+;fun2(); a+;void fun2(void) a+;圖二的函數(shù)關系a;void fun1(void); void fun2(void); main() a+;fun1();void fun1(void) a+;fun2();void fun2(void)a+;區(qū)別在于調用函數(shù)的語句之后是否還有代碼。四、標準堆棧格式為任務切換函數(shù)所承認的堆棧格式如下:按標準格式調整好的棧內容,都可以被順利的彈出現(xiàn)場。其次,來對代碼進行分析:一、OSTaskStkInit,代碼如下:OS

4、_STK * OSTaskStkInit (void (*task)(void *pd), void *pdata,OS_STK *ptos, 16U opt)unsigned*stk;optstk= opt;= (unsigned/*opt is not used, prevent warning*/*)ptos;/* Load stack poer*/* build a context for the new task */*-stk = (unsigned*-stk = (unsigned) task;) task;/* pc */* lr */*-stk = 0;*-stk = 0;*

5、-stk = 0;*-stk = 0;*-stk = 0;/* r12 */* r11 */* r10 */* r9 */* r8 */*-stk = 0;*-stk = 0;*-stk = 0;*-stk = 0;*-stk = 0;*-stk = 0;*-stk = 0;*-stk = (unsigned*-stk = (0 x1f|0 x00);*-stk = (0 x1f|0 x00);/這是標準的棧結構 return (void *)stk);/* r7 */* r6 */* r5 */* r4 */* r3 */* r2 */* r1 */* r0 */* cpsrSys mode

6、 FIQ IRQ Enable*/* spsrSys mode FIQ IRQ Enable */) pdata;用于任務初始化時堆棧的建立,為 OSTaskCreate()調用;結構清晰,參見標準棧結構。其來源于:OS_CPU_C.c二、OSStartHighRdy,代碼如下:EXPORT OSStartHighRdy;功能示例;STCBHighRdy-OSTCBStkPtr;OSTCBCur=OSTCBHighRdy;彈出現(xiàn)場OSStartHighRdyLDRLDRr4, addr_OSTCBCur; Get current task TCB addressr5, addr_OSTCBHi

7、ghRdy; Get highest priority task TCB addressLDR LDR;Sr5, r5sp, r5; get stack poer; switch to the new stackTCBHighRdy-OSTCBStkPtrSTR r5, r4; set new current task TCB address;OSTCBCur=OSTCBHighRdyLDMFD MSR LDMFD MSRLDMFDsp!, r4 CPSR_cxsf, r4 sp!, r4CPSR_cxsf, r4; YYY; get new se from top of the stack;

8、 CPSR should be SYS32Modesp!, r0-r12, lr, pc ; start the new task用于系統(tǒng)開始時,從系統(tǒng)切換到第一個任務,為OSStart()調用。其來源于:OS_CPU_a.s三、OS_ENTER/EXIT_CRITICAL,這是兩個宏,定義見代碼,注意對壓棧方式論證的分析:下面的代碼來源于 OS_CPU.h#defineOS_CRITICAL_METHOD0#if #define #define#endifOS_CRITICAL_METHOD = 0OS_ENTER_CRITICAL()ARMDisable() /disableOS_EXIT

9、_CRITICAL() ARMEnable()/enable下面的代碼來源于 OS_CPU_a.s;下面是兩個開關中斷的函數(shù),其只用來操作 CPSR 中的 I 位,;不要擔心進入切換前的任務被了中斷:主動放棄 CPU 的;任務,其 CPSR 一定是中斷的(注意理解),但是其返回;一定是返回到OSCtxSw 之后,“”時,自然會有 enable 來恢;復中斷,凡是中斷放棄 CPU 的任務,CPSR 一定是允許中斷的。;不論怎樣返回也一定返回到被中斷的現(xiàn)場。;帶來的版本是利用用戶的堆棧來盛放 CPSR,隨后 pop 出來。;在這里是不可以的:使用棧方式保存 CPSR 要保證 Enable 在切換后

10、;可以被運行到,在 OSSched 中(主動放棄 CPU)OS_TASK_SW 被Disable 與 Enable;前后包圍,進入 OS_TASK_SW 也可以從中返回,進出時棧結構是相同的;這是可以使用的。;但是,在中斷切換的情況下便不同了,在 OSCtxSw 前的 Disable;使用的棧內容不能被保存起來,只將任務運行時的現(xiàn)場保護起來,;不會保留中斷標志的壓棧信息,因此,這種方式也可使用,但是在沒有;增加效率的前提下反而會將堆棧結構復雜化,不建議使用。EXPORT ARMDisableARMDisableSTMDB MRS ORR MSR LDMIAMOVsp!, r0 ;r0 要保存,

11、不可以破壞調用函數(shù)的現(xiàn)場r0, CPSRr0, r0, #0 x80CPSR_c, r0 sp!, r0 pc, lrEXPORT ARMEnable ARMEnableSTMDB sp!, r0MRSr0, CPSRBIC r0, r0, #0 x80MSR LDMIAMOVCPSR_c, r0 sp!, r0pc, lr其來源于:OS_CPU_a.s四、OS_TASK_SW,見代碼:EXPORT OS_TASK_SW;功能示例;現(xiàn)場壓棧;OSPrioCur = OSPrioHighRdy;OSTCBCur-OSTCBStkPtr=SP 保存 SP 到當前任務控制塊;STCBHighRdy-

12、OSTCBStkPtr;OSTCBCur=OSTCBHighRdy;彈出現(xiàn)場OS_TASK_SWSTMFD sp!, lrSTMFD sp!, lr; save pc; save lr;分析:OS_TASK_SW 是個函數(shù),在任務間接的調用它時會在最后失去 CPU,再次;獲得 CPU 時,其恰好在 OS_TASK_SW 調用完畢后的那個位置,因此,lr 被放入pc;在棧中的位置;此外,lr 放入 lr 在棧中的位置也是無關緊要的,因為,子函數(shù);返回時的 lr 是無意義的。STMFD MRS STMFD;MRSsp!, r0-r12 r4, CPSRsp!, r4r4, SPSR; save r

13、egister file and ret address; save current PSR; YYY+ 這里掉是因為任務運行的;模式是 SYS,沒有SPSR,棧中的 CPSR 與 SPSR 相同; YYY+ save SPSRSTMFDsp!, r4LDR LDR LDRBSTRBr4, addr_OSPrioCurr5, addr_OSPrioHighRdy r6, r5r6, r4; OSPrioCur = OSPrioHighRdy; Get current task TCB addressLDRLDRr4, addr_OSTCBCurr5, r4STR sp, r5; store s

14、p in preempted taskss TCB;OSTCBCur-OSTCBStkPtr=SP 保存 SP 到當前任務控制塊; Get highest priority task TCB addressLDR LDR LDR;Sr6, addr_OSTCBHighRdyr6, r6sp, r6; get new tasks stack poerTCBHighRdy-OSTCBStkPtr 更新 SP 為即將運行的任務STR r6, r4; set new current task TCB address; OSTCBCur = OSTCBHighRdyLDMFD;MSR LDMFD MSR

15、LDMFDsp!, r4 SPSR_cxsf, r4 sp!, r4CPSR_cxsf, r4; YYY+; YYY+運行在 sys 模式下,無需 SPSR 的更新; YYY+; YYY+sp!, r0-r12, lr, pc ; YYY+;現(xiàn)場恢復完畢其來源于:OS_CPU_a.s這個函數(shù)是任務主動放棄 CPU 時最終調用的的函數(shù), 其為 OSSched() 調用, 前后為OS_ENTER/EXIT_CRITICAL 所包圍。因此進入OS_TASK_SW 時,IRQ 是被的,保存到堆棧中的 CPSR I 位也是為 1,但是放心,OS_TASK_SW 保存的現(xiàn)場恰好是從OSSched()中 O

16、S_TASK_SW 返回的地方,任務時緊接著是后面解除的代碼。五、OSCtxSw,首先,見調用示意圖:可見,中斷中的調用是較復雜,嵌套較深,這也是的原因。在 OSCtxSw 中從底向上發(fā)掘數(shù)據其次,見代碼,根據上圖的 IRQ 棧結構,可以分析如何將其中的有用數(shù)據搬運到被中斷任務的堆棧中:IMPORTIRQ_STACK EXPORTOSCtxSwCtxSw;該函數(shù)運行在 IRQ 狀態(tài),他返回 SYS 模式,并將壓入 SP_IRQ 的;現(xiàn)場數(shù)據搬運到 SP_SYS 中構造出標準棧,保存該棧指針;再;切換到其它的任務中(后半部分與 OSCtxSw 相同);該函數(shù)是不返回的,IRQ 處理函數(shù)在調用到該

17、函數(shù)時,不知道OS;已經壓了多少的棧,而不需要從棧頂向下挖掘出當時壓;入的現(xiàn)場,只要知道進入 IRQ 狀態(tài)時的SP 是多少,便可以;由棧底來發(fā)掘出 r0-r12 和 pc+4(其實就是 lr_IRQ),見圖;這種方法建立的前提是:在 IRQ 的中斷處理代碼之前對其SP 賦值;這樣便不可以實現(xiàn) IRQ 的嵌套了。;IRQ 處理代碼的最前有一句 LDRSP,=IRQ_STACK(見 init.s)LDRr0,=IRQ_STACK ;要找到這個地方sub SP,r0,#14*4;壓入的內容從r0-r12 pc+4(lr_irq)14 個;字,現(xiàn)在SP 指向最低位置的r0,可見 圖四mrs r0,SP

18、SR;在 IRQ 狀態(tài)下讀SPSR 其實就是被中斷現(xiàn)場的 CPSR;現(xiàn)在,irq 棧中的最低位置為 CPSRstmfdsp!,r0orrmsrr0,r0,#0 x80;spsr 中的 I 位CPSR_cxsf,r0 ;返回現(xiàn)場狀態(tài),注意,這時 lr_sys 還沒變;要不是 sys 模式,SPSR 也是沒變的ldr ldrsubr0,=IRQ_STACKr1,r0,#-1*4! ;現(xiàn)在 r0 指向 PC+4,且取出放入r1 r1,r1,#4 ;現(xiàn)在 r1 中是返回的 PCstmfdstmfdsp!,r1 ;壓入 pcsp!,lr ;壓入 lr現(xiàn)在開始構造標準的任務棧ldmdb stmfd ldm

19、db stmfdcpsr,r0-r12r0!,r4-r11;r0 指向 PC+4,先減后 sp!,r4-r11r0!,r4-r9出 8 個,參見 移植參的棧示意sp!,r4-r9;兩次批量搬運從 irq 棧到 sys 棧轉移 14 個數(shù)據,有低到高;mrs spsr,r4;若任務運行模式不為 sys 則,spsr 需要保存,否則,依然壓入 CPSR;r4 中為 CPSRstmfdsp!,r4;到此為止,的標準棧結構已經建立起來,所有需要的現(xiàn)場已被壓到 sp_sys;后面的內容和OSCtxSw 的后半部分相同,依次為;OSPrioCur = OSPrioHighRdy;OSTCBCur-OSTC

20、BStkPtr=SP 保存 SP 到當前任務控制塊;STCBHighRdy-OSTCBStkPtr;OSTCBCur=OSTCBHighRdy;彈出現(xiàn)場LDR LDR LDRBSTRBr4, addr_OSPrioCurr5, addr_OSPrioHighRdy r6, r5r6, r4; OSPrioCur = OSPrioHighRdy; Get current task TCB addressLDRLDRr4, addr_OSTCBCurr5, r4STR sp, r5; store sp in preempted taskss TCB;OSTCBCur-OSTCBStkPtr=SP

21、保存 SP 到當前任務控制塊; Get highest priority task TCB addressLDR LDR LDR;Sr6, addr_OSTCBHighRdyr6, r6sp, r6; get new tasks stack poerTCBHighRdy-OSTCBStkPtr 更新 SP 為即將運行的任務STR r6, r4; set new current task TCB address; OSTCBCur = OSTCBHighRdyLDMFD;MSR LDMFD MSRLDMFDsp!, r4 SPSR_cxsf, r4 sp!, r4CPSR_cxsf, r4; Y

22、YY+; YYY+運行在 sys 模式下,無需 SPSR 的更新; YYY+; YYY+sp!, r0-r12, lr, pc ; YYY+;現(xiàn)場恢復完畢其來源于:OS_CPU_a.s小結:OSCtxSw 是一個較為復雜的函數(shù),作為任務的中斷終結者,他的是 IRQ 的堆棧,有用的現(xiàn)場數(shù)據在 IRQ 進入時便被壓到 IRQ 棧的最低層,CSPR、SP、PC、LR 全部被換。因此,只能先回到SYS 的任務模式,而后由 IRQ 的棧中從底而上取出數(shù)據,按標準格式壓入任務堆棧。其后的事情與OS_CTX_SW 相同。此外,如果在 OSExit()的判斷中,沒有新任務需要切換運行,OSCtxSw 便不會被

23、運行,其會層層返回正常的回到被中斷的任務。OSCtxSw 對堆棧的處理方式使不可以實現(xiàn) IRQ 嵌套,但是,OSCtxSw 是健壯的不論前面嵌套了多少的函數(shù),堆棧被壓入多少的內容,回到任務。都可以用OSCtxSw 直接的未實現(xiàn)的技術和對未來的想法:周立功的 ARM 書上有關于 ucOS 系統(tǒng)和用戶代碼分開編譯加載的內容,它是將系統(tǒng)單獨編譯,將系統(tǒng)調用的函數(shù)地址組一張表格放到確定的地方,燒寫到 flash 中;用戶程序加載后,到這張表格中調用系統(tǒng)服務。我有一種更好的想法:ARM 有SWI 軟中斷的功能,完全可以將所有的系統(tǒng)調用加載在 SVC狀態(tài)下的SWI 處理函數(shù)中。這樣,系統(tǒng)燒寫在 flash 中,其后加載用戶任務,直接執(zhí)行軟中斷即可。于 ucOS 移植成功后總結2004-4-7第三次移植的小結:前后移植了 3 次,其關鍵之處在于中斷后對堆棧的處理以及 OSCtxSw 的編寫,三

溫馨提示

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

評論

0/150

提交評論