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

📄 os_cpu_a.asm

📁 uCOS-II在TMS320F2812上的移植
💻 ASM
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                              (c) Copyright 2002, Micrium, Inc., Weston, FL
;                                          All Rights Reserved
;
;                                               TI TMS320F2812
;
;
; File         : OS_CPU_A.S43
; By           : Jian Chen (yenger@hotmail.com)
;                Jean J. Labrosse
;********************************************************************************************************

;********************************************************************************************************
;                                           MACRO DEFINITIONS
;********************************************************************************************************
PUSHALL .MACRO
  PUSH AR1H:AR0H ; 32-bit
  PUSH XAR2      ; 32-bit
  PUSH XAR3      ; 32-bit
  PUSH XAR4      ; 32-bit
  PUSH XAR5      ; 32-bit
  PUSH XAR6      ; 32-bit
  PUSH XAR7      ; 32-bit
  PUSH XT        ; 32-bit
  PUSH RPC
  .ENDM
  
POPALL .MACRO
  POP RPC
  POP XT
  POP XAR7
  POP XAR6
  POP XAR5
  POP XAR4
  POP XAR3
  POP XAR2
  POP AR1H:AR0H
  .ENDM

;********************************************************************************************************
;                                  PUBLIC AND EXTERNAL DECLARATIONS
;********************************************************************************************************
  .REF _OSIntExit
  .REF _OSIntNesting

  .REF _OSISRStkPtr

  .REF _OSPrioCur
  .REF _OSPrioHighRdy

  .REF _OSRunning

  .REF _OSTCBCur
  .REF _OSTCBHighRdy

  .REF _OSTaskSwHook
  .REF _OSTimeTick
            
  .DEF _OSCtxSw
  .DEF _OSIntCtxSw
  .DEF _OSStartHighRdy
  
  .DEF _Timer2_Isr
  .DEF _OSTaskStkInit

;********************************************************************************************************
;                                  START HIGHEST PRIORITY READY TASK
;
; Description: This function is called by OSStart() to start the highest priority task that is ready to run.
;
; Note       : OSStartHighRdy() MUST:
;                 a) Call OSTaskSwHook() then,
;                 b) Set OSRunning to TRUE,
;                 c) Switch to the highest priority task.
;********************************************************************************************************
  .TEXT                    ; Program code

_OSStartHighRdy


  LCR  #_OSTaskSwHook

  MOV  DP,#_OSRunning            ;OSRunning = 1
  MOV  @_OSRunning,#01H

  MOV  *(0:_OSISRStkPtr),@SP     ;OSISRStkPTR = SP
 
  MOV DP,#_OSTCBHighRdy
  MOVZ AR4,@_OSTCBHighRdy        ;SP = OSTCBHighRdy
  MOV AL,*XAR4
  MOV @SP,AL

  POPALL                        ;pop all registers
             
  IRET                          ;emulate return from interrupt
  
;********************************************************************************************************
;                                     TASK LEVEL CONTEXT SWITCH
;
; Description: This function is called by OS_Sched() to perform a task level context switch.
;
; Note       : OSCtxSw() MUST:
;                 a) Save the current task's registers onto the current task stack
;                 b) Save the SP into the current task's OS_TCB
;                 c) Call OSTaskSwHook()
;                 d) Copy OSPrioHighRdy to OSPrioCur
;                 e) Copy OSTCBHighRdy to OSTCBCur
;                 f) Load the SP with OSTCBHighRdy->OSTCBStkPtr
;                 g) Restore all the registers from the high priority task stack
;                 h) Perform a return from interrupt
;********************************************************************************************************
_OSCtxSw
  PUSHALL                       ; push all registers             

  MOV  DP,#_OSTCBCur
  MOVZ AR4,@_OSTCBCur           ; OSTCBCur->OSTCBStkPtr = SP
  MOV  AL,@SP
  MOV  *XAR4,AL       

  LCR  #_OSTaskSwHook

  MOV  AL,*(0:_OSPrioHighRdy)   ; OSPrioCur = OSPrioHighRdy
  MOV  *(0:_OSPrioCur),AL
  
  MOV  DP,#_OSTCBHighRdy
  MOVZ AR4,@_OSTCBHighRdy      ; OSTCBCur  = OSTCBHighRdy
  MOV  *(0:_OSTCBCur),AR4
  MOV  AL,*XAR4
  MOV  @SP,AL                   ; SP        = OSTCBHighRdy->OSTCBStkPtr                          
             
  POPALL                        ; pop all registers
             
  IRET                          ; return from interrup
  
;********************************************************************************************************
;                                       ISR LEVEL CONTEXT SWITCH
;
; Description: This function is called by OSIntExit() to perform an ISR level context switch.
;
; Note       : OSIntCtxSw() MUST:
;                 a) Call OSTaskSwHook()
;                 b) Copy OSPrioHighRdy to OSPrioCur
;                 c) Copy OSTCBHighRdy to OSTCBCur
;                 d) Load the SP with OSTCBHighRdy->OSTCBStkPtr
;                 e) Restore all the registers from the high priority task stack
;                 f) Perform a return from interrupt
;********************************************************************************************************
_OSIntCtxSw

  LCR   #_OSTaskSwHook

  MOV  AL,*(0:_OSPrioHighRdy)   ; OSPrioCur = OSPrioHighRdy
  MOV  *(0:_OSPrioCur),AL
  
  MOV  DP,#_OSTCBHighRdy
  MOVZ AR4,@_OSTCBHighRdy      ; OSTCBCur  = OSTCBHighRdy
  MOV  *(0:_OSTCBCur),AR4
  MOV  AL,*XAR4
  MOV  @SP,AL                   ; SP        = OSTCBHighRdy->OSTCBStkPtr                          
             
  POPALL                        ; pop all registers
  IRET                          ; return from interrup

;********************************************************************************************************
;                                              TICK ISR
;
; Description: This ISR handles tick interrupts.  This ISR uses the Timera timer as the tick source.
;
; Notes      : 1) The following C pseudo-code describes the operations being performed in the code below.
;
;                 Save all the CPU registers
;                 if (OSIntNesting == 0) {
;                     OSTCBCur->OSTCBStkPtr = SP;
;                     SP                    = OSISRStkPtr;  /* Use the ISR stack from now on           */
;                 }
;                 OSIntNesting++;
;                 Enable interrupt nesting;                 /* Allow nesting of interrupts (if needed) */
;                 Clear the interrupt source;
;                 OSTimeTick();                             /* Call uC/OS-II's tick handler            */
;                 DISABLE general interrupts;               /* Must DI before calling OSIntExit()      */
;                 OSIntExit();
;                 if (OSIntNesting == 0) {
;                     SP = OSTCBHighRdy->OSTCBStkPtr;       /* Restore the current task's stack        */
;                 }
;                 Restore the CPU registers
;                 Return from interrupt.
;
;              2) ALL ISRs should be written like this!
;
;              3) You MUST disable general interrupts BEFORE you call OSIntExit() because an interrupt 
;                 COULD occur just as OSIntExit() returns and thus, the new ISR would save the SP of 
;                 the ISR stack and NOT the SP of the task stack.  This of course will most likely cause
;                 the code to crash.  By disabling interrupts BEFORE OSIntExit(), interrupts would be
;                 disabled when OSIntExit() would return.  This assumes that you are using OS_CRITICAL_METHOD
;                 #3 (which is the prefered method).
;
;              4) If you DON'T use a separate ISR stack then you don't need to disable general interrupts 
;                 just before calling OSIntExit().  The pseudo-code for an ISR would thus look like this:
;
;                 Save all the CPU registers
;                 if (OSIntNesting == 0) {
;                     OSTCBCur->OSTCBStkPtr = SP;
;                 }
;                 OSIntNesting++;
;                 Enable interrupt nesting;                 /* Allow nesting of interrupts (if needed) */
;                 Clear the interrupt source;
;                 OSTimeTick();                             /* Call uC/OS-II's tick handler            */
;                 OSIntExit();
;                 Restore the CPU registers
;                 Return from interrupt.
;********************************************************************************************************
_Timer2_Isr
  AND IER,#7FFFH             ;diable RTOSINT
  PUSHALL
  
  MOV AH,#0
  MOV AL,*(0:_OSIntNesting)
  BF TM_ISR_1,NEQ
  MOV DP,#_OSTCBCur
  MOVZ AR4,@_OSTCBCur        ; save task stack
  MOV AH,@SP
  MOV *XAR4,AH    
  MOV @SP,*(0:_OSISRStkPtr) ; load interrupt stack  TM_ISR_1
  ADD AL,#01
  MOV *(0:_OSIntNesting),AL
  EINT

  LCR #_OSTimeTick
  
  LCR #_OSIntExit
  
  MOV AH,#0
  MOV AL,*(0:_OSIntNesting)
  BF TM_ISR_2,NEQ
  MOV DP,#_OSTCBCur
  MOVZ AR4,@_OSTCBCur
  MOV AL,*XAR4
  MOV @SP,AL

TM_ISR_2  
  POPALL
  IRET

  .REF _OSExtIntExit
  .DEF _OSExtIntIsr
_OSExtIntIsr
  PUSHALL

  MOV DP,#_OSTCBCur
  MOVZ AR4,@_OSTCBCur        ; save task stack
  MOV AH,@SP
  MOV *XAR4,AH    

  LCR #_OSExtIntExit

  POPALL
  IRET  
;*********************************************************************************************************
;*                                        INITIALIZE A TASK'S STACK
;*
;* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
;*              stack frame of the task being created.  This function is highly processor specific.
;*
;* Arguments  : task          is a pointer to the task code
;*
;*              pdata         is a pointer to a user supplied data area that will be passed to the task
;*                            when the task first executes.
;*
;*              ptos          is a pointer to the top of stack.  It is assumed that 'ptos' points to
;*                            a 'free' entry on the task stack.  If OS_STK_GROWTH is set to 1 then 
;*                            'ptos' will contain the HIGHEST valid address of the stack.  Similarly, if
;*                            OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
;*                            of the stack.
;*
;*              opt           specifies options that can be used to alter the behavior of OSTaskStkInit().
;*                            (see uCOS_II.H for OS_TASK_OPT_???).
;*
;* Returns    : Always returns the location of the new top-of-stack' once the processor registers have
;*              been placed on the stack in the proper order.
;*
;* Note(s)    : The register passing convention for the IAR compiler is that the LEFTMOST two parameters
;*              are passed in registers:
;*              1st parameter:  R12 for a 16-bit value or,  R13:R12 for a 32-bit value
;*              2nd parameter:  R14 for a 16-bit value or,  R15:R14 for a 32-bit value
;*
;*              OSTaskStkInit() thus needs to place 'p_arg' in R12 since when the task is started, 'p_arg'
;*              is the FIRST argument of the task declaration:
;*
;*                 void  Task (void *p_arg)
;*                 {
;*                 }
;*********************************************************************************************************
;OS_STK  *OSTaskStkInit (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT16U opt)
;                        XAR4,                   XAR5       , -SP[4],       AL 
_OSTaskStkInit  
  ADDB SP,#04

  MOVL *-SP[2],XAR4
  MOV  *-SP[4],AL
  MOVL XAR4,*-SP[8]  ;XAR4 = ptos
  ADDB XAR4,#01
  AND AR4,#0FFFEH

  ASP
  NASP

  PUSH T:ST0
  POP ACC
  MOVL *XAR4++,ACC   ;ST0,T
  MOVL *XAR4++,ACC    ;ACC
  MOVL *XAR4++,P
  MOV *XAR4++,AR0    ;AR0
  MOV *XAR4++,AR1    ;AR1
  PUSH DP:ST1
  POP ACC
  MOVL *XAR4++,ACC   ;ST1,DP
  PUSH IER
  POP *XAR4++        ;IER
  PUSH DBGIER
  POP *XAR4++        ;DBGIER
  MOVL ACC,*-SP[2]
  MOVL *XAR4++,ACC   ;ADDR

  ADDB XAR4,#01

  MOVL ACC,XAR0
  MOV *XAR4++,AH     ;AR0H
  MOVL ACC,XAR1
  MOV *XAR4++,AH     ;AR1H
  MOVL *XAR4++,XAR2  ;XAR2
  MOVL *XAR4++,XAR3  ;XAR3
  MOVL ACC,*-SP[2]
  MOVL *XAR4++,ACC   ;XAR4 
  MOVL *XAR4++,XAR5  ;XAR5
  MOVL *XAR4++,XAR6  ;XAR6
  MOVL *XAR4++,XAR7  ;XAR7
  MOVL *XAR4++,XT    ;XT
  MOVL ACC,*-SP[2]
  MOVL *XAR4++,ACC   ;ADDR
  
  SUBB SP,#04
  LRETR
 

  .ref _c_int00
  .sect "codestart"
  LB _c_int00
  .end    

⌨️ 快捷键说明

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