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

📄 os_cpu_a.s

📁 ucos 在smartarm2200上的移植
💻 S
📖 第 1 页 / 共 2 页
字号:
;
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;
;                             (c) Copyright 1992-2006, Micrium, Weston, FL
;                                          All Rights Reserved
;
;                                           Generic ARM Port
;
; File      : OS_CPU_A.ASM
; Version   : V1.81
; By        : Jean J. Labrosse
;             Jean-Denis Hatier
;
; For       : ARM7 or ARM9
; Mode      : ARM or Thumb
; Toolchain : ADS1.2
;/********************************************************************************************************
; Modified by     : ZengFan
; Modified date   : 2009/03/30
; Descriptions    : 该文件是参考ucos官方的移植文件,并根据编译器不同和目标处理器不同做了部分修改
;********************************************************************************************************/
;                                           
;********************************************************************************************************
;                                           IMPORT / EXPORT FUNCTIONS
;/********************************************************************************************************
;从IAR移植到ADS的时候需要注意,二者对于外部全局变量和外部函数的声明以及内部函数的定义方式
;是不同的,所以移植的时候需要修改 ................................................zf
;********************************************************************************************************/
    IMPORT  OSRunning
    IMPORT  OSPrioCur
    IMPORT  OSPrioHighRdy
    IMPORT  OSTCBCur
    IMPORT  OSTCBHighRdy
    IMPORT  OSIntNesting
    IMPORT  OSIntExit
    IMPORT  OSTaskSwHook

    IMPORT  OS_CPU_ExceptHndlr
                                                                ; Functions declared in this file
    EXPORT  OS_CPU_SR_Save
    EXPORT  OS_CPU_SR_Restore
    EXPORT  OSStartHighRdy
    EXPORT  OSCtxSw
    EXPORT  OSIntCtxSw                                          ;?ZF

                                                                ; Functions related to exception handling
    EXPORT  OS_CPU_ARM_ExceptResetHndlr
    EXPORT  OS_CPU_ARM_ExceptUndefInstrHndlr
    EXPORT  OS_CPU_ARM_ExceptSwiHndlr
    EXPORT  OS_CPU_ARM_ExceptPrefetchAbortHndlr
    EXPORT  OS_CPU_ARM_ExceptDataAbortHndlr
    EXPORT  OS_CPU_ARM_ExceptAddrAbortHndlr
    EXPORT  OS_CPU_ARM_ExceptIrqHndlr
    EXPORT  OS_CPU_ARM_ExceptFiqHndlr



;********************************************************************************************************
;                                                EQUATES
;********************************************************************************************************

OS_CPU_ARM_CONTROL_INT_DIS        EQU  0xC0                     ; Disable both FIQ and IRQ
OS_CPU_ARM_CONTROL_FIQ_DIS        EQU  0x40                     ; Disable FIQ
OS_CPU_ARM_CONTROL_IRQ_DIS        EQU  0x80                     ; Disable IRQ
OS_CPU_ARM_CONTROL_THUMB          EQU  0x20                     ; Set THUMB mode
OS_CPU_ARM_CONTROL_ARM            EQU  0x00                     ; Set ARM mode

OS_CPU_ARM_MODE_MASK              EQU  0x1F
OS_CPU_ARM_MODE_USR               EQU  0x10
OS_CPU_ARM_MODE_FIQ               EQU  0x11
OS_CPU_ARM_MODE_IRQ               EQU  0x12
OS_CPU_ARM_MODE_SVC               EQU  0x13
OS_CPU_ARM_MODE_ABT               EQU  0x17
OS_CPU_ARM_MODE_UND               EQU  0x1B
OS_CPU_ARM_MODE_SYS               EQU  0x1F

OS_CPU_ARM_EXCEPT_RESET           EQU  0x00
OS_CPU_ARM_EXCEPT_UNDEF_INSTR     EQU  0x01
OS_CPU_ARM_EXCEPT_SWI             EQU  0x02
OS_CPU_ARM_EXCEPT_PREFETCH_ABORT  EQU  0x03
OS_CPU_ARM_EXCEPT_DATA_ABORT      EQU  0x04
OS_CPU_ARM_EXCEPT_ADDR_ABORT      EQU  0x05
OS_CPU_ARM_EXCEPT_IRQ             EQU  0x06
OS_CPU_ARM_EXCEPT_FIQ             EQU  0x07


;********************************************************************************************************
;                                      CODE GENERATION DIRECTIVES
;********************************************************************************************************


    AREA    OSKernelSchedular, CODE, READONLY


;*********************************************************************************************************
;                                  CRITICAL SECTION METHOD 3 FUNCTIONS
;
; Description: Disable/Enable interrupts by preserving the state of interrupts.  Generally speaking you
;              would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
;              disable interrupts.  "cpu_sr" is allocated in all of uC/OS-II functions that need to
;              disable interrupts.  You would restore the interrupt disable state by copying back 'cpu_sr'
;              into the CPU status register.
;
; Prototypes : OS_CPU_SR  OS_CPU_SR_Save    (void);
;              void       OS_CPU_SR_Restore (OS_CPU_SR  os_cpu_sr);
;
;
; Note(s)    : (1) These functions are used in general like this:
;
;                 void Task (void  *p_arg)
;                 {
;                                                               /* Allocate storage for CPU status register.            */
;                 #if (OS_CRITICAL_METHOD == 3)
;                      OS_CPU_SR  os_cpu_sr;
;                 #endif
;
;                          :
;                          :
;                      OS_ENTER_CRITICAL();                     /* os_cpu_sr = OS_CPU_SR_Save();                        */
;                          :
;                          :
;                      OS_EXIT_CRITICAL();                      /* OS_CPU_SR_Restore(cpu_sr);                           */
;                          :
;                          :
;                 }
;
;              (2) OS_CPU_SR_Restore() is implemented as recommended by Atmel application note:
;
;                    "Disabling Interrupts at Processor Level"
;*********************************************************************************************************
OS_CPU_SR_Save
    MRS     R0, CPSR

OS_CPU_SR_Save_Loop
                                                                ; Set IRQ and FIQ bits in CPSR to disable all interrupts
    ORR     R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS
    MSR     CPSR_c, R1
    MRS     R1, CPSR                                            ; Confirm that CPSR contains the proper interrupt disable flags
    AND     R1, R1, #OS_CPU_ARM_CONTROL_INT_DIS
    CMP     R1,     #OS_CPU_ARM_CONTROL_INT_DIS
    BNE     OS_CPU_SR_Save_Loop                                 ; Not properly disabled (try again)
    BX      LR                                                  ; Disabled, return the original CPSR contents in R0


OS_CPU_SR_Restore                                               ; See Note #2
    MSR     CPSR_c, R0
    BX      LR


;*********************************************************************************************************
;                                           START MULTITASKING
;                                       void OSStartHighRdy(void)
;
; Note(s) : 1) OSStartHighRdy() MUST:
;              a) Call OSTaskSwHook() then,
;              b) Set OSRunning to TRUE,
;              c) Switch to the highest priority task.
;*********************************************************************************************************

OSStartHighRdy

                                                                ; Change to SYS mode
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)

    LDR     R0, =OSRunning                                     ; OSRunning = TRUE;
    MOV     R1, #1
    STRB    R1, [R0]

    LDR     R0, =OSTaskSwHook                                  ; OSTaskSwHook();
    MOV     LR, PC
    BX      R0

                                                                ; SWITCH TO HIGHEST PRIORITY TASK
    LDR     R0, =OSTCBHighRdy                                  ;    Get highest priority task TCB address
    LDR     R0, [R0]                                            ;    get stack pointer
    LDR     SP, [R0]                                            ;    switch to the new stack

    LDR     R0, [SP], #4                                        ;    pop new task CPSR
    MSR     CPSR_cxsf, R0
    LDMFD   SP!, {R0-R12, LR, PC}                               ;    pop new task context


;*********************************************************************************************************
;                         PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
;
; Note(s) : 1) OSCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
;
;           2) The pseudo-code for OSCtxSw() is:
;              a) Save the current task context onto the current task stack
;              b) OSTCBCur->OSTCBStkPtr = SP;
;              c) OSTaskSwHook();
;              d) OSPrioCur             = OSPrioHighRdy;
;              e) OSTCBCur              = OSTCBHighRdy;
;              f) SP                    = OSTCBHighRdy->OSTCBStkPtr;
;              g) Restore the new task      context from the new task stack
;              h) Return to new task code
;
;           3) Upon entry:
;              OSTCBCur      points to the OS_TCB of the task to suspend
;              OSTCBHighRdy  points to the OS_TCB of the task to resume
;*********************************************************************************************************

OSCtxSw
                                                                ; SAVE CURRENT TASK CONTEXT
    STMFD   SP!, {LR}                                           ;     Push return address
    STMFD   SP!, {LR}
    STMFD   SP!, {R0-R12}                                       ;     Push registers
    MRS     R0, CPSR                                            ;     Push current CPSR
    TST     LR, #1                                              ;     See if called from Thumb mode
    ORRNE   R0, R0, #OS_CPU_ARM_CONTROL_THUMB                   ;     If yes, Set the T-bit
    STMFD   SP!, {R0}

    LDR     R0, =OSTCBCur                                      ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R0]
    STR     SP, [R1]

    LDR     R0, =OSTaskSwHook                                  ; OSTaskSwHook();
    MOV     LR, PC
    BX      R0

    LDR     R0, =OSPrioCur                                     ; OSPrioCur = OSPrioHighRdy;
    LDR     R1, =OSPrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]

    LDR     R0, =OSTCBCur                                      ; OSTCBCur  = OSTCBHighRdy;
    LDR     R1, =OSTCBHighRdy
    LDR     R2, [R1]
    STR     R2, [R0]

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

                                                                ; RESTORE NEW TASK CONTEXT
    LDMFD   SP!, {R0}                                           ;    Pop new task CPSR
    MSR     CPSR_cxsf, R0

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


;*********************************************************************************************************
;                     PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
;
; Note(s) : 1) OSIntCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
;
;           2) The pseudo-code for OSCtxSw() is:
;              a) OSTaskSwHook();
;              b) OSPrioCur             = OSPrioHighRdy;
;              c) OSTCBCur              = OSTCBHighRdy;
;              d) SP                    = OSTCBHighRdy->OSTCBStkPtr;
;              e) Restore the new task context from the new task stack
;              f) Return to new task code
;
;           3) Upon entry:
;              OSTCBCur      points to the OS_TCB of the task to suspend
;              OSTCBHighRdy  points to the OS_TCB of the task to resume
;*********************************************************************************************************
;/********************************************************************************************************
; OSIntCtxSw函数是被中断异常处理函数调用,在调用它之前已经对当前任务进行了保护,在这里只需要恢复高优先级

⌨️ 快捷键说明

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