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

📄 ucos_asm.s03

📁 embed in keil
💻 S03
📖 第 1 页 / 共 2 页
字号:
         mov     DPH, WORK                  ;Complete pointer update
         inc     dptr                       ;Skip pointer type again
         mov     a, WORK+1                  ;Load pointer to 'xstack' base (high)
         movx    @dptr, a                   ;Pass it to tcb
         inc     dptr                       ;Increment pointer
         mov     a, WORK+2                  ;Load pointer to 'xstack' base (low)
         movx    @dptr, a                   ;Pass it to tcb
      
; Now we proceed to make next higher priority task ready to run, the new current task:

         mov     dptr, #OSTCBHighRdy + 1    ;Get OSTCBHighRdy
         movx    a, @dptr                   ;Read pointer high
         mov     WORK, a                    ;Save it in the work area
         inc     dptr                       ;Increment pointer
         movx    a, @dptr                   ;Read pointer low
         mov     WORK+1, a                  ;Save it in the work area
         mov     dptr, #OSTCBCur + 1        ;Get OSTCBCur
         mov     a, WORK                    ;Load pointer high
         movx    @dptr, a                   ;Update tcb
         inc     dptr                       ;Increment pointer
         mov     a, WORK+1                  ;Load pointer low
         movx    @dptr, a                   ;Update tcb
         mov     DPL, WORK+1                ;Point to OSTCBHighRdy->STCKPTR 
         mov     DPH, WORK                  ;Update pointer high

; Now we proceed to restore the task context to run scheduled task.

         inc     dptr                       ;Increment pointer to skip pointer type (01)
         movx    a, @dptr                   ;Get pointer high
         mov     WORK, a                    ;Save in work area
         inc     dptr                       ;Increment pointer         
         movx    a, @dptr                   ;Get pointer low
         mov     DPL, a                     ;Update pointer low             
         mov     DPH, WORK                  ;Load pointer high

; We are now pointing to the top of the 'xstack' of the task to be switched in

         movx    a, @dptr                   ;First byte is number of bytes on external stack
         mov     WORK, a                    ;Save it in work area
         clr     c                          ;Clear carry
         mov     a, DPL                     ;Load pointer low
         subb    a, WORK                    ;Substract number of bytes from the DPTR
         mov     DPL, a                     ;Update pointer low
         jnc     cs_01                      ;If no carry, skip on
         dec     DPH                        ;DPTR now points to the base of the task's stack

cs_01:   mov     R0, #60h                   ;Hardware stack ('istack at IRAM), starts at 60h
         mov     R1, WORK                   ;Load number of bytes on stack in R1
cs_02:   movx    a, @dptr                   ;Get byte from task's external stack
         mov     @R0, a                     ;Pass it to internal stack 
         inc     dptr                       ;Increment source pointer   
         inc     R0                         ;Increment destination pointer
         djnz    R1, cs_02                  ;Copy the whole 'xstack' back into 'istack'

         mov     a, WORK                    ;Load number of bytes on stack      
         add     a, #5Fh                    ;Add offset (SP points to a byte) 
         mov     SP, a                      ;Restore the stack pointer
         pop     XSP+1                      ;Restore 'xstack' base pointer
         pop     XSP                        ;..(high and low)
         pop     DPL                        ;Restore pointer low
         pop     DPH                        ;Restore pointer high
         pop     Bk0_r7                     ;Restore register R7 (Bank #0)
         pop     Bk0_r6                     ;Restore register R6 (Bank #0)
         pop     Bk0_r5                     ;Restore register R5 (Bank #0)
         pop     Bk0_r4                     ;Restore register R4 (Bank #0)
         pop     Bk0_r3                     ;Restore register R3 (Bank #0)
         pop     Bk0_r2                     ;Restore register R2 (Bank #0)
         pop     Bk0_r1                     ;Restore register R1 (Bank #0)
         pop     Bk0_r0                     ;Restore register R0 (Bank #0)
         pop     b                          ;Restore register B
         pop     ACC                        ;Restore accumulator
         pop     PSW                        ;Restore PSW
         setb    EA                         ;Exit critical section
         reti                               ;Jump to execute scheduled task
         
         ENDMOD 
;----------------------------------------------------------------------------------------+                               PERFORM A CONTEXT SWITCH (From interrupt level)         |
;                          PERFORM A CONTEXT SWITCH (From interrupt level)               |
;                                                                                        |
; void OSIntCtxSw(void)                                                                  |
;                                                                                        |
; This module is used to perform a task switch as a result of an interrupt event.        |
;----------------------------------------------------------------------------------------+
         MODULE   OSINTCTXSW        ;Module name
         RSEG     CODE              ;Relocatable Segment

;<---[ Symbols available for other modules: ]-------------------------------------------->

         PUBLIC   OSIntCtxSw        ;Performs a task-level context switch
         
;<---[ Module definition for 'C' calls: ]------------------------------------------------>

         $DEFFN   OSIntCtxSw(0,0,0,0,32768,0,0,0)

;<---[ Symbols referenced, in other modules: ]------------------------------------------->

         EXTERN   OSTCBHighRdy      ;TCB of highest priority task ready to run
         EXTERN   OSTCBCur          ;TCB of current task
         EXTERN   OSPrioHighRdy     ;Priority of highest priority task ready to run
         EXTERN   OSPrioCur         ;Priority of current task
;<--------------------------------------------------------------------------------------->
OSIntCtxSw:                         ;Module entry point
                                        
         clr     EA                         ;Enter critical section
         clr     c                          ;Clear carry
         mov     a, SP                      ;Load Stack Pointer
         subb    a, #04                     ;Substract 4 bytes because there have been two function calls
         mov     SP, a                      ;Now SP points to the base of current xstack

; On the stack the first two bytes are XSP (the pointer to the base of the stack). 
; We pop the XSP into DPTR because we need it to copy the internal stack to.
        
         pop     DPL                        ;Get XSP+1
         pop     DPH                        ;Get XSP
         push    DPH                        ;Save it again to keep the stack intact
         push    DPL                        ;..(high and low)
         clr     c                          ;Clear accumulator
         subb    a, #5Fh                    ;See how many bytes are on stack
         mov     R1, a                      ;Save result in R1
         mov     WORK, a                    ;Save to move on top of 'xstack'
         mov     R0, #60h                   ;Bottom of internal stack

loop:    mov     a, @R0                     ;Get byte from 'istack'
         movx    @dptr, a                   ;Move to 'xstack'
         inc     dptr                       ;Increment destination pointer
         inc     R0                         ;Increment source pointer
         djnz    R1, loop                   ;Copy the whole 'istack' over to 'xstack'
         mov     a, WORK                    ;Load number of bytes in stack
         movx    @dptr, a                   ;Pass this data to xstack

; The current tasks context has been saved over external RAM.

         mov     XSP,   DPH                 ;Update 'xstack' pointer high
         mov     XSP+1, DPL                 ;Update 'xstack' pointer low

; Now, we'll update the piority buffers:

         mov     dptr, #OSPrioHighRdy       ;Point to buffer of top priority ready to run
         movx    a, @dptr                   ;Read it
         mov     dptr, #OSPrioCur           ;Point to buffer of current priority
         movx    @dptr, a                   ;Update current priority

         mov     dptr, #OSTCBCur + 1        ;Point to TCB of current task (skip pointer type)
         movx    a, @dptr                   ;Read pointer high
         mov     WORK, a                    ;Save in the work area
         inc     dptr                       ;Increment pointer
         movx    a, @dptr                   ;Read pointer low
         mov     DPL, a                     ;Point TO OSTCBCUR->STCKPTR 
         mov     DPH, WORK                  ;Complete pointer update
         inc     dptr                       ;Skip pointer type
         mov     a, XSP                     ;Load pointer to task (high)
         movx    @dptr, a                   ;Pass it to tcb
         inc     dptr                       ;Increment pointer
         mov     a, XSP+1                   ;Load pointer to task (low)
         movx    @dptr, a                   ;Pass it to tcb

         mov     dptr, #OSTCBHighRdy + 1    ;Point to OSTCBHighRdy (skip pointer type)
         movx    a, @dptr                   ;Read pointer high
         mov     WORK, a                    ;Save it in the work area
         inc     dptr                       ;Increment pointer
         movx    a, @dptr                   ;Read pointer low
         mov     WORK+1, a                  ;Save it in the work area
         mov     dptr, #OSTCBCur + 1        ;Point to OSTCBCur (skip pointer type)
         mov     a, WORK                    ;Load pointer high
         movx    @dptr, a                   ;Update tcb
         inc     dptr                       ;Increment pointer
         mov     a, WORK+1                  ;Load pointer low
         movx    @dptr, a                   ;Update tcb
         mov     DPL, WORK+1                ;Point to OSTCBHighRdy->STCKPTR 
         mov     DPH, WORK                  ;Update pointer high

; Now we proceed to restore the task context to run scheduled task.

         inc     dptr                       ;Increment pointer to skip pointer type
         movx    a, @dptr                   ;Get pointer high
         mov     WORK, a                    ;Save in work area
         inc     dptr                       ;Increment pointer         
         movx    a, @dptr                   ;Get pointer low
         mov     DPL, a                     ;Update pointer low             
         mov     DPH, WORK                  ;Load pointer high

         movx    a, @dptr                   ;First byte is number of bytes on 'xstack'
         mov     WORK, a                    ;Save it in work area
         clr     c                          ;Clear carry
         mov     a, DPL                     ;Load pointer low
         subb    a, WORK                    ;Substract number of bytes from the DPTR
         mov     DPL, a                     ;Update pointer low
         jnc     cs_00                      ;If no carry, skip on
         dec     DPH                        ;DPTR now points to the base of the task's stack

cs_00:   mov     R0, #60h                   ;Hardware stack ('istack' at IRAM), starts at 60h
         mov     R1, WORK                   ;Load number of bytes on stack in R1
cs_01:   movx    a, @dptr                   ;Get byte from task's external stack
         mov     @R0, a                     ;Pass it to internal stack 
         inc     dptr                       ;Increment source pointer   
         inc     R0                         ;Increment destination pointer
         djnz    R1, cs_01                  ;Copy the whole 'xstack' back into 'istack'
         mov     a, WORK                    ;Load number of bytes on stack
         add     a, #5Fh                    ;Add offset (SP points to a byte) 
         mov     SP, a                      ;Restore the stack pointer
         pop     XSP+1                      ;Restore the 'xstack' base pointer
         pop     XSP                        ;..(high and low)
         pop     DPL                        ;Restore pointer low
         pop     DPH                        ;Restore pointer high
         pop     Bk0_r7                     ;Restore register R7 (Bank #0)
         pop     Bk0_r6                     ;Restore register R6 (Bank #0)
         pop     Bk0_r5                     ;Restore register R5 (Bank #0)
         pop     Bk0_r4                     ;Restore register R4 (Bank #0)
         pop     Bk0_r3                     ;Restore register R3 (Bank #0)
         pop     Bk0_r2                     ;Restore register R2 (Bank #0)
         pop     Bk0_r1                     ;Restore register R1 (Bank #0)
         pop     Bk0_r0                     ;Restore register R0 (Bank #0)
         pop     B                          ;Restore register B
         pop     ACC                        ;Restore accumulator
         pop     PSW                        ;Restore PSW
         setb    EA                         ;Exit critical section
         reti                               ;Jump to execute scheduled task

         END

⌨️ 快捷键说明

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