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

📄 softwareinterrupt.s

📁 FreeRTOS在EasyARM2200上的移植代码
💻 S
字号:
;  SWI中断处理函数,由此进入SVC处理模式,调用系统函数进行任务切换
;  nuaa  tedden   导航研究中心   2008-12-8
;
;
;
;
;
;
;

NoInt       EQU 0x80

SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f

	CODE32
	
	AREA    SWI_INT, CODE, READONLY
	
	;引入外部变量
		IMPORT	pxCurrentTCB           ;当前任务TCB的指针
		IMPORT  ulCriticalNesting      ;中断嵌套层数全局变量
		IMPORT  StackUsr
		IMPORT  vTaskSwitchContext     ;OS系统函数
		
		EXPORT  SoftWareInterrupt      ;软件中断入口
		
SoftWareInterrupt
;////////////////////////////加上偏移//////////////////////////////////////////////////
	ADD     LR, LR, #4       
;///////////////////////////保护中断现场///////////////////////////////////////////////
	; Push R0 as we are going to use the register. 
	STMDB	SP!, {R0}                 ;先将R0压入栈底,后面要用到R0
	
	; Set R0 to point to the task stack pointer. 
	STMDB	SP,{SP}^                  ;将SYS模式的SP指针入栈,^
	NOP
	SUB		SP, SP, #4                ;
	LDMIA	SP!,{R0}	              ;

	; Push the return address onto the stack. 
	STMDB	R0!, {LR}                 ;将返回地址压栈,从堆栈的结构来看应该压在栈底

	; Now we have saved LR we can use it instead of R0. 
	MOV	LR, R0
	
	; Pop R0 so we can save it onto the system mode stack. 	
	LDMIA	SP!, {R0}
	
	; Push all the system mode registers onto the task stack. 
	STMDB	LR,{R0-LR}^	
	NOP
	SUB	LR, LR, #60		
	
	; Push the SPSR onto the task stack. 
	MRS	R0, SPSR	
	STMDB	LR!, {R0}	
	
	LDR	R0, =ulCriticalNesting
	LDR	R0, [R0]
	STMDB	LR!, {R0}	
	
	; Store the new top of stack for the task. 	
	LDR	R0, =pxCurrentTCB
	LDR	R0, [R0]	
	STR	LR, [R0]	
;//////////////////////////保护中断现场结束////////////////////////////////////////////////////////
;//////////////////////////切换处理器模式,重定位SP指针///////////////////////////////////////////
	MSR   CPSR_c, #(NoInt | SYS32Mode)    ; 切换到系统模式
	LDR   SP, =StackUsr             ;堆栈定义到Usr段
;//////////////////////////模式切换结束///////////////////////////////////////////////////////////
;//////////////////////////调用SWI系统函数////////////////////////////////////////////////////////
	BL   vTaskSwitchContext
;/////////////////////////调用结束////////////////////////////////////////////////////////////////
;///////////////////////////切换到SVC模式/////////////////////////////////////////////////////////
	MSR  CPSR_c, #(NoInt | SVC32Mode)
;//////////////////////////恢复断点内容///////////////////////////////////////////////////////////
	;Set the LR to the task stack. 
	;将LR指向当前任务堆栈顶													
	LDR		R0, =pxCurrentTCB	       ;获取当前任务TCB结构体指针							
	LDR		R0, [R0]				   ;获取指向存储栈顶数据的指针					
	LDR		LR, [R0]				   ;取出栈顶指针数据到LR中
																		
	; The critical nesting depth is the first item on the stack. 
	; Load it into the ulCriticalNesting variable. 
	;弹出栈顶的中断层数到全局变量中					
	LDR		R0, =ulCriticalNesting	   					
	LDMFD	LR!, {R1}											
	STR		R1, [R0]										
																		
	; Get the SPSR from the stack. 
	;弹出保存的SPSR
	LDMFD	LR!, {R0}		          ;栈顶的首个数据是保存的SPSR					
	MSR		SPSR_cxsf, R0			  ;将SPSR恢复							
																		
	; Restore all system mode registers for the task. 
	; 恢复R0~R14				
	LDMFD	LR, {R0-R14}^			  ;依次恢复R0-R14,LR不会被改写。^表示更改的是用户模式的寄存器,因此将恢复用户模式的
	;LR.要进行任务切换有两种情况.一是在中断的时候处于中断模式;或是处于SWI中断中,在特权模式								
	NOP															
																		
	; Restore the return address. 
	; 获取返回地址									
	LDR		LR, [LR, #+60]			  ;获取存放在栈底的返回地址							
																		
	; And return - correcting the offset in the LR to obtain the 
	; correct address. 			
	;设置PC,执行跳转									
	SUBS	PC, LR, #4		          ;返回地址-4,返回任务断点			
	;MOVS	PC, LR  ;执行SWI异常返回
	
	END

⌨️ 快捷键说明

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