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

📄 os_cpu_a.s

📁 移植到GBA上的uCOS2.85操作系统和ZLGGUI用户图形界面
💻 S
字号:
;/********************************************************************************************************/
;/* 文件       os_cpu_a.s
;/* 作者       焦进星
;/* 时间       2008年1月29日
;/* 描述       ucosii 2.85 在GBA上与CPU有关的移植代码
;/* QQ         376637405
;/* E_mail     wyoujtg@163.com  
;/*            用VisualBoyAdvance 模拟器仿真
;/********************************************************************************************************/


;//模式与标志定义
ARM_MODE_USER           EQU     0x10
ARM_MODE_FIQ            EQU     0x11
ARM_MODE_IRQ            EQU     0x12
ARM_MODE_SVC            EQU     0x13
ARM_MODE_ABORT          EQU     0x17
ARM_MODE_UNDEF          EQU     0x1B
ARM_MODE_SYS            EQU     0x1F

I_BIT                   EQU     0x80
F_BIT                   EQU     0x40
T_BIT                   EQU     0x20

		EXTERN  OSRunning                    ;//声名输入
		EXTERN  OSPrioCur
		EXTERN  OSPrioHighRdy
		EXTERN  OSTCBCur
		EXTERN  OSTCBHighRdy
		EXTERN  OSIntNesting
		EXTERN  OSIntExit

		EXPORT  OS_CPU_SR_Save               ;//声名输出
		EXPORT  OS_CPU_SR_Restore
		EXPORT  OSStartHighRdy
		EXPORT  OSCtxSw
		EXPORT  OSIntCtxSw		             

;/*******************************************************************************************************/
;/*                                   第三种临界处理方式                                                */
;/*******************************************************************************************************/
			AREA    |.text|, CODE, READONLY
			CODE32

OS_CPU_SR_Save
        MRS     R0,CPSR                     ;//保存CPSR到R0并禁止IRQ和FIQ中断
        ORR     R1,R0,#(I_BIT | F_BIT)
        MSR     CPSR_c,R1
        BX      LR                         

OS_CPU_SR_Restore                           ;//将R0恢复到CPSR
        MSR     CPSR_c,R0
        BX      LR

;/********************************************************************************************************/
;/*                                  void OSStartHighRdy(void)                                           */  
;/*                                  进入最高级就绪任务                                                  */
;/********************************************************************************************************/
			AREA    |.text|, CODE, READONLY
			CODE32

OSStartHighRdy

        MSR     CPSR_c, #(I_BIT | F_BIT| ARM_MODE_SYS)	;//进入系统模式并禁止IRQ和FIQ中断 

        LDR     R4, OS_Running          ;//设定多任务开始标志
        MOV     R5, #1
        STRB    R5, [R4]
                              ; 
        LDR     R4, OS_TCBHighRdy       ;//得到最高优先级任务的TCB地址
        LDR     R6, [R4]                ;//得到该任务堆栈指针
        
        LDR     R4, [R6]                ;//R4(SP) = OSTCBHighRdy->OSTCBStkPtr
        MOV     SP, R4
                                        ;//恢复新任务上下文
        LDMFD   SP!, {R4}               
        MSR     CPSR_c, R4              ;//恢复新任务CPSR 
        LDMFD   SP!, {R0-R12,LR,PC}     ;//恢复新任务上下文
 
;/********************************************************************************************************/
;/*                         void OSCtxSw(void)                                                           */
;/*                         任务级任务切换函数                                                           */
;/********************************************************************************************************/
			AREA    |.text|, CODE, READONLY
			CODE32
OSCtxSw                                 ;//保存任务上下文
        STMFD   SP!, {LR}               ;//保存返回地址(LR代替PC)
        STMFD   SP!, {R0-R12, LR}       ;//保存寄存器
        MRS     R4,  CPSR               ;//保存CPSR
        STMFD   SP!, {R4}

OSCtxSw1
        LDR     R4, OS_TCBCur           ;//OSTCBCur->OSTCBStkPtr = SP
        LDR     R5, [R4]
        STR     SP, [R5]

        LDR     R4, OS_PrioCur          ;//OSPrioCur = OSPrioHighRdy
        LDR     R5, OS_PrioHighRdy
        LDRB    R6, [R5]
        STRB    R6, [R4]

        LDR     R4, OS_TCBCur           ;//OSTCBCur  = OSTCBHighRdy
        LDR     R6, OS_TCBHighRdy
        LDR     R6, [R6]
        STR     R6, [R4]

OSCtxSw2
        LDR     R4, [R6]                ;//R4(SP) = OSTCBHighRdy->OSTCBStkPtr
        MOV     SP, R4
                                        ;//恢复新任务上下文
        LDMFD   SP!, {R4}               
        MSR     CPSR_c, R4              ;//恢复新任务CPSR 
        LDMFD   SP!, {R0-R12,LR,PC}     ;//恢复新任务上下文

;/********************************************************************************************************/
;/*                         void OSIntCtxSw(void)                                                        */
;/*                         中断级任务切换函数                                                           */
;/********************************************************************************************************/
			AREA    |.text|, CODE, READONLY
			CODE32
OSIntCtxSw
;/********************************************************************
; IRQ STACK <LOW> R4 R14 | SPSR R0 R1 R2 R3 R11 R12 LR(PC) <HIGH>
;********************************************************************/

		ADD		SP, SP, #(0+8)*4		;//因不在IRQ模式保存上下文,先调整IRQ模式堆栈指针
										
		SUB		R0, SP, #3*4			

		MSR     CPSR_c, #(I_BIT | F_BIT | ARM_MODE_SYS)	;// 进入系统模式

        ;//作堆栈转换
		LDMIA	R0,  {R1-R3}			;// R11,R12,LR(PC)=>R1,R2,R3
		SUB		R0,  R0, #5*4			;// Moving (SPSR, R3-R0)
		STMFD	SP!, {R3}				;// R3(PC)=>[SP]
		STMFD	SP!, {R1-R2, LR}		;// R1(R11),R2(R12),LR=>[SP]
		STMFD	SP!, {R4-R10}			;// R4-R10=>[SP]

		LDMIA	R0,  {R4-R8}			;// SPSR,R0-R3=>R4-R8
		STMFD	SP!, {R4-R8}			;// R4(SPSR),R5-R8(R0-R3)=>[SP]
		
		B		OSCtxSw1		        ;//恢复新任务上下文

;/**********************************************************************************************************/
;/*				                       中断向量                                                            */
;/**********************************************************************************************************/
    IMPORT     IntrTable                    ;//声名输入
    EXPORT     intr_main                    ;//声名输出
    
    AREA    |.text|, CODE, READONLY
    CODE32
intr_main

		SUB		LR, LR, #4			        ;//调整和保存 LR_irq 在IRQ 堆栈

		STMFD	SP!, {R0-R3, R11, R12, LR}	;//保存用到的寄存器和LR到IRQ堆栈
									        ;//保存R11是为了用其暂存LR_svc						        
									        						        
		MRS		R14, SPSR		            ;//保存SPSR
		STMFD	SP!, {R14}

	   	LDR		R11, =OSIntNesting	        ;//OSIntNesting++,跟踪中断嵌套
		LDRB	R12, [R11]
		ADD		R12, R12,#1
		STRB	R12, [R11]
					             					             	             			            						             
        mov     r3, #0x4000000           ;// REG_BASE
        ldr     r2, [r3,#0x200]!         ;// Read REG_IE
        and     r1, r2, r2, lsr #16      ;// r1 = IE & IF
        ldr     r2, =IntrTable

        ands    r0, r1, #1               ;// V-Blank Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #2               ;// H-Blank Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #4               ;// V Counter Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #8               ;// Timer 0 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x10            ;// Timer 1 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x20            ;// Timer 2 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x40            ;// Timer 3 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x80            ;// Serial Communication Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x100           ;// DMA0 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x200           ;// DMA1 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x400           ;// DMA2 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x800           ;// DMA3 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x1000          ;// Key Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x2000          ;// Cart Interrupt

jump_intr
        strh    r0, [r3, #2]             ;// IF Clear
        ldr     r0, [r2]                 ;// Jump to user IRQ process
        
        MSR		CPSR_c, #ARM_MODE_SYS		;//进入SVC模式 开IRQ和FIQ中断
		MOV		R11, LR				        ;//R11<-LR_svc,暂存LR_svc
        
       	MOV  	LR, PC	    		        ;//中断服务例程返回用
       	 
        BX      r0                          ;//执行中断服务例程
        
		MOV		LR, R11					    ;//恢复LR
		
		MSR		CPSR_c, #(I_BIT | F_BIT | ARM_MODE_IRQ)	;//进入IRQ模式 禁止IRQ和FIQ中断
		
		BL		OSIntExit		                        ;//调用中断退出处理 OSIntExit()

		LDR		R0, =OSPrioCur		                    ;//if (OSPrioCur != OSPrioHighRdy) 需要调度
		LDR		R1, =OSPrioHighRdy
		LDRB	R0, [R0]
		LDRB	R1, [R1]
		CMP		R0, R1
		BNE		OSIntCtxSw			                    ;//执行中断任务切换OSIntCtxSw()

		LDMFD	SP!, {R14}			                    ;//恢复SPSR_irq from从IRQ堆栈
		MSR		SPSR_cxsf, R14

		LDMFD	SP!, {R0-R3, R11, R12, PC}^	            ;//恢复调整后的LR_irq,直接恢复PC返回,执行原子操作恢复新任务CPSR 
		
;/********************************************************************************************************/
;/*                                     指针变量                                                         */
;/********************************************************************************************************/
OS_IntExit
        DCD    OSIntExit

OS_IntNesting
        DCD    OSIntNesting

OS_PrioCur
        DCD    OSPrioCur

OS_PrioHighRdy
        DCD    OSPrioHighRdy

OS_Running
        DCD    OSRunning

OS_TCBCur
        DCD    OSTCBCur

OS_TCBHighRdy
        DCD    OSTCBHighRdy

        END
;/********************************************************************************************************/
;/*                                      结束文件                                                        */
;/********************************************************************************************************/        

⌨️ 快捷键说明

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