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

📄 os_cpu_c.c

📁 uCOS-II的移植代码 for 8051 [绝对原著]
💻 C
📖 第 1 页 / 共 3 页
字号:

    ;(7)得到将要重新开始运行的任务(新任务)的堆栈指针
    ;?C_XBP    = OSTCBHighRdy->OSTCBStkPtr;(0x0217)
    ;(8)拷贝原任务(新任务)中的?C_XBP到SP(系统)堆栈中    SP    满向上
        ;然后清空它(即?C_XBP中的原堆栈内容)            ?C_XBP
    满向下
    CtxSw:
        LCALL    _ComCtxSw2
    LCALL    _CopyC_XBPtoSP

           ;(9)从新任务堆栈中恢复处理器所有寄存器的值
    POPALL
    ;OS_EXIT_CRITICAL
    ;(10)执行返回指令
    SETB     EA            ;强行开中断!!!!!!
    RET
/*$PAGE*/
;*******************************************************************************
**************************
;                                PERFORM A CONTEXT SWITCH (From an ISR)
;                                        void OSIntCtxSw(void)
;    ;中断级切换:在OSInExit()中已判断了有高优先级的任务在就绪队列中,所以直接切
换到高优先级任务
;*******************************************************************************
**************************

    ?PR?_?OSIntCtxSw?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_?OSIntCtxSw?OS_CPU_A
_?OSIntCtxSw:
    USING    0
    ;OS_ENTER_CRITICAL
    ACALL    _IntRETI
    JMP    IntCtxSw        
_IntRETI:
    RETI
;*******************************************************************************
**************************
;                                            HANDLE TICK ISR
;*******************************************************************************
**************************
        CSEG    AT     000BH        ;设置T0中断向量
        LJMP    _?OSTickISR

    ?PR?_?OSTickISR?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_?OSTickISR?OS_CPU_A
_?OSTickISR:
    USING    0
    CLR    EA
    ;(1)保存处理器寄存器  先PUSH到SP在COPY到?C_XBP  OSTCBHighRdy
    PUSHALL
    LCALL    _CopySPtoC_XBP            ;COPY SP 的内容到?
C_XBP

    ;(2)记忆中断的嵌套层OSIntNesting++    进入中断
    ;(3) if (OSIntNesting == 1)
    ;    OSTCBCur->OSTCBStkPtr <= ?C_XBP
    LCALL    _Enter_INT

    ;(4)Clear inter
    CLR    TR0                ;TR0;清中断
    ;(5)[TH0,TL0]<= New Value
    MOV    TH0,#3CH            ;TH0=0x3ch;
    MOV    TL0,#0B0H            ;TL0=0x0b0h;
    SETB     TR0
    ;MOV    P1,0

    ;(6) Call OSTimeTick();
    LCALL    _?OSTimeTick

    ;(7) Call OSIntExit();
    LCALL    _?OSIntExit

    ;(8) 恢复处理器寄存器        ;没有高优先级任务在就绪队列中
    ;LCALL    _ComCtxSw2
    LCALL    _CopyC_XBPtoSP
    POPALL
    SETB    EA
    ;(9) 执行中断返回指令
    RETI

;*******************************************************************************
***************************
;                    内部函数 : ComCtxSw1()
;    ;(4)调用OSTaskSwHook();
;    ;(5)OSTCBCur    = OSTCBHighRdy;
;          ;(6)OSPrioCur    = OSPrioHighRdy;
;*******************************************************************************
***************************
    ?PR?_ComCtxSw1?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_ComCtxSw1?OS_CPU_A
_ComCtxSw1:
    ;调用OSTaskSwHook();
        LCALL    _?OSTaskSwHook            ;中断是关着的

    ;OSTCBCur    = OSTCBHighRdy;
    MOV     DPH,#HIGH(OSTCBHighRdy)
    MOV     DPL, #LOW(OSTCBHighRdy)
     MOVX     A,@DPTR
     MOV      R3,A
     INC      DPTR
     MOVX     A,@DPTR
     MOV      R2,A
     INC      DPTR
     MOVX     A,@DPTR
     MOV      R1,A

    MOV     DPH,#HIGH(OSTCBCur)
    MOV     DPL, #LOW(OSTCBCur)
    MOV      A,R3
     MOVX     @DPTR,A
     INC      DPTR
     MOV      A,R2
     MOVX     @DPTR,A
     INC      DPTR
     MOV      A,R1
     MOVX     @DPTR,A


           ;OSPrioCur    = OSPrioHighRdy;
    MOV     DPH,#HIGH(OSPrioHighRdy)
    MOV     DPL, #LOW(OSPrioHighRdy)
    MOVX     A,@DPTR
    MOV      R7,A

    MOV     DPH,#HIGH(OSPrioCur)
    MOV     DPL, #LOW(OSPrioCur)
    MOV      A,R7
     MOVX     @DPTR,A

    RET
;*******************************************************************************
***************************
;                    内部函数 : ComCtxSw2()
;    ;(7)得到将要重新开始运行的任务(新任务)的堆栈指针
;    ;?C_XBP    = OSTCBHighRdy->OSTCBStkPtr;(0x0217)
;*******************************************************************************
***************************
    ?PR?_ComCtxSw2?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_ComCtxSw2?OS_CPU_A
_ComCtxSw2:

    POP    ACC                ;因为函数调用而调整
SP,并保存到R1,R2
    MOV    R1,ACC
    POP    ACC
    MOV    R2,ACC

    ;得到将要重新开始运行的任务(新任务)的堆栈指针
    ;C_XBP    = OSTCBHighRdy->OSTCBStkPtr;(0x0217)
    MOV     DPH,#HIGH(OSTCBCur)        ;结构:OSTCBHighRdy-
>OSTCBStkPtr{[][H][L]}->?C_XBP
    MOV     DPL, #LOW(OSTCBCur)
    INC    DPTR                ;跳过指针类型编号
    MOVX    A,@DPTR
    INC     DPTR
    MOV    R3,A                ;读出高字节      为
了得到新任务的任务栈指针
    MOVX    A,@DPTR                ;读出底字节
    MOV    DPH,R3
    MOV    DPL,A

    INC    DPTR
    MOVX    A,@DPTR
    MOV    ?C_XBP,A
    INC    DPTR
    MOVX    A,@DPTR
    MOV    ?C_XBP+1,A

    MOV    ACC,R2                ;从R1,R2中恢复SP
    PUSH    ACC
    MOV    ACC,R1
    PUSH    ACC
    
    RET



;*******************************************************************************
***************************
;                    内部函数 : CopyC_XBPtoSP()
;    ?C_XBP => SP
;    ;拷贝原任务(新任务)中的?C_XBP到SP(系统)堆栈中    SP    满向上
;       ;然后清空它(即?C_XBP中的原堆栈内容)        ?C_XBP    满向下
;*******************************************************************************
***************************
    ?PR?_CopyC_XBPtoSP?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_CopyC_XBPtoSP?OS_CPU_A
_CopyC_XBPtoSP:
                        ;OSTCBHighRdy
    POP    ACC                ;因为函数调用而调整
SP,并保存到R1,R2
    MOV    R1,ACC
    POP    ACC
    MOV    R2,ACC

           MOV    DPH,?C_XBP
    MOV    DPL,?C_XBP+1

    MOVX    A,@DPTR
    MOV    R7,A                ;读出SP栈元素的总数
    MOV    SP,#?STACK-1
    COPYCXBP_TO_SP:                ;拷贝?C_XBP的内容到SP中
    INC    DPTR
    MOVX    A,@DPTR
    PUSH    ACC
    DJNZ    R7,COPYCXBP_TO_SP

    INC    DPTR
    
    MOV    A,DPH
    MOV    ?C_XBP,A
    MOV    A,DPL
    MOV    ?C_XBP+1,A

    MOV    ACC,R2                ;从R1,R2中恢复SP
    PUSH    ACC
    MOV    ACC,R1
    PUSH    ACC

    RET
;*******************************************************************************
***************************
;                    内部函数 : CopySPtoC_XBP()
;    ?C_XBP <= SP
;    ;(2)拷贝SP(系统)堆栈中的内容到?C_XBP,      SP            满向上
;       ;然后清空它(即MOV SP,#?STACK-1)          ?C_XBP    满向下
;
;*******************************************************************************
***************************
    ?PR?_CopySPtoC_XBP?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_CopySPtoC_XBP?OS_CPU_A
_CopySPtoC_XBP:                    ;OSTCBHighRdy

    POP    ACC                ;因为函数调用而调整
SP,并保存到R1,R2
    MOV    R1,ACC
    POP    ACC
    MOV    R2,ACC

    MOV    DPH,?C_XBP
    MOV    DPL,?C_XBP+1

    MOV     R7,#?STACK-1
    MOV    A,SP
    SUBB    A,R7                ;因为SP-(?STACK-1)不
可能为零所以不用判断0
    MOV    R7,A
    MOV    R6,A
    ;INC    DPTR;%%%%????%%%%%%        ;不用防止!!!    以前的注释:防止
多减一个单元
    COPYSP_TO_CXBP:                ;拷贝SP的内容到?C_XBP中
        MOV    A,DPL
    SUBB    A,0
    JNZ    NOZERO
    DEC    DPH
    NOZERO:
        DEC    DPL
    POP    ACC
    MOVX    @DPTR,A
    DJNZ    R7,COPYSP_TO_CXBP

        MOV    A,DPL
    SUBB    A,0
    JNZ    NOZERO2
    DEC    DPH
    NOZERO2:
        DEC    DPL
    MOV    A,R6
    MOVX    @DPTR,A                ;?C_XBP栈顶保存的是
SP栈元素的总数

    MOV    A,DPH                ;?C_XBP是满向下不用
减了 
    MOV    ?C_XBP,A
    MOV    A,DPL
    MOV    ?C_XBP+1,A

    MOV    ACC,R2                ;从R1,R2中恢复SP
    PUSH    ACC
    MOV    ACC,R1
    PUSH    ACC

    RET
;*******************************************************************************
***************************
;                        内部函数 : Enter_INT
()
;
;    ;(2)记忆中断的嵌套层OSIntNesting++    进入中断
;    ;(3) if (OSIntNesting == 1)
;    ;    OSTCBCur->OSTCBStkPtr <= ?C_XBP
;*******************************************************************************
***************************
    ?PR?_Enter_INT?OS_CPU_A             SEGMENT CODE
    RSEG    ?PR?_Enter_INT?OS_CPU_A
_Enter_INT:

    ;(2)记忆中断的嵌套层OSIntNesting++    进入中断
    MOV    DPH,#HIGH(OSIntNesting)
    MOV    DPL, #LOW(OSIntNesting)
    MOVX    A,@DPTR
    INC    A
    MOVX    @DPTR,A

    ;(3) if (OSIntNesting == 1)
    ;    OSTCBCur->OSTCBStkPtr <= C_XBP
    DEC    A
    JNZ    NOONE

    MOV     DPH,#HIGH(OSTCBCur)
    MOV     DPL, #LOW(OSTCBCur)

    INC    DPTR                ;指针是3字节的
把我害死了
    MOVX    A,@DPTR
    MOV    R1,A
    INC    DPTR
    MOVX    A,@DPTR
    MOV    DPH,R1
    MOV    DPL,A
    
    INC    DPTR                ;指针是3字节的
把我害死了
    MOV    A,?C_XBP
    MOVX    @DPTR,A
    INC    DPTR
    MOV    A,?C_XBP+1
    MOVX    @DPTR,A
    NOONE:

        RET
            END
;*******************************************************************************
***************************
;                    文件结束
;*******************************************************************************
***************************

⌨️ 快捷键说明

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