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

📄 os_cpu_a.asm

📁 keil C166下ucos-ii,c164ci的移植程序
💻 ASM
📖 第 1 页 / 共 3 页
字号:
                BCLR    IEN                         ; Disable interrupts

                EXTP    #PAG OSTCBHighRdy,#02h      ; OSTCBCur = OSTCBHighRdy;
                MOV     R12,POF OSTCBHighRdy        ; 间接寻址,取OSTCBHighRdy所指向地址的页面偏移
                MOV     R13,POF (OSTCBHighRdy+2)    ; 间接寻址,取OSTCBHighRdy所指向地址的页号
                EXTP    #PAG OSTCBCur,#02h
                MOV     POF (OSTCBCur),R12          ; 
                MOV     POF (OSTCBCur+2),R13        

                EXTP    R13,#02h                    ; pStack = OSTCBCur->OSTCBStkPtr;
                MOV     R14,[R12+]                  ;     Load Offset pointer
                MOV     R15,[R12]                   ;     Load Page pointer

;                                                   ; Load Task's Context from TCB
                EXTP    R15,#02h                    ;     Start Of Task USR Stack Offset
                MOV     R0,[R14+#0AH]               ;     Task R0
                MOV     R1,[R14+#08H]               ;     Task DPP1

                EXTP    R15,#02h
                MOV     R2,[R14+#04H]               ;     Task IP
                MOV     R3,[R14+#02H]               ;     Task CSP
                
                MOV     SP,#DPP3:TOS                ; 初始化系统堆栈

                MOV     DPP1,R1                     ;     Start Of Task USER Stack Page
                PUSH    R3                          ;     Load "saved" CSP on System Stack
                PUSH    R2                          ;     Load "saved" IP  on System Stack

                %RestoreContext()                     ; Restore context.

                BSET    IEN                         ; Enable interrupts
                RETS                                ; Execute Task

OSStartHighRdy ENDP
;********************************************************************************************************
;                                 PERFORM A CONTEXT SWITCH (From task level)
;                                            void OSCtxSw(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 system stack frame of the task to suspend looks as follows:
;                                                SYSTEM STACK AREA
;                                     SP -> +00  OFFSET  of task to suspend    (Low memory)
;                                           +02  SEGMENT of task to suspend
;                                           +04  PSW     of task to suspend    (High memory)
;
;          3) The user stack frame of the task to resume looks as follows:
;
;                                                TASK STACK AREA                              (High Memory)
;                                           +12  TASK DATA PARAMETER PAGE pointer of task
;                                           +10  TASK DATA PARAMETER OFFSET pointer of task
;                                           +0E  SEGMENT of task code address
;                                           +0C  OFFSET  of task code address
;                                           +0A  USER STACK OFFSET POINTER (R0) of task
;                                           +08  USER STACK PAGE POINTER (DPP1) of task
;                                           +06  PSW flags of task
;                                           +04  OFFSET  of task return address
;                                            02  SEGMENT of task return address
;             OSTCBHighRdy->OSTCBStkPtr -->   0
;                                           -02  R[1 ..15] General Purpose registers of task
;                                           -20  CP     Context pointer of task
;                                           -22  DPP3   Data page pointer 3 of task
;                                           -24  DPP2   Data page pointer 2 of task
;                                           -26  DPP0   Data page pointer 0 of task
;                                           -28  MDC    Multiply/Divide Control of task
;                                           -2A  MDH    Multiply/Divide High register of task
;                                           -2C  MDL    Multiply/Divide Low register of task  (Low Memory)
;********************************************************************************************************
OSCtxSw         PROC    INTERRUPT  UCOS_OSCtxSw = 0x50
                BCLR    IEN                         ; Disable interrupts

                %SaveContext()                        ; Save Register Context

                POP     R2                          ; Get "current" IP
                POP     R1                          ; Get "current" CSP
                POP     R3                          ; Get "current" PSW
                                                                    
                EXTP    #PAG OSTCBCur,#02h         ; pStack = OSTCBCur->OSTCBStkPtr
                MOV     R8,POF (OSTCBCur)          ; 堆栈指针页号:偏移量 = R9:R8
                MOV     R9,POF (OSTCBCur+2)
                EXTP    R9,#02h
                MOV     R6,[R8+]
                MOV     R7,[R8]

                EXTP    R7,#03h                                                    
                MOV     [R6+#02h],R1                ;     Task CSP
                MOV     [R6+#04h],R2                ;     Task IP
                MOV     [R6+#06h],R3                ;     Task STATUS

                MOV     R4,#TOS                     ; Get the top of the System Stack
                MOV     R5,SP
_OSCtxSwSave:
                CMP     R4,R5                       ; Compare if Pointer is equal to Current Stack position on system stack
                JMPA    cc_EQ,_OSCtxSwSaveEnd       ; Exit the Loop if they are equal
                SUB     R4,#02H                     ; Decrement pointer of System Stack
                EXTS    #0,#1
                MOV     R3,[R4]                     ; Read data from system stack
                MOV     [-R0],R3                    ; Save System Stack Value to the Task Satck
                JMPA    cc_UC,_OSCtxSwSave          ; Do loop again
_OSCtxSwSaveEnd:

                MOV     R4,DPP1                     ; Get "current" DPP1

                EXTP    R7,#03h
                MOV     [R6+#08H],R4                ;     Task DPP1
                MOV     [R6+#0AH],R0                ;     Task R0
                MOV     [R6+#0CH],R5                ;     Task SP


                CALLS   SEG(OSTaskSwHook),SOF(OSTaskSwHook)  ; Call user defined task switch hook

_ADDR01:
                EXTP    #PAG OSTCBHighRdy,#02h     ; Get the stack pointer of the task to resume
                MOV     R8,POF OSTCBHighRdy        ; OSTCBCur = OSTCBHighRdy
                MOV     R9,POF (OSTCBHighRdy+2)
                EXTP    #PAG OSTCBCur,#02h
                MOV     POF (OSTCBCur),R8
                MOV     POF (OSTCBCur+2),R9

                EXTP    #PAG OSPrioHighRdy,#01h    ;  OSPrioCur = OSPrioHighRdy;
                MOVB    RL1,POF OSPrioHighRdy
                EXTP    #PAG OSPrioCur,#01h
                MOVB    POF OSPrioCur,RL1

                EXTP    R9,#02h                     ; R7:R6 = OSTCBHighRdy->OSTCBStkPtr
                MOV     R6,[R8+]
                MOV     R7,[R8]

                EXTP    R7,#03h
                MOV     R5,[R6+#0Ch]                ;     Get Task SP
                MOV     R0,[R6+#0Ah]                ;     Get Task R0
                MOV     R4,[R6+#08h]                ;     Get Task DPP1

                MOV     DPP1,R4                     ; Write "current task" DPP1

                MOV     SP,R5                       ; Replace the Task System Stack Pointer
                MOV     R4,#TOS                     ; Get the top of the System Stack
_OSCtxSwRestore:
                CMP     R4,R5                       ; Compare if Pointer is equal to Satck Pointer (SP)
                JMPA    cc_EQ,_OSCtxSwRestoreEnd    ; Loop if not equal
                MOV     R3,[R0+]                    ; Read value in the task stack
                EXTS    #0,#1
                MOV     [R5],R3                     ; Replace System Stack Value
                ADD     R5,#02H                     ; Increment pointer of System Stack
                JMPA    cc_UC,_OSCtxSwRestore       ; Do loop again
_OSCtxSwRestoreEnd:

                EXTP    R7,#03h                     ; Load this task's interrupt context on the system stack
                MOV     R3,[R6+#06h]                ;     Get Task PSW
                MOV     R2,[R6+#04h]                ;     Get Task IP
                MOV     R1,[R6+#02h]                ;     Get Task CSP

                PUSH    R3                          ; Replace PSW on System stack
                PUSH    R1                          ; Replace CSP on system Stack
                PUSH    R2                          ; Replace IP on System Stack

                %RestoreContext()                   ; Restore all processor registers from the new task's stack

                BSET    IEN                         ; Enable interrupts

                RETI                                ; Return to new task

                               ; Return to new task

OSCtxSw        ENDP
;********************************************************************************************************
;                                 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 system stack frame of the task to suspend looks as follows:
;                                           SYSTEM STACK AREA
;                                     SP -> +0  OFFSET  of task to suspend    (Low memory)
;                                           +2  SEGMENT of task to suspend
;                                           +4  PSW     of task to suspend    (High memory)
;
;          3) The user stack frame of the task to resume looks as follows:
;
;                                                TASK STACK AREA                              (High Memory)
;                                           +12  TASK DATA PARAMETER PAGE pointer of task
;                                           +10  TASK DATA PARAMETER OFFSET pointer of task
;                                           +0E  SEGMENT of task code address
;                                           +0C  OFFSET  of task code address

⌨️ 快捷键说明

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