📄 os_cpu_a.s
字号:
;----------------------------------------------------------------------------------
; OSIntEnter() 龋免 肚绰 OSIntNesting 蔼阑 1 刘啊;
;----------------------------------------------------------------------------------
BL OSIntEnter
;----------------------------------------------------------------------------------
; 鸥捞赣 牢磐反飘 惯积厘摹 努府绢;
;----------------------------------------------------------------------------------
MOV R1, #1
MOV R1, R1, LSL #14 ; Timer4 Source Pending Reg.
LDR R0, =SRCPND
STR R1, [R0]
LDR R0, =INTPND
LDR R1, [R0]
STR R1, [R0]
;----------------------------------------------------------------------------------
; OSTimeTick();
;----------------------------------------------------------------------------------
BL OSTimeTick
;----------------------------------------------------------------------------------
; OSIntExit();
;----------------------------------------------------------------------------------
BL OSIntExit
;----------------------------------------------------------------------------------
; if(OSIntCtxSwFlag == TRUE) _IntCtxSw();
;----------------------------------------------------------------------------------
LDR R0, =OSIntCtxSwFlag ; See if we need to do a context switch
LDR R1, [R0]
CMP R1, #1
BEQ OS_IntCtxSw ; Yes, Switch to Higher Priority Task
;----------------------------------------------------------------------------------
; 橇肺技辑 饭瘤胶磐 汗备;
;----------------------------------------------------------------------------------
LDMFD SP!, {R0-R3, R12, LR} ; No, Restore registers of interrupted task''s stack
;----------------------------------------------------------------------------------
; 牢磐反飘 汗蓖 疙飞 角青;
;----------------------------------------------------------------------------------
SUBS PC, LR, #4 ; Return from IRQ
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From an ISR)
; void OSIntCtxSw(void)
;
; Description: 1) This code performs a context switch if a higher priority task has been made ready-to-run
; during an ISR.
;
; 2) The stack frame of the task to suspend looks as follows:
;
; LR(R14) (High memory)
; R12
; R11
; R10
; R9
; R8
; R7
; R6
; R5
; R4
; R3
; R2
; R1
; R0
; CPSR
; OSTCBCur->OSTCBStkPtr ----> SPSR (Low memory)
;
;
; 3) The stack frame of the task to resume looks as follows:
;
; LR(R14) (High memory)
; R12
; R11
; R10
; R9
; R8
; R7
; R6
; R5
; R4
; R3
; R2
; R1
; R0
; CPSR
; OSTCBHighRdy->OSTCBStkPtr ----> SPSR (Low memory)
;*********************************************************************************************************
OSIntCtxSw
LDR R0, =OSIntCtxSwFlag ;OSIntCtxSwFlag = TRUE
MOV R1, #1
STR R1, [R0]
MOV PC, LR
OS_IntCtxSw ; 捞 何盒篮 ARM俊 措秦 肋 舅酒具 秦籍捞 啊瓷窃
LDR R0, =OSIntCtxSwFlag ; OSIntCtxSwFlag = FALSE
MOV R1, #0
STR R1, [R0]
LDMFD SP!, {R0-R3, R12, LR} ; Clean up IRQ stack
STMFD SP!, {R0-R3} ; We will use R0-R3 as temporary registers
MOV R1, SP
ADD SP, SP, #16
SUB R2, LR, #4
MRS R3, SPSR ; Disable interrupts for when we go back to SVC mode
ORR R0, R3, #0xC0
MSR SPSR_c, R0
; 捞何盒捞 抗贱烙^^, 颇捞橇扼牢阑 捞秦 秦具窃
LDR R0, =.+8 ; Switch back to SVC mode (Code below, current location + 2 instructions)
MOVS PC, R0 ; Restore PC and CPSR
; SAVE OLD TASK''S CONTEXT ONTO OLD TASK''S STACK
STMFD SP!, {R2} ; Push task''s PC
STMFD SP!, {R4-R12, LR} ; Push task''s LR,R12-R4
MOV R4, R1 ; Move R0-R3 from IRQ stack to SVC stack
MOV R5, R3
LDMFD R4!, {R0-R3} ; Load R0-R3 from IRQ stack
STMFD SP!, {R0-R3} ; Push R0-R3
STMFD SP!, {R5} ; Push task''s CPSR
MRS R4, SPSR
STMFD SP!, {R4} ; Push task''s SPSR
;----------------------------------------------------------------------------------
; 泅犁 怕胶农狼 胶琶 器牢磐甫 泅犁 怕胶农狼 怕胶农 牧飘费 喉废俊 历厘:
; OSTCBCur->OSTCBStkPtr = 胶琶 器牢磐;
;----------------------------------------------------------------------------------
LDR R0, =OSTCBCur
LDR R0, [R0]
STR SP, [R0]
;----------------------------------------------------------------------------------
; 荤侩磊 沥狼 窃荐 OSTaskSwHook()阑 龋免茄促;
;----------------------------------------------------------------------------------
BL OSTaskSwHook
;----------------------------------------------------------------------------------
; OSTCBCur = OSTCBHighRdy;
;----------------------------------------------------------------------------------
LDR R0, =OSTCBHighRdy
LDR R1, =OSTCBCur
LDR R0, [R0]
STR R0, [R1]
;----------------------------------------------------------------------------------
; OSPrioCur = OSPrioHighRdy;
;----------------------------------------------------------------------------------
LDR R0, =OSPrioHighRdy
LDR R1, =OSPrioCur
LDRB R0, [R0]
STRB R0, [R1]
;----------------------------------------------------------------------------------
; 犁角青且 怕胶农狼 胶琶 器牢磐 汗备:
; 胶琶 器牢磐 = OSTCBHighRdy->OSTCBStkPtr;
;----------------------------------------------------------------------------------
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR R0, [R0]
MOV SP, R0
;----------------------------------------------------------------------------------
; 犁角青且 怕胶农狼 胶琶栏肺何磐 橇肺技辑 饭瘤胶磐 汗备
;----------------------------------------------------------------------------------
LDMFD SP!, {R0}
MSR SPSR_cxsf, R0
LDMFD SP!, {R0}
MSR CPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}
;*********************************************************************************************************
; CRITICAL SECTION METHOD 3 FUNCTIONS
;
; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II''s functions that need to
; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
; into the CPU''s status register.
;
; Prototypes : OS_CPU_SR OSCPUSaveSR(void);
; void OSCPURestoreSR(OS_CPU_SR cpu_sr);
;
;
; Note(s) : 1) These functions are used in general like this:
;
; void Task (void *p_arg)
; {
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
;
; :
; :
; OS_ENTER_CRITICAL(); /* cpu_sr = OSCPUSaveSR(); */
; :
; :
; OS_EXIT_CRITICAL(); /* OSCPURestoreSR(cpu_sr); */
; :
; :
; }
;
; 2) OSCPUSaveSR() is implemented as recommended by Atmel''s application note:
;
; "Disabling Interrupts at Processor Level"
;*********************************************************************************************************
OSCPUSaveSR
MRS R0, CPSR ; Set IRQ and FIQ bits in CPSR to disable all interrupts
ORR R1, R0, #0xC0
MSR CPSR_c, R1
MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags
AND R1, R1, #0xC0
CMP R1, #0xC0
BNE OSCPUSaveSR ; Not properly disabled (try again)
MOV PC, LR ; Disabled, return the original CPSR contents in R0
OSCPURestoreSR
MSR CPSR_c, R0
MOV PC, LR
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -