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

📄 irq.inc.bak

📁 FreeRTOS在EasyARM2200上的移植代码
💻 BAK
字号:
;LPC2200系列在FreeRTOS下的中断处理汇编宏
;nuaa tedden 导航研究中心  2008-12-9
;
;
;
;
;
;
NoInt       EQU 0x80

SYS32Mode   EQU 0x1f
IRQ32Mode   EQU 0x12


;引入的外部标号在这声明
       IMPORT	 pxCurrentTCB           ;当前任务TCB的指针
	IMPORT  ulCriticalNesting      ;中断嵌套层数全局变量
	IMPORT  StackUsr

	CODE32

    AREA    IRQ,CODE,READONLY

    MACRO
$IRQ_Label HANDLER $IRQ_Exception_Function
	
	EXPORT  $IRQ_Label                      ; 输出的标号
       IMPORT  $IRQ_Exception_Function         ; 引用的外部标号

$IRQ_Label                   ;中断入口
;///////////////////////////保护中断现场///////////////////////////////////////////////
	; 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}^                  ;将当前的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   $IRQ_Exception_Function         ; 调用c语言的中断处理程序
;/////////////////////////调用结束////////////////////////////////////////////////////////////////
;///////////////////////////切换到IRQ模式/////////////////////////////////////////////////////////
	MSR  CPSR_c, #(NoInt | IRQ32Mode)
;//////////////////////////恢复断点内容///////////////////////////////////////////////////////////
	;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?,返回任务断点	
    MEND

    END

⌨️ 快捷键说明

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