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

📄 os_cpu_a.asm

📁 UcOS2.76在ATMEL AT91RM9200 ARM9上的移植代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
        LDR     R0, ??OS_TaskSwHook     ; OSTaskSwHook();
        MOV     LR, PC
        BX      R0

        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]

        LDR     SP,[R6]                 ; SP = OSTCBHighRdy->OSTCBStkPtr;

                                        ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R4}               ;    Pop new task's CPSR
        MSR     SPSR_cxsf, R4

        LDMFD   SP!, {R0-R12,LR,PC}^    ;    Pop new task's context


;*********************************************************************************************************
;                                      IRQ Interrupt Service Routine
;*********************************************************************************************************

        RSEG CODE:CODE:NOROOT(2)
        CODE32

OS_CPU_IRQ_ISR

	STMFD	sp!, {r4}                ;/* 这个SP是IRQ模式下的*/
	
	LDR		r4, =LINK_SAVE
	STR		lr, [r4]				 ;/* LINK_SAVE = lr_irq */

	LDR		lr, =PSR_SAVE
	MRS		r4,	spsr
	STR		r4, [lr]			 ;/*	 PSR_SAVE = spsr_irq  */


	LDMFD	sp!, {r4}                ;/* 重新恢复R4 */
	
	MRS		lr,	spsr
	ORR		lr, lr,	#0x80		;/*	 Mask irq for context switching before */
	MSR		cpsr_cxsf, lr 		;/*	returning back from irq mode.我们还没有 */
								;	/* 保存好现场,如果打开中断,就有可能发生新的 */
								;	/* 抢占式调度,于是这个现场就OVER了。现场保 */
								;	/* 护和现场恢复都要一气呵成 */

	SUB		sp, sp, #4			;	 /* Space for PC  这个SP是svc(任务)模式下的*/
	STMFD	sp!, {r0-r12, lr}

	LDR		r4, =LINK_SAVE
	LDR		lr, [r4, #0]
	SUB		lr, lr, #4			;	 /* PC = LINK_SAVE - 4 */
	STR		lr, [sp, #(14*4)]	;	 /* SAVE PC [..]the return address for pc */

	LDR		r4, =PSR_SAVE
	LDR		r4, [r4]			; /* r4 = PSR_SAVE */
	STMFD	sp!, {r4}		      ;   /* CPSR of the task */

 	LDR		r5, =OSIntNesting
 	LDRB 	r4, [r5]
 	ADD     r4, r4, #1   ;/* OSIntNesting++ */
 	STRB     r4, [r5]
 	CMP		r4, #1
 	
 	BNE		NOT_FIRST
 	
	LDR		r4, =OSTCBCur
	LDR		r4, [r4]
	STR		sp, [r4]				; /* OSTCBCur -> stkptr = sp  保存现场完毕 */

NOT_FIRST

	LDR  r4, =0xFFFFF100  ;AT91C_AIC_IVR
	LDR  r4, [r4]				;/*获得中断向量,同时清除中断,边沿触发时功能同上面注释得的代码*/
	CMP	 r4, #0
	BEQ   EXIT_INT

    MRS     R0,CPSR                     ;/* 开中断*/
    AND     R1,R0,#0xffffff7f;
    MSR     CPSR_c,R1

	MOV  lr, pc
	BX   r4	

EXIT_INT
    MRS     R0,CPSR                     ;/*关闭中断*/
    ORR     R4,R0,#0x80;
    MSR     CPSR_c,R4
								
	LDR  r4, =0xFFFFF130  ;AT91C_AIC_EOICR
	STR  r0, [r4]				;/*中断服务程序处理完成*/
	
	BL	OSIntExit
	
	LDMFD 	sp!, {r4}              ;  /* pop current task cpsr */
	MSR 	cpsr_cxsf, r4
	LDMFD 	sp!, {r0-r12,lr,pc}    ;  /*  pop current task r0-r12,lr & pc */



;*********************************************************************************************************
;                                      FIQ Interrupt Service Routine
;*********************************************************************************************************

        RSEG CODE:CODE:NOROOT(2)
        CODE32

OS_CPU_FIQ_ISR

        STMFD   SP!, {R1-R3}                   ; PUSH WORKING REGISTERS ONTO FIQ STACK

        MOV     R1, SP                         ; Save   FIQ stack pointer

        ADD     SP, SP,#12                     ; Adjust FIQ stack pointer

        SUB     R2, LR,#4                      ; Adjust PC for return address to task

        MRS     R3, SPSR                       ; Copy SPSR (i.e. interrupted task's CPSR) to R3

        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; Change to SVC mode

                                               ; SAVE TASK'S CONTEXT ONTO TASK'S STACK
        STMFD   SP!, {R2}                      ;    Push task's Return PC
        STMFD   SP!, {LR}                      ;    Push task's LR
        STMFD   SP!, {R4-R12}                  ;    Push task's R12-R4

        LDMFD   R1!, {R4-R6}                   ;    Move task's R1-R3 from FIQ stack to SVC stack
        STMFD   SP!, {R4-R6}
        STMFD   SP!, {R0}                      ;    Push task's R0    onto task's stack
        STMFD   SP!, {R3}                      ;    Push task's CPSR (i.e. FIQ's SPSR)

                                               ; HANDLE NESTING COUNTER
        LDR     R0, ??OS_IntNesting            ; OSIntNesting++;
        LDRB    R1, [R0]
        ADD     R1, R1,#1
        STRB    R1, [R0]

        CMP     R1, #1                         ; if (OSIntNesting == 1) {
        BNE     OS_CPU_FIQ_ISR_1

        LDR     R4, ??OS_TCBCur                ;     OSTCBCur->OSTCBStkPtr = SP
        LDR     R5, [R4]
        STR     SP, [R5]                       ; }

OS_CPU_FIQ_ISR_1
        MSR     CPSR_c, #(NO_INT | FIQ32_MODE) ; Change to FIQ mode (to use the FIQ stack to handle interrupt)

      ;  LDR     R0, ??OS_CPU_FIQ_ISR_Handler   ; OS_CPU_FIQ_ISR_Handler();
      ;  MOV     LR, PC
      ;  BX      R0

        MSR     CPSR_c, #(NO_INT | SVC32_MODE) ; Change to SVC mode

        LDR     R0, ??OS_IntExit               ; OSIntExit();
        MOV     LR, PC
        BX      R0

                                               ; RESTORE NEW TASK'S CONTEXT
        LDMFD   SP!, {R4}                      ;    Pop new task's CPSR
        MSR     SPSR_cxsf, R4

        LDMFD   SP!, {R0-R12,LR,PC}^           ;    Pop new task's context


;*********************************************************************************************************
;                                     POINTERS TO VARIABLES
;*********************************************************************************************************

        DATA

??OS_TaskSwHook:
        DC32    OSTaskSwHook

??OS_CPU_IRQ_ISR_Handler:
        DC32    OS_CPU_IRQ_ISR_Handler

??OS_CPU_FIQ_ISR_Handler:
        DC32    0; OS_CPU_FIQ_ISR_Handler

??OS_IntExit:
        DC32    OSIntExit

??OS_IntNesting:
        DC32    OSIntNesting

??OS_PrioCur:
        DC32    OSPrioCur

??OS_PrioHighRdy:
        DC32    OSPrioHighRdy

??OS_Running:
        DC32    OSRunning

??OS_TCBCur:
        DC32    OSTCBCur

??OS_TCBHighRdy:
        DC32    OSTCBHighRdy


LINK_SAVE:
        DC32	0x00
PSR_SAVE:
        DC32	0x00
INTMSK_SAVE:
        DC32	0x00


        END

⌨️ 快捷键说明

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