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

📄 os_cpu_a.asm

📁 uCosII+543+lcd 128*64 汉字显示
💻 ASM
📖 第 1 页 / 共 2 页
字号:
     OR     CCR, #40H                              ;
#endif
     SAVE_REGISTERS_CONTEXT                        ; Save context of resister of interrupted task
;

#if MEMMODEL == SMALL || MEMMODEL == MEDIUM        ; Save SP of the task to suspend for small and medium models
     MOVW   A,SP                                   ;
     MOVW   A,_OSTCBCur                            ;
     MOVW   @AL,AH                                 ; OSTCBCur->OSTCBStkPtr = SP
#endif

#if MEMMODEL == COMPACT || MEMMODEL == LARGE       ; Save SSB:SP of the task to suspend for compact and large models
     MOV    A, #bnksym _OSTCBCur                   ;
     MOV    ADB, A                                 ; Set bank of  _OSTCBCur

     MOVL   A,ADB:_OSTCBCur                        ; Get OSTCBCur->OSTCBStkPtr

     SWAPW                                         ; Set bank for access to
     MOV    ADB, A                                 ; *OSTCBCur->OSTCBStkPtr
     SWAPW                                         ;

     MOVW   A,SP                                   ;
     SWAPW                                         ;
     MOVW   @AL,AH                                 ; OSTCBCur->OSTCBStkPtr = SP
#endif

;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
     CALL   _OSTaskSwHook                          ; Call user defined task switch hook
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
     CALLP   _OSTaskSwHook                         ; Call user defined task switch hook
#endif
;

#if MEMMODEL == SMALL || MEMMODEL == MEDIUM        ;
     MOV    A,_OSPrioHighRdy                       ; OSPrioCur = OSPrioHighRdy
     MOV    _OSPrioCur,A                           ;
;
     MOVW   A,_OSTCBHighRdy                        ; OSTCBCur = OSTCBHighRdy
     MOVW   _OSTCBCur,A                            ;

     MOVW   A,@A                                   ;
     MOVW   SP,A                                   ; SP = *OSTCBHighRdy->OSTCBStkPtr
#endif

#if MEMMODEL == COMPACT || MEMMODEL == LARGE       ;
     MOV    A, #bnksym _OSPrioHighRdy
     MOV    ADB, A
     MOV    A,ADB:_OSPrioHighRdy                   ; OSPrioCur = OSPrioHighRdy
     MOV    ADB:_OSPrioCur, A                      ;
;
     MOVL   A,ADB:_OSTCBHighRdy                    ; OSTCBCur = OSTCBHighRdy
     MOVL   ADB:_OSTCBCur,A                        ;

     PUSHW  A                                      ;

     SWAPW                                         ; Set bank for access to
     MOV    ADB, A                                 ; *OSTCBHighRdy->OSTCBStkPtr
     SWAPW                                         ;
;
     MOVW   A,ADB:@A                               ;
     POPW   A                                      ;
     SWAPW                                         ;
     MOVW   SP,A                                   ; SP = *OSTCBHighRdy->OSTCBStkPtr

     SWAPW                                         ;
     ADDW   A,#2                                   ;
     MOVW   A,ADB:@A                               ;
     MOV    SSB,A
#endif

;
     RESTORE_REGISTERS_CONTEXT                     ; Restore context of resisters of interrupted task
;
     RETI                                          ; Return to new task


;*********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From an ISR)
;                                        void OSIntCtxSw(void)
;
; Note(s): 1) Upon entry,
;             OSTCBCur     points to the OS_TCB of the task to suspend
;             OSTCBHighRdy points to the OS_TCB of the task to resume
;
;          2) The stack frame of the task to suspend looks as follows:
;
;            (High memory)
;          |       |       |
;          |       |       | <- a value of SSP before the interrupt occurrence
;          |       AH      |
;          |       AL      |
;          |  DPR  |  ADB  |
;          |  DTB  |  PCB  |
;          |       PC      |
;          |       PS      | <- a value of SSP after the interrupt occurrence
;          +---------------+----------------------------+
;          |  Return address to caller of OSIntExit()   |
;          +--------------------------------------------+-----------------+
;          |  RW0(RW1)-bank(ISRbank) saved by OSIntExit()                 |
;          | (different for different memory models and critical methods) |
;          +--------------------------------------------+-----------------+
;          |  Return address to caller of OSIntCtxSw()  | <- a value of SSP after
;          +---------------+----------------------------+    entry in OSIntCtxSw
;          |       |       |
;            (Low memory)
;
;
;          3) If task to suspend uses bank of registers other that #0, then the
;             stack frame of the task must be changed as follows:
;
;            (High memory)
;          |       |       |
;          |       |       | <- a value of SSP before the interrupt occurrence
;          |       AH      |
;          |       AL      |
;          |  DPR  |  ADB  |
;          |  DTB  |  PCB  |
;          |       PC      |
;          |       PS      | <- a value of SSP after the interrupt occurrence
;          |       |       |
;            (Low memory)
;
;          4) If task to suspend uses bank of registers #0, then
;             OSIntCtxSw must save context of registers bank #0 in the stack.
;             The stack frame of the task to suspend must be changed as follows:
;
;            (High memory)
;          |       |       |
;          |       |       | <- a value of SSP before the interrupt occurrence
;          |       AH      |
;          |       AL      |
;          |  DPR  |  ADB  |
;          |  DTB  |  PCB  |
;          |       PC      |
;          |       PS      | <- a value of SSP after the interrupt occurrence
;          |  RW7-bank(0)  |
;          |  RW6-bank(0)  |
;          |  RW5-bank(0)  |
;          |  RW4-bank(0)  |
;          |  RW3-bank(0)  |
;          |  RW2-bank(0)  |
;          |  RW1-bank(0)  |
;          |  RW0-bank(0)  |
;          |       PS      | <- a value of SSP must be here after registers context saved
;          |       |       |
;            (Low memory)
;
;
;          5) If task to resume uses bank of registers other that #0, then the
;             stack frame of the task looks as follows:
;
;            (High memory)
;          |       |       |
;          |       |       | <- a value of SSP must be here after reti instruction
;          |       AH      |
;          |       AL      |
;          |  DPR  |  ADB  |
;          |  DTB  |  PCB  |
;          |       PC      |
;          |       PS      | <- OSTCBHighRdy->OSTCBStkPtr
;          |       |       |
;            (Low memory)
;
;          6) If task to resume uses bank of registers #0, then the stack frame
;             of the task looks as follows:
;            (High memory)
;          |       |       |
;          |       |       | <- a value of SSP must be here after reti instruction
;          |       AH      |
;          |       AL      |
;          |  DPR  |  ADB  |
;          |  DTB  |  PCB  |
;          |       PC      |
;          |       PS      | <- a value of SSP must be here after registers context restored
;          |  RW7-bank(0)  |
;          |  RW6-bank(0)  |
;          |  RW5-bank(0)  |
;          |  RW4-bank(0)  |
;          |  RW3-bank(0)  |
;          |  RW2-bank(0)  |
;          |  RW1-bank(0)  |
;          |  RW0-bank(0)  |
;          |       PS      | <- OSTCBHighRdy->OSTCBStkPtr
;          |       |       |
;            (Low memory)
;
;*********************************************************************************************************

_OSIntCtxSw:

#if MEMMODEL == SMALL                              ; Ignore calls to OSIntExit, OSIntCtxSw,
                                                   ; saved RW0 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
  #if OS_CRITICAL_METHOD == 1
     ADDSP  #6                                     ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
     ADDSP  #8                                     ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #endif
#endif  ; MEMMODEL == SMALL

#if MEMMODEL == COMPACT                            ; Ignore calls to OSIntExit, OSIntCtxSw,
                                                   ; saved RW0,RW1 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
  #if OS_CRITICAL_METHOD == 1
     ADDSP  #8                                     ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
     ADDSP  #10                                    ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #endif
#endif  ; MEMMODEL == COMPACT

#if MEMMODEL == MEDIUM                             ; Ignore calls to OSIntExit, OSIntCtxSw,
                                                   ; saved RW0 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
  #if OS_CRITICAL_METHOD == 1
     ADDSP  #10                                    ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
     ADDSP  #12                                    ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #endif
#endif  ; MEMMODEL == MEDIUM

#if MEMMODEL == LARGE                              ; Ignore calls to OSIntExit, OSIntCtxSw,
                                                   ; saved RW0,RW1 (and PS, if OS_CRITICAL_METHOD == 2 or 12)
  #if OS_CRITICAL_METHOD == 1
     ADDSP  #12                                    ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #elif (OS_CRITICAL_METHOD == 2) || (OS_CRITICAL_METHOD == 12)
     ADDSP  #14                                    ; (for OS_CRITICAL_METHOD see OS_CPU.H)
  #endif
#endif  ; MEMMODEL == LARGE

     SAVE_REGISTERS_CONTEXT                        ; Save context of resister of interrupted task

#if MEMMODEL == SMALL || MEMMODEL == MEDIUM        ; Save SP of the task to suspend for small and medium models
     MOVW   A,SP                                   ;
     MOVW   A,_OSTCBCur                            ;
     MOVW   @AL,AH                                 ; OSTCBCur->OSTCBStkPtr = SP
#endif

#if MEMMODEL == COMPACT || MEMMODEL == LARGE       ; Save SSB:SP of the task to suspend for compact and large models
     MOV    A, #bnksym _OSTCBCur                   ;
     MOV    ADB, A                                 ; Set bank of _OSTCBCur

     MOVL   A,ADB:_OSTCBCur                        ; Get OSTCBCur->OSTCBStkPtr

     SWAPW                                         ; Set bank for access to
     MOV    ADB, A                                 ; *OSTCBCur->OSTCBStkPtr
     SWAPW                                         ;

     MOVW   A,SP                                   ;
     SWAPW                                         ;
     MOVW   @AL,AH                                 ; OSTCBCur->OSTCBStkPtr = SP
#endif

;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
     CALL   _OSTaskSwHook                          ; Call user defined task switch hook
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
     CALLP  _OSTaskSwHook                          ; Call user defined task switch hook
#endif

#if MEMMODEL == SMALL || MEMMODEL == MEDIUM        ;
;
     MOV    A,_OSPrioHighRdy                       ; OSPrioCur = OSPrioHighRdy
     MOV    _OSPrioCur,A                           ;
;
     MOVW   A,_OSTCBHighRdy                        ; OSTCBCur = OSTCBHighRdy
     MOVW   _OSTCBCur,A                            ;

     MOVW   A,@A                                   ;
     MOVW   SP,A                                   ; SP = *OSTCBHighRdy->OSTCBStkPtr
#endif

#if MEMMODEL == COMPACT || MEMMODEL == LARGE       ;
     MOV    A, #bnksym _OSPrioHighRdy
     MOV    ADB, A
     MOV    A,ADB:_OSPrioHighRdy                   ; OSPrioCur = OSPrioHighRdy
     MOV    ADB:_OSPrioCur, A                      ;
;
     MOVL   A,ADB:_OSTCBHighRdy                    ; OSTCBCur = OSTCBHighRdy
     MOVL   ADB:_OSTCBCur,A                        ;

     PUSHW  A                                      ;

     SWAPW                                         ; Set bank for access to
     MOV    ADB, A                                 ; *OSTCBHighRdy->OSTCBStkPtr
     SWAPW                                         ;
;
     MOVW   A,ADB:@A                               ;
     POPW   A                                      ;
     SWAPW                                         ;
     MOVW   SP,A                                   ; SP = *OSTCBHighRdy->OSTCBStkPtr

     SWAPW                                         ;
     ADDW   A,#2                                   ;
     MOVW   A,ADB:@A                               ;
     MOV    SSB,A
#endif
;
     RESTORE_REGISTERS_CONTEXT                     ; Restore context of resisters of interrupted task
;
     RETI                                          ; Return to new task

;*********************************************************************************************************
;                                            HANDLE TICK ISR
;
; Description: This is the system timer interrupt handler.
;
; Arguments  : none
;
; Returns    : none
;
; Note(s)    : For reset the interrupt request flag the handler uses function OSTimeTickHook in OS_CPU_C.C
;*********************************************************************************************************

_OSTickISR:
     MOV     RP,#1                                 ; Set register bank 1 for TickISR
     ASM_ISR_ENTER                                 ;
;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
     CALL    _OSTimeTick                           ; Process system tick
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
     CALLP   _OSTimeTick                           ; Process system tick
#endif
;
     RETI

;*********************************************************************************************************
;                                Delayed Interrupt ISR
;  Causes switching the context after  completion of processing of all interrupts.
;
;  Disable the interrupts for prevention of coming the more priority interrupt when switching the context.
;  Reset the bit in register "dirr", avoiding reason Delayed Interrupt.
;  Reset _OSIntNesting, reporting this OS about that that all interrupts are finished.
;  Call _OSIntExit.
;*********************************************************************************************************
_iDIRR_ISR:
#if (OS_CRITICAL_METHOD == 1) || (OS_CRITICAL_METHOD == 2)
     AND    CCR, #191                              ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#elif OS_CRITICAL_METHOD == 12
     MOV    ILM,#1                                 ; (for OS_CRITICAL_METHOD see OS_CPU.H)
#endif
;
     MOVN    A, #0
     MOV     I:__dirr, A                           ; Reset delayed interrupt request
;
     MOV     _OSIntNesting, A                      ; Notify OS about last interrupt
;
     MOV    RP,#1                                  ; Set register bank #1 for Delayed ISR
;
#if MEMMODEL == SMALL || MEMMODEL == COMPACT
     CALL    _OSIntExit                            ; Reschedule, if necessary
#elif MEMMODEL == MEDIUM || MEMMODEL == LARGE
     CALLP   _OSIntExit                            ; Reschedule, if necessary
#endif
;
     RETI

        .END

⌨️ 快捷键说明

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