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

📄 os_cpu_a.s

📁 ucos 在 arm9 芯片上的移植
💻 S
字号:
;/****************************************Copyright (c)**************************************************
;**                               广州周立功单片机发展有限公司
;**                                     研    究    所
;**                                        产品一部 
;**
;**                                 http://www.zlgmcu.com
;**
;**--------------文件信息--------------------------------------------------------------------------------
;**文   件   名: os_cpu_s.s
;**创   建   人: 陈明计
;**最后修改日期: 2003年6月19日
;**描        述: μCOS-II在LPC210x上的移植代码汇编代码部分,用ADS1.2编译
;**
;**--------------历史版本信息----------------------------------------------------------------------------
;** 创建人: 陈明计
;** 版  本: V1.0
;** 日 期: 2003年6月5日
;** 描 述: 原始版
;**
;**------------------------------------------------------------------------------------------------------
;** 修改人: 陈明计
;** 版  本: V1.1
;** 日 期: 2003年6月11日
;** 描 述: 配合Vectors.s更正IRQ嵌套的BUG而作相应的修改
;**
;**------------------------------------------------------------------------------------------------------
;** 修改人: 陈明计
;** 版  本: V1.2
;** 日 期: 2003年6月13日
;** 描 述: 按照μCOS-II V2.52的要求修改(以前是基于μCOS-II V2.0)
;**
;**------------------------------------------------------------------------------------------------------
;** 修改人: 陈明计
;** 版  本: V1.3
;** 日 期: 2003年6月19日
;** 描 述: 不完全按照μCOS-II V2.52的要求以提高效率
;**
;**--------------当前版本修订------------------------------------------------------------------------------
;** 修改人: 
;** 日 期:
;** 描 述:
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
;定义系统模式堆栈的大小
SVC_STACK_LEGTH     EQU         32
NoInt       EQU 0x80

USR32Mode   EQU 0x10
SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f
IRQ32Mode   EQU 0x12
FIQ32Mode   EQU 0x11

;T_bit用于检测进入异常前cpu是否处于THUMB状态
T_bit               EQU         0x20

    CODE32
    ; add by hgf
    PRESERVE8
    ; add by hgf
    AREA    |subr|, CODE, READONLY

            IMPORT  OSTCBCur                    ;指向当前任务TCB的指针
            IMPORT  OSTCBHighRdy                ;指向将要运行的任务TCB的指针
            IMPORT  OSPrioCur                   ;当前任务的优先级
            IMPORT  OSPrioHighRdy               ;将要运行的任务的优先级
            IMPORT  OSTaskSwHook                ;任务切换的钩子函数
            IMPORT  OSRunning                   ;uC/OS-II运行标志

            IMPORT  SWI_Exception               ;软中断异常处理程序
            IMPORT  OSIntEnter
            IMPORT  OSTimeTick
            IMPORT  OSIntExit
            IMPORT  tick_hook
            
            EXPORT  OSStartHighRdy            
            EXPORT  OSIntCtxSw                  ;中断退出时的入口,参见startup.s中的IRQ_Handler
            EXPORT  OSTickISR        
            
;/***********************************************************************
;
; 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 spsr_cxsf
        MSR     spsr_cxsf, r4
        LDMFD   sp!, {r4}                ; pop new task s psr
        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:
;   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
        IMPORT  OSPrioCur
        IMPORT  OSPrioHighRdy
        IMPORT  OSTCBCur
        IMPORT  OSTaskSwHook
        IMPORT  OSTCBHighRdy
        
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_cxsf
                
_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_cxsf
        MSR     spsr_cxsf, 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: 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
;
;*********************************************************************/
        EXPORT  OSIntCtxSw
        IMPORT  OSIntCtxSwFlag
OSIntCtxSw
        LDR     r0, =OSIntCtxSwFlag      ; OSIntCtxSwFlag = true
        MOV     r1, #1
        STR     r1, [r0]
        
        MOV     pc, lr                   ; return 

SAVED_LR_USR    DCD   0x00000000         ; some variables for temparal use
SAVED_LR_IRQ    DCD   0x00000000
SAVED_SPSR      DCD   0x00000000


OSTickISR
        BL      OSIntEnter
        BL      OSTimeTick
        BL      tick_hook                ; 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_cxsf, r4            ; prepare spsr_cxsf to return svc mode
        LDMFD   sp!, {r0-r12,pc}^        
        
_IntCtxSw
        MOV     r1, #0                   ; clear OSIntCtxSwFlag = flase
        STR     r1, [r0]
        
        LDMFD   sp!, {r4}                ; restore spsr_cxsf_irq 
        MSR     spsr_cxsf, r4   
        str     r4, SAVED_SPSR
        LDMFD   sp!, {r0-r12, lr}        ; recover the irq stack pointer

        
        STR     lr,  SAVED_LR_IRQ         ; save lr_irq to SAVED_LR_IRQ  
        ; IRQ中断中的lr,则是表示中断之前运行到的地方,即最近一次用户模式下的PC指针
        MOV     lr,  #0x000000d0          ; change forcely cpsr to svc mode
        MSR     cpsr_cxsf, lr   
        ; USR模式下的LR,即跳转到当前USR的上一个LR
        STR     lr,  SAVED_LR_USR         ; 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_USR         ; get lr_svc value saved in SAVED_LR_SVC 
        
        STMFD   sp!, {r0-r12,lr}         ; push lr & r0-r12 register file
        ldr     r4,  SAVED_SPSR
        STMFD   sp!, {r4}                ; push current psr
        STMFD   sp!, {r4}                ; push spsr_cxsf
        
        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".
;
;*********************************************************************/
        EXPORT  ARMDisableInt
ARMDisableInt
    MRS r0, cpsr
    STMFD   sp!, {r0}            ; push current PSR
    ORR r0, r0, #0xC0
    MSR cpsr_c, r0       ; disable IRQ Int s

    MOV pc, lr


    ;------------------------------------------------------------------------
        EXPORT  ARMEnableInt
ARMEnableInt
    LDMFD   sp!, {r0}                ; pop current PSR
    MSR cpsr_c, r0               ; restore original cpsr    

    MOV pc, lr



        
    END
;/*********************************************************************************************************
;**                            End Of File
;********************************************************************************************************/

⌨️ 快捷键说明

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