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

📄 portmacro.s

📁 FreeRTOS在EasyARM2200上的移植代码
💻 S
字号:
;作者nuaa.tedden   2008-12-6    导航研究中心
;描述:  改文件是FreeRTOS移植代码的CPU支持部分,ADS1.2编译器
;主要的函数有
;portRESTORE_CONTEXT   (任务堆栈恢复)  
;portSAVE_CONTEXT       (任务堆栈保护)
;portDISABLE_INTERRUPTS  (全局中断关闭)
;portENABLE_INTERRUPTS    (全局中断打开)
;
;
;
;
;
;
;
;
;
;
;
;
NoInt       EQU 0x80

SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f
		 
		 
		CODE32                   ;32位ARM代码

    AREA    OsSupport, CODE, READONLY
    
	;引入外部变量
		IMPORT	pxCurrentTCB           ;当前任务TCB的指针
		IMPORT  ulCriticalNesting      ;中断嵌套层数全局变量
		
		EXPORT  portRESTORE_CONTEXT    ;堆栈内容恢复
		EXPORT  portSAVE_CONTEXT       ;保存寄存器内容
		EXPORT  portDISABLE_INTERRUPTS ;禁止中断
		EXPORT  portENABLE_INTERRUPTS  ;打开中断


portRESTORE_CONTEXT
	;进入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,执行跳转									
	MOVS	PC, LR 		          ;返回地址,返回任务断点										
														
	
	
portSAVE_CONTEXT                      ;保护任务现场,在这里实际并没有调用
	; 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}^                  ;
	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]	
	
;以下两个函数被C函数调用	
portDISABLE_INTERRUPTS
	STMDB	SP!, {R0}		; Push R0.将R0入栈						
	MRS		R0, CPSR		; Get CPSR.获取CPSR						
	ORR		R0, R0, #0xC0	; Disable IRQ, FIQ.FIQ,IRQ禁止			
	MSR		CPSR_cxsf, R0	; Write back modified value.	
	LDMIA	SP!, {R0}	 	; Pop R0.R0恢复						
	MOV     PC, LR          ; 函数返回
	
portENABLE_INTERRUPTS
	STMDB	SP!, {R0}		; Push R0.						
	MRS		R0, CPSR		; Get CPSR.					
	BIC		R0, R0, #0xC0	; Enable IRQ, FIQ.				
	MSR		CPSR_cxsf, R0	; Write back modified value.	
	LDMIA	SP!, {R0}		; Pop R0.	
	MOV     PC, LR			; 函数返回		




	END

⌨️ 快捷键说明

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