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

📄 os_cpu_a.a30

📁 原创!!! 刚刚完成的ucos2 2.76 for 瑞萨m16/60
💻 A30
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
;                                          All Rights Reserved
;
;********************************************************************************************************
;
; Port to Mitsubishi M16C/60 Series
;
; (c) Florian Stassen
; started 2003-01-18
;
;********************************************************************************************************

            ; interne Funktionen
            .glb _OSStartHighRdy
            .glb _OSCtxSw
            .glb _OSIntCtxSw
            .glb _OSTickISR
            .glb _OSTickISR1

            ; externe Funktionen
            .glb _OSIntEnter
            .glb _OSIntExit
            .glb _OSTimeTick
            .glb _OSTaskSwHook

            ; externe Variablen
            .glb _OSIntNesting              ; declared as INT8U
            .glb _OSPrioHighRdy             ; declared as INT8U
            .glb _OSPrioCur                 ; declared as INT8U
            .glb _OSRunning                 ; declared as INT8U
            .glb _OSTCBCur                  ; declared as OS_TCB *
            .glb _OSTCBHighRdy              ; declared as OS_TCB *


            .section  program,align

            .PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                   Start High Ready Task
;                                 void OSStartHighRdy(void)
;
; Description: This function is called from OSStart()
;
; Arguments  : none
;
; The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> R0              (Low memory)
;                               R1
;                               R2
;                               R3
;                               A0
;                               A1
;                               SB
;                               FB
;                               PC
;                               FLG/PC          (High memory)
;
; Note : OSStartHighRdy() MUST:
;           a) Call OSTaskSwHook() then,
;           b) Set OSRunning to TRUE,
;           c) Switch to the highest priority task.
;*********************************************************************************************************

            .ALIGN

_OSStartHighRdy:
            JSR         _OSTaskSwHook

            MOV.W       _OSTCBHighRdy, A0               ; SP = OSTCBHighRdy->OSTCBStkPtr
            LDC         [A0], SP

            MOV.B       #01H, _OSRunning                ; OSRunning = TRUE

            POPM        R0,R1,R2,R3,A0,A1,SB,FB

            REIT


            .PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                       Context Switch
;                                     void OSCtxSw(void)
;
; Description: This function is called from OSSched()
;
; Arguments  : none
;
; Note:     OSCtxSw() is always called in User-Mode (USP active),
;           so there are no problems with USP and ISP.
;
; Note(s): 1) You must map the address of OSCtxSw() to interrupt #0 in the vector table
;
; 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:
;
;                 SP -> PC        (Low memory)
;                       FLG/PC    (High memory)
;
;          3) The stack frame of the task to resume looks as follows:
;
;                 OSTCBHighRdy->OSTCBStkPtr --> R0              (Low memory)
;                                               R1
;                                               R2
;                                               R3
;                                               A0
;                                               A1
;                                               SB
;                                               FB
;                                               PC
;                                               FLG/PC          (High memory)
;
;*********************************************************************************************************

            .ALIGN

_OSCtxSw:
            PUSHM       R0,R1,R2,R3,A0,A1,SB,FB

            MOV.W       _OSTCBCur, A0                    ; OSTCBCur->OSTCBStkPtr = SP
            STC         SP, [A0]

            JSR         _OSTaskSwHook                   ; OSTaskSwHook()

            MOV.W       _OSTCBHighRdy, _OSTCBCur          ; OSTCBCur  = OSTCBHighRdy

            MOV.B       _OSPrioHighRdy, _OSPrioCur        ; OSPrioCur = OSPrioHighRdy

            MOV.W       _OSTCBHighRdy, A0                ; SP = OSTCBHighRdy->OSTCBStkPtr
            LDC         [A0], SP

            POPM        R0,R1,R2,R3,A0,A1,SB,FB         ; Restore all processor registers from the new task's stack

            REIT


            .PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                  Context Switch from ISR
;                                   void OSIntCtxSw(void)
;
; Description: This function is called from OSIntExit()
;
; Arguments  : none
;
; Note      This function is always called from inside an ISR, so ISP is used.
;           On first ISR the registers of the current task are stored on the interrupt stack (ISP).
;           OSIntCtxSw() has to move the registers from the interrupt stack to the
;           user stack and process the second half of a normal context switch.
;
; 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:
;             (ISP active)
;
;             OSTCBCur->OSTCBStkPtr ------>   R0              (Low memory)
;                                             R1
;                                             R2
;                                             R3
;                                             A0
;                                             A1
;                                             SB
;                                             FB
;                                             PC
;                                             FLG/PC          (High memory)
;
;          3) The stack frame of the task to resume looks as follows:
;             (USP active)
;
;             OSTCBHighRdy->OSTCBStkPtr -->   R0              (Low memory)
;                                             R1
;                                             R2
;                                             R3
;                                             A0
;                                             A1
;                                             SB
;                                             FB
;                                             PC
;                                             FLG/PC          (High memory)
;
;*********************************************************************************************************

            .ALIGN

_OSIntCtxSw:
            MOV.W       _OSTCBCur, A0                   ; SP = OSTCBCur->OSTCBStkPtr
            LDC         [A0], SP                        ; SP is ISP

            fset        U                               ; switch to USP

            mov.w       #10,r3                          ; move 10 words
            mov.b       #0,r1h
            mov.w       [a0],a0                         ; R1H & A0 = ISP = Src Address
            stc         sp,a1                           ; A1 = USP
            sub.w       #20,a1                          ; 10 words space, A1 = Dest Address
            ldc         a1,sp                           ; new USP
            smovf.w                                     ; String Move Forward

            ; A0 contains corrected ISP
            ldc         a0,isp

            ; now all registers and PC and FLG are on the user stack
            ; and SP (=USP) point to the correct address

            MOV.W       _OSTCBCur, A0                    ; OSTCBCur->OSTCBStkPtr = SP
            STC         SP, [A0]

            ; here we have a normal enviroment for a context switch

            JSR         _OSTaskSwHook                    ; OSTaskSwHook()

            MOV.W       _OSTCBHighRdy, _OSTCBCur          ; OSTCBCur  = OSTCBHighRdy

            MOV.B       _OSPrioHighRdy, _OSPrioCur        ; OSPrioCur = OSPrioHighRdy

            MOV.W       _OSTCBHighRdy, A0                ; SP = OSTCBHighRdy->OSTCBStkPtr
            LDC         [A0], SP

            POPM        R0,R1,R2,R3,A0,A1,SB,FB         ; Restore all processor registers from the new task's stack

            REIT


            .PAGE                                   ; /*$PAGE*/
;*********************************************************************************************************
;                                    Time ticker ISR
;                                  void OSTickISR(void)
;
; Description: This function is invoked by hardware timer
;
; Arguments  : none
;
; Note(s)    : 1) Pseudo code:
;
;                 Save all registers
;                 OSIntNesting++
;                 if (OSIntNesting == 1) {
;                     OSTCBCur->OSTCBStkPtr = SP
;                 }
;                 OSTimeTick();
;                 OSIntExit();
;                 Restore all registers
;                 Return from interrupt;
;*********************************************************************************************************

            .ALIGN

_OSTickISR:

            PUSHM       R0,R1,R2,R3,A0,A1,SB,FB         ; Save current task's registers

            jsr         _OSIntEnter                     ; OSIntEnter()
            CMP.B       #1,_OSIntNesting                 ; if (OSIntNesting == 1) {
            JNE         _OSTickISR1

            MOV.W       _OSTCBCur, A0                    ; OSTCBCur->OSTCBStkPtr = SP
            STC         SP, [A0]

_OSTickISR1:
            JSR         _OSTimeTick                     ; OSTimeTick()

            JSR         _OSIntExit                      ; OSIntExit()

            POPM        R0,R1,R2,R3,A0,A1,SB,FB         ; Restore registers from the new task's stack

            REIT


;*********************************************************************************************************
            .END

⌨️ 快捷键说明

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