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

📄 os_cpu_a.s

📁 包括EPA协议栈
💻 S
字号:
;---------------------------------------------------------------------------------------------------
;-                                               uC/OS-II
;-                                         The Real-Time Kernel
;-
;-                               (c) Copyright 1992-2004, Micrium, Weston, FL
;-                                          All Rights Reserved
;-
;-                                           Generic ARM Port
;-
;- File      : OS_CPU_A.S
;- Version   : V1.60
;- By        : Jean J. Labrosse
;-
;- For       : ARM7 or ARM9
;- Mode      : ARM or Thumb
;- Toolchain : IAR-s EWARM V4.11a and higher
;---------------------------------------------------------------------------------------------------

ARM_MODE_USER           EQU     0x10
ARM_MODE_FIQ            EQU     0x11
ARM_MODE_IRQ            EQU     0x12
ARM_MODE_SVC            EQU     0x13
ARM_MODE_ABORT          EQU     0x17
ARM_MODE_UNDEF          EQU     0x1B
ARM_MODE_SYS            EQU     0x1F

I_BIT                   EQU     0x80
F_BIT                   EQU     0x40
T_BIT                   EQU     0x20

  IMPORT  OSRunning                    ; External references
  IMPORT  OSPrioCur
  IMPORT  OSPrioHighRdy
  IMPORT  OSTCBCur
  IMPORT  OSTCBHighRdy
  IMPORT  OSIntNesting
  IMPORT  OSIntExit
  
  EXPORT  OS_CPU_SR_Save               ; Functions declared in this file
  EXPORT  OS_CPU_SR_Restore
  EXPORT  OSStartHighRdy               
  EXPORT  OSCtxSw
  EXPORT  OSIntCtxSw

  AREA         OSCtxOPs, CODE, READONLY
  
  CODE32
  
;---------------------------------------------------------------------------------------------------
;-                                          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
  msr          CPSR_c, #I_BIT:OR:F_BIT:OR:ARM_MODE_SVC       ;- Switch to SVC mode with IRQ and FIQ disabled
  
  ldr          r4, =OSRunning                               ;- OSRunning = TRUE
  mov          r5, #1
  strb         r5, [r4]
                                                            ;- SWITCH TO HIGHEST PRIORITY TASK
  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          SPSR_cxsf, r4
  ldmfd        sp!, {r0-r12, lr, pc}^                       ;-  pop new task-s 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-s context onto the current task-s stack
;-              b) OSTCBCur->OSTCBStkPtr = SP;
;-              c) OSTaskSwHook();
;-              d) OSPrioCur             = OSPrioHighRdy;
;-              e) OSTCBCur              = OSTCBHighRdy;
;-              f) SP                    = OSTCBHighRdy->OSTCBStkPtr;
;-              g) Restore the new task-s context from the new task-s stack
;-              h) Return to new task-s 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
  stmfd        sp!, {lr}
  stmfd        sp!, {r0-r12, lr}
  mrs          r0, SPSR
  stmfd        sp!, {r0}

  ldr          r4, =OSPrioCur                               ;- OSPrioCur = OSPrioHighRdy
  ldr          r5, =OSPrioHighRdy
  ldrb         r6, [r5]
  strb         r6, [r4]
  
  ldr          r1, =OSTCBCur                                ;- OSTCBCur->OSTCBStkPtr = SP;
  ldr          r2, [r1]
  str          sp, [r2]
  
  ldr          r5, =OSTCBHighRdy                            ;- OSTCBCur  = OSTCBHighRdy;
  ldr          r6, [r5]
  str          r6, [r1]
  
  ldr          sp, [r6]                                     ;- SP = OSTCBHighRdy->OSTCBStkPtr;
  
  ldmfd        sp!, {r4}                                    ;- pop new task-s CPSR
  msr          SPSR_cxsf, r4
  ldmfd        sp!, {r0-r12, lr, pc}^                       ;- pop new task-s 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-s context from the new task-s stack
;-              f) Return to new task-s 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
;  ldr          r0, =OSTaskSwHook                            ;- OSTaskSwHook();
;  mov          lr, pc
;  bx           r0
  
  ldr          r4, =OSPrioCur                               ;- OSPrioCur = OSPrioHighRdy
  ldr          r5, =OSPrioHighRdy
  ldrb         r6, [r5]
  strb         r6, [r4]
  
  ldr          r4, =OSTCBCur                                ;- OSTCBCur  = OSTCBHighRdy;
  ldr          r5, =OSTCBHighRdy
  ldr          r6, [r5]
  str          r6, [r4]
  
  ldr          sp, [r6]                                     ;- SP = OSTCBHighRdy->OSTCBStkPtr;
  
  ldmfd        sp!, {r4}                                    ;- pop new task-s CPSR
  msr          SPSR_cxsf, r4
  ldmfd        sp!, {r0-r12, lr, pc}^                       ;- pop new task-s context

;---------------------------------------------------------------------------------------------------
;-                                   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-s functions that need to 
;-              disable interrupts.  You would restore the interrupt disable state by copying back -cpu_sr-
;-              into the CPU-s status register.
;-
;- Prototypes :     OS_CPU_SR  OS_CPU_SR_Save(void);
;-                  void       OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
;-
;-
;- Note(s)    : 1) These functions are used in general like this:
;-
;-                 void Task (void *p_arg)
;-                 {
;-                 #if OS_CRITICAL_METHOD == 3          /* Allocate storage for CPU status register */
;-                     OS_CPU_SR  cpu_sr;
;-                 #endif
;-
;-                          :
;-                          :
;-                     OS_ENTER_CRITICAL();             /* cpu_sr = OS_CPU_SaveSR();                */
;-                          :
;-                          :
;-                     OS_EXIT_CRITICAL();              /* OS_CPU_RestoreSR(cpu_sr);                */
;-                          :
;-                          :
;-                 }
;-
;-              2) OS_CPU_SaveSR() is implemented as recommended by Atmel-s application note:
;-
;-                    "Disabling Interrupts at Processor Level"
;---------------------------------------------------------------------------------------------------
OS_CPU_SR_Save
  mrs          r0, CPSR                     ; Set IRQ and FIQ bits in CPSR to disable all interrupts
  orr          r1, r0, #I_BIT:OR:F_BIT
  msr          CPSR_c, r1
  mrs          r1, CPSR                     ; Confirm that CPSR contains the proper interrupt disable flags
  and          r1, r1, #I_BIT:OR:F_BIT
  cmp          r1, #I_BIT:OR:F_BIT
  bne          OS_CPU_SR_Save               ; Not properly disabled (try again)
  mov          pc, lr                       ; Disabled, return the original CPSR contents in R0


OS_CPU_SR_Restore
  msr          CPSR_c, R0
  mov          pc, lr
  
  
  END

⌨️ 快捷键说明

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