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

📄 os_cpu_a1.s

📁 S3C4510B是arm7内核的芯片
💻 S
字号:
#------------------------------------------------------------------------------
#- File: os_cpu_a.s
#------------------------------------------------------------------------------
#-            (c) Copyright ARM Limited 1999.  All rights reserved. 
#-
#-                              ARM Specific code
#------------------------------------------------------------------------------
#-
#- 
#-	Functions defined in this module:
#-
#-	OS_CPU_SR GetProcST_DisableIntr(void)	disable interrupts when in SVC
#-	void SetProcST(OS_CPU_SR cpu_sr)		enable interrupts when in SVC
#-	void OS_TASK_SWAP(void)		context switch
#-	void OSStartHighRdy(void)	start highest priority task

#################define some constants##############
	.EQU 	NoIRQ,		0x80
	.EQU	INTPEND,	0x03FF4004
	.EQU	BIT_TIMER0,	(0x1<<10)

	.EQU	SVC32Mode,	0x13
	.EQU	IRQ32Mode,	0x12
	.EQU	FIQ32Mode,	0x11

#	AREA	|subr|, CODE, READONLY

######## External symbols we need the addresses of##########
#			.EXTERN	OSTCBCur
#addr_OSTCBCur:		.LONG	OSTCBCur
#			.EXTERN	OSTCBHighRdy
#addr_OSTCBHighRdy:	.LONG	OSTCBHighRdy
#			.EXTERN	OSPrioCur
#addr_OSPrioCur:		.LONG	OSPrioCur
#			.EXTERN	OSPrioHighRdy
#addr_OSPrioHighRdy:	.LONG	OSPrioHighRdy
#			.EXTERN OSRunning
#addr_OSRunning:		.LONG	OSRunning
#			.EXTERN OSIntNesting
#addr_OSIntNesting:	.LONG	OSIntNesting

#########declare all external variables and functions#########
#	.extern OSIntEnter
#	.extern OSIntExit
#	.extern	OSTimeTick
	

#############all functions realized###############

	.GLOBAL Timer0IRQHandler
Timer0IRQHandler:				@ 中断向量
	.extern	TickHandler
#	SUBS	lr,lr,#4
#	STMFD	sp!,{lr}
#	ADD		lr,lr,#4
	STMFD	sp!, {r0-r12, lr}	@ 中断栈保存 
	MRS	r4, CPSR
	STMFD	sp!, {r4}		@ save current PSR
	MRS	r4, SPSR			@ YYY+
	STMFD	sp!, {r4}		@ YYY+ save SPSR

	#(Clear pending bit of INTPEND that don't accessed it.)
	#	rI_ISPC= BIT_TIMER0;
	LDR	r0, =INTPEND
	LDR	r1, =BIT_TIMER0
	STR	r1, [r0]
	



	#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	#Change Supervisor mode
	#!!!r12 register don't preserved. (r12 that PC of task)

#	MRS             lr, SPSR
#	AND				lr, lr, #0xFFFFFFE0
#	ORR				lr, lr, #0x13
#	MSR             CPSR_cxsf, lr


#	BL	TickHandler			@ 中断C处理函数

	BL	OSIntEnter
	
	#OSIntNesting == 1?
	LDR 	r4, addr_OSIntNesting
	LDR	r5,[r4]
	CMP		r5, #1
	LDRNE	pc, =INTRNESTING

	# Get current task TCB address 
	#and store sp to preempted tasks's TCB
#	LDR	r4, addr_OSTCBCur
#	LDR	r5, [r4]
#	STR	sp, [r5]		@ store sp in preempted tasks's TCB

#INTRNESTING:

#	BL	OSTimeTick

#	BL	OSIntExit

_NOCTXSW:
	LDMFD	sp!, {r4}		@ YYY+
	MSR	SPSR_cxsf, r4		@ YYY+
	LDMFD	sp!, {r4}		@ YYY+
	MSR	CPSR_cxsf, r4		@ YYY+
	LDMFD	sp!, {r0-r12, lr,pc}	@ 恢复中断栈

#	.GLOBAL	OSIntCtxSw
#OSIntCtxSw:
	#BL	OSTaskSwHook

	#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	#Change Supervisor mode
	#!!!r12 register don't preserved. (r12 that PC of task)
#	MRS             lr, SPSR
#	AND				lr, lr, #0xFFFFFFE0
#	ORR				lr, lr, #0x13
#	MSR             CPSR_cxsf, lr

	##############################
	#now lay in supervisor mode
	##############################
	# OSPrioCur = OSPrioHighRdy
#	LDR	r4, addr_OSPrioCur
#	LDR	r5, addr_OSPrioHighRdy
#	LDRB	r6, [r5]
#	STRB	r6, [r4]
	
	# Get current task TCB address
#	LDR	r4, addr_OSTCBCur
	# Get highest priority task TCB address
#	LDR	r6, addr_OSTCBHighRdy
#	LDR	r6, [r6]

	# OSTCBCur = OSTCBHighRdy
#	STR	r6, [r4]		@ set new current task TCB address

#	LDR	sp, [r6]		@ give new task's stack pointer to sp

#	LDMFD	sp!, {r4}		@ YYY+
#	MSR	SPSR_cxsf, r4		@ YYY+
#	LDMFD	sp!, {r4}		@ YYY+
#	MSR	CPSR_cxsf, r4		@ YYY+
#	LDMFD	sp!, {r0-r12, lr, pc}	@ YYY+


#	OS_CPU_SR GetProcST_DisableIntr(void)
#	void SetProcST(OS_CPU_SR cpu_sr)
#
#	Disable and enable IRQ and FIQ preserving current CPU mode.
#
#	.GLOBAL	GetProcST_DisInt
#GetProcST_DisInt:
#	STMDB	sp!, {r8}
#	MRS		a1, CPSR
#	ORR		r8, a1, #NoIRQ
#	MSR		CPSR_cxsf, r8
#	LDMIA	sp!, {r8}
#	MOV	pc, lr

#	.GLOBAL	SetProcST
#SetProcST:
#	MSR	CPSR_cxsf, a1
#	MOV	pc, lr


#	.GLOBAL	ARMDisableInt
#ARMDisableInt:
#	STMDB	sp!, {r0}
#	MRS		r0, CPSR
#	ORR		r0, r0, #NoIRQ
#	MSR		CPSR_cxsf, r0
#	LDMIA	sp!, {r0}
#	MOV	pc, lr
	
#	.GLOBAL	ARMEnableInt
#ARMEnableInt:
#	STMDB	sp!, {r0}
#	MRS	r0, CPSR
#	BIC	r0, r0, #NoIRQ
#	MSR	CPSR_cxsf, r0
#	LDMIA	sp!, {r0}
#	MOV	pc, lr

#	.GLOBAL	ARMIsDisableInt
#ARMIsDisableInt:		@return value [disable: 1      enable: 0]
#	MRS	a1, CPSR
#	AND	a1, a1, #NoIRQ
#	MOV	pc, lr		


#	void OSCtxSw(void)
#	
#	Perform a context switch.
#
#	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.
#	.GLOBAL	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 current PSR
#	MRS	r4, SPSR			@ YYY+
#	STMFD	sp!, {r4}		@ YYY+ save SPSR
#
	# OSPrioCur = OSPrioHighRdy
#	LDR	r4, addr_OSPrioCur
#	LDR	r5, addr_OSPrioHighRdy
#	LDRB	r6, [r5]
#	STRB	r6, [r4]
	
	@ Get current task TCB address and save current task stack pointer
#	LDR	r4, addr_OSTCBCur
#	LDR	r5, [r4]
#	STR	sp, [r5]			@ store sp in preempted tasks's TCB

	# Get highest priority task TCB address
#	LDR	r6, addr_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}		@ YYY+
#	MSR	SPSR_cxsf, r4		@ YYY+
#	LDMFD	sp!, {r4}		@ YYY+
#	MSR	CPSR_cxsf, r4		@ YYY+
#	LDMFD	sp!, {r0-r12, lr, pc}	@ YYY+



#	void OSStartHighRdy(void)
#	
#	Start the task with the highest priority;
#

#	.GLOBAL	OSStartHighRdy
#OSStartHighRdy:
	#.extern OSTaskSwHook
	#BL	OSTaskSwHook
#	LDR	r4, addr_OSTCBCur		@ Get current task TCB address
#	LDR	r5, addr_OSTCBHighRdy	@ Get highest priority task TCB address

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

#	STR	r5, [r4]				@ set new current task TCB address

#	LDMFD	sp!, {r4}			@ YYY
#	MSR	SPSR_cxsf, r4
#	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

	.END

⌨️ 快捷键说明

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