1 / 35

Presenter:Wytai

Porting uC/OS-II to XSBase255. Presenter:Wytai. Date:06/04. Outline. Introduction Porting overview OS_CPU.h OS_CPU_A.asm OS_CPU_C.c Conclusion. Introduction. Preparation uC/OS-II source code http://www.micrium.com/ V.2.86 Porting file http://www.micrium.com/ V.1.50 ADS or GNU

dahlia
Download Presentation

Presenter:Wytai

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Porting uC/OS-II to XSBase255 Presenter:Wytai Date:06/04 /

  2. Outline • Introduction • Porting overview • OS_CPU.h • OS_CPU_A.asm • OS_CPU_C.c • Conclusion /

  3. Introduction • Preparation • uC/OS-II source code http://www.micrium.com/ • V.2.86 • Porting file http://www.micrium.com/ • V.1.50 • ADS or GNU • Hardware • XSBase255 • Hardware Spec • Compiler Spec • ARM assembly knowing /

  4. Introduction • Porting = bootloader + OS • Bootloader • Initialize hardware, vectors, memory, stack, register value • There are two ways • 分開成兩個檔案(bin),bootloader裡面要設定OS Image存放的位址(OS入口),需要兩者一致方可成功啟動OS • 合成一個bin檔,在bootloader執行完以後,透過跳轉__main進入OS入口 /

  5. Introduction • Hardware limit • 處理器的C 編譯器能產生可重入程式碼。 • 用C 語言就可以打開和關閉中斷。 • 處理器支援中斷,並且能產生定時中斷(通常在10 至100Hz 之間)。 • 處理器支援能夠容納一定數量的資料的硬體堆疊(可能是幾千位元組)。 • 處理器有將堆疊指標和其他CPU 暫存器讀出和存儲到堆疊或記憶體中的指令。 • Ex • Motorola 6805 : 4,5 /

  6. Overview /

  7. Overview • OS_CPU.h • Define some reg value and datatype • OS_CPU_A.asm • OSStartHighRdy() • OSCtwSw() • OSTickISR() • OSIntCtxSw() • OS_CPU_C.c • OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskStatHook()、OSTimeTickHook() /

  8. OS_CPU.h • Compiler dependent(請查看compiler手冊) • typedef unsigned char BOOLEAN; • typedef unsigned char INT8U; • typedef signed char INT8S; • typedef unsigned short INT16U; • typedef signed short INT16S; • typedef unsigned int INT32U; • typedef signed int INT32S; • typedef float FP32; • typedef double FP64; • typedef unsigned int OS_STK; /

  9. OS_CPU.h • Processor dependent • #define OS_ENTER_CRITICAL() • {cpu_sr = OS_CPU_SR_Save();} • #define OS_EXIT_CRITICAL() • {OS_CPU_SR_Restore(cpu_sr);} • #define OS_STK_GROWTH 1 • #define OS_TASK_SW() OSCtxSw() /

  10. OS_CPU_A.asm • 一般寫完bootloader後,常要觀察其與OS搭配後,是否可以順利進入OS • 為了往後可以測試task context switch 是否成功,因此建立2個task,不同的priority,分別進行不同動作,例如輸出不同字元(FFUART)或是使不同的led燈亮起(GPIO) • taskA priority 5 並在while迴圈中加入OStimedly • taskB priority 10並在while迴圈中加入OStimedly /

  11. OS_CPU_A.asm • OSStartHighRdy() • 由於Osstart()後,會去執行schedule,並且挑出最高priority的task執行 • Pseudocode • void OSStartHighRdy (void) • { • Call user definable OSTaskSwHook();  • Get the stack pointer of the task to resume: • Stack pointer = OSTCBHighRdy->OSTCBStkPtr;  • OSRunning = TRUE;  • Restore all processor registers from the new task's stack;  • Execute a return from interrupt instruction; • } /

  12. OS_CPU_A.asm • OSStartHighRdy • Call user definable OSTaskSwHook(); • BL OSTaskSwHook • Stack pointer = OSTCBHighRdy->OSTCBStkPtr; • LDR R4, = OSTCBHighRdy • LDR R4, [R4] • LDR SP, [R4] • OSRunning = TRUE; • LDR R4, = OSRunning • MOV R5, #1 • STRB R5, [R4] /

  13. OS_CPU_A.asm • Restore all processor registers from the new task's stack;  • LDMFD SP!, {R4} • MSR CPSR_cxsf, R4 • Execute a return from interrupt instruction; • LDMFD SP!,{R0-R12, LR, PC} • 若是此函式完成後 • 可以觀察到taskA的動作 • 若是沒有預期動作,則表示先前的準備工作尚未全部完成 • Ex.bootloader、OS_CPU.h…… /

  14. OS_CPU_A.asm • OSCtxSw() • 若是目前task ready queue中有更高priority的task,則使用此函式將目前正在執行的task與之交換 • Pseudo code • void OSCtxSw(void) • { • 保存處理器暫存器;  • 將當前task 的堆疊指標保存到當前task 的OS_TCB 中:  • OSTCBCur->OSTCBStkPtr = Stack pointer;  • 呼叫使用者定義的OSTaskSwHook();  • OSTCBCur = OSTCBHighRdy;  • OSPrioCur = OSPrioHighRdy;  • 得到需要恢復的task 的堆疊指標:  • Stack pointer = OSTCBHighRdy->OSTCBStkPtr;  • 將所有處理器暫存器從新task 的堆疊中恢復出來;  • 執行中斷返回指令; • } /

  15. OS_CPU_A.asm • OSCtxSw • 保存處理器暫存器;  • STR LR, [SP, #-4]! • STMFD SP!, {R0-R12, LR} • MRS R4, CPSR • STR R4, [SP, #-4]! • OSTCBCur->OSTCBStkPtr = Stack pointer; • LDR R4, =OSTCBCur • LDR R4, [R4] • STR SP, [R4] /

  16. OS_CPU_A.asm • 呼叫使用者定義的OSTaskSwHook();  • BL OSTaskSwHook • OSTCBCur = OSTCBHighRdy; • LDR R4, = OSTCBCur • LDR R5, = OSTCBHighRdy • LDR R5, [R5] • STR R5, [R4] • OSPrioCur = OSTCBHighRdy; • LDR R4, = OSPrioCur • LDR R5, = OSTCBHighRdy • LDR R5, [R5] • STR R5, [R4] /

  17. OS_CPU_A.asm • Stack pointer = OSTCBHighRdy->OSTCBStkPtr; • LDR R4, = OSTCBHighRdy • LDR R4, [R4] • LDR SP, [R4] • 將所有處理器暫存器從新task 的堆疊中恢復出來;  • 執行中斷返回指令; • LDMFD SP!, {R4} • MSR CPSR_cxsf, R4 • LDMFD SP!,{R0-R12, LR, PC} • 此函式成功,則在taskA動作結束後,taskB會隨之動作 /

  18. OS_CPU_A.asm • OSTickISR() • 此函式用來決定一個tick所需要的clock數,來實現time delay和系統時間前進的功能 • 而運行此函式還必須要初始化timer interrupt,此動作規定在OSStart()後較不會發生問題 • void main(void) • { • . • OSInit(); . • /* 應用程式初始化程式碼... */ • /* ... 呼叫OSTaskCreate() 建立至少一個task */ • . • 允許tick interrupt; /* 千萬不要在這裏允許! */ • . • OSStart(); /* 開始多工排程 */ • } /

  19. OS_CPU_A.asm • 初始化timer interrupt的動作最好在priority最高的task中運行,如此可保證在OSStart()後緊接執行,不會有OS運行狀態不明的情形發生 • There are two ways • 專屬的task,運行後利用uC/OS-ii中的函示將該task lock,不再執行 • 在目前最高的priority的task中,初始的地方運行(不是在while迴圈中) /

  20. OS_CPU_A.asm • Timer Registers • OSCR – 自動遞增的計數器 • OSMR0-3– 4個match的reg,一旦與OSCR match就發生中斷 • OIER– 當OSMR == OSCR時,允許OSSR設置flag • OSSR– 當OSMR == OSCR時,在對應的地方設置flag • Timerinitial • OSMRx=xxx • OSSR=0xffffffff • OIER = OIER_EO • OSCR = 0 or OSCR = OSCR + time interval /

  21. OS_CPU_A.asm • Interrupt control • ICPR – 表示目前系統正發生中斷 • ICMR– 用來mask對應的中斷位元 • ICLP– 用來決定中斷是IRQ或是FIQ • ICIP– 標記發生IRQ的device • ICFP– 標記發生FIQ的device • Initial • ICMR 使之不mask OSMRx(對應位元 = 1) • ICLR 使之決定IRQ或是FIQ /

  22. OS_CPU_A.asm • Pseudo Code • void OSTickISR(void) • { • 保存處理器暫存器; • 呼叫OSIntEnter() 或者直接將OSIntNesting 加1; • 呼叫OSTimeTick(); • 呼叫OSIntExit(); • 恢復處理器暫存器; • 執行中斷返回指令; • } /

  23. OS_CPU_A.asm • Assumption • 皆已初始化timer和interrupt • 會自動去決定下一次tick應該在何時發生 • OSMR = OSCR + interval • OSSR 清除 /

  24. OS_CPU_A.asm • OSTickISR • 保存處理器暫存器; • 呼叫OSIntEnter() 或者直接將OSIntNesting 加1; • BL OSIntEnter • 呼叫OSTimeTick(); • BL OSTimeTick • 呼叫OSIntExit(); • BL OSIntExit • 恢復處理器暫存器; • 執行中斷返回指令; • 此函式完成後,可以在此函式中加入輸出,若是此書出可以依照interval持續到來,表示成功 /

  25. OS_CPU_A.asm • LDR R11, =osTimer_OSSR • MOV R4, #0xf • STR R4, [R11] • ;//enable timer interrupt • LDR R4, =int_ICMR • MOV R5, #0x04000000 • STR R5, [R4] • LDR R6, =osTimer_OSMR0 • LDR R7, =ChkTimeInterval • LDR R8, =osTimer_OSCR • LDR R9, [R8] • ADD R7, R7, R9 ;// OSCR + interval • STR R7, [R6] /

  26. OS_CPU_A.asm • OSIntCtxSw() • 為了能在ISR中直接進行task切換,若是利用原本的方式,需要結束ISR後回到原本的task,再進行OSCtxSw,如此反應上較慢,稍不realtime • There are two ways • 調整SP到適當的位置 • 在此函式中僅設置旗標,離開OSIntExit後才根據旗標決定是否進行task 切換 /

  27. OS_CPU_A.asm • Assumption • 在進行ISR之前就已將目前的狀態、data push進stack • OSIntCtxSw所處的mode最好與task執行的mode一致 /

  28. OS_CPU_A.asm /

  29. OS_CPU_A.asm • Pseudo code • void OSIntCtxSw(void) • { • 調整SP • 將當前task 的堆疊指標保存到當前task 的OS_TCB 中:  • OSTCBCur->OSTCBStkPtr = Stack pointer;  • 呼叫使用者定義的OSTaskSwHook();  • OSTCBCur = OSTCBHighRdy;  • OSPrioCur = OSPrioHighRdy;  • 得到需要恢復的task 的堆疊指標:  • Stack pointer = OSTCBHighRdy->OSTCBStkPtr;  • 將所有處理器暫存器從新task 的堆疊中恢復出來;  • 執行中斷返回指令; • } /

  30. OS_CPU_A.asm • OSIntCtxSw • 由於僅有第一行與OSCtxSw不相同,因此在切換mode之後,可以直接呼叫OSCtxSw • SP調整 • 由於每個mode下都有各自的stack,並且在access其他mode的data會受到限制,加上每個task都有各自的stack,因此,mode和stack的關係要十分清楚,否則此處調整SP會有極大的機率造成錯誤 /

  31. OS_CPU_A.asm • 若是要利用第2種方法(設旗標) • 則在OSIntCtxSw中 • 保存處理器暫存器; • LDR R4, =needCtxSw • MOV R5, #0x1 • STR R5, [R4] • 將所有處理器暫存器從新task 的堆疊中恢復出來;  • 執行中斷返回指令; • 在TickISR中(在OSIntExit之後) • LDR R4, =needCtxSw • LDR R4, [R4] • CMP R4, #1 • BEQ OSCtxSw /

  32. OS_CPU_C.c • OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskStatHook()、OSTimeTickHook() • Hook主要用來進行功能擴展 • OSTaskStkInit() • 對於task stack進行初始化動作 /

  33. Conclusion • OS_CPU.h 須查閱spec,並且在porting過程中需不斷加上新的變數值或是新的函式 • Bootloader在porting過程中也需要修改,例如加入新的handler以及加入新的中斷向量 • OSIntCtxSw 和 OSTickISR與暫存器的設置有關 • Mode • Stack /

  34. Conclusion /

  35. Q & A • Thanks /

More Related