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

📄 os_cpu_a.s

📁 lwip在ucos上的移植源码
💻 S
字号:
@**********************************************************************
@****************************************************
@ $Workfile:   os_cpu_a.S   for SkyEye simulator    $  
@ $Revision: 1.1.1.1 $
@ $Author: chenyu $
@ $Email:   lmcs00@mails.tsinghua.edu.cn            $
@ $Date: 2003/05/17 05:06:55 $
@****************************************************
@****************************************************
@ $Workfile:   os_cpu_a.S   for SkyEye simulator    $  
@ $Revision: 1.1.1.1 $
@ $Author: chenyu $
@ $Email:   chenyu@hpclab.cs.tsinghua.edu.cn        $
@ $Email:   lmcs00@mails.tsinghua.edu.cn            $
@ $Date: 2003/05/17 05:06:55 $
@****************************************************
@****************************************************
@ $Workfile:   os_cpu_a.S   for SkyEye simulator    $  
@ $Revision: 1.1.1.1 $
@ $Author: chenyu $
@ $Email:   chenyu@hpclab.cs.tsinghua.edu.cn        $
@ $Email:   lmcs00@mails.tsinghua.edu.cn            $
@ $Date: 2003/05/17 05:06:55 $
@****************************************************
@ BASED ON
@***************************************************
@ $Workfile:   Os_cpu_a.s  $
@ $Revision: 1.1.1.1 $
@ $Author: chenyu $
@ $Date: 2003/05/17 05:06:55 $
@ **************************************************

@********************************************************************/
        .file   "os_cpu_a.S"

.text    

@/***********************************************************************
@
@ Function: OSStartHighRdy
@
@ Purpose:
@ 	   To start the task with the highest priority during OS startup
@
@ Processing:
@    See uC/OS-II Task Level Context Switch flow chart
@
@ Parameters: void
@
@ Outputs:  None
@
@ Returns:  void
@
@ Notes:
@   Called once during OSStart()
@
@*********************************************************************/
        .align  2
        .global OSStartHighRdy
        .type    OSStartHighRdy,function
OSStartHighRdy:
        BL 	OSTaskSwHook             @ Call user-defined hook function

        LDR 	r4,=OSRunning            @ Indicate that multitasking has started
        MOV 	r5, #1                   
        STRB 	r5, [r4]                 @ OSRunning = true

        LDR 	r4, =OSTCBHighRdy        @ Get highest priority task TCB address
        LDR 	r4, [r4]                 @ get stack pointer
        LDR 	sp, [r4]                 @ switch to the new stack

        LDMFD 	sp!, {r4}                @ pop new task s spsr
        MSR 	spsr, r4
        LDMFD 	sp!, {r4}                @ pop new task s psr
        MSR 	cpsr, r4
        LDMFD 	sp!, {r0-r12,lr,pc}      @ pop new task s r0-r12,lr & pc

 	
@/***********************************************************************
@
@ Function: OS_TASK_SW 
@
@ Purpose:
@ 	To perform a context switch from the Task Level.
@
@ Processing:
@    See uC/OS-II Task Level Context Switch flow chart
@
@ Parameters: void
@
@ Outputs:  None
@
@ Returns:  void
@
@ Notes:
@   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.
@
@*********************************************************************/
        .align  2
        .global OSCtxSw
        .type    OSCtxSw,function
OSCtxSw:
        STMFD 	sp!, {lr}                @ push pc (lr is actually be pushed in place of PC)
        STMFD 	sp!, {r0-r12,lr}         @ push lr & register file
        MRS 	r4, cpsr
        STMFD 	sp!, {r4}                @ push current psr
        MRS 	r4, spsr
        STMFD 	sp!, {r4}                @ push current spsr

_OSCtxSw:
        LDR 	r4, =OSPrioCur           @ OSPrioCur = OSPrioHighRdy
        LDR 	r5, =OSPrioHighRdy
        LDRB 	r6, [r5]
        STRB 	r6, [r4]
        
        LDR 	r4, =OSTCBCur            @ Get current task TCB address
        LDR 	r5, [r4]
        STR 	sp, [r5]                 @ store sp in preempted tasks s TCB

        BL 	OSTaskSwHook             @ call Task Switch Hook

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

        STR 	r6, [r4]                 @ set new current task TCB address

        LDMFD 	sp!, {r4}                @ pop new task spsr
        MSR 	spsr, r4
        LDMFD 	sp!, {r4}                @ pop new task cpsr
        MSR 	cpsr, r4
        LDMFD 	sp!, {r0-r12,lr,pc}      @ pop new task r0-r12,lr & pc


@***********************************************************************
@
@ Function: OSIntCtxSw
@
@ Purpose:
@ 	To perform a context switch from the interrupt level.
@
@ Processing:
@    See uC/OS-II Interrupt Level Context Switch flow chart
@
@ Parameters: void
@
@ Outputs:  None
@
@ Returns:  void
@
@ Notes:
@   Sets up the stacks and registers to call the task level
@   context switch
@
@*********************************************************************/
        .align  2
        .global OSIntCtxSw
        .type    OSIntCtxSw,function
OSIntCtxSw:	
        LDR 	r0, =OSIntCtxSwFlag      @ OSIntCtxSwFlag = true
        MOV 	r1, #1
        STR 	r1, [r0]
        
        MOV 	pc, lr                   @ return 

@/***********************************************************************
@
@yangye 2003-2-14
@changed this function name from OSTickISR to OSISR(it is not a TICK isr)
@ Function: OSISR
@
@ Purpose:
@ 	   The IRQ interrupt handler
@
@ Processing:
@    Saves context
@    Calls the IRQ dispatcher
@    Checks if context switch necessary
@    If not, restores context and returns from interrupt
@    If switch required, branches without link to IRQContextSwap
@       which performs context switch if interrupts not nested
@       and returns from interrupt to new context
@
@ Parameters: void
@
@ Outputs:  None
@
@ Returns:  void
@
@ Notes:
@   (1) here we use OSIntCtxSwFlag to indicate a request for int-level 
@       context switch 
@   (2) _IntCtxSw is used to perform a real switch operation
@
@*********************************************************************/	

	SAVED_LR_SVC:	.long   0x00000000        @ some variables for temparal use
	SAVED_LR_IRQ:	.long   0x00000000

	.align  2
        .global  OSISR
        .type    OSISR,function
OSISR:
	SUB	lr, lr, #4            
	STMFD	sp!, {r0-r12, lr}        @ push r0-r12 register file and lr( pc return address )
 
        MRS 	r4, spsr        
	STMFD 	sp!, {r4}                @ push current spsr_irq ( =cpsr_svc )

	BL	OSIntEnter
	@yangye 2003-2-14
	@call OSTimeTick in do_irq 
	@BL 	OSTimeTick
	BL	do_irq                   @ here do_IRQ is used to clear some virtual-hardware flags
	BL	OSIntExit
	
	LDR	r0, =OSIntCtxSwFlag      @ check if OSIntCtxFlag is marked as true
	LDR 	r1, [r0]
	CMP	r1, #1
	
	BEQ	_IntCtxSw	         @ if OSIntCtxFlag = true, then jump to _IntCtxSw
		
        LDMFD 	sp!, {r4}                @ get cpsr_svc from stack
	MSR     spsr, r4                 @ prepare spsr to return svc mode	
	LDMFD	sp!, {r0-r12, pc}^       @ recover r0-r12 and pc from stack, cpsr also


_IntCtxSw:
        MOV 	r1, #0                   @ clear OSIntCtxSwFlag = flase
        STR 	r1, [r0]
	
        LDMFD 	sp!, {r4}                @ restore spsr_irq 
	MSR 	spsr, r4 	
	LDMFD	sp!, {r0-r12, lr}        @ recover the irq stack pointer

	STR	lr, SAVED_LR_IRQ         @ save lr_irq to SAVED_LR_IRQ 	
	MOV	lr, #0x00000093          @ change forcely cpsr to svc mode
	MSR	cpsr, lr	
	STR     lr, SAVED_LR_SVC         @ save lr_svc to SAVED_LR_SVC
	LDR	lr, SAVED_LR_IRQ         @ get lr_irq value saved in SAVED_LR_IRQ 
	STMFD 	sp!, {lr}                @ push future task pc (lr_irq should be pushed in place of PC)
	LDR	lr, SAVED_LR_SVC         @ get lr_svc value saved in SAVED_LR_SVC 
        STMFD 	sp!, {r0-r12,lr}         @ push lr & r0-r12 register file
        MRS 	r4, spsr
        STMFD 	sp!, {r4}                @ push current psr
        MRS 	r4, spsr
        STMFD 	sp!, {r4}                @ push spsr

	B	_OSCtxSw                 @ jump to _OSCtxSw	
	
	
	
@/***********************************************************************
@
@ Functions: ARMDisableInt
@ 	     ARMEnableInt
@
@ Purpose:
@    Disable and enable IRQ and FIQ preserving current CPU mode.
@
@ Processing:
@    Push the cpsr onto the stack
@    Disable IRQ and FIQ interrupts
@    Return 
@
@ Parameters: void
@
@ Outputs:  None
@
@ Returns:  void
@
@ Notes:
@   (1) Can be called from SVC mode to protect Critical Sections. 
@   (2) Do not use these calls at interrupt level.
@   (3) Used in pairs within the same function level@
@   (4) Will restore interrupt state when called@ i.e., if interrupts
@       are disabled when DisableInt is called, interrupts will still
@       still be disabled when the matching EnableInt is called.
@   (5) Uses the method described by Labrosse as "Method 2".
@
@*********************************************************************/
        .align  2
        .global ARMDisableInt
        .type    ARMDisableInt,function
ARMDisableInt:	
	MRS	r0, cpsr
	STMFD	sp!, {r0}	         @ push current PSR
	ORR	r0, r0, #0x80
	MSR	cpsr, r0		 @ disable IRQ Int s

	MOV	pc, lr


    @------------------------------------------------------------------------
        .align  2
        .global ARMEnableInt
        .type    ARMEnableInt,function
ARMEnableInt:	
	LDMFD	sp!, {r0}                @ pop current PSR
	MSR	cpsr_c, r0               @ restore original cpsr	
	
	MOV	pc, lr
    @------------------------------------------------------------------------
    	

⌨️ 快捷键说明

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