欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

os_cpu_a.s

这个是MDK上的44BO的UCOSII的编译程序
S
字号:
;#------------------------------------------------------------------------------
;#- File: os_cpu_a.s
;#------------------------------------------------------------------------------
;#-            (c) Copyright ARM Limited 1999.  All rights reserved. 
;#-
;#-                              ARM Specific code
;#------------------------------------------------------------------------------
;#-
;#- 
;#-	Functions defined in this module:
;#-
;#-	void ARMDisableInt(void)	disable interrupts when in SVC
;#-	void ARMEnableInt(void)		enable interrupts when in SVC
;#-	void OS_TASK_SWAP(void)		context switch
;#-	void OSStartHighRdy(void)	start highest priority task


	 PRESERVE8
     AREA	|subr|, CODE, READONLY

SwiV        EQU   0x08
IrqV        EQU   0x18
FiqV        EQU   0x1C
NoInt       EQU   0x80

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

OSEnterSWI  EQU   0x00

BIT_TIMER0  EQU   (0x1<<13)
I_ISPC      EQU   0x1e00024
INTMSK      EQU   0x1e0000c


;# External symbols we need the addresses of
	 import	OSTCBCur
;addr_OSTCBCur		DCW 	OSTCBCur
	 import	OSTCBHighRdy
;addr_OSTCBHighRdy	DCW 	OSTCBHighRdy
     import	OSPrioCur
;addr_OSPrioCur		DCW 	OSPrioCur
	 import	OSPrioHighRdy
;addr_OSPrioHighRdy  DCW	    OSPrioHighRdy

	 import	OSRunning
	 import	SysENInterrupt
	 import OSTaskSwHook 
	 import	need_to_swap_context
	 import	IrqStart
	 import	OSTimeTick
	 import	IrqFinish
	 import	SysDISInterrupt
	
	 export	IRQContextSwap
	 export	TickHandler
	 export	RunNewTask
	
IRQContextSwap
	MOV	a1, #1
	MOV	lr, pc
	
TickHandler
	STMDB    sp!,{r0-r11,lr}

;	#interrupt disable(not nessary)
	mrs		r0, CPSR
	orr		r0, r0, #0x80	;	@ and set IRQ disable flag
	msr		CPSR_cxsf, r0
	
	ldr     r0,=0x4000000
	BL      SysDISInterrupt
	
;	#End of interrupt
;	#(Clear pending bit of INTPEND that don't accessed it.)
;	#	rI_ISPC= BIT_TIMER0;
	LDR	r0, =I_ISPC
	LDR	r1, =BIT_TIMER0
	STR	r1, [r0]

	BL	IrqStart
	
	BL	OSTimeTick

	BL	IrqFinish		;@a1= return value	0:not context switch, otherwise:context switch

	CMP		a1, #0
	LDRNE	pc, =_CON_SWAP


_NOT_CON_SWAP
;	#not context switching
	ldr     r0,=0x4000000
	BL      SysENInterrupt
	LDMIA    sp!,{r0-r11, lr}
	SUBS	pc, lr, #4


_CON_SWAP
;	#now context switching
	LDMIA    sp!,{r0-r11,lr}
RunNewTask
	SUB		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, #0xFFFFFFE0
	ORR				lr, lr, #0x13
	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
	STMFD	sp!, {r4}		;@ save current PSR
	MRS		r4, SPSR		;@ YYY+
	STMFD	sp!, {r4}		;@ YYY+ save SPSR


;	# 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

;	# 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}		;@ YYY+
;#	AND		r4, r4, #0xFFFFFF20
;#	ORR		r4, r4, #0x13
	MSR	SPSR_cxsf, r4		;@ YYY+
	LDMFD	sp!, {r4}		;@ YYY+
;#	AND		r4, r4, #0xFFFFFF20
;#	ORR		r4, r4, #0x13
	MSR	CPSR_cxsf, r4		;@ YYY+
	ldr     r0,=0x4000000
	BL      SysENInterrupt
	LDMFD	sp!, {r0-r12, lr, pc}	;@ YYY+


SAVED_LR		;.LONG		0


;#	void DisableInt(void)
;#	void EnableInt(void)
;#
;#	Disable and enable IRQ and FIQ preserving current CPU mode.
;#
	export	ARMDisableInt
ARMDisableInt
	STMDB	sp!, {r0,lr}
	MRS		r0, CPSR
	ORR		r0, r0, #NoInt
	MSR		CPSR_cxsf, r0
	LDMIA	sp!, {r0,pc}
;#	MOV	pc, lr


	export	ARMEnableInt
ARMEnableInt
	STMDB	sp!, {r0,lr}
	MRS	r0, CPSR
	BIC	r0, r0, #NoInt
	MSR	CPSR_cxsf, r0
	LDMIA	sp!, {r0,pc}
;#	MOV	pc, lr

	export	ARMIsDisableInt
ARMIsDisableInt		;@return value [disable: 1      enable: 0]
	MRS	a1, CPSR
	AND	a1, a1, #NoInt
;	bx lr		


;#	void OS_TASK_SW(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.
	export	OS_TASK_SW
OS_TASK_SW
	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, =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

;	# 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}		;@ 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;
;#
	export	OSStartHighRdy
OSStartHighRdy
	BL	OSTaskSwHook
	MOV	R0,#1
	LDR	R1,=OSRunning
	STRB	R0,[R1]

	LDR	r4, =OSTCBCur		;@ Get current task TCB address
	LDR	r5, =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 + -