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

📄 os_cpu_a.s

📁 提高μCOS-II在ARM上执行效率的几种方法》相应代码
💻 S
📖 第 1 页 / 共 2 页
字号:
        
	; push lr_svc is lr, push lr and r0-r12
	LDR 	lr, 	SAVED_LR_SVC 
    STMFD 	sp!, 	{r0-r12} 
    STMFD   sp!,    {lr}
        
	LDR 	r4, 	SAVED_SPSR
    STMFD 	sp!, 	{r4} 
    STMFD 	sp!, 	{r4} 
    
    B _OSCtxSw 

    ]   ;end of method 2
;**********************************************************
;			INT_PORT_METHOD 3
;**********************************************************

	[ INT_PORT_METHOD = 3	
EInt0Isr
	SUB	lr,  lr, #4
	STMFD	sp!, {r0-r12, lr}	

	bl 		OSIntEnter
	
	; ClearPending(BIT_EINT0);
	LDR		r0,		=SRCPND
	LDR		r1,		=BIT_EINT0
	STR		r1,		[r0]
	LDR		r0,		=INTPND
	STR		r1,		[r0]
	
	; OSSemPost(mysem);
	LDR     r1,     =mysem
	LDR     r0,     [r1]
	BL      OSSemPost
	
	SET_TIMER   
	
	BL		OSIntExit
	
	LDMFD		sp!,	{r0-r12, pc}^
OSTickISR
	; lr - 4 will be the return address(pc). in all task stack we
	; get r0-r12, pc(lr_irq), cpsr(spsr_irq), but now sp_svc, lr_svc, spsr_svc
	; is not available.
	SUB	    lr,  lr, #4
	STMFD	sp!, {r0-r12, lr}	
	
	bl 		OSIntEnter
	bl		OSTimeTick
	
	; ClearPending(BIT_TIMER0);
	LDR		r0,		=SRCPND
	LDR		r1,		=BIT_TIMER0
	STR		r1,		[r0]
	LDR		r0,		=INTPND
	STR		r1,		[r0]
	
	BL		OSIntExit
	
	LDMFD		sp!, {r0-r12, pc}^

OSIntCtxSw
    ;**********************************************************
    ;		adjust sp to just enter isr(after push registers)
    ;**********************************************************
	add     sp,	sp,	#0x10

    ;**********************************************************************
    ; save information before leave irq mode
	;**********************************************************************

	;save spsr_irq, sp_irq(need to copy to sp_svc)
    MRS 	r0,	    spsr
    MOV     r2,     sp
   
	;**********************************************************************
	; change to svc
	;**********************************************************************

	MRS 	r1, 	cpsr
    ORR 	r1, 	r1,		#1 
    MSR 	cpsr_cxsf,	    r1 

	;**********************************************************************
	; copy sp_irq to svc_irq
	;**********************************************************************
    MOV     sp,     r2

	;**********************************************************************
    ; push registers 
	;**********************************************************************

    STMFD 	sp!, 	{lr} 
        
    STMFD 	sp!, 	{r0} 
    STMFD 	sp!, 	{r0} 
    
    B _OSCtxSw 

    ]   ;end of method 3
;**********************************************************
;			INT_PORT_METHOD 4
;**********************************************************

	[ INT_PORT_METHOD = 4	
EInt0Isr
	
	; ClearPending(BIT_EINT0);
	LDR		r0,		=SRCPND
	LDR		r1,		=BIT_EINT0
	STR		r1,		[r0]
	LDR		r0,		=INTPND
	STR		r1,		[r0]
	
    ; re-enalbe the ISR bit in CPSR
    msr     cpsr_c, #0x00000053
    
	bl 		OSIntEnter
	
	; OSSemPost(mysem);
	LDR     r1,     =mysem
	LDR     r0,     [r1]
	BL      OSSemPost
	
	SET_TIMER    
	
	BL		OSIntExit
	
    LDMFD       sp!, {r0}
    msr         cpsr_cxsf,  r0
    LDMFD       sp!, {lr}
	LDMFD		sp!, {r0-r12, pc}
	
OSTickISR
    
	; before re-enable the ISR bit in CPSR ClearPending(BIT_TIMER0);
	LDR		r0,		=SRCPND
	LDR		r1,		=BIT_TIMER0
	STR		r1,		[r0]
	LDR		r0,		=INTPND
	STR		r1,		[r0]

    ; re-enalbe the ISR bit in CPSR
    msr     cpsr_c, #0x00000053

	bl 		OSIntEnter
	bl		OSTimeTick
	
	BL		OSIntExit
	
    LDMFD       sp!, {r0}
    msr         cpsr_cxsf,  r0
    LDMFD       sp!, {lr}
	LDMFD		sp!, {r0-r12, pc}

OSIntCtxSw
    ;**********************************************************
    ;		adjust sp to just enter isr(after push registers)
    ;**********************************************************
	add     sp,	sp,	#0x10


	;**********************************************************************
    ; all other registers are pushed except the spsr 
	;**********************************************************************
    mrs     r0,     spsr
    STMFD 	sp!, 	{r0} 

    B _OSCtxSw 

    ]   ;end of method 4
;**********************************************************************
;	void OS_TASK_SW(void)
;	
;	Perform a context switch.
;
;	On entry, OSTCBCur and OSPrioCur hold the current TCB and priority
;	and OSTCBHighRdy and OSPrioHighRdy contain the same for the task
;	to be switched to.
;
;	The following code assumes that the virtual memory is directly
;	mapped into  physical memory. If this is not true, the cache must 
;	be flushed at context switch to avoid address aliasing.
;**********************************************************************


OS_TASK_SW

	;**********************************************************************
	; push the cpu status registers
	;**********************************************************************
	
	STMFD	sp!, {lr}		; save pc
	STMFD	sp!, {r0-r12}	; save registers and ret address
	STMFD	sp!, {lr}		; save lr
	MRS	r4, CPSR
	STMFD	sp!, {r4}		; save current PSR
	MRS	r4, SPSR	
	STMFD	sp!, {r4}		; save SPSR
	
_OSCtxSw	
	;**********************************************************************
	; store sp to OSTCBCur->OSTCBStkPtr
	;**********************************************************************

	; Get current task TCB address
	LDR	r4, =OSTCBCur
	LDR	r5, [r4]
	STR	sp, [r5]		; store sp in preempted tasks's TCB
	
	;**********************************************************************
	; store sp to OSTaskSwHook();
	;**********************************************************************

	;**********************************************************************
	; OSTCBCur  = OSTCBHighRdy;
    ; OSPrioCur = OSPrioHighRdy;
	;**********************************************************************

	; OSPrioCur = OSPrioHighRdy, this is a 8bit value
	LDR		r4, =OSPrioCur
	LDR		r5, =OSPrioHighRdy
	LDRB	r6, [r5]
	STRB	r6, [r4]
	
	; OSTCBCur = OSTCBHighRdy
	LDR		r4, =OSTCBCur
	LDR		r5, =OSTCBHighRdy
	LDR		r6, [r5]
	STR		r6, [r4]
	
	;**********************************************************************
	; get sp in OSTCBHighRdy->OSTCBStkPtr;
	;**********************************************************************

	; Get highest priority task TCB address
	LDR		r6, =OSTCBHighRdy
	LDR		r6, [r6]
	LDR		sp, [r6]		; get new task's stack pointer

	;**********************************************************************
	; pop the cpu status registers
	;**********************************************************************

   ; restore task's mode regsiters
	LDMFD	sp!, {r4}
	MSR	SPSR_cxsf, r4
	LDMFD	sp!, {r4}
	MSR	CPSR_cxsf, r4

    ; return in new task context
    LDMFD   sp!, {lr}
    LDMFD	sp!, {r0-r12, pc}


;************************************************
;	void OSStartHighRdy(void)
;	
;	Start the task with the highest priority;
;************************************************


OSStartHighRdy
	
	;***********************************************
	;	Call user definable OSTaskSwHook();
	;***********************************************

	;***********************************************
	;	Stack pointer = OSTCBHighRdy->OSTCBStkPtr;
	;***********************************************
	
	LDR	r5, =OSTCBHighRdy	; Get highest priority task TCB address, r5 = &OSTCBHighRdy

	LDR	r5, [r5]				; get stack pointer. r5 == OSTCBHighRdy
	LDR	sp, [r5]				; switch to the new stack. sp = *OSTCBHighRdy 
								; and is OSTCBHighRdy->OSTCBStkPtr, because OSTCBStkPtr is the first unit.
	
	;***********************************************
	;OSRunning = 1
	;***********************************************
	
	LDR  r0, =OSRunning
	LDR  r1, =1
	STRB r1, [r0]				;note: OSRunning is a bit8 value

	;***********************************************
	; OSTCBCur = OSTCBHighRdy
	;***********************************************
	LDR	r4, =OSTCBCur		; Get current task TCB address
	STR	r5, [r4]				; set new current task TCB address
	
	;***********************************************
	; Restore all processor registers from the new task's stack;             
    ; Execute a return from interrupt instruction;                           
	;***********************************************

	; get spsr and cpsr. the two registers is the fisrt two unit in the stack
	LDMFD	sp!, {r4}		; YYY
	MSR	SPSR_cxsf, r4
	LDMFD	sp!, {r4}		; get new state from top of the stack
	MSR	CPSR_cxsf, r4		; CPSR should be SVC32Mode

	; get other value in stack
    LDMFD   sp!, {lr}
	LDMFD	sp!, {r0-r12,pc }	; start the new task

	END

⌨️ 快捷键说明

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