📄 os_cpu_a.s
字号:
AREA |subr|, CODE, READONLY
IMPORT OSRunning ; EXTERNAL references
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSIntNesting
IMPORT OSIntExit
IMPORT OSTaskSwHook
IMPORT OSIntEnter
IMPORT OSTimeTick
EXPORT OS_CPU_SR_Save ; Functions declared in this file
EXPORT OS_CPU_SR_Restore
EXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSIntCtxSw
EXPORT OSTickISR
EXPORT OSIntISR
OSIntCtxSwFlag DCD 0x00000000
SAVED_LR_SVC DCD 0x00000000 ; some variables for temparal use
SAVED_LR_IRQ DCD 0x00000000
SAVED_SPSR DCD 0x00000000
NO_INT EQU 0xC0 ; Mask used to disable interrupts (Both FIR and IRQ)
SYS32_MODE EQU 0x1F
FIQ32_MODE EQU 0x11
IRQ32_MODE EQU 0x12
OS_CPU_SR_Save
MRS R0,CPSR ; Set IRQ and FIQ bits in CPSR to disable all interrupts
ORR R1,R0,#NO_INT ;0XC0
MSR CPSR_c,R1
MRS R1,CPSR ; Confirm that CPSR contains the proper interrupt disable flags
AND R1,R1,#NO_INT
CMP R1,#NO_INT
BNE OS_CPU_SR_Save ; Not properly disabled (try again)
MOV PC,LR ; Disabled, return the original CPSR contents in R0
OS_CPU_SR_Restore
MSR CPSR_c,R0
MOV PC,LR
OSStartHighRdy
PRESERVE8
BL OSTaskSwHook ; Call user-defined hook function
LDR r4,=OSRunning ; Indicate that multitasking has started
MOV r5, #1
STRB r5, [r4] ; OSRunning = true
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_cxsf, r4
LDMFD sp!, {r4} ; pop new task s psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task s r0-r12,lr & pc
OSCtxSw
STMFD sp!, {lr} ; push pc (lr is actually 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
_OSCtxSw
LDR r4, =OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR r5, =OSPrioHighRdy
LDRB r6, [r5]
STRB r6, [r4]
LDR r4, =OSTCBCur ; Get current task TCB address
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks s TCB
BL OSTaskSwHook ; call Task Switch Hook
LDR r6, =OSTCBHighRdy ; Get highest priority task TCB address
LDR r6, [r6]
LDR sp, [r6] ; get new task s stack pointer
STR r6, [r4] ; set new current task TCB address
LDMFD sp!, {r4} ; pop new task spsr
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task cpsr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task r0-r12,lr & pc
OSIntCtxSw
LDR r0, =OSIntCtxSwFlag ; OSIntCtxSwFlag = true
MOV r1, #1
STR r1, [r0]
MOV pc, lr ; return
clear_irq
MOV r0,#0xffffffff;#0x400
MOV r1,#0x1e00000
STR r0,[r1,#0x24]
MOV pc,r14
OSTickISR
OSISR
OSIntISR
SUB lr, lr, #4
STMFD sp!, {r0-r12, lr} ; push r0-r12 register file and lr( pc return address )
MRS r4, spsr
STMFD sp!, {r4} ; push current spsr_irq ( =cpsr_svc )
BL OSIntEnter
BL OSTimeTick
; here do_IRQ is used to clear some virtual-hardware flags
;AND RELOAD THE TIMER
BL OSIntExit
;bl clear_irq
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;bl clear_irq
MOV r0,#0xffffffff;#0x400 ;clear all irq flags!
MOV r1,#0x1e00000
STR r0,[r1,#0x24]
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
LDR r0, =OSIntCtxSwFlag ; check if OSIntCtxFlag is marked as true
LDR r1, [r0]
CMP r1, #1
BEQ _IntCtxSw ; if OSIntCtxFlag = true, then jump to _IntCtxSw
LDMFD sp!, {r4} ; get cpsr_svc from stack
MSR spsr_cxsf, r4 ; prepare spsr to return svc mode
LDMFD sp!, {r0-r12, pc}^ ; recover r0-r12 and pc from stack, cpsr also
_IntCtxSw
MOV r1, #0 ; clear OSIntCtxSwFlag = flase
STR r1, [r0]
LDMFD sp!, {r4} ; restore spsr_irq
MSR spsr_cxsf, r4
STR r4, SAVED_SPSR
LDMFD sp!, {r0-r12, lr} ; recover the irq stack pointer
STR lr, SAVED_LR_IRQ ; save lr_irq to SAVED_LR_IRQ
MOV lr, #0x000000d3 ; change forcely cpsr to svc mode
MSR cpsr_cxsf, lr
STR lr, SAVED_LR_SVC ; save lr_svc to SAVED_LR_SVC
LDR lr, SAVED_LR_IRQ ; get lr_irq value saved in SAVED_LR_IRQ
STMFD sp!, {lr} ; push future task pc (lr_irq should be pushed in place of PC)
LDR lr, SAVED_LR_SVC ; get lr_svc value saved in SAVED_LR_SVC
STMFD sp!, {r0-r12,lr} ; push lr & r0-r12 register file
LDR r4, SAVED_SPSR
;MRS r4, spsr
STMFD sp!, {r4} ; push current psr
;MRS r4, spsr
STMFD sp!, {r4} ; push spsr
B _OSCtxSw ; jump to _OSCtxSw
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -