?? os_cpu_a.s
字號:
;
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
;
; (c) Copyright 1992-2006, Micrium, Weston, FL
; All Rights Reserved
;
; Generic ARM Port
;
; File : OS_CPU_A.ASM
; Version : V1.81
; By : Jean J. Labrosse
; Jean-Denis Hatier
;
; For : ARM7 or ARM9
; Mode : ARM or Thumb
; Toolchain : ADS1.2
;/********************************************************************************************************
; Modified by : ZengFan
; Modified date : 2009/03/30
; Descriptions : 該文件是參考ucos官方的移植文件,并根據編譯器不同和目標處理器不同做了部分修改
;********************************************************************************************************/
;
;********************************************************************************************************
; IMPORT / EXPORT FUNCTIONS
;/********************************************************************************************************
;從IAR移植到ADS的時候需要注意,二者對于外部全局變量和外部函數的聲明以及內部函數的定義方式
;是不同的,所以移植的時候需要修改 ................................................zf
;********************************************************************************************************/
IMPORT OSRunning
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSIntNesting
IMPORT OSIntExit
IMPORT OSTaskSwHook
IMPORT OS_CPU_ExceptHndlr
; Functions declared in this file
EXPORT OS_CPU_SR_Save
EXPORT OS_CPU_SR_Restore
EXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSIntCtxSw ;?ZF
; Functions related to exception handling
EXPORT OS_CPU_ARM_ExceptResetHndlr
EXPORT OS_CPU_ARM_ExceptUndefInstrHndlr
EXPORT OS_CPU_ARM_ExceptSwiHndlr
EXPORT OS_CPU_ARM_ExceptPrefetchAbortHndlr
EXPORT OS_CPU_ARM_ExceptDataAbortHndlr
EXPORT OS_CPU_ARM_ExceptAddrAbortHndlr
EXPORT OS_CPU_ARM_ExceptIrqHndlr
EXPORT OS_CPU_ARM_ExceptFiqHndlr
;********************************************************************************************************
; EQUATES
;********************************************************************************************************
OS_CPU_ARM_CONTROL_INT_DIS EQU 0xC0 ; Disable both FIQ and IRQ
OS_CPU_ARM_CONTROL_FIQ_DIS EQU 0x40 ; Disable FIQ
OS_CPU_ARM_CONTROL_IRQ_DIS EQU 0x80 ; Disable IRQ
OS_CPU_ARM_CONTROL_THUMB EQU 0x20 ; Set THUMB mode
OS_CPU_ARM_CONTROL_ARM EQU 0x00 ; Set ARM mode
OS_CPU_ARM_MODE_MASK EQU 0x1F
OS_CPU_ARM_MODE_USR EQU 0x10
OS_CPU_ARM_MODE_FIQ EQU 0x11
OS_CPU_ARM_MODE_IRQ EQU 0x12
OS_CPU_ARM_MODE_SVC EQU 0x13
OS_CPU_ARM_MODE_ABT EQU 0x17
OS_CPU_ARM_MODE_UND EQU 0x1B
OS_CPU_ARM_MODE_SYS EQU 0x1F
OS_CPU_ARM_EXCEPT_RESET EQU 0x00
OS_CPU_ARM_EXCEPT_UNDEF_INSTR EQU 0x01
OS_CPU_ARM_EXCEPT_SWI EQU 0x02
OS_CPU_ARM_EXCEPT_PREFETCH_ABORT EQU 0x03
OS_CPU_ARM_EXCEPT_DATA_ABORT EQU 0x04
OS_CPU_ARM_EXCEPT_ADDR_ABORT EQU 0x05
OS_CPU_ARM_EXCEPT_IRQ EQU 0x06
OS_CPU_ARM_EXCEPT_FIQ EQU 0x07
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
AREA OSKernelSchedular, CODE, READONLY
;*********************************************************************************************************
; 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 functions that need to
; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
; into the CPU status register.
;
; Prototypes : OS_CPU_SR OS_CPU_SR_Save (void);
; void OS_CPU_SR_Restore (OS_CPU_SR os_cpu_sr);
;
;
; Note(s) : (1) These functions are used in general like this:
;
; void Task (void *p_arg)
; {
; /* Allocate storage for CPU status register. */
; #if (OS_CRITICAL_METHOD == 3)
; OS_CPU_SR os_cpu_sr;
; #endif
;
; :
; :
; OS_ENTER_CRITICAL(); /* os_cpu_sr = OS_CPU_SR_Save(); */
; :
; :
; OS_EXIT_CRITICAL(); /* OS_CPU_SR_Restore(cpu_sr); */
; :
; :
; }
;
; (2) OS_CPU_SR_Restore() is implemented as recommended by Atmel application note:
;
; "Disabling Interrupts at Processor Level"
;*********************************************************************************************************
OS_CPU_SR_Save
MRS R0, CPSR
OS_CPU_SR_Save_Loop
; Set IRQ and FIQ bits in CPSR to disable all interrupts
ORR R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS
MSR CPSR_c, R1
MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags
AND R1, R1, #OS_CPU_ARM_CONTROL_INT_DIS
CMP R1, #OS_CPU_ARM_CONTROL_INT_DIS
BNE OS_CPU_SR_Save_Loop ; Not properly disabled (try again)
BX LR ; Disabled, return the original CPSR contents in R0
OS_CPU_SR_Restore ; See Note #2
MSR CPSR_c, R0
BX LR
;*********************************************************************************************************
; 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.
;*********************************************************************************************************
OSStartHighRdy
; Change to SYS mode
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
LDR R0, =OSRunning ; OSRunning = TRUE;
MOV R1, #1
STRB R1, [R0]
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
; SWITCH TO HIGHEST PRIORITY TASK
LDR R0, =OSTCBHighRdy ; Get highest priority task TCB address
LDR R0, [R0] ; get stack pointer
LDR SP, [R0] ; switch to the new stack
LDR R0, [SP], #4 ; pop new task CPSR
MSR CPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC} ; pop new task context
;*********************************************************************************************************
; 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 context onto the current task stack
; b) OSTCBCur->OSTCBStkPtr = SP;
; c) OSTaskSwHook();
; d) OSPrioCur = OSPrioHighRdy;
; e) OSTCBCur = OSTCBHighRdy;
; f) SP = OSTCBHighRdy->OSTCBStkPtr;
; g) Restore the new task context from the new task stack
; h) Return to new task 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
;*********************************************************************************************************
OSCtxSw
; SAVE CURRENT TASK CONTEXT
STMFD SP!, {LR} ; Push return address
STMFD SP!, {LR}
STMFD SP!, {R0-R12} ; Push registers
MRS R0, CPSR ; Push current CPSR
TST LR, #1 ; See if called from Thumb mode
ORRNE R0, R0, #OS_CPU_ARM_CONTROL_THUMB ; If yes, Set the T-bit
STMFD SP!, {R0}
LDR R0, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R1, [R0]
STR SP, [R1]
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK CONTEXT
LDMFD SP!, {R0} ; Pop new task CPSR
MSR CPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC} ; Pop new task context
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
;
; Note(s) : 1) OSIntCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
;
; 2) The pseudo-code for OSCtxSw() is:
; a) OSTaskSwHook();
; b) OSPrioCur = OSPrioHighRdy;
; c) OSTCBCur = OSTCBHighRdy;
; d) SP = OSTCBHighRdy->OSTCBStkPtr;
; e) Restore the new task context from the new task stack
; f) Return to new task 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
;*********************************************************************************************************
;/********************************************************************************************************
; OSIntCtxSw函數是被中斷異常處理函數調用,在調用它之前已經對當前任務進行了保護,在這里只需要恢復高優先級
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -