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

📄 os_cpu_a.s

📁 最近移植在s3c44b0x上的最新的ucos v2.85版本
💻 S
字号:
;****************************************************************************
; Name		 : OS_CPU_A.S									                *
; Modified	 : xuwei        2007-09-07  			                        *
; Description: 用汇编语言编写与处理器相关的函数,至少包括以下四个函数:     *
;			   OSStartHighRdy();											*
;			   OSCtxSw():													*
;			   OSIntCtxSw();												*
;			   OSTickISR();													*
;****************************************************************************
BIT_TIMER5	EQU		(0x1<<8)
I_ISPC		EQU		0x1e00024
INTMSK		EQU		0x1e0000c

	AREA	|subr|, CODE, READONLY
	
	IMPORT	OSTCBCur
addr_OSTCBCur		DCD	OSTCBCur
	IMPORT	OSTCBHighRdy
addr_OSTCBHighRdy	DCD	OSTCBHighRdy
	IMPORT	OSPrioCur
addr_OSPrioCur		DCD	OSPrioCur
	IMPORT	OSPrioHighRdy
addr_OSPrioHighRdy	DCD	OSPrioHighRdy	
	
	IMPORT  OSRunning

	IMPORT	OSIntEnter
	IMPORT	OSIntExit
	IMPORT	OSTimeTick
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: 	OSStartHighRdy																			;
; Purpose:		该函数由OSStart()函数调用,功能是让进入就绪态的优先级最高的任务运行						;
; Processing:	See uC/OS-II Task Level Context Switch flow chart										;
; Parameters: 	void																					;
; Outputs:  	None																					;
; Returns:  	void																					;
; Notes:		在调用OSStart()之前,必须先调用OSInit()函数,且已经建立了至少一个任务					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	EXPORT	OSStartHighRdy
OSStartHighRdy
	LDR		r0, =OSRunning			; OSRunning = 1
	MOV		r1, #1
	STRB	r1, [r0]
	
	LDR		r5, addr_OSTCBHighRdy	; Get highest priority task TCB address

	LDR		r5, [r5]				; get stack pointer
	LDR		sp, [r5]				; switch to the new stack

	LDMFD	sp!, {r4}				; get new state from top of the stack
	MSR		CPSR_cxsf, r4			; CPSR should be SVC32Mode
	LDMFD	sp!, {r0-r12, lr, pc }	; start the new task

	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: 	OS_TASK_SW 																				;
; Purpose: 		实现任务上下文切换										;
; Processing:	See uC/OS-II Task Level Context Switch flow chart										;
; Parameters:	void																					;
; Outputs:  	None																					;
; Returns:		void																					;
; Notes:		The whole function is executed in CRITICAL state. See OSSched().						;
;																										;
; 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
OSCtxSw
	STMFD	sp!, {lr}				; save pc
	STMFD	sp!, {lr}				; save lr
	STMFD	sp!, {r0-r12}			; save register file and ret address
	MRS		r4, CPSR
	STMFD	sp!, {r4}				; save CPSR
		
	LDR		r4, addr_OSTCBCur		; 在当前任务的任务控制块中保存当前任务的堆栈指针
	LDR		r5, [r4]
	STR		sp, [r5]				; 

	LDR		r4, addr_OSPrioCur		; OSPrioCur = OSPrioHighRdy
	LDR		r5, addr_OSPrioHighRdy
	LDRB	r6, [r5]
	STRB	r6, [r4]
	
	LDR		r4, addr_OSTCBHighRdy	; OSTCBCur = OSTCBHighRdy
	LDR		r5, addr_OSTCBCur	
	LDR		r4, [r4]
	STR		r4, [r5] 

	LDR		sp, [r4]				; 从新任务的任务控制块中弹出堆栈指针
	LDMFD	sp!, {r4}				; 
	MSR		CPSR_cxsf, r4			; 
	LDMFD	sp!, {r0-r12, lr, pc}	; 弹出处理器所有寄存器值


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: 	OSIntCtxSW 																				;
; Purpose: 		在ISR中实现任务切换功能,假定所有处理器寄存器都已被正确地保存到了被中断任务的堆栈中		;
; Processing:	See uC/OS-II Interrupt Level Context Switch flow chart									;
; Parameters:	void																					;
; Outputs:  	None																					;
; Returns:		void																					;
; Notes:		The whole function is executed in CRITICAL state. See OSIntExit().						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	EXPORT 	OSIntCtxSw
OSIntCtxSw
	LDR		r6, addr_OSPrioHighRdy	;OSPrioCur = OSPrioHighRdy
	LDR		r5, addr_OSPrioCur	
	LDRB	r6, [r6]
	STRB	r6, [r5]			

	
	LDR		r4, addr_OSTCBHighRdy	;OSTCBCur = OSTCBHighRdy
	LDR		r5, addr_OSTCBCur	
	LDR		r4, [r4]
	STR		r4, [r5] 

	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:		Timer5 Interrupt Sever																	;
; Processing:	Call OSTimeTick																			;
; Parameters: 	void																					;
; Outputs:		None																					;
; Returns:		void																					;
; Notes:																								;					
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LINK_SAVE	DCD		0
PSR_SAVE	DCD		0

	EXPORT 	OSTickISR
OSTickISR
	STMFD	sp!, {r4}				 ; 先保存寄存器r4
	LDR		r4, =LINK_SAVE
	STR		lr, [r4]				 ; 将lr保存在LINK_SAVE中
	MRS		lr,	spsr				 ; lr = spsr
	STR		lr, [r4, #4]			 ; 将spsr_irq保存在PSR_SAVE中
	LDMFD	sp!, {r4}				 ; 寄存器r4出栈
	ORR		lr, lr,	#0x80			 ; 将spsr_irq中IRQ位禁止
	MSR		cpsr_cxsf, lr 			 ; 将当前程序状态寄存器CPSR中IRQ位禁止

	SUB		sp, sp, #4				 ; Space for PC寄存器
	STMFD	sp!, {r0-r12, lr}		 ; 将除PC外的所有处理器寄存器入栈
	LDR		r4, =LINK_SAVE
	LDR		lr, [r4, #0]
	SUB		lr, lr, #4				 ; lr中保存的值为PC+4
	STR		lr, [sp, #(14*4)]		 ; PC寄存器入栈
	LDR		r4, [r4, #4]			 ; r4 = PSR_SAVE,
	STMFD	sp!, {r4}		         ; spsr_irq最后入栈

	LDR		r4, addr_OSTCBCur		 ; 将保存好的堆栈指针保存到被中断任务的任务块中
	LDR		r4, [r4]
	STR		sp, [r4]

	LDR		r0, =I_ISPC				 ; 必须手动清除中断pending位
	LDR		r1, =BIT_TIMER5
	STR		r1, [r0]
	
	BL	OSIntEnter
	BL 	OSTimeTick
	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
	MRS		r0, cpsr
	STMFD	sp!, {r0}	         	; push current PSR
	ORR		r0, r0, #0xC0
	MSR		cpsr_c, r0		 		; disable IRQ Int s
	MOV	pc, lr

	EXPORT 	ARMEnableInt
ARMEnableInt
	LDMFD	sp!, {r0}				; pop current PSR
	MSR		cpsr_c, r0				; restore original cpsr	
	MOV		pc, lr
		
	END
	

⌨️ 快捷键说明

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