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

📄 os_cpu_a.s

📁 zigbee 飞思卡尔 音频传输 基于ucos的所有源码
💻 S
📖 第 1 页 / 共 2 页
字号:
  MOVEM.L  D0-D7/A0-A6,(A7)     ; Save the registers of the current task

  MOVE.L   (_OSTCBCur),A1       ; Save the stack pointer in the suspended task TCB
  MOVE.L   A7,(A1)

  JSR      _OSTaskSwHook        ; Invoke user defined context switch hook

  MOVE.L   (_OSTCBHighRdy),A1   ; OSTCBCur = OSTCBHighRdy
  MOVE.L   A1,(_OSTCBCur)
  MOVE.L   (A1),A7			    ; Get the stack pointer of the task to resume
  
  MOVE.B   (_OSPrioHighRdy),D0  ; OSPrioCur = OSPrioHighRdy
  MOVE.B   D0,(_OSPrioCur)
  
  MOVEM.L  (A7),D0-D7/A0-A6     ; Restore the CPU registers
  LEA	   60(A7),A7

  RTE                           ; Run task


;******************************************************************************************
;                             INTERRUPT LEVEL CONTEXT SWITCH
;
;
; Description : This function is provided for backward compatibility.
;
; Arguments   : none
;
; Note(s)     : 1) The stack frame upon entry:
;
;                  SP +  0  ---->  Return PC of OSIntCtxSw()         Low Memory
;                     +  4         Return PC of OSIntExit()

;                     +  8         D0    (H)           
;                     + 12         D1    (H)
;                     + 16         D2    (H)
;                     + 20         D3    (H)
;                     + 24         D4    (H)
;                     + 28         D5    (H)
;                     + 32         D6    (H)
;                     + 36         D7    (H)

;                     + 40         A0    (H)
;                     + 44         A1    (H)
;                     + 48         A2    (H)
;                     + 52         A3    (H)
;                     + 56         A4    (H)
;                     + 60         A5    (H)
;                     + 64         A6    (H)

;                     + 68         SR of interrupted task  --   ColdFire SR area is 32 bits.
;                     + 72         PC of task                          High Memory
;********************************************************************************************************

_OSIntCtxSw: 
  JSR      _OSTaskSwHook        ; Invoke user defined context switch hook

  MOVE.L   (_OSTCBHighRdy),A1   ; OSTCBCur = OSTCBHighRdy
  MOVE.L   A1,(_OSTCBCur)
  MOVE.L   (A1),A7              ; CPU stack pointer = OSTCBHighRdy->OSTCBStkPtr
  
  MOVE.B   (_OSPrioHighRdy),D0  ; OSPrioCur = OSPrioHighRdy
  MOVE.B   D0,(_OSPrioCur)
  
  MOVEM.L  (A7),D0-D7/A0-A6     ; Pop all the CPU registers from the new task's stack
  LEA	   60(A7),A7

  RTE                           ; Run task



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

_OSIntExitCF:
    MOVE      SR, D0
    ORI.L     #$0700,D0             ; Disable interrupts
    MOVE      D0, SR
    
    MOVE.B    (_OSIntNesting),D0   
    SUBQ.L    #1,D0                ; OSIntNesting--
    MOVE.B    D0,(_OSIntNesting)     ; if (OSIntNesting == 0)
    TST.B     _OSIntNesting
    BNE       OSIntExitCF_Exit

    TST.B     _OSLockNesting        ; if (OSLockNesting == 0) 
    BNE       OSIntExitCF_Exit
                    
    MOVEQ.L   #0,D0                ; y = OSUnMapTbl[OSRdyGrp]
    MOVE.B    _OSRdyGrp,D0
    LEA       _OSUnMapTbl,A0
    MOVE.B    (A0,D0.L),D3         ; y is in D3
    
    
    MOVEQ.L   #0,D0                ;
    MOVE.B    D3,D0                ; copy y into D0
    LEA       _OSRdyTbl,A0         ;
    MOVEQ.L   #0,D1                ;
    MOVE.B    (A0,D0.L),D1         ; D1 = OSRdyTbl[y]
    LEA       _OSUnMapTbl,A0       ; OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]])
    MOVE.B    D3,D0
    LSL.L     #3,D0                ; D0 = (y << 3)
    MOVE.B    (A0,D1.L),D1         ; D1 = OSUnMapTbl[OSRdyTbl[y]]
    ADD.L     D1,D0                ; 
    MOVE.B    D0,_OSPrioHighRdy    ;
    
    MOVE.B    _OSPrioHighRdy,D0
    MOVE.B    _OSPrioCur,D1
    ANDI.L    #0xFF,D1
    ANDI.L    #0xFF,D0
    CMP.L     D1,D0                ; if (OSPrioHighRdy != OSPrioCur) { 
    BEQ       OSIntExitCF_Exit
          
    MOVEQ.L   #0,D0                ; OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
    MOVE.B    _OSPrioHighRdy,D0
    LEA       _OSTCBPrioTbl,A0
    MOVEA.L   (A0,D0.L*4),A0
    MOVE.L    A0,_OSTCBHighRdy
    
    ADDQ.L    #1,_OSCtxSwCtr      ; OSCtxSwCtr++; 
                   
                                  ; PERFORM INTERRUPT LEVEL CONTEXT SWITCH: 
    JSR      _OSTaskSwHook        ; Invoke user defined context switch hook

    MOVE.L   (_OSTCBHighRdy),A1   ; OSTCBCur = OSTCBHighRdy
    MOVE.L   A1,(_OSTCBCur)
    MOVE.L   (A1),A7              ; CPU stack pointer = OSTCBHighRdy->OSTCBStkPtr
  
    MOVE.B   (_OSPrioHighRdy),D0  ; OSPrioCur = OSPrioHighRdy
    MOVE.B   D0,(_OSPrioCur)

OSIntExitCF_Exit:
    MOVEM.L  (A7),D0-D7/A0-A6      ; Restore processor registers from stack
    LEA      60(A7),A7
    RTE                            ; Return to task or nested ISR



;********************************************************************************
;                               SYSTEM TICK ISR
;
; Description : This function is the ISR used to notify uC/OS-II that a system tick has occurred.  
;
; Arguments   : none
;
; Notes       : 1) You MUST increment 'OSIntNesting' and NOT call OSIntEnter()
;               2) You MUST save ALL the CPU registers as shown below
;               3) You MUST JUMP to OSIntExitCF() instead of call the function.
;               4) You MUST NOT use OSIntExit() to exit an ISR with the 68K.
;
;  Procedure : OSTickISR					    
;								    
;  The procedure is installed as the timer tick ISR and called   
;  each time TIMER0 on the MCF5282 reaches it's reference value.
;
;  Notice that all ISRs *must* leave the same stack context
;  at the time of the call to OSIntExit() since if a context
;  switch does occur, OSIntCtxSw() must be able to find this
;  frame.
;*********************************************************************

_OSTickISR:
  LEA      -60(A7),A7         ; Save processor registers onto stack
  MOVEM.L  D0-D7/A0-A6,(A7)

  MOVEQ.L  #0,D0              ; This use of D0 is absolutely necessary when
  MOVE.B   (_OSIntNesting),D0 ; using an optimizing compiler. Since ColdFire
  ADDQ.L   #1,D0              ; can only add Long, whereas OSIntNesting is defined
  MOVE.B   D0,(_OSIntNesting) ; as INT8U in C code.

  CMPI.L   #1, d0		      ; if OSIntNesting == 1, then continue
  BNE 	   _SkipSave          ; if Timer interrupts while in another ISR, skip the save
  MOVE.L   (_OSTCBCur), A1    ; Otherwise, save stack pointer onto current task's stack
  MOVE.L   A7,(A1)

 _SkipSave:
   
  MOVEA.L  #_PIT0_PCSR,A0     ; Clear the reference event
  MOVE.W   (A0),D0            ; Again a point of note, since ORI only works with
  ORI.L    #_PIF,D0   		  ; data registers you must do the copy unlike 68k which
  MOVE.W   D0,(A0)            ; has more assembly language options.
 
  JSR      _OSTimeTick
;  JSR      _OSIntExit        ; Can either jump to C IntExit or use assembly
  JMP      _OSIntExitCF       ; language, either method seems to work

  MOVEM.L  (A7),D0-D7/A0-A6   ; Restore processor registers from stack after JSR
  LEA      60(A7),A7          ; If using JMP to IntExitCF, these commands are
  RTE                         ; skipped and the restore is at the end of IntExitCF


⌨️ 快捷键说明

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