?? os_cpu_a.s
字號:
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1992-2003, Micrium, Inc., Weston, FL
; (c) Copyright 2003, JIDEC Consultants, Sherbrooke, QC
; All Rights Reserved
;
; ARM7 Port
; Sharp LH79520
; GNU C Compiler
; File : OS_CPU_A_GNU.S
; Originally by: Jean J. Labrosse
; Modified by : Jean-Denis Hatier
;
;********************************************************************************************************
NO_INT EQU 0xC0 ; Mask used to disable interrupts (Both FIQ and IRQ)
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
AREA |subr|, CODE, READONLY
IMPORT OSRunning
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSIntEnter
IMPORT OSIntExit
IMPORT OSTaskSwHook
EXPORT OSStartHighRdy
OSStartHighRdy
BL OSTaskSwHook ; Call user defined task switch hook
LDR R4,=OSRunning ; OSRunning = TRUE
MOV R5,#1
STRB R5,[R4]
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 CPSR
MSR CPSR_cxsf,R4
LDMFD SP!,{R0-R12,LR,PC} ; pop new task's R0-R12,LR & PC
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From task level)
;
; Note(s): Upon entry:
; OSTCBCur points to the OS_TCB of the task to suspend
; OSTCBHighRdy points to the OS_TCB of the task to resume
;*********************************************************************************************************
EXPORT OSCtxSw
EXPORT OS_CtxSW
OSCtxSw
STMFD SP!,{LR} ; push pc (lr should 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
OS_CtxSW
LDR R4,=OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR R5,=OSPrioHighRdy
LDRB R6,[r5]
STRB R6,[r4]
LDR R4,=OSTCBCur ; Get current task's OS_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's OS_TCB address
LDR R6,[R6]
LDR SP,[R6] ; get new task's stack pointer
STR R6,[R4] ; OSTCBCur = OSTCBHighRdy
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
;*********************************************************************************************************
; 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 OS_CPU_SaveSR(void);
; void OS_CPU_RestoreSR(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"
;*********************************************************************************************************
EXPORT OS_CPU_SaveSR
OS_CPU_SaveSR
MRS R0,CPSR ; Set IRQ and FIQ bits in CPSR to disable all interrupts
ORR R1,R0,#NO_INT
MSR CPSR_c,R1
MOV PC,LR ; Disabled, return the original CPSR contents in R0
EXPORT OS_CPU_RestoreSR
OS_CPU_RestoreSR
MSR CPSR_c,R0
MOV PC,LR
EXPORT Enable_CPU_Inter
Enable_CPU_Inter
MRS R3,CPSR
BIC R3,R3,#0x80
MSR CPSR_c,R3
MOV PC,LR
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -