www.pudn.com > S3C2440_uCos-II.rar > os_cpu_a.s


;********************************************************************/ 
      AREA	|subr|, CODE, READONLY 
 
;/*********************************************************************** 
; 
; Function: OSStartHighRdy 
; 
; Purpose: 
; 	   To start the task with the highest priority during OS startup 
; 
; Processing: 
;    See uC/OS-II Task Level Context Switch flow chart 
; 
; Parameters: void 
; 
; Outputs:  None 
; 
; Returns:  void 
; 
; Notes: 
;   Called once during OSStart() 
; 
;*********************************************************************/ 
	EXPORT 	OSStartHighRdy 
	IMPORT	OSTaskSwHook 
	IMPORT  OSTCBHighRdy  
	IMPORT  OSRunning 
 
OSStartHighRdy 
        BL 	    OSTaskSwHook             ; Call user-defined hook function 
 
        LDR 	r4,=OSRunning            ; Indicate that multitasking has started 
        MOV 	r5, #1                    
        STRB 	r5, [r4]                 ; OSRunning = true 
 
        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_cxsf 
        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 
 
 	 
;/*********************************************************************** 
; 
; Function: OS_TASK_SW  
; 
; Purpose: 
; 	To perform a context switch from the Task Level. 
; 
; Processing: 
;    See uC/OS-II Task Level Context Switch flow chart 
; 
; Parameters: void 
; 
; Outputs:  None 
; 
; Returns:  void 
; 
; Notes: 
;   On entry, OSTCBCur and OSPrioCur hold the current TCB and priority 
;   and OSTCBHighRdy and OSPrioHighRdy contain the same for the task 
;   to be switched to. 
;  
;   The following code assumes that the virtual memory is directly 
;   mapped into  physical memory. If this is not true, the cache must  
;   be flushed at context switch to avoid address aliasing. 
; 
;*********************************************************************/ 
        EXPORT 	OSCtxSw 
        IMPORT	OSPrioCur 
        IMPORT	OSPrioHighRdy 
        IMPORT	OSTCBCur 
        IMPORT	OSTaskSwHook 
        IMPORT	OSTCBHighRdy 
         
OSCtxSw 
        STMFD 	sp!, {lr}                ; push pc (lr is actually 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_cxsf 
 
_OSCtxSw 
        LDR 	r4, =OSPrioCur           ; OSPrioCur = OSPrioHighRdy 
        LDR 	r5, =OSPrioHighRdy 
        LDRB 	r6, [r5] 
        STRB 	r6, [r4] 
         
        LDR 	r4, =OSTCBCur            ; Get current task 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 TCB address 
        LDR 	r6, [r6] 
        LDR 	sp, [r6]                 ; get new task s stack pointer 
 
        STR 	r6, [r4]                 ; set new current task TCB address 
 
        LDMFD 	sp!, {r4}                ; pop new task spsr_cxsf 
        MSR 	spsr_cxsf, r4 
        LDMFD 	sp!, {r4}                ; pop new task cpsr 
        MSR 	cpsr_cxsf, r4 
        LDMFD 	sp!, {r0-r12,lr,pc}      ; pop new task r0-r12,lr & pc 
 
 
;*********************************************************************** 
; 
; Function: OSIntCtxSw 
; 
; Purpose: 
; 	To perform a context switch from the interrupt level. 
; 
; Processing: 
;    See uC/OS-II Interrupt Level Context Switch flow chart 
; 
; Parameters: void 
; 
; Outputs:  None 
; 
; Returns:  void 
; 
; Notes: 
;   Sets up the stacks and registers to call the task level 
;   context switch 
; 
;*********************************************************************/ 
        EXPORT 	OSIntCtxSw 
        IMPORT	OSIntCtxSwFlag 
OSIntCtxSw 
        LDR 	r0, =OSIntCtxSwFlag      ; OSIntCtxSwFlag = true 
        MOV 	r1, #1 
        STR 	r1, [r0] 
         
        MOV 	pc, lr                   ; return  
 
;/*********************************************************************** 
; 
;yangye 2003-2-14 
;changed this function name from OSTickISR to OSISR(it is not a TICK isr) 
; Function: OSISR 
; 
; Purpose: 
; 	   The IRQ interrupt handler 
; 
; Processing: 
;    Saves context 
;    Calls the IRQ dispatcher 
;    Checks if context switch necessary 
;    If not, restores context and returns from interrupt 
;    If switch required, branches without link to IRQContextSwap 
;       which performs context switch if interrupts not nested 
;       and returns from interrupt to new context 
; 
; Parameters: void 
; 
; Outputs:  None 
; 
; Returns:  void 
; 
; Notes: 
;   (1) here we use OSIntCtxSwFlag to indicate a request for int-level  
;       context switch  
;   (2) _IntCtxSw is used to perform a real switch operation 
; 
;*********************************************************************/	 
 
SAVED_LR_SVC	DCD   0x00000000        ; some variables for temparal use 
SAVED_LR_IRQ	DCD   0x00000000 
SAVED_SPSR		DCD	  0x00000000 
SAVED_LR		DCD	  0x00000000 
 
SRCPND       EQU  0x4a000000    ;Interrupt request status 
INTPND       EQU  0x4a000010    ;Interrupt request status 
BIT_TIMER4   EQU  (0x1<<14) 
BIT_TIMER0   EQU  (0x1<<10) 
 
 
	EXPORT 	OSTickISR 
	IMPORT	OSIntEnter 
	IMPORT	OSTimeTick 
	IMPORT	OSIntExit 
	IMPORT	OSIntCtxSwFlag 
	 
OSTickISR 
	STMFD	sp!, {r0-r12, lr}        ; push r0-r12 register file and lr( pc return address ) 
 
	ldr r0,=SRCPND 
	ldr r1,=BIT_TIMER4 
	;ldr r1,=BIT_TIMER0 
	str r1,[r0] 
	 
	ldr r0,=INTPND 
	str r1,[r0] 
	 
	BL	OSIntEnter 
	BL 	OSTimeTick 
	BL	OSIntExit 
    B   OSIntReturn 
	 
    EXPORT  OSIntReturn 
OSIntReturn 
	LDR	    r0, =OSIntCtxSwFlag      ; check if OSIntCtxFlag is marked as true 
	LDR 	r1, [r0] 
	CMP	    r1, #1 
	BEQ	    _IntCtxSw	         ; if OSIntCtxFlag = true, then jump to _IntCtxSw 
 
	LDMIA    sp!,{r0-r12, lr} 
	SUBS	 pc,lr, #4 
 
 
_IntCtxSw 
    MOV 	r1, #0                   ; clear OSIntCtxSwFlag = flase 
    STR 	r1, [r0] 
 
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
    LDMIA    sp!,{r0-r12, lr} 
	SUBS	 lr,lr, #4 
 
	STR		 lr, SAVED_LR		;STR lr, [pc, #SAVED_LR-.-8] 
 
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
	;Change Supervisor mode 
	;!!!r12 register don't preserved. (r12 that PC of task) 
 
	MRS             lr, SPSR 
    AND				lr, lr, #0xFFFFFF00 
    ORR				lr, lr, #0xD3 
	MSR             CPSR_cxsf, lr 
	 
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
	;Now  Supervisor mode 
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
	STR		r12, [sp, #-8]	; saved r12 
	LDR		r12, SAVED_LR	;LDR r12, [pc, #SAVED_LR-.-8] 
	STMFD	sp!, {r12}		; r12 that PC of task 
	SUB		sp, sp, #4		; inclease stack point 
	LDMIA	sp!, {r12}		; restore r12 
	STMFD	sp!, {lr}		; save lr 
	STMFD	sp!, {r0-r12}	; save register file and ret address 
	MRS		r4, CPSR 
    AND		r4, r4, #0xFFFFFF00 
    ORR		r4, r4, #0x53 
         
    STMFD 	sp!, {r4}                ; push current psr 
    STMFD 	sp!, {r4}                ; push spsr_cxsf 
 
	B	_OSCtxSw                 ; jump to _OSCtxSw	 
	 
	 
	 
;/*********************************************************************** 
; 
; Functions: ARMDisableInt 
; 	     ARMEnableInt 
; 
; Purpose: 
;    Disable and enable IRQ and FIQ preserving current CPU mode. 
; 
; Processing: 
;    Push the cpsr onto the stack 
;    Disable IRQ and FIQ interrupts 
;    Return  
; 
; Parameters: void 
; 
; Outputs:  None 
; 
; Returns:  void 
; 
; Notes: 
;   (1) Can be called from SVC mode to protect Critical Sections.  
;   (2) Do not use these calls at interrupt level. 
;   (3) Used in pairs within the same function level; 
;   (4) Will restore interrupt state when called; i.e., if interrupts 
;       are disabled when DisableInt is called, interrupts will still 
;       still be disabled when the matching EnableInt is called. 
;   (5) Uses the method described by Labrosse as "Method 2". 
; 
;*********************************************************************/ 
 
         EXPORT 	ARMDisableInt 
ARMDisableInt 
    STMDB	sp!, {r0-r1,lr} 
	MRS	    r0, cpsr 
    and     r1,r0,#3 
	CMP	    r1, #2 
	BEQ	    __IntUDIS 
 
	ORR	    r0, r0, #0xC0 
 
__IntUDIS 
	MSR	    CPSR_cxsf, r0		     ; disable IRQ Int s 
    LDMIA	sp!, {r0-r1,pc} 
 
 
 
    ;------------------------------------------------------------------------ 
        EXPORT 	ARMEnableInt 
ARMEnableInt 
	STMDB	sp!, {r0-r1,lr} 
	MRS	    r0, cpsr 
    and     r1,r0,#3 
	CMP	    r1, #2 
	BEQ	    __IntUEN 
 
	BIC	    r0, r0, #0x80 
     
 
__IntUEN 
    MSR	    CPSR_cxsf, r0		     ; enable IRQ Int s 
	LDMIA	sp!, {r0-r1,pc} 
 
    ;------------------------------------------------------------------------            
	END