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

📄 os_cpu_a.s

📁 网络服务器上实现操作系统和嵌入式协议栈的 结合
💻 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 OSStartHighRdy(void)	/* start highest priority task */
;	OS_TASK_SW			/* Context Switch*/
;	ARMDisableINT & ARMEnableINT
;	OSIntCtxSw



	AREA	OS_CPU_A, CODE, READONLY

	; External symbols we need the addresses of
			IMPORT	OSTCBCur
addr_OSTCBCur		DCD	OSTCBCur
			IMPORT	OSTCBHighRdy
addr_OSTCBHighRdy	DCD	OSTCBHighRdy
			IMPORT	OSPrioCur
addr_OSPrioCur		DCD	OSPrioCur
			IMPORT	OSPrioHighRdy
addr_OSPrioHighRdy	DCD	OSPrioHighRdy


;-+---+---++-+--+-++-+++--++--+++
	EXPORT	OSStartHighRdy
;示例
;SP=OSTCBHighRdy->OSTCBStkPtr
;OSTCBCur=OSTCBHighRdy
;弹出现场
	
OSStartHighRdy
	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
	;SP=OSTCBHighRdy->OSTCBStkPtr
	STR	r5, [r4]		; set new current task TCB address
	;OSTCBCur=OSTCBHighRdy

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



;-+---+---++-+--+-++-+++--++--+++
	EXPORT	OS_TASK_SW
;示例
;现场压栈
;OSPrioCur = OSPrioHighRdy
;OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
;SP=OSTCBHighRdy->OSTCBStkPtr
;OSTCBCur=OSTCBHighRdy
;弹出现场

OS_TASK_SW
	STMFD	sp!, {lr}		; save pc
	STMFD	sp!, {lr}		; save lr
	;分析:OS_TASK_SW是个函数,在任务间接的调用它时会在最后失去CPU,再次
	;获得CPU时,其恰好在OS_TASK_SW调用完毕后的那个位置,因此,lr被放入pc
	;在栈中的位置;此外,lr放入lr在栈中的位置也是无关紧要的,因为,子函数
	;返回时的lr是无意义的。
	STMFD	sp!, {r0-r12}	; save register file and ret address
	MRS	r4, CPSR
	STMFD	sp!, {r4}		; save current PSR
	;MRS	r4, SPSR		; YYY+ 这里屏蔽掉是因为任务运行的
					;模式是SYS,没有SPSR,栈中的CPSR与SPSR相同
	STMFD	sp!, {r4}		; YYY+ save SPSR


	LDR	r4, addr_OSPrioCur
	LDR	r5, addr_OSPrioHighRdy
	LDRB	r6, [r5]
	STRB	r6, [r4]
	; OSPrioCur = OSPrioHighRdy
		
	; Get current task TCB address
	LDR	r4, addr_OSTCBCur
	LDR	r5, [r4]
	STR	sp, [r5]		; store sp in preempted tasks's TCB
	;OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
	
	; Get highest priority task TCB address
	LDR	r6, addr_OSTCBHighRdy
	LDR	r6, [r6]
	LDR	sp, [r6]		; get new task's stack pointer
	;SP=OSTCBHighRdy->OSTCBStkPtr	更新SP为即将运行的任务
	
	STR	r6, [r4]		; set new current task TCB address
	; OSTCBCur = OSTCBHighRdy
	
	LDMFD	sp!, {r4}		; YYY+
	;MSR	SPSR_cxsf, r4		; YYY+运行在sys模式下,无需SPSR的更新
	LDMFD	sp!, {r4}		; YYY+
	MSR	CPSR_cxsf, r4		; YYY+
	LDMFD	sp!, {r0-r12, lr, pc}	; YYY+
	;现场恢复完毕



;-+---+---++-+--+-++-+++--++--+++
	EXPORT	ARMDisableInt
ARMDisableInt
	STMFD	sp!, {r0}
	MRS		r0, CPSR
	ORR		r0, r0, #0x80
	MSR		CPSR_c, r0
	LDMFD	sp!, {r0}
	
	MOV		pc, lr

	EXPORT	ARMEnableInt
ARMEnableInt
	STMFD	sp!, {r0}
	MRS		r0, CPSR
	BIC 	r0, r0, #0x80
	MSR		CPSR_c, r0
	LDMFD	sp!, {r0}
	
	MOV		pc, lr



;-+---+---++-+--+-++-+++--++--+++
        IMPORT  IRQ_STACK
	EXPORT  OSIntCtxSw
OSIntCtxSw
	;新的代码,实现了中断的嵌套
	;该函数被OSIntExit调用,OSIntExit在ISR_IrqHandler中被
	;调用(而不是以前在安装后的向量中,这是为了简化堆栈处理)
	;该函数运行依赖于调用ISR_IrqHandler之前的模式转换和栈构造
	;运行于SYS模式,其首先调整SP_sys指针到下图中SPSR处
	;后半部分与OSCtxSw相同
	;
 	;该函数是不返回的,进入时堆栈结构是已知的,除了原来的构造的
 	;标准栈,还压入了r4 r14(可以参看编译后的汇编代码)


;irq的栈结构,进入OSIntExit()时,sp指向的恰好是标准栈顶,但是,由于
;函数中又调用了函数,起始第一句便是一个stmfd sp!,{r4,r14},于是进入
;OSIntCtxSw后还得我们来调整
;-+---+---++-+--+-++-+++--++--+++-+---+---++-+--+-++-+++--++--+++
;低  r4 r14 spsr cpsr r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 lr PC  高
;-+---+---++-+--+-++-+++--++--+++-+---+---++-+--+-++-+++--++--+++	
	ldmfd	sp!,{r0,r1}	;我们的sp_sys已经指向标准栈结构
	
	;后面的内容和OSCtxSw的后半部分相同,依次为
;OSPrioCur = OSPrioHighRdy
;OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
;SP=OSTCBHighRdy->OSTCBStkPtr
;OSTCBCur=OSTCBHighRdy
;弹出现场
		
	LDR	r4, addr_OSPrioCur
	LDR	r5, addr_OSPrioHighRdy
	LDRB	r6, [r5]
	STRB	r6, [r4]
	; OSPrioCur = OSPrioHighRdy 
		
	; Get current task TCB address
	LDR	r4, addr_OSTCBCur
	LDR	r5, [r4]
	STR	sp, [r5]		; store sp in preempted tasks's TCB
	;OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
	; Get highest priority task TCB address
	LDR	r6, addr_OSTCBHighRdy
	LDR	r6, [r6]
	LDR	sp, [r6]		; get new task's stack pointer
	;SP=OSTCBHighRdy->OSTCBStkPtr	更新SP为即将运行的任务
	
	STR	r6, [r4]		; set new current task TCB address
	; OSTCBCur = OSTCBHighRdy
	
	LDMFD	sp!, {r4}		; YYY+
	;MSR	SPSR_cxsf, r4		; YYY+运行在sys模式下,无需SPSR的更新
	LDMFD	sp!, {r4}		; YYY+
	MSR	CPSR_cxsf, r4		; YYY+
	LDMFD	sp!, {r0-r12, lr, pc}	; YYY+
	;现场恢复完毕
	
		

	END
;-+---+---++-+--+-++-+++--++--+++	

⌨️ 快捷键说明

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