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

📄 os_cup_a.s

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 S
字号:
;******************************************************************************
;
; os_cpu_a.s
;
; Architecture specific code for AT91M40800
;
; eking
; 2004-06-01
;

;
; change log
; -----------
; 01e,20040713,eking  Define LINK_SAVE PSR_SAVE in os_cpu_c.c, fixed run in FLASH error bug.
; 01d,20040712,eking  Modify OSIntCtxSw fixed stack error bug.
; 01c,20040710,eking  Modify OSTickISR according AT91 interrupt handle flow.
; 01b,20040610,eking  Modify ARMDisableInt and ARMEnableInt, we do it by push and pop CPSR.
; 01a,20040601,eking  created from S3C44B0 ucosii.
;

;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
;                                          All Rights Reserved
;
;
;                                       Architecture Specific code
;                                          LARGE MEMORY MODEL
;
;                                        ARM Compatible Target
;
; File : OS_CPU_A.S
; By   : Jean J. Labrosse
;********************************************************************************************************




;********************************************************************************************

							AREA  |subr|, CODE, READONLY

							INCLUDE at91m40800.inc

;********************************************************************************************
;
; 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()
;
;********************************************************************************************
		EXPORT  OSStartHighRdy
		
		IMPORT  OSTaskSwHook
		IMPORT  OSTCBHighRdy 
		IMPORT  OSRunning
		
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 cpsr
        MSR     cpsr_cxsf, 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:
;   The whole function is executed in CRITICAL state. See OSSched().
;
;   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.
;
;********************************************************************************************
        EXPORT  OSCtxSw
        EXPORT  OSIntCtxSw
        EXPORT  OS_TASK_SW
        
        IMPORT  OSPrioCur
        IMPORT  OSPrioHighRdy
        IMPORT  OSTCBCur
        IMPORT  OSTaskSwHook
        IMPORT  OSTCBHighRdy

OSIntCtxSw
;- Push working register in SVC stack
		stmfd	sp!, {r4,r14}
		
;- Disable Interrupt and switch back in IRQ mode
        mrs	    r4, CPSR
        bic     r4, r4, #ARM_MODE_SVC
        orr     r4, r4, #I_BIT:OR:ARM_MODE_IRQ
        msr     CPSR_c, r4
;- Mark the End of Interrupt on the AIC
        ldr     r4, =AT91C_BASE_AIC
        str	    r4, [r4, #AIC_EOICR]
;- Pop IRQ stack
        ldmia   sp!, {r4, r14}
        ldmia	sp!, {r14}
        orr		r4, r4, #I_BIT
        msr     CPSR_cxsf, r4
;- Now in SVC mode, pop working register
		ldmia	sp!, {r4, r14}
		b       __OSCtxSw


OS_TASK_SW
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

        LDR     r4, =OSTCBCur            ; Get current task TCB address
        LDR     r5, [r4]
        STR     sp, [r5]                 ; store sp in preempted tasks s TCB



        IMPORT OSTaskSwHook
__OSCtxSw
        BL      OSTaskSwHook
        
        LDR     r4, =OSTCBHighRdy
        LDR     r4, [r4]
        LDR     r5, =OSTCBCur
        STR     r4, [r5]                 ; OSTCBCur = OSTCBHighRdy

        LDR     r6, =OSPrioHighRdy
        LDRB    r6, [r6]
        LDR     r5, =OSPrioCur
        STRB    r6, [r5]                 ; OSPrioCur = OSPrioHighRdy

        LDR     sp, [r4]
        LDMFD   sp!, {r4}                ; pop new task cpsr
        MSR     cpsr_cxsf, r4
        LDMFD   sp!, {r0-r12,lr,pc}      ; pop new task r0-r12,lr & pc



;********************************************************************************************
;
; Function: OSTickISR
;
; 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
;
;********************************************************************************************

	    EXPORT  OSTickISR
	    IMPORT  OSIntEnter
	    IMPORT  OSTimeTick
	    IMPORT  OSIntExit

		IMPORT  LINK_SAVE
		IMPORT  PSR_SAVE
		IMPORT  R4_SAVE

OSTickISR

;- Adjust and save LR_irq in IRQ stack and LINK_SAVE
		sub     lr, lr, #4
		stmfd   sp!, {r4, lr}
		
;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
        ldr     r4, =AT91C_BASE_AIC
        str     r4, [r4, #AIC_IVR]

		ldr     r4, =LINK_SAVE
		str     lr, [r4]                 ; LINK_SAVE = lr_irq

                                
;- Save SPSR in IRQ stack and PSR_SAVE
		mrs     lr, spsr
		stmfd	sp!, {lr}
		
		str     lr, [r4, #4]             	; PSR_SAVE = spsr_irq
;read the interrupt status reg to clear it
        ldr     r4,=AT91C_BASE_TC0			; load tc0  base address <- eking ->
        ldr     r4,[r4, #0x020]				; read from status register offse
             	 
        ldr     r4, [sp, #(1*4)]            ;get value of r4          
;- Switch to previous mode with interrupt disabled???这里中断如果禁止,那什么时候打开呢???
		;orr     lr, lr, #I_BIT				; Mask irq for context switching before////这里应该不要关中断 
		msr     cpsr_cxsf, lr				; returning back from irq mode.
 

		stmfd	sp!, {lr}
		stmfd   sp!, {r0-r12, lr}

		ldr     r4, =LINK_SAVE
		ldr     lr, [r4, #0]
		str     lr, [sp, #(14*4)]        	; the return address for pc.

		ldr     r4, [r4, #4]             	; r4 = PSR_SAVE,
		stmfd	sp!, {r4}                	; CPSR of the task

		ldr		r4, =OSTCBCur
		ldr		r4, [r4]
		str		sp, [r4]                 	; OSTCBCur -> stkptr = sp

		BL		OSIntEnter
		BL		OSTimeTick
		BL		OSIntExit

__jump
;- Disable Interrupt and switch back in IRQ mode
        mrs	    r4, CPSR
        bic     r4, r4, #ARM_MODE_SVC
        orr     r4, r4, #I_BIT:OR:ARM_MODE_IRQ
        msr     CPSR_c, r4
;- Mark the End of Interrupt on the AIC
        ldr     r4, =AT91C_BASE_AIC
        str	    r4, [r4, #AIC_EOICR]
;- Pop IRQ stack
        ldmfd   sp!, {r4, r14}
        ldmfd	sp!, {r14}
        orr		r4, r4, #I_BIT
        msr     CPSR_cxsf, r4
;- Now in SVC mode
		ldmfd	sp!, {r4}
		msr		CPSR_cxsf, r4
		ldmfd	sp!, {r0-r12,lr,pc}


;********************************************************************************************
;
; 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".
;
;********************************************************************************************


        EXPORT  ARMDisableInt
        
ARMDisableInt
		mrs 	r0, cpsr
		stmfd	sp!, {r0}                ; push current PSR
		orr 	r0, r0, #I_BIT
		msr 	cpsr_c, r0                   ; disable IRQ Int s

		bx		lr

        EXPORT  ARMEnableInt
        
ARMEnableInt
		ldmfd	sp!, {r0}                ; pop current PSR
		msr 	cpsr_c, r0                   ; restore original cpsr    

		bx		lr
        

;---------------------------------------------------------------------
; function : dump stack
; Only for debug
;---------------------------------------------------------------------
        EXPORT  DmpStk
DmpStk
        LDR     r0, =Dump_Pool
        MOV     r1, sp
        MOV     r2, sp
        ADD     r2, r2, #64
DmpLoop
        LDR     r3, [r1]
        STR     r3, [r0]
        ADD     r0, r0, #4
        ADD     r1, r1, #4
        CMP     r1, r2
        BNE     DmpLoop
        MOV     pc, lr

        ALIGN
Dump_Pool   DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
            DCD     0
        END

⌨️ 快捷键说明

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