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

📄 os_cpu_a.s

📁 《嵌入式网络系统设计-基于Atmel ARM7 系列》这个本书的光盘资料
💻 S
字号:
;--------------------------------------------------------------------------------------------------
;							- uC/OS-II的内核调度程序 - 作者:焦海波 - 
;--------------------------------------------------------------------------------------------------
;- 文件名称 : os_cpu_a.s
;- 功能描述 : 提供任务级的和中断级的内核调度程序
;-   版本 : V0.1
;- 建立时间 : 2007/05/08 10:00
;--------------------------------------------------------------------------------------------------
						INCLUDE		at91sam7x256/include/AT91SAM7X256.inc
						INCLUDE		arm7tdmi/include/arm.inc
;--------------------------------------------------------------------------------------------------
;- 导入的一些外部符号
;--------------------------------------------------------------------------------------------------
						IMPORT		OSRunning
						IMPORT		OSTCBHighRdy
						IMPORT		OSTCBCur
						IMPORT		OSPrioCur
						IMPORT		OSPrioHighRdy
						IMPORT		blIsNeedCtxSw
						
						IMPORT		OSTaskSwHook
						IMPORT  	OSIntEnter
				        IMPORT  	OSIntExit
				        IMPORT		OSTimeTick
				        IMPORT		OSStartPIT
;--------------------------------------------------------------------------------------------------
;- 允许导出的符号
;--------------------------------------------------------------------------------------------------
						EXPORT		ARMCoreDisableIntExt
						EXPORT		ARMCoreRestoreIntStatus
						EXPORT		OSStartHighRdy
						EXPORT		OSCtxSw
						EXPORT		OSIntCtxSwExt
						EXPORT		IRQHandler
						EXPORT		FIQHandler
;--------------------------------------------------------------------------------------------------
;- 宏定义区
;--------------------------------------------------------------------------------------------------
	MACRO									;- OSTCBCur->OSTCBStkPtr = SP
		__macEditStkPtr	$R0, $SP			
		
		LDR		$R0, =OSTCBCur
		LDR		$R0, [$R0]
		STR		$SP, [$R0]
	MEND

	MACRO									;- OSPrioCur = OSPrioHighRdy
		__macEditOSPrioCur	$R0, $R1		
		
		LDR		$R0, =OSPrioCur
		LDR		$R1, =OSPrioHighRdy
		LDRB	$R1, [$R1]
		STRB	$R1, [$R0]
	MEND
	
	MACRO									;- OSTCBCur = OSTCBHighRdy
		__macEditOSTCBCur	$R0, $R1		
		
		LDR		$R0, =OSTCBCur				
		LDR		$R1, =OSTCBHighRdy
		LDR		$R1, [$R1]
		STR		$R1, [$R0]
	MEND
	
	MACRO									;- 结束内核调度中断
		__macEndInt	$R0						
        
        LDR     $R0, =AT91C_BASE_AIC		;- 结束中断
        STR		$R0, [$R0, #AIC_EOICR]
	MEND
	
	MACRO
		__macIntHandler		$IntVR			;- 中断处理入口,完成用户自定义的中断处理和任务调度
		
		SUB		LR, LR, #4
		STMFD	SP!, {R0-R3, LR}
		
		BL		OSIntEnter					;- 进入用户自定义的中断服务子函数
		
		LDR		R0, =AT91C_BASE_AIC
		LDR		R0, [R0, $IntVR]
		LDR		LR, =.+8
		BX		R0
		
		BL		OSIntExit					;- 退出中断,看看是否进行任务切换
		
		LDR		R0, =blIsNeedCtxSw			;- 判断是否需要任务切换
		LDRB	R1, [R0]
        CMP		R1, #1
        BEQ		OSIntCtxSwExt
		
		__macEndInt	R0						;- 结束中断
        
        LDMFD	SP!, {R0-R3, PC}^
	MEND
;--------------------------------------------------------------------------------------------------
;- 代码区
;--------------------------------------------------------------------------------------------------
						AREA        OSKernelSchedular, CODE, READONLY
;--------------------------------------------------------------------------------------------------						
;- 临界处理函数
ARMCoreDisableIntExt
		MRS     R0,CPSR                     ;- 将CPSR寄存器的值传送到参数寄存器R0中

__DisableInt
        ORR     R1,R0,#I_BIT:OR:F_BIT
        
        MSR     CPSR_c,R1                   ;- 进行判断的目的是确认中断禁止操作已经成功后再开始临界处理
        MRS     R1,CPSR                     
        AND     R1,R1,#I_BIT:OR:F_BIT
        CMP     R1,#I_BIT:OR:F_BIT
        BNE     __DisableInt                
        BX		LR                          ;- 返回调用函数并返回原来的CPSR值

ARMCoreRestoreIntStatus
		MSR		CPSR_c, R0                  
		BX		LR

;--------------------------------------------------------------------------------------------------						
;- 启动uC/OS-II,开始多任务处理,OSStart()调用该函数
OSStartHighRdy
		LDR		R0, =OSRunning				;- OSRunning = TRUE
		MOV		R1, #1
		STRB	R1, [R0]
		
		BL      OSTaskSwHook				;- 调用任务切换钩子函数
		
		BL		OSStartPIT					;- 开启定时器
		
		LDR		R0, =OSTCBHighRdy   		;- 获得最高优先级任务的堆栈地址
		LDR		R0, [R0]
		LDR		SP, [R0]
		
		LDMFD	SP!, {R0}
		MSR		CPSR_cxsf, R0
		
		LDMFD	SP!, {R0-R12, LR, PC}

;--------------------------------------------------------------------------------------------------						
;- 任务级的任务切换函数
OSCtxSw
		STMFD	SP!, {LR}					;- 实际上,LR保存的返回地址就是当前任务恢复运行后的开始
		STMFD	SP!, {R0-R12, LR}	        ;- ……地址,这个值会被恢复到PC指针寄存器中
		MRS		R0, CPSR
		STMFD	SP!, {R0}
		
		__macEditStkPtr	R0, SP				;- 由于前面进行了入栈操作,所以在这里应该修改当前任务控
											;- ……制块TCB中保存的堆栈指针,OSTCBCur->OSTCBStkPtr = SP
		
		BL      OSTaskSwHook				;- 调用任务切换钩子函数
		
		__macEditOSPrioCur	R0, R1			;- OSPrioCur = OSPrioHighRdy
		
		__macEditOSTCBCur	R0, R1			;- OSTCBCur = OSTCBHighRdy
		
		LDR		SP, [R1]					;- SP = OSTCBHighRdy->OSTCBStkPtr
		
		LDMFD	SP!, {R0}					;- 把高优先级任务从堆栈中推入到CPU的寄存器中,恢复高优先级任务的运行
		MSR		CPSR_cxsf, R0
		LDMFD	SP!, {R0-R12, LR, PC}

;--------------------------------------------------------------------------------------------------						
;- 中断处理入口,这两个入口函数提供中断服务及任务调度功能
IRQHandler
		__macIntHandler		#AIC_IVR
		
FIQHandler
		__macIntHandler		#AIC_FVR

OSIntCtxSwExt
		MOV		R1, #0						;- blIsNeedCtxSw = OS_FALSE
		STRB	R1, [R0]
		
		LDMFD	SP!, {R0-R3, LR}			;- LR出栈
		STMFD	SP!, {R0-R3}                ;- 由于R0-R3寄存器在下面的代码中仍然使用,所以这里再一次入栈保护
		
		MOV		R0, LR						;- 保存当前正在运行的任务的返回地址
		MRS		R1, SPSR					;- 保存当前正在运行的任务的CPSR寄存器的值
		MOV		R2, SP						;- 保存IRQ堆栈地址
		
		ADD		SP, SP, #16					;- 在返回到先前的模式之前,调整IRQ(或FIQ)堆栈指针到正确位置,因为
		                                    ;- ……模式切换后,IRQ(或FIQ)堆栈中保存的R0-R3寄存器会被转移到任务
		                                    ;- ……堆栈中,这实际上相当于出栈操作
		
		ORR		R3, R1, #I_BIT:OR:F_BIT		;- 切换到先前的模式之前,必须禁止中断,当前处理不能被中断打断
		MSR		SPSR_c, R3					;- 切换到先前的模式,这实际上就是被中断的任务所处的模式
		LDR		R3, =.+8
		MOVS	PC, R3
		
		STMFD	SP!, {R0}					;- 保存当前任务的PC指针
		STMFD	SP!, {R4-R12, LR}			;- 保存当前任务使用的工作寄存器、LR
		
		MOV		R4, R1						;- 把R0-R3寄存器的值从IRQ(或FIQ)堆栈转移到任务堆栈,并将当前任务的CPSR入栈
		MOV		R5, R2
		LDMFD	R5!, {R0-R3}
		STMFD	SP!, {R0-R3}
		STMFD	SP!, {R4}					;- 保存当前任务的CPSR寄存器				
		
		__macEditStkPtr	R0, SP				;- OSTCBCur->OSTCBStkPtr = SP
		
		BL      OSTaskSwHook				
		
		__macEditOSPrioCur	R0, R1			;- OSPrioCur = OSPrioHighRdy
		
		__macEditOSTCBCur	R0, R1			;- OSTCBCur = OSTCBHighRdy
		
		LDR		SP, [R1]					;- SP = OSTCBHighRdy->OSTCBStkPtr
		
		LDMFD	SP!, {R0}					;- 从堆栈中恢复CPSR
		MSR		CPSR_cxsf, R0
		
		__macEndInt	R0						;- 结束中断
        
        LDMFD	SP!, {R0-R12, LR, PC}		;- 恢复高优先级任务的运行
					
						END

⌨️ 快捷键说明

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