?? os_cpu_a.s
字號:
.file "os_cpu_a.S".text @------------------------------------------------------------------------- .align 2 .global OSStartHighRdy .type OSStartHighRdy,functionOSStartHighRdy: @ // 1) 調(diào)用 用戶編寫的 hook 函數(shù) BL OSTaskSwHook @ Call user defined task switch hook @ // 2) 設(shè)置 OSRunning 變量為 true , 表示多任務(wù)調(diào)度開始 LDR r4,=OSRunning @ Indicate that multitasking has started MOV r5, #1 STRB r5, [r4] @ // 3) 獲得最高優(yōu)先級任務(wù)的 TCB 塊指針,得到該任務(wù)的堆棧, @ // 從堆棧中依次恢復(fù)出 SPSR, CPSR, r0-r12, lr, pc LDR r4, =OSTCBHighRdy @ Get highest priority task TCB address LDR r4, [r4] @ get stack pointer LDR sp, [r4] @ switch to the new stack LDMFD sp!, {r4} @ pop new task s spsr MSR SPSR, r4 LDMFD sp!, {r4} @ pop new task s psr MSR CPSR, r4 LDMFD sp!, {r0-r12,lr,pc} @ pop new task s r0-r12,lr & pc @ End of OSStartHighRdy @----------------------------------------------------------------------- .align 2 .global OSCtxSw .type OSCtxSw,functionOSCtxSw:/* Perform a context switch. On entry, OSTCBCur and OSPrioCur hold the current TCB and priority and OSTCBHighRdy and OSPrioHighRdy contain the same for the task to be switched to. The following code assumes that the virtual memory is directly mapped into physical memory. If this is not true, the cache must be flushed at context switch to avoid address aliasing.*/ @ // 1) PUSH ALL 將當(dāng)前執(zhí)行任務(wù)的 CPU 現(xiàn)場保存到 該任務(wù)的堆棧中 @ // 依次將 pc, lr, r12-r0, CPSR, SPSR 推入 堆棧 sp 中 STMFD sp!, {lr} @ push pc (lr should be pushed in place of PC) STMFD sp!, {r0-r12,lr} @ push lr & register file MRS r4, cpsr STMFD sp!, {r4} @ push current psr MRS r4, spsr STMFD sp!, {r4} @ push current spsr @ // 2) 設(shè)置當(dāng)前優(yōu)先級為最高任務(wù)的優(yōu)先級 OSPrioHighRdy @ OSPrioCur = OSPrioHighRdy LDR r4, =OSPrioCur LDR r5, =OSPrioHighRdy LDRB r6, [r5] STRB r6, [r4] @ // 3) 獲得當(dāng)前執(zhí)行任務(wù)的 TCB 塊指針 @ Get current task TCB address LDR r4, =OSTCBCur LDR r5, [r4] STR sp, [r5] @ store sp in preempted tasks s TCB @ // 4) 調(diào)用用戶定義的 hook 函數(shù) BL OSTaskSwHook @ call Task Switch Hook @ // 5) 獲得最高優(yōu)先級任務(wù)的 TCB 塊指針, 并且將它的堆棧指針復(fù)制到 CPU 的 sp 中, 改變當(dāng)前堆棧 @ Get highest priority task TCB address LDR r6, =OSTCBHighRdy LDR r6, [r6] LDR sp, [r6] @ get new task s stack pointer @ // 6) 將最高優(yōu)先級任務(wù)的 TCB 塊指針 復(fù)制到 當(dāng)前任務(wù) TCB 指針中 @ OSTCBCur = OSTCBHighRdy STR r6, [r4] @ set new current task TCB address @ // 7) 將堆棧中保存的最高優(yōu)先級任務(wù)的 CPU 現(xiàn)場恢復(fù)出來 @ // 一次從堆棧中彈出 SPSR, CPSR, r0-r12, lr, pc LDMFD sp!, {r4} @ pop new task s spsr MSR SPSR, r4 LDMFD sp!, {r4} @ pop new task s psr MSR CPSR, r4 LDMFD sp!, {r0-r12,lr,pc} @ pop new task s r0-r12,lr & pc @----------------------------------------------------------------------- .align 2 .global OSIntCtxSw .type OSIntCtxSw,functionOSIntCtxSw: @ // 1) 這個就是會被 OSIntExit() 調(diào)用的 OSIntCtxSw() 函數(shù)入口 @ // 在這里的處理僅僅是設(shè)置了一個標(biāo)志位 OSIntCtxSwFlag = True @ OSIntCtxSwFlag = True LDR r0, =OSIntCtxSwFlag MOV r1, #1 STR r1, [r0] @ // 2) 函數(shù)返回 MOV pc, lr .align 2 .global OSTickISR .type OSTickISR,functionOSTickISR: @ // 1) PUSH ALL 將當(dāng)前執(zhí)行任務(wù)的 CPU 現(xiàn)場保存到 該任務(wù)的堆棧中 STMDB sp!, {r0-r11, lr} @ // 2) 調(diào)用系統(tǒng)中斷進(jìn)入和退出的 hook 函數(shù) @BL OSIntEnter BL OSTimeTick BL do_IRQ @BL OSIntExit @ // 3) 從 OSIntExit() 中退出時,如果需要進(jìn)行中斷級的上下文切換,則系統(tǒng)會調(diào)用 OSIntCtxSw @ // 其結(jié)果就是 此時的標(biāo)志位 OSIntCtxSwFlag == True LDR r0, =OSIntCtxSwFlag LDR r1, [r0] CMP r1, #1 BEQ _IntCtxSw @ // 如果此時標(biāo)志位被設(shè)置,則跳轉(zhuǎn)到 _IntCtxSw 執(zhí)行中斷級的上下文切換 @ // 4) 如果此時 標(biāo)志位 沒有被設(shè)置, 則不需要進(jìn)行調(diào)度,直接從中斷中返回原來的任務(wù) LDMFD sp!, {r0-r11, lr} SUBS pc, lr, #4 _IntCtxSw: @ // 3.0) 改變處理器模式, MRS lr, SPSR AND lr, lr, #0xFFFFFFE0 ORR lr, lr, #0x13 MSR CPSR, lr @ // 3.1) 先恢復(fù)堆棧指針 sp 到初始位置:即 1) PUSH ALL 以前的值,同時恢復(fù)原來任務(wù)的上下文 LDMFD sp!, {r0-r11, lr} SUB lr, lr, #4 @ // 3.2) 執(zhí)行跳轉(zhuǎn)到 任務(wù)上下文的切換 代碼 B OSCtxSw @---------------------------------------------------------------------- .align 2 .global ARMDisableInt .type ARMDisableInt,functionARMDisableInt: @ // 1) 保存 CPSR 到當(dāng)前任務(wù)的堆棧 => push CPSR MRS r0, CPSR STMFD sp!, {r0} @ push current PSR @ // 2) 設(shè)置 CPSR 的中斷屏蔽位 @ORR r0, r0, #0xC0 @ mask IRQ Int s ORR r0, r0, #0x80 @ mask IRQ Int s @ // 3) 屏蔽中斷 MSR CPSR, r0 @ disable IRQ Int s @ // 4) 返回 MOV pc, lr @------------------------------------------------------------------------ .align 2 .global ARMEnableInt .type ARMEnableInt,functionARMEnableInt: @ // 1) 從堆棧中彈出 CPSR => pop CPSR 到 r0 LDMFD sp!, {r0} @ pop current PSR @ // 2) 用 r0 來恢復(fù) CPSR MSR CPSR, r0 @ restore original CPSR @ // 3) 返回 MOV pc, lr @------------------------------------------------------------------------ @-------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -