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

📄 os_cpu_a.asm

📁 uCOS2嵌入式操作系统源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; Returns    : none
;
; Note(s)    : The following C-like pseudo-code describe the operation being performed in the code below.
;
;              Save all registers on the current task's stack;
;              OSIntNesting++;
;              if (OSIntNesting == 1) {
;                 OSTCBCur->OSTCBStkPtr = SS:SP
;              }
;              OSTickDOSCtr--;
;              if (OSTickDOSCtr == 0) {
;                  OSTickDOSCtr = 11;
;                  INT 81H;               Chain into DOS every 54.925 mS
;                                         (Interrupt will be cleared by DOS)
;              } else {
;                  Send EOI to PIC;       Clear tick interrupt by sending an End-Of-Interrupt to the 8259
;                                         PIC (Priority Interrupt Controller)
;              }
;              OSTimeTick();              Notify uC/OS-II that a tick has occured
;              OSIntExit();               Notify uC/OS-II about end of ISR
;              Restore all registers that were save on the current task's stack;
;              Return from Interrupt;
;*********************************************************************************************************
;
_OSTickISR  PROC   FAR
;
            PUSHA                                ; Save interrupted task's context
            PUSH   ES
            PUSH   DS
;
            MOV    AX, SEG(_OSIntNesting)        ; Reload DS
            MOV    DS, AX
            INC    BYTE PTR DS:_OSIntNesting     ; Notify uC/OS-II of ISR
;
            CMP    BYTE PTR DS:_OSIntNesting, 1	 ; if (OSIntNesting == 1)
            JNE    SHORT _OSTickISR1             
            MOV    AX, SEG(_OSTCBCur)            ;     Reload DS
            MOV    DS, AX
            LES    BX, DWORD PTR DS:_OSTCBCur    ;     OSTCBCur->OSTCBStkPtr = SS:SP
            MOV    ES:[BX+2], SS                 ;
            MOV    ES:[BX+0], SP                 ;
;
_OSTickISR1:
            MOV    AX, SEG(_OSTickDOSCtr)        ; Reload DS
            MOV    DS, AX
            DEC    BYTE PTR DS:_OSTickDOSCtr
            CMP    BYTE PTR DS:_OSTickDOSCtr, 0
            JNE    SHORT _OSTickISR2             ; Every 11 ticks (~199.99 Hz), chain into DOS
;
            MOV    BYTE PTR DS:_OSTickDOSCtr, 11
            INT    081H                          ; Chain into DOS's tick ISR
            JMP    SHORT _OSTickISR3

_OSTickISR2:
            MOV    AL, 20H                       ; Move EOI code into AL.
            MOV    DX, 20H                       ; Address of 8259 PIC in DX.
            OUT    DX, AL                        ; Send EOI to PIC if not processing DOS timer.
;
_OSTickISR3:
            CALL   FAR PTR _OSTimeTick           ; Process system tick
;
            CALL   FAR PTR _OSIntExit            ; Notify uC/OS-II of end of ISR
;
            POP    DS                            ; Restore interrupted task's context
            POP    ES
            POPA
;
            IRET                                 ; Return to interrupted task
;
_OSTickISR  ENDP
;
            END


















;----------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------
;-------------------2006-12-20 17:54 新添加-----------------------------
        RSEG ? PR? OSStartHighRdy? OS_CPU_A
OSStartHighRdy:
        USING  0
        LCALL _? OSTaskSwHook

OSCtxSw_in:
        ;OSTCBCur => DPTR  获得当前TCB指针
        MOV R0,#LOW(OSTCBCur)
        INC R0
        MOV DPH,@R0
        INC R0
        MOV DPL,@R0
        ;任务堆栈映象指针=> DPTR
        INC DPTR
        MOVX A,@DPTR
        MOV R0,A
        INC DPTR
        MOVX A,@DPTR
        MOV R1,A
        MOV DPH,R0
        MOV DPL,R1
        
        ;任务堆栈映象长度*UserStkPtr => R5
        MOVX A,@DPTR
        MOV R5,A   ;R5 = 任务堆栈映象长度
        
        ;把待运行任务堆栈映像的内容复制到系统堆栈
        MOV R0,#OSStkStart
restore_stack:
        INC DPTR
        INC R0
        MOVX A,@DPTR
        MOV @R0,A
        DJNZ R5,restore_stack
        
        ;恢复系统堆栈指针 ?C_XBP
        INC DPTR
        MOVX A,@DPTR
        MOV ?C_XBP,A
        INC DPTR
        MOVX A,@DPTR
        MOV ?C_XBP+1,A
        
        ;OSRunning = TRUE
        MOV R0,#LOW(OSRunning)
        MOV @R0,#01
        
        POPALL  ;把系统堆栈内容弹入CPU
        SETB EA
        RETI  ;利用中断返回指令,使系统切换至待运行状态
        
;----------------------------------------------------------------------------------------------------------

        RSEG ?PR?OSCtxSw?OS_CPU_A
;任务切换函数入口
OSCtxSw:
        PUSHALL   ;把被中止运行任务的CPU内容压栈
        
OSIntCtxSw_in:
        ;获得堆栈长度和起始地址
        MOV A,SP
        CLR C
        SUBB A,#OSStkStart
        MOV R5,A   ;获得堆栈长度
        
        ;OSTCBCur =>  DPTR  ;获得当前任务TCB指针
        MOV R0,#LOW(OSTCBCur)
        INC R0
        MOV DPH,@R0
        INC R0
        MOV DPL,@R0
        
        ;获得任务堆栈映像指针
        INC DPTR
        MOVX A,@DPTR
        MOV R0,A
        INC DPTR
        MOVX A,@DPTR
        MOV R1,A
        MOV DPH,R0
        MOV DPL,R1
        
        ;保存堆栈长度
        MOV A,R5
        MOVX @DPTR,A
        
        MOV R0,#OSStkStart  ;获得堆栈地址
;把系统堆栈内容复制到任务堆栈映像
save_stack:
        INC DPTR
        INC R0
        MOV A,@R0
        MOVX @DPTR,A
        DJNZ R5,save_stack
        
        ;保存任务堆栈映像指针 ?C_XBP
        INC DPTR
        MOV A,?C_XBP
        MOVX @DPTR,A
        INC DPTR
        MOV A,?C_XBP + 1
        MOVX @DPTR,A
        
        ;调用用户程序
        LCALL _?OSTaskSwHook
        
        ;获得最高级就绪任务的TCB
        MOV R0,#OSTCBCur
        MOV R1,#OSTCBHighRdy
        MOV A,@R1
        MOV @R0,A
        INC R0
        INC R1
        MOV A,@R1
        MOV @R0,A
        INC R0
        INC R1
        MOV A,@R1
        MOV @R0,A
        
        MOV R0,#OSPrioCur
        MOV R1,#OSPrioHighRdy
        MOV A,@R1
        MOV @R0,A
        
        LJMP OSCtxSw_in
;----------------------------------------------------------------------------------------------------------

        RSEG ?PR?OSIntCtxSw?OS_CPU_A

OSIntCtxSw:
        ;调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()
        ;过程中压入堆栈的多余内容SP = SP - 4
        MOV A,SP
        CLR C
        SUBB A,#4
        MOV SP,A
        LJMP OSIntCtxSw_in
        
;----------------------------------------------------------------------------------------------------------
;定义压栈出栈宏
PUSHALL   MACRO
        PUSH PSW
        PUSH ACC
        PUSH B
        PUSH DPL
        PUSH DPH
        MOV A,R0   ;R0-R7入栈
        PUSH ACC
        MOV A,R1
        PUSH ACC
        MOV A,R2
        PUSH ACC
        MOV A,R3
        PUSH ACC
        MOV A,R4
        PUSH ACC
        MOV A,R5
        PUSH ACC
        MOV A,R6
        PUSH ACC
        MOV A,R7
        PUSH ACC
        ;PUSH SP    ;不必保存SP,任务切换时由相应程序调整
        ENDM
        
POPALL    MACRO
        ;POP ACC   ;不必保存SP,任务切换时由相应程序调整
        POP ACC  ;R0-R7出栈
        MOV R7,A
        POP ACC
        MOV R6,A
        POP ACC
        MOV R5,A
        POP ACC
        MOV R4,A
        POP ACC
        MOV R3,A
        POP ACC
        MOV R2,A
        POP ACC
        MOV R1,A
        POP ACC
        MOV R0,A
        POP DPH
        POP DPL
        POP B
        POP ACC
        POP PSW
        ENDM
;----------------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

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