?? 復(fù)件 os_cpu_asm.s
字號:
;//*********************************************************************************************************
;// uC/OS-II
;// The Real-Time Kernel
;//
;// (c) Copyright 1992-2003, Jean J. Labrosse, Weston, FL
;// All Rights Reserved
;//
;// ARM920T Port
;// ADS v1.2 Compiler
;// Samsung S3C2440A
;//
;// File : os_cpu_a.s refrence to ucos application note for arm AN-1014
;// Des : S3C2440 uC/OS-II Port
;// by : tangxiaofeng xidian 503
;// History :
;// OSCtxSw(), OSIntCtxSw() OSStartHighRdy() OS_CPU_IRQ_ISR() OSTickISR()
;//******************************************************************************************************** */
SRCPND EQU 0x4a000000 ;// Source pending
INTPND EQU 0x4a000010 ;// Interrupt request status
rEINTPEND EQU 0x560000a8
INTOFFSET EQU 0x4a000014
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;//*********************************************************************************************************
;// EXPORT and EXTERNAL REFERENCES
;//*********************************************************************************************************/
IMPORT OSRunning
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSIntNesting
IMPORT OSIntEnter
IMPORT OSIntExit
IMPORT OSTaskSwHook
IMPORT OSTimeTick
IMPORT HandleEINT0
EXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSTickISR
EXPORT OSIntCtxSw
EXPORT OSCPUSaveSR
EXPORT OSCPURestoreSR
;// EXPORT OS_CPU_IRQ_ISR
AREA UCOS_ARM, CODE, READONLY
;//*********************************************************************************************************
;// START MULTITASKING
;// void OSStartHighRdy(void)
;//
;// The stack frame is assumed to look as follows:
;//
;// Entry Point(Task Name) (High memory)
;// LR(R14)
;// R12
;// R11
;// R10
;// R9
;// R8
;// R7
;// R6
;// R5
;// R4
;// R3
;// R2
;// R1
;// R0 : argument
;// OSTCBHighRdy->OSTCBStkPtr --> CPSR (Low memory)
;//
;// Note : OSStartHighRdy() MUST:
;// a) Call OSTaskSwHook() then,
;// b) Set OSRunning to TRUE,
;// c) Switch to the highest priority task.
;//********************************************************************************************************** */
OSStartHighRdy
;//----------------------------------------------------------------------------------
;// OSRunning = TRUE;//
;//----------------------------------------------------------------------------------
;//MSR CPSR_cxsf,#SVCMODE|NOINT ;//Switch to SVC mode with IRQ&FIQ disable
BL OSTaskSwHook ;//Call user define Task switch hook
LDR R0, =OSRunning ;// OSRunning =TRUE
MOV R1, #1
STRB R1, [R0]
;//----------------------------------------------------------------------------------
;// SP = OSTCBHighRdy->OSTCBStkPtr;//
;//----------------------------------------------------------------------------------
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR SP, [R0]
;//----------------------------------------------------------------------------------
;// Prepare to return to proper mode
;//----------------------------------------------------------------------------------
LDMFD SP!, {R0}
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^
;//**********************************************************************************************************
;// PERFORM A CONTEXT SWITCH (From task level)
;// void OSCtxSw(void)
;//
;// Note(s): 1) Upon entry:
;// OSTCBCur points to the OS_TCB of the task to suspend
;// OSTCBHighRdy points to the OS_TCB of the task to resume
;//
;// 2) The stack frame of the task to suspend looks as follows:
;//
;// PC (High memory)
;// LR(R14)
;// R12
;// R11
;// R10
;// R9
;// R8
;// R7
;// R6
;// R5
;// R4
;// R3
;// R2
;// R1
;// R0
;// OSTCBCur->OSTCBStkPtr ----> CPSR (Low memory)
;//
;//
;// 3) The stack frame of the task to resume looks as follows:
;//
;// PC (High memory)
;// LR(R14)
;// R12
;// R11
;// R10
;// R9
;// R8
;// R7
;// R6
;// R5
;// R4
;// R3
;// R2
;// R1
;// R0
;// OSTCBHighRdy->OSTCBStkPtr ----> CPSR (Low memory)
;//*********************************************************************************************************/
OSCtxSw
STMFD SP!, {LR} ;//PC
STMFD SP!, {R0-R12, LR} ;//R0-R12 LR
MRS R0, CPSR ;//Push CPSR
STMFD SP!, {R0}
;//----------------------------------------------------------------------------------
;// OSTCBCur->OSTCBStkPtr = SP
;//----------------------------------------------------------------------------------
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 SP, [R0]
;//----------------------------------------------------------------------------------
;//Restore New task context
;//----------------------------------------------------------------------------------
LDMFD SP!, {R0} ;//POP CPSR
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^
;//*********************************************************************************************************
;// TICK HANDLER
;//
;// Description:
;// This handles all the Timer0(INT_TIMER0) interrupt which is used to generate the uC/OS-II tick.
;//*********************************************************************************************************/
OSTickISR
MOV R5,LR
MOV R1, #1
MOV R1, R1, LSL #10 ;// Timer0 Source Pending Reg.
LDR R0, =SRCPND
LDR R2, [R0]
ORR R1, R1,R2
STR R1, [R0]
LDR R0, =INTPND
LDR R1, [R0]
STR R1, [R0]
;//----------------------------------------------------------------------------------
;// OSTimeTick();//
;//----------------------------------------------------------------------------------
BL OSTimeTick
MOV PC, R5 ;// Return
;//*********************************************************************************************************
;// 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:
;//
;// PC (High memory)
;// LR(R14)
;// R12
;// R11
;// R10
;// R9
;// R8
;// R7
;// R6
;// R5
;// R4
;// R3
;// R2
;// R1
;// R0
;//
;// OSTCBCur->OSTCBStkPtr ----> CPSR (Low memory)
;//
;//
;// 3) The stack frame of the task to resume looks as follows:
;//
;// PC (High memory)
;// LR(R14)
;// R12
;// R11
;// R10
;// R9
;// R8
;// R7
;// R6
;// R5
;// R4
;// R3
;// R2
;// R1
;// R0
;// OSTCBHighRdy->OSTCBStkPtr ----> CPSR (Low memory)
;//*********************************************************************************************************/
OSIntCtxSw
;//----------------------------------------------------------------------------------
;// Call 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]
;//----------------------------------------------------------------------------------
;// SP = OSTCBHighRdy->OSTCBStkPtr;//
;//----------------------------------------------------------------------------------
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR SP, [R0]
;//----------------------------------------------------------------------------------
;// Restore New Task context
;//----------------------------------------------------------------------------------
LDMFD SP!, {R0} ;//POP CPSR
MSR SPSR_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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -