📄 os_cpu_a.s
字号:
@********************************************************************************************************
@ uC/OS-II
@ The Real-Time Kernel
@
@ (c) Copyright 1992-2004, Micrium, Weston, FL
@ All Rights Reserved
@
@ ARM Generic Port
@ GCC Compiler
@
@ File : OS_CPU_A.ASM
@ Version : V1.50 (IAR)
@ By : Jean J. Labrosse
@
@ AN-1011 Rev D. IAR compiler version ported to GCC.
@ NOTE: this file contains only source relevent to uCOS-II v2.52 (book source).
@
@********************************************************************************************************
@********************************************************************************************************
@ EXTERNAL DECLARATIONS
@********************************************************************************************************
.extern OSRunning
.extern OSPrioCur
.extern OSPrioHighRdy
.extern OSTCBCur
.extern OSTCBHighRdy
.extern OSIntNesting
.extern OSIntExit
.extern OSTaskSwHook
.extern OS_CPU_IRQ_ISR_Handler
.extern OS_CPU_FIQ_ISR_Handler
@********************************************************************************************************
@ PUBLIC DECLARATIONS
@********************************************************************************************************
.global CPSR_Read
.global OS_CPU_SR_Save
.global OS_CPU_SR_Restore
.global OSStartHighRdy
.global OSCtxSw
.global OSIntCtxSw
.global OS_CPU_IRQ_ISR
.global OS_CPU_FIQ_ISR
@********************************************************************************************************
@ PARAMETERS
@********************************************************************************************************
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F
.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
@*********************************************************************************************************
@ CRITICAL SECTION METHOD 3 FUNCTION
@
@ 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 OS_CPU_SR_Save(void);
@ void OS_CPU_SR_Restore(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 = OS_CPU_SaveSR(); */
@ :
@ :
@ OS_EXIT_CRITICAL(); /* OS_CPU_RestoreSR(cpu_sr); */
@ :
@ :
@ }
@
@ 2) OS_CPU_SaveSR() is implemented as recommended by Atmel's application note:
@
@ "Disabling Interrupts at Processor Level"
@
@ p328 of the ARM System Developers Guide has the first three asm statements and
@ does not use the check.
@
@ NOTE: the flags can ONLY be modified by a priviledged mode, so if you accidentally
@ call this function from user-mode, the processor will lock up (in the loop check).
@
@*********************************************************************************************************
.text
.arm
.align 2
.func OS_CPU_SR_Save
OS_CPU_SR_Save:
MRS R0,CPSR @ Set IRQ and FIQ bits in CPSR to disable all interrupts
ORR R1,R0,#I_Bit|F_Bit
MSR CPSR_c,R1
@ Interrupt disable check:
@
@ This is a slight variation on the Atmel app note code,
@ as it checks that both FIQ and IRQ disable bits get set.
MRS R1,CPSR @ Confirm that CPSR contains the proper interrupt disable flags
AND R1,R1,#I_Bit|F_Bit
CMP R1,#I_Bit|F_Bit
BNE OS_CPU_SR_Save @ Not properly disabled (try again)
MOV PC,LR @ Disabled, return the original CPSR contents in R0
.endfunc
.text
.arm
.align 2
.func OS_CPU_SR_Restore
OS_CPU_SR_Restore:
MSR CPSR_c,R0
MOV PC,LR
.endfunc
@*********************************************************************************************************
@ START MULTITASKING
@ void OSStartHighRdy(void)
@
@ Note(s) : 1) OSStartHighRdy() MUST:
@ a) Call OSTaskSwHook() then,
@ b) Set OSRunning to TRUE,
@ c) Switch to the highest priority task.
@*********************************************************************************************************
.text
.arm
.align 2
.func OSStartHighRdy
OSStartHighRdy:
MSR CPSR_cxsf, #0xDF @ Switch to SYS mode with IRQ and FIQ disabled
BL OSTaskSwHook @ OSTaskSwHook();
LDR R4, OS_Running_Addr @ OSRunning = TRUE
MOV R5, #1
STRB R5, [R4]
@ SWITCH TO HIGHEST PRIORITY TASK
LDR R4, OS_TCBHighRdy_Addr @ Get highest priority task TCB address
LDR R4, [R4] @ get stack pointer
LDR SP, [R4] @ switch to the new stack
LDR R4, [SP], #4 @ pop new task's CPSR
MSR CPSR_cxsf,R4
LDR R0, [SP], #4 @ pop new task's context
LDR R1, [SP], #4
LDR R2, [SP], #4
LDR R3, [SP], #4
LDR R4, [SP], #4
LDR R5, [SP], #4
LDR R6, [SP], #4
LDR R7, [SP], #4
LDR R8, [SP], #4
LDR R9, [SP], #4
LDR R10, [SP], #4
LDR R11, [SP], #4
LDR R12, [SP], #4
LDR LR, [SP], #4
LDR PC, [SP], #4
.endfunc
@*********************************************************************************************************
@ PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
@
@ Note(s) : 1) OSCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
@
@ 2) The pseudo-code for OSCtxSw() is:
@ a) Save the current task's context onto the current task's stack
@ b) OSTCBCur->OSTCBStkPtr = SP;
@ c) OSTaskSwHook();
@ d) OSPrioCur = OSPrioHighRdy;
@ e) OSTCBCur = OSTCBHighRdy;
@ f) SP = OSTCBHighRdy->OSTCBStkPtr;
@ g) Restore the new task's context from the new task's stack
@ h) Return to new task's code
@
@ 3) Upon entry:
@ OSTCBCur points to the OS_TCB of the task to suspend
@ OSTCBHighRdy points to the OS_TCB of the task to resume
@*********************************************************************************************************
.text
.arm
.align 2
.func OSCtxSw
OSCtxSw:
@ SAVE CURRENT TASK'S CONTEXT
STR LR, [SP, #-4]! @ Return address
STR LR, [SP, #-4]!
STR R12, [SP, #-4]!
STR R11, [SP, #-4]!
STR R10, [SP, #-4]!
STR R9, [SP, #-4]!
STR R8, [SP, #-4]!
STR R7, [SP, #-4]!
STR R6, [SP, #-4]!
STR R5, [SP, #-4]!
STR R4, [SP, #-4]!
STR R3, [SP, #-4]!
STR R2, [SP, #-4]!
STR R1, [SP, #-4]!
STR R0, [SP, #-4]!
MRS R4, CPSR @ push current CPSR
STR R4, [SP, #-4]!
LDR R4, OS_TCBCur_Addr @ OSTCBCur->OSTCBStkPtr = SP;
LDR R5, [R4]
STR SP, [R5]
BL OSTaskSwHook @ OSTaskSwHook();
LDR R4, OS_PrioCur_Addr @ OSPrioCur = OSPrioHighRdy
LDR R5, OS_PrioHighRdy_Addr
LDRB R6, [R5]
STRB R6, [R4]
LDR R4, OS_TCBCur_Addr @ OSTCBCur = OSTCBHighRdy;
LDR R6, OS_TCBHighRdy_Addr
LDR R6, [R6]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -