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

📄 os_cpu_a.s

📁 ucos2 移植到44b0 上的源代码,支持中断嵌套,调试通过.
💻 S
字号:
;/****************************************Copyright (c)**************************************************
;**                                       中南民族大学
;**                                     电子信息工程学院
;**                                    2005级电子信息工程  
;**									yangbin6b210@yahoo.com.cn
;**                                 
;**
;**----------------------------------------文件信息------------------------------------------------------
;**文   件   名: os_cpu_s.s
;**创   建   人: 杨斌
;**最后修改日期: 2007年12月12日
;**描        述: μCOS-II在S3C44B0X上的移植代码汇编代码部分,用ADS1.2编译
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
NoInt		EQU	0x80

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





		CODE32

		AREA    |subr|, CODE, READONLY
		
		IMPORT	OSIntNesting
		IMPORT  OSTCBCur
		IMPORT	IsrIRQ
		IMPORT	OSIntExit
		IMPORT	OSTaskSwHook
		IMPORT  OSTCBCur
        IMPORT  OSTCBHighRdy
        IMPORT  OSPrioCur                   
        IMPORT  OSPrioHighRdy 
        IMPORT	IRQStack
        IMPORT	OSRunning
        
		EXPORT	OSIRQISR
		EXPORT	OSIntCtxSw
		EXPORT	OS_TASK_SW
		EXPORT	OSStartHighRdy
		EXPORT	OS_ENTER_CRITICAL
		EXPORT	OS_EXIT_CRITICAL



;/*********************************************************************************************************
;** 函数名称: OSIRQISR
;** 功能描述: 中断进入和退出时的接口
;** 输 入:   无
;**          
;**          
;** 输 出 :  无  
;** 全局变量: OSIntNesting、OSTCBCur、IRQStack 
;** 调用模块: 无
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月12日
;**-------------------------------------------------------------------------------------------------------
;  系统模式堆栈            IRQ模式堆栈
;	|PC  |					|LR  |=断点处的将要执行的PC值                        
;	|LR  |	 				|R3  |		
;	|R12 |					|R2  |
;	|R11 |					|R1  |
;	|R10 |					|R0  |
;	|R9  |					|LR  |=系统模式的LR
;	|R8  |					|SP  |=系统模式的SP
;	|R7  |				SP→|SPSR|=断点处的CPSR
;	|R6  |
;	|R5  |
;	|R4  |
;	|R3  |
;	|R2  |
;	|R1  |
;	|R0  |	
; 	|CPSR|←SP
;/********************************************************************************************************/
OSIRQISR
		SUB		LR,LR,#4							;调整返回地址
		STMFD	SP!,{R0-R3,LR}
		MRS		R3,SPSR
		STMFD	SP,{R3,SP,LR}^						;							系统模式SP→|R0  |						
		
		SUB		SP,SP,#4*3							;							系统模式SP→|SPSR|
		
		LDR		R0,=OSIntNesting
		LDRB	R1,[R0]
		ADD		R1,R1,#1
		STRB	R1,[R0]								;OSIntNesting加1														
		
		MOV		R2,LR
		MSR     CPSR_c, #(NoInt | SYS32Mode)
		CMP		R1,#1
		BNE		OSIRQ_NEXT							;若OSIntNesting为1,则保存当前任务的寄存器到当前任务的堆栈中
		STMFD	SP!,{R2}							;保存当前任务的PC,			系统模式SP→|PC  |
		STMFD	SP!,{LR}							;保存当前任务的LR, 			系统模式SP→|LR  |
		STMFD	SP!,{R4-R12}						;保存当前任务的R4-R12,		系统模式SP→|R4  |
		STR		R3,[SP,#-5*4]						;保存当前任务的CPSR		
		
		MSR     CPSR_c, #(NoInt | IRQ32Mode)		;进入IRQ模式
		ADD		SP,SP,#4*3							;							IRQ模式SP→ |R0  |
		LDMFD	SP,{R0-R3}							;取出R0-R3
		SUB		SP,SP,#4*3							;							IRQ模式SP→ |SPSR|
		MSR     CPSR_c, #(NoInt | SYS32Mode)		;进入系统模式
		STMFD	SP!,{R0-R3}							;保存R0-R3,				系统模式SP→|R0  |	
		SUB		SP,SP,#4							;调整SP,					系统模式SP→|CPSR|
		
		LDR		R0,=OSTCBCur
		LDR		R0,[R0]
		STR		SP,[R0]								;OSTCBCur->OSTCBStkPtr=SP
		
OSIRQ_NEXT		
		BL		IsrIRQ								;调用IRQ中断服务函数,在此中断服务函数中必须清除中断挂起位
		
	    BL      OSIntExit							;调用推出系统中断函数,在此函数中OSIntNesting减1,也有可能会切换到其他任务中
        
        MSR     CPSR_c, #(NoInt | IRQ32Mode)		;进入IRQ模式。
        
        LDR		R0,=OSIntNesting					
        LDRB	R0,[R0]
        CMP		R0,#0								;若OSIntNesting=0则表明这是第一层中断
        BEQ		OSIRQ_LEAVE
        
        LDMFD	SP,{R0,SP,LR}^						;程序运行到此处,此时处在嵌套中断中
		MSR		SPSR_cxsf,R0						;恢复系统模式的SP,LR,IRQ模式SPSR
		ADD		SP,SP,#4*3							;调整IRQ模式SP,			IRQ模式SP→ |R0  |
		LDMFD	SP!,{R0-R3,PC}^						;恢复R0-R3,PC,CPSR,		IRQ模式SP→ |X	 |←上一层中断的堆栈顶部
		
OSIRQ_LEAVE																			
		LDR		R0,=IRQStack						;程序运行到此处,表明这是第一层中断且不需要切换任务	
		LDR		R0,[R0]
		MOV		SP,R0								;							IRQ模式SP→ |X   |←中断模式堆栈栈底
		SUB		SP,SP,#8*4							;							IRQ模式SP→ |SPSR|
		
		LDMFD	SP,{R0,SP,LR}^						;恢复系统模式的SP,LR,		系统模式SP→|X   |←当前任务中断时的SP
		MSR		SPSR_cxsf,R0						;恢复IRQ模式SPSR
		ADD		SP,SP,#4*3							;调整IRQ模式SP,			IRQ模式SP→ |R0  |			
		
		MSR     CPSR_c, #(NoInt | SYS32Mode)		;切换到系统模式,			
		SUB		SP,SP,#11*4							;调整系统模式SP,			系统模式SP→|R4  |
		LDMFD	SP,{R4-R12}							;恢复R4-R12
		ADD		SP,SP,#11*4							;调整系统模式SP,			系统模式SP→|X   |←当前任务中断时的SP
		
		MSR     CPSR_c, #(NoInt | IRQ32Mode)		;切换到IRQ模式
		LDMFD	SP!,{R0-R3,PC}^						;恢复R0-R3、CPSR并从中断返回到当前任务断点处
		
;/*********************************************************************************************************
;** 函数名称: OSIntCtxSw
;** 功能描述: 中断级任务切换
;** 输 入:   IRQ模式堆栈结构(出栈次序):SPSR、SP(系统模式)、LR(系统模式)、R0-R3、LR 
;**			  当前任务(系统模式)堆栈结构:CPSR、R0-R12、LR、PC          
;**          
;** 输 出 :  无  
;** 全局变量: OSTCBHighRdy、OSTCBCur、OSPrioCur、OSPrioHighRdy、IRQStack
;** 调用模块: OSTaskSwHook
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OSIntCtxSw
		BL		OSTaskSwHook							;调用钩子函数OSTaskSwHook()
        
       	MSR     CPSR_c, #(NoInt | IRQ32Mode)
       	LDR     R0, =OSTCBHighRdy
        LDR     R0, [R0]
        LDR     R1, =OSTCBCur
        STR		R0,	[R1]								;OSTCBCur=OSTCBHighRdy
        
        LDR		R0,=OSPrioCur
        LDR		R1,=OSPrioHighRdy
        LDRB	R1,[R1]
        STRB	R1,[R0]									;OSPrioCur=OSPrioHighRdy
       
        LDR		R0,=IRQStack
		LDR		R0,[R0]
		SUB		R0,R0,#4								;
		MOV		SP,R0									;IRQ模式堆栈保留一个字
		
		MSR     CPSR_c, #(NoInt | SYS32Mode)			;进入系统模式
		LDR     R2, =OSTCBHighRdy
        LDR     R2, [R2]								
        LDR		R2, [R2]								;取得新任务堆栈指针OSTCBHighRdy->OSTCBStkPtr并存入R2中
       
        LDR		R1,[R2]									;取得新任务的CPSR存入R1中
        LDR		R3,[R2,#15*4]							;取得新任务的PC存入R3中
        STR		R3,[R0]									;把新任务的PC存入IRQ模式的堆栈中
        
        MSR     CPSR_c, #(NoInt | IRQ32Mode)			;进入IRQ模式
        MSR		SPSR_cxsf,R1							;把新任务的CPSR保存到IRQ模式的SPSR中
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)			;进入系统模式                       
      	ADD		R2,R2,#4								;调整新任务堆栈指针
      	MOV		SP,R2									;							系统模式SP→|R0  |
      	LDMFD	SP!,{R0-R12,LR}							;恢复新任务的R0-R12,LR,	系统模式SP→|PC  |    
      	ADD		SP,SP,#4								;调整系统模式堆栈指针
      	
      	MSR     CPSR_c, #(NoInt | IRQ32Mode)			;进入IRQ模式
      	LDMFD	SP!,{PC}^								;恢复新任务的CPSR、PC和IRQ模式SP
;/*********************************************************************************************************
;** 函数名称: OS_TASK_SW
;** 功能描述: 在任务调度中切换任务
;** 输 入:	  无   
;**			         
;**          
;** 输 出 :  无  
;** 全局变量: OSTCBCur、OSTCBHighRdy、OSPrioCur、OSPrioHighRdy 
;** 调用模块: OSTaskSwHook
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/   
OS_TASK_SW
		STMFD	SP!,{LR} 								;保存当前任务的PC
		STMFD	SP!,{R0-R12,LR}							;依次保存R0-R12、LR
		MRS		R0,CPSR
		STMFD	SP!,{R0}								;保存CPSR
		
		LDR		R1,=OSTCBCur
		LDR		R1,[R1]
		STR		SP,[R1]									;OSTCBCur->OSTCBStkPtr = SP(在当前任务控制块中保存当前任务的堆栈指针)       
        
	    BL		OSTaskSwHook							;调用OSTaskSwHook()
	    
	    LDR		R3,=OSPrioCur
        LDR		R4,=OSPrioHighRdy
        LDRB	R4,[R4]
        STRB	R4,[R3]									;OSPrioCur=OSPrioHighRdy
        
__OSStartHighRdy
        LDR		R1,=OSTCBCur
        LDR		R2,=OSTCBHighRdy
        LDR		R2,[R2]
        STR		R2,[R1]									;OSTCBCur=OSTCBHighRdy
        
        LDR		SP,[R2]									;得到将要重新运行的任务的堆栈指针SP=OSTCBHighRdy->OSTCBStkPtr
        
        LDMFD	SP!,{R0}								;取出将要运行任务的CPSR存入R0中
       
        MSR     CPSR_c, #(NoInt | SVC32Mode)			;进入管理模式
        MSR		SPSR_cxsf,R0							;管理模式SPSR=将要运行任务的CPSR
        LDR		SP,[R2]									;管理模式SP=将要重新运行的任务的堆栈指针
        ADD		SP,SP,#15*4								;调整SP
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)			;进入系统模式
        LDMFD	SP!,{R0-R12,LR}							;恢复R0-R12、LR
        ADD		SP,SP,#4								;恢复要重新运行的任务的堆栈指针SP
        
        MSR     CPSR_c, #(NoInt | SVC32Mode)			;进入管理模式
        LDMFD	SP,{PC}^								;恢复任务的CPSR并开始运行任务
        	 
;/*********************************************************************************************************
;** 函数名称: OSStartHighRdy
;** 功能描述: uC/OS-II启动时调用此程序运行第一个任务
;** 输 入:	  无   
;**			         
;**          
;** 输 出 :  无  
;** 全局变量: OSRunning
;** 调用模块: OSTaskSwHook
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/          
OSStartHighRdy
		MSR		CPSR_c,#(NoInt | SYS32Mode )
		
		LDR		R1,=OSRunning
		MOV		R2,#1
		STRB	R2,[R1]									;OSRunning=1
		
		BL		OSTaskSwHook							;调用OSTaskSwHook()
		
		B		__OSStartHighRdy						;运行最高优先级任务       
        
;/*********************************************************************************************************
;** 函数名称: OS_ENTER_CRITICAL
;** 功能描述: 关闭中断
;** 输 入:   无  
;**			         
;**          
;** 输 出 :  无  
;** 全局变量: 无 
;** 调用模块: 无
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OS_ENTER_CRITICAL
		STMFD	SP!,{R0}
		MRS		R0,CPSR
		ORR		R0,R0,#NoInt
		MSR		CPSR_cxsf,R0
		LDMFD	SP!,{R0}
		MOV		PC,LR  
		
		
		
;/*********************************************************************************************************
;** 函数名称: OS_EXIT_CRITICAL  
;** 功能描述: 打开中断 
;** 输 入:   无 
;**			         
;**          
;** 输 出 :  无 
;** 全局变量: 无 
;** 调用模块: 无 
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OS_EXIT_CRITICAL
		STMFD	SP!,{R0}
		MRS		R0,CPSR
		BIC		R0,R0,#NoInt
		MSR		CPSR_cxsf,R0
		LDMFD	SP!,{R0}
		MOV		PC,LR  		      
		
		END
;/*********************************************************************************************************
;**                                   End Of File
;*********************************************************************************************************/

        
     
        
        
        
		
        
        
        
        
        
        
		
		
		
		
		
		
		
		
		
		
        
        
        
        
		
		
		
		
		
		
		
		
		
		
	
		
		






⌨️ 快捷键说明

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