瑞星微公司RK27XX系列芯片的SDK开发包

源代码在线查看: cpu_a.s

软件大小: 26915 K
上传用户: mislrb
关键词: SDK RK 27 XX
下载地址: 免注册下载 普通下载 VIP

相关代码

					;移植,huangsl。
				;********************************************************************************************************/
						INCLUDE ../boot/CONDEFINE.s
						
				;定义系统模式堆栈的大小
				
				    CODE32
				
				    AREA    |OSIRQ|, CODE, READONLY		;OSSCHEDE
				
				;import here , 080301,huangsl,下面的变量 必须放到 SRAM,以避免 CACHE问题.
				
				            IMPORT  OSTCBCur                    ;指向当前任务TCB的指针
				            IMPORT  OSTCBHighRdy                ;指向将要运行的任务TCB的指针
				            IMPORT  OSPrioCur                   ;当前任务的优先级
				            IMPORT  OSPrioHighRdy               ;将要运行的任务的优先级
				            IMPORT  OSRunning                   ;uC/OS-II运行标志
				;						IMPORT	OSIntNesting
										
										IMPORT	OSIntEnter
				            IMPORT 	IrqCHandler               	;IRQ C语言中断处理函数
										IMPORT 	OSIntExit 
										
										IF {FALSE}
										IMPORT	OSTaskStackCheck
										ENDIF 
				;export here
				            EXPORT OSCtxSw 
				            EXPORT  OSStartHighRdy            
				            EXPORT  OSIntCtxSw                  ;中断退出时的入口,参见startup.s中的IRQ_Handler
				        ;    EXPORT  SoftwareInterrupt           ;软中断入口
										EXPORT	OSIrqIsr
										
										EXPORT OSDisableInt 
										EXPORT OSEnableInt 
										
				;/*********************************************************************************************************
				;** 函数名称: OSIrqIsr
				;** 功能描述: IRQ 中断服务程序
				;** 输 入:   依功能而定
				;** 输 出 :  依功能而定
				;** 全局变量: 无
				;具体功能可以通过 C函数实现.
				;**-------------------------------------------------------------------------------------------------------
				;********************************************************************************************************/
				OSIrqIsr
					
					IF	:DEF: ARMULATE
					;|   LR |
					;| SPSR |
					STR	   R0 , [SP,#-4]
					LDR	   R0 , [SP]
					LDR	   LR , [SP,#4]
					MSR	   SPSR_cxsf, R0
					LDR    R0 , [SP,#-4]
					ADD	   SP , SP , #8			   ; adjust sp.
					ENDIF
					
					SUB     LR, LR, #4                             ;计算返回地址
					
				        STMFD   SP!, {R0-R3, R12, LR}        					;保存任务环境,因为可能在调用 C 语言处理函数时会改变
				        MRS     R3, SPSR                               ;保存状态
				        STMFD   SP!, {R3}															;防止中断嵌透时丢失
				
								IF {FALSE}
				        LDR     R2,  =OSIntNesting                  ;OSIntNesting++
				        LDRB    R1, [R2]
				        ADD     R1, R1, #1
				        STRB    R1, [R2]
				        ELSE
				        BL			OSIntEnter
				        ENDIF
				        
				        BL      IrqCHandler                       	;调用C语言的中断处理程序
				 ;MSR写状态寄存器指令使得CPSR[7:0]=0b10010010
				 ;作用为关IRQ中断
				 				MSR CPSR_c, #IRQMODE|NOINT									;关中断
				 				
				        BL      OSIntExit                                  ;调用OSIntExit(该函数需要修改,内部不能调用 OSIntCtxSw)
				 
				 ;比较OSTCBHighRdy和OSTCBCur
				 ;作用为判断在退出中断处理之后是否进行任务切换
				        LDR     R0, =OSTCBHighRdy
				        LDR     R0, [R0]
				        LDR     R1, =OSTCBCur
				        LDR     R1, [R1] 
				        CMP     R0, R1    
				        
				        LDMFD   SP!, {R3}   
				        MSR     SPSR_cxsf, R3                              ;SPSR[31:0]=R3
				
				        LDMEQFD SP!, {R0-R3, R12, PC}^          ;不进行任务切换则恢复任务环境
				        LDR     PC, =OSIntCtxSw
				
				
				OSCtxSw 
								STMFD 	sp!, {lr} 					; OSCtxSw是被调用的,lr的值就是调用前的PC值,入栈 
								STMFD 	sp!, {r0-r12,lr} 		; 将lr和其他寄存器入栈 
								MRS 		r4, cpsr 						;通过MRS指令将cpsr入栈 
								STMFD 	sp!, {r4} 					; 被挂起的当前任务的寄存器保存完毕,下面接着保存该 
																						;任务的堆栈指针,以便下次恢复时,可以找到其堆栈指针,便可恢复其寄存器 
																						
								LDR r4, =OSTCBCur 					; 得到当前TCB块的地址,传给r4 
								LDR r5, [r4] 								; 将OSTCBCur中的值传给r5,注意OSTCBCur存的是指针 
								STR sp, [r5] 								; 将当前任务的sp传到OSTCBCur存的指针中去 
								
								;进行任务切换
								B			OSIntCtxSw_0
				;/*********************************************************************************************************
				;** 函数名称: OSIntCtxSw
				;** 功能描述: 中断退出时的入口
				;** 输 入:   R3    :当前任务的状态寄存器CPSR(即SPSR的值)
				;**           R4-R12:当前任务的R4-R11
				;**           当前处理器模式的堆栈结构(出栈次序):R0-R3、R12、PC(当前任务的)
				;** 输 出 :  无
				;** 全局变量: OSPrioCur,OSPrioHighRdy,OSPrioCur,OSPrioHighRdy
				;** 调用模块: 无
				;** 
				;任务切换退出中断
				;080204,huangsl,任务切换时必须保证 R13 指向正确的堆栈,否则会 DATA ABORT.目前发现 FFT 运算会使用 R13 作为
				;临时寄存器,此时中断发生 任务切换会 死机.
				;**-------------------------------------------------------------------------------------------------------
				;********************************************************************************************************/
				OSIntCtxSw
				                                                    ;下面为保存任务环境
								;前 处于 IRQ 状态,并且 堆栈次序为  R0-R3、R12、PC,里面保存的时被中断的任务的 context.
								;首先出栈                                                  
				        LDR     R2, [SP, #20]                       ;获取PC
				        LDR     R12, [SP, #16]                      ;获取R12
				        
				        ;保存当前 CPSR(IRQ STATE)
				        MRS     R0, CPSR
				        
				        ;切换到 SVC模式(任务运行模式)
				        MSR     CPSR_c, #SVCMODE|NOINT			;局部修改 CPSR,该指令可能不支持
				        MOV     R1, LR
				        STMFD   SP!, {R1-R2}                        ;保存LR,PC
				        STMFD   SP!, {R4-R12}                       ;保存R4-R12
								
							;下面保存 R0-R3,需要先出 IRQ STACK,然后保存到 SVC STACK.
				        MSR     CPSR_cxfs, R0
				        LDMFD   SP!, {R4-R7}                        ;获取R0-R3
				        ADD     SP, SP, #8                          ;出栈R12,PC,即忽略这两个数据
				        
				        MSR     CPSR_c, #SVCMODE|NOINT							;局部修改 CPSR,该指令可能不支持
				        STMFD   SP!, {R4-R7}                        ;保存R0-R3
				        
				        STMFD		SP!,{R3}														;保存CPSR
				                                                    
				                                                    ;保存当前任务堆栈指针到当前任务的TCB
				        LDR     R1, =OSTCBCur
				        LDR     R1, [R1]
				        STR     SP, [R1]
				
				        ;BL      OSTaskSwHook                        ;调用钩子函数
				 
				OSIntCtxSw_0                                                  ;OSPrioCur 				        LDR     R4, =OSPrioCur
				        LDR     R5, =OSPrioHighRdy
				        LDRB    R6, [R5]
				        STRB    R6, [R4]
				                                                    ;OSTCBCur 				        LDR     R6, =OSTCBHighRdy
				        LDR     R6, [R6]
				        LDR     R4, =OSTCBCur
				        STR     R6, [R4]
								
				OSIntCtxSw_1
				        LDR 		sp, [r6] 											; 切换到新任务的堆栈 
				        
				        ;********测试堆栈数据***********
				        IF {FALSE}
				        MOV			R0,SP
				        BL			OSTaskStackCheck
				        ENDIF
				        ;********测试堆栈数据结束***********
				        
								LDMFD 	sp!, {r4} 									;从新任务堆栈中读取第一个参数(CPSR)到(r4) 
								
								MSR 		spsr_cxsf, r4 								;再传给cpsr,堆栈中的CPSR弹出到CPU的cpsr寄存器 
								LDMFD 	sp!, {r0-r12,lr,pc}^ 				;依次恢复该任务r0~r12,lr,pc,切换到该任务 
					
					;			MSR 		cpsr_cxsf, r4 								;直接传递给 CPSR,会导致开中断.
					;			LDMFD 	sp!, {r0-r12,lr,pc} 				;依次恢复该任务r0~r12,lr,pc,切换到该任务 
								                          
				;/*********************************************************************************************************
				;** 函数名称: __OSStartHighRdy
				;** 功能描述: uC/OS-II启动时使用OSStartHighRdy运行第一个任务,
				;**           OSStartHighRdy会调用__OSStartHighRdy
				;** 输 入:   无
				;** 输 出 :  无
				;** 全局变量: OSRunning,OSTCBCur,OSTCBHighRdy,OsEnterSum
				;** 调用模块: OSTaskSwHook
				;**-------------------------------------------------------------------------------------------------------
				;********************************************************************************************************/
				
				OSStartHighRdy
				
				 				;告诉uC/OS-II自身已经运行
				        LDR     R4, =OSRunning
				        MOV     R5, #1
				        STRB    R5, [R4]
				
				        ;BL      OSTaskSwHook                    ;调用钩子函数
				
				        LDR     R6, =OSTCBHighRdy
				        LDR     R6, [R6]
				        B       OSIntCtxSw_1
				        
				        
				OSDisableInt 
								MRS r0, cpsr 				;由于任务和内核都运行在svc模式下,因此可方便地操作cpsr 
							;	STMFD sp!, {r0} 		; 保存当前的cpsr 
								ORR r1, r0, #0xc0 		;屏蔽FIQ,IRQ中断 
								MSR cpsr_c, r1 			;回写cpsr,只屏蔽IRQ中断 
								MOV pc, lr 					;返回 
					
					
				OSEnableInt 								;必须和 OSDisableInt 成对使用 
							;	LDMFD sp!, {r0} 		;弹出在 OSDisableInt 中被保存的cpsr 
								MSR cpsr_c, r0 			;恢复关中断前的cpsr 
								MOV pc, lr 					;返回     
				
				    END
				    
				;/*********************************************************************************************************
				;**                            End Of File
				;********************************************************************************************************/
							

相关资源