⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.s

📁 s3c44b0x上实现的ucos+tftp
💻 S
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
;                                          All Rights Reserved
;
; File : OS_CPU_A.ASM
; By   : Jean J. Labrosse
;********************************************************************************************************

;********************************************************************************************************
;                                               ARM Port
;
;                 Target           : ARM (Includes ARM7, ARM9)
;                 Ported by        : Michael Anburaj
;                 URL              : http://geocities.com/michaelanburaj/    Email : michaelanburaj@hotmail.com
;
;********************************************************************************************************
				
        AREA  UCOS_ARM, CODE, READONLY

;*********************************************************************************************************
;                                          START MULTITASKING
;                                       void OSStartHighRdy(void)
;
; Note : OSStartHighRdy() MUST:
;           a) Call OSTaskSwHook() then,
;           b) Set OSRunning to TRUE,
;           c) Switch to the highest priority task.
;*********************************************************************************************************
				
        IMPORT  OSTaskSwHook
        IMPORT  OSRunning
        IMPORT  OSTCBHighRdy

        EXPORT  OSStartHighRdy

OSStartHighRdy  

        bl OSTaskSwHook             ; Call user defined task switch hook

        ldr r4,=OSRunning           ; Indicate that multitasking has started
        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 psr
        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)
;                                           void OSCtxSw(void)
;
; 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
;
;*********************************************************************************************************

        IMPORT  OSTCBCur
        IMPORT  OSTaskSwHook
        IMPORT  OSTCBHighRdy
        IMPORT  OSPrioCur
        IMPORT  OSPrioHighRdy

        EXPORT  OSCtxSw

OSCtxSw
; Special optimised code below:
        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

        ; OSPrioCur = OSPrioHighRdy
        ldr r4,=OSPrioCur
        ldr r5,=OSPrioHighRdy
        ldrb r6,[r5]
        strb r6,[r4]
        
        ; Get current task TCB address
        ldr r4,=OSTCBCur
        ldr r5,[r4]
        str sp,[r5]                 ; store sp in preempted tasks's TCB

        bl OSTaskSwHook             ; call Task Switch Hook

        ; Get highest priority task TCB address
        ldr r6,=OSTCBHighRdy
        ldr r6,[r6]
        ldr sp,[r6]                 ; get new task's stack pointer

        ; OSTCBCur = OSTCBHighRdy
        str r6,[r4]                 ; set new current task TCB address

        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: 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 OSTaskSwHook

OSIntCtxSw
		BL		OSTaskSwHook
		
		LDR		r4, =OSTCBHighRdy
		LDR		r4, [r4]
		LDR		r5, =OSTCBCur
		STR		r4, [r5]				 ; OSTCBCur = OSTCBHighRdy

		LDR		r6, =OSPrioHighRdy
		LDRB	r6, [r6]
		LDR		r5, =OSPrioCur
		STRB	r6, [r5]				 ; OSPrioCur = OSPrioHighRdy

		LDR		sp, [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:		OSTickISR																				;
; Purpose:		Timer0 Interrupt Sever																	;
; Processing:	Call OSTimeTick																			;
; Parameters: 	void																					;
; Outputs:		None																					;
; Returns:		void																					;
; Notes:																								;					
;*********************************************************************************************************
	EXPORT 	OSTickISR
	IMPORT	OSIntEnter
	IMPORT	OSTimeTick
	IMPORT	tick_hook	
	IMPORT	OSIntExit
	IMPORT	printa
	IMPORT	printb
	IMPORT	printc

LINK_SAVE	DCD		0
PSR_SAVE	DCD		0

OSTickISR
	STMFD	sp!, {r4}
	
	LDR		r4, =LINK_SAVE
	STR		lr, [r4]				 ; LINK_SAVE = lr_irq

	MRS		lr,	spsr
	STR		lr, [r4, #4]			 ; PSR_SAVE = spsr_irq
	
	LDMFD	sp!, {r4}
		
	ORR		lr, lr,	#0x80			 ; Mask irq for context switching before 
	MSR		cpsr_cxsf, lr 			 ; returning back from irq mode.

	SUB		sp, sp, #4				 ; Space for PC
	STMFD	sp!, {r0-r12, lr}

	LDR		r4, =LINK_SAVE
	LDR		lr, [r4, #0]
	SUB		lr, lr, #4				 ; lr = LINK_SAVE - 4,
	STR		lr, [sp, #(14*4)]		 ; the return address for pc.

	LDR		r4, [r4, #4]			 ; r4 = PSR_SAVE,
	STMFD	sp!, {r4}		         ; CPSR of the task
 
	LDR		r4, =OSTCBCur
	LDR		r4, [r4]
	STR		sp, [r4]				 ; OSTCBCur -> stkptr = sp
	
	BL	OSIntEnter
	BL 	OSTimeTick	
	BL	tick_hook  	                 ; here do_IRQ is used to clear some virtual-hardware flags
	BL	OSIntExit

	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:		RTL8019ISR																				;
; Purpose:		EINT1 Interrupt Sever																	;
; Processing:	Call RTL8019ISR																			;
; Parameters: 	void																					;
; Outputs:		None																					;
; Returns:		void																					;
; Notes:																								;					
;*********************************************************************************************************
	EXPORT 	RTL8019ISR
	IMPORT	rtl_hook
	IMPORT	OSIntEnter
	IMPORT	OSIntExit
	IMPORT	rtl8019_print
	
LINK_SAVE2	DCD		0
PSR_SAVE2	DCD		0

RTL8019ISR
	STMFD	sp!, {r4}
	
	LDR		r4, =LINK_SAVE2
	STR		lr, [r4]				 ; LINK_SAVE = lr_irq

	MRS		lr,	spsr
	STR		lr, [r4, #4]			 ; PSR_SAVE = spsr_irq
	
	LDMFD	sp!, {r4}
		
	ORR		lr, lr,	#0x80			 ; Mask irq for context switching before 
	MSR		cpsr_cxsf, lr 			 ; returning back from irq mode.

	SUB		sp, sp, #4				 ; Space for PC
	STMFD	sp!, {r0-r12, lr}

	LDR		r4, =LINK_SAVE2
	LDR		lr, [r4, #0]
	SUB		lr, lr, #4				 ; lr = LINK_SAVE - 4,
	STR		lr, [sp, #(14*4)]		 ; the return address for pc.

	LDR		r4, [r4, #4]			 ; r4 = PSR_SAVE,
	STMFD	sp!, {r4}		         ; CPSR of the task
 
	LDR		r4, =OSTCBCur
	LDR		r4, [r4]
	STR		sp, [r4]				 ; OSTCBCur -> stkptr = sp
	
	BL	OSIntEnter		
	BL	rtl_hook
	BL 	rtl8019_print
	BL	OSIntExit

	LDMFD 	sp!, {r4}                ; pop new task cpsr
	MSR 	cpsr_cxsf, r4
	LDMFD 	sp!, {r0-r12,lr,pc}      ; pop new task r0-r12,lr & pc
	
;*********************************************************************************************************
; 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}
	MRS		r0, CPSR
	ORR		r0, r0, #0xC0
	MSR		cpsr_cxsf, r0		 		; disable IRQ Int s
	LDMIA	sp!, {r0}
	MOV	pc, lr

	EXPORT 	ARMEnableInt
ARMEnableInt
	STMDB	sp!, {r0}
	MRS	r0, CPSR
	BIC	r0, r0, #0xC0
	MSR	CPSR_cxsf, r0
	LDMIA	sp!, {r0}
	MOV		pc, lr

        END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -