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

📄 os_cpu_a.s

📁 SAM7X256开发有关资料,包括中断AICuC/OS-II等资料.
💻 S
字号:
;//--------------------------------------------------------------------------------------------------
;//							- uC/OS-II的内核调度程序 
;//--------------------------------------------------------------------------------------------------
;//- 文件名称 : os_cpu_a.s
;//- 功能描述 : 提供任务级的和中断级的内核调度程序
;//-   版本 : V0.1
;//- 建立时间 : 2007/05/08 10:00
;//--------------------------------------------------------------------------------------------------
						INCLUDE		at91sam7x256/include/AT91SAM7X256.inc
						INCLUDE		at91sam7x256/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 + -