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

📄 os_cpu_a.s43

📁 适用MCU: TI MSP430 5XX 适用ucos-ii版本:2.86 编译环境:IAR4.11B 主要的工作: 在MICRIUM网站上430移植代码的基础上进行了修改:5XX系列PC寄
💻 S43
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                              (c) Copyright 2002, Micrium, Inc., Weston, FL
;                                          All Rights Reserved
;
;                                               TI MSP430
;
;
; File         : OS_CPU_A.S43
; By           : Jian Chen (yenger@hotmail.com)
;                Jean J. Labrosse
;********************************************************************************************************

#include   <msp430x54x.h>

;********************************************************************************************************
;                                           MACRO DEFINITIONS
;********************************************************************************************************

PUSHALL     MACRO
            push.w   r4           ;push     r4
            push.w   r5           ;push     r5
            push.w   r6           ;push     r6
            push.w   r7           ;push     r7
            push.w   r8           ;push     r8
            push.w   r9           ;push     r9
            push.w   r10          ;push     r10
            push.w   r11          ;push     r11
            push.w   r12          ;push     r12
            push.w   r13          ;push     r13
            push.w   r14          ;push     r14
            push.w   r15          ;push     r15
            ENDM

POPALL      MACRO
            pop.w    r15          ;pop      r15
            pop.w    r14          ;pop      r14
            pop.w    r13          ;pop      r13
            pop.w    r12          ;pop      r12
            pop.w    r11          ;pop      r11
            pop.w    r10          ;pop      r10
            pop.w    r9           ;pop      r9
            pop.w    r8           ;pop      r8
            pop.w    r7           ;pop      r7
            pop.w    r6           ;pop      r6
            pop.w    r5           ;pop      r5
            pop.w    r4           ;pop      r4          
            ENDM
            
;********************************************************************************************************
;                                  PUBLIC AND EXTERNAL DECLARATIONS
;********************************************************************************************************

            EXTERN  OSIntExit
            EXTERN  OSIntNesting

            EXTERN  OSISRStkPtr

            EXTERN  OSPrioCur
            EXTERN  OSPrioHighRdy

            EXTERN  OSRunning

            EXTERN  OSTCBCur
            EXTERN  OSTCBHighRdy

            EXTERN  OSTaskSwHook
            EXTERN  OSTimeTick

            PUBLIC  OSCtxSw
            PUBLIC  OSCPURestoreSR
            PUBLIC  OSCPUSaveSR
            PUBLIC  OSIntCtxSw
            PUBLIC  OSStartHighRdy
            PUBLIC  WDT_ISR

;********************************************************************************************************
;                                  START HIGHEST PRIORITY READY TASK
;
; Description: This function is called by OSStart() to start the highest priority task that is ready to run.
;
; Note       : OSStartHighRdy() MUST:
;                 a) Call OSTaskSwHook() then,
;                 b) Set OSRunning to TRUE,
;                 c) Switch to the highest priority task.
;********************************************************************************************************

            RSEG    CODE                    ; Program code

OSStartHighRdy
            calla    #OSTaskSwHook

            mov.b    #1, &OSRunning         ; kernel running

            mov.w    SP, &OSISRStkPtr       ; save interrupt stack              

            mov.w    &OSTCBHighRdy, R13     ; load highest ready task stack
            mov.w    @R13, SP

            POPALL                          ; pop all registers
             
            reti                            ; emulate return from interrupt
 

;********************************************************************************************************
;                                     TASK LEVEL CONTEXT SWITCH
;
; Description: This function is called by OS_Sched() to perform a task level context switch.
;
; Note       : OSCtxSw() MUST:
;                 a) Save the current task's registers onto the current task stack
;                 b) Save the SP into the current task's OS_TCB
;                 c) Call OSTaskSwHook()
;                 d) Copy OSPrioHighRdy to OSPrioCur
;                 e) Copy OSTCBHighRdy to OSTCBCur
;                 f) Load the SP with OSTCBHighRdy->OSTCBStkPtr
;                 g) Restore all the registers from the high priority task stack
;                 h) Perform a return from interrupt
;********************************************************************************************************

OSCtxSw
            PUSHALL                         ; push all registers 
            mov.w     sr,R4                 ;
            mov.w     SP,R13                ;
            mov.w     26(R13),R5            ;
            mov.w     24(R13),26(R13)       ;
           
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            RLA       R5
            BIS       R5,R4
            mov.w     R4,24(R13)
                       
            mov.w     &OSTCBCur, R13        ; OSTCBCur->OSTCBStkPtr = SP
            mov.w     SP, 0(R13)
            calla     #OSTaskSwHook

            mov.b     &OSPrioHighRdy, R13   ; OSPrioCur = OSPrioHighRdy
            mov.b     R13, &OSPrioCur       ;
                          
            mov.w     &OSTCBHighRdy, R13    ; OSTCBCur  = OSTCBHighRdy
            mov.w     R13, &OSTCBCur        ;
                          
            mov.w     @R13, SP              ; SP        = OSTCBHighRdy->OSTCBStkPtr
             
            POPALL                          ; pop all registers
             
            reti                            ; return from interrup



;********************************************************************************************************
;                                       ISR LEVEL CONTEXT SWITCH
;
; Description: This function is called by OSIntExit() to perform an ISR level context switch.
;
; Note       : OSIntCtxSw() MUST:
;                 a) Call OSTaskSwHook()
;                 b) Copy OSPrioHighRdy to OSPrioCur
;                 c) Copy OSTCBHighRdy to OSTCBCur
;                 d) Load the SP with OSTCBHighRdy->OSTCBStkPtr
;                 e) Restore all the registers from the high priority task stack
;                 f) Perform a return from interrupt
;********************************************************************************************************

OSIntCtxSw
             
            calla     #OSTaskSwHook

            mov.b     &OSPrioHighRdy, R13   ; OSPrioCur = OSPrioHighRdy
            mov.b     R13, &OSPrioCur       ;
                          
            mov.w     &OSTCBHighRdy, R13    ; OSTCBCur  = OSTCBHighRdy
            mov.w     R13, &OSTCBCur        ;
                          
            mov.w     @R13, SP              ; SP        = OSTCBHighRdy->OSTCBStkPtr
             
            POPALL                          ; pop all registers
             
            reti                            ; return from interrup


;********************************************************************************************************
;                                              TICK ISR
;
; Description: This ISR handles tick interrupts.  This ISR uses the Watchdog timer as the tick source.
;
; Notes      : 1) The following C pseudo-code describes the operations being performed in the code below.
;
;                 Save all the CPU registers
;                 if (OSIntNesting == 0) {
;                     OSTCBCur->OSTCBStkPtr = SP;
;                     SP                    = OSISRStkPtr;  /* Use the ISR stack from now on           */
;                 }
;                 OSIntNesting++;
;                 Enable interrupt nesting;                 /* Allow nesting of interrupts (if needed) */
;                 Clear the interrupt source;
;                 OSTimeTick();                             /* Call uC/OS-II's tick handler            */
;                 DISABLE general interrupts;               /* Must DI before calling OSIntExit()      */
;                 OSIntExit();
;                 if (OSIntNesting == 0) {
;                     SP = OSTCBHighRdy->OSTCBStkPtr;       /* Restore the current task's stack        */
;                 }
;                 Restore the CPU registers
;                 Return from interrupt.
;
;              2) ALL ISRs should be written like this!
;
;              3) You MUST disable general interrupts BEFORE you call OSIntExit() because an interrupt 
;                 COULD occur just as OSIntExit() returns and thus, the new ISR would save the SP of 
;                 the ISR stack and NOT the SP of the task stack.  This of course will most likely cause
;                 the code to crash.  By disabling interrupts BEFORE OSIntExit(), interrupts would be
;                 disabled when OSIntExit() would return.  This assumes that you are using OS_CRITICAL_METHOD
;                 #3 (which is the prefered method).
;
;              4) If you DON'T use a separate ISR stack then you don't need to disable general interrupts 
;                 just before calling OSIntExit().  The pseudo-code for an ISR would thus look like this:
;
;                 Save all the CPU registers
;                 if (OSIntNesting == 0) {
;                     OSTCBCur->OSTCBStkPtr = SP;
;                 }
;                 OSIntNesting++;
;                 Enable interrupt nesting;                 /* Allow nesting of interrupts (if needed) */
;                 Clear the interrupt source;
;                 OSTimeTick();                             /* Call uC/OS-II's tick handler            */
;                 OSIntExit();
;                 Restore the CPU registers
;                 Return from interrupt.
;********************************************************************************************************

WDT_ISR                                     ; wd timer ISR
            PUSHALL                         ; push all registers             
             
            bic.b    #0x01, SFRIE1_L        ; bic.b    #0x01, SFRIE1             ; disable wd timer interrupt
             
            cmp.b    #0, &OSIntNesting      ; if (OSIntNesting == 0)  
            jne      WDT_ISR_1
                               
            mov.w    &OSTCBCur, R13         ;     save task stack
            mov.w    SP, 0(R13)

            mov.w    &OSISRStkPtr, SP       ;     load interrupt stack             

WDT_ISR_1
            inc.b    &OSIntNesting          ; increase OSIntNesting
            bis.b    #0x01, SFRIE1_L          ;bis.b    #0x01, SFRIE1             ; enable wd timer interrupt
             
            EINT                            ; enable general interrupt to allow for interrupt nesting

            calla    #OSTimeTick            ; call ticks routine             

            DINT                            ; IMPORTANT: disable general interrupt BEFORE calling OSIntExit()

            calla    #OSIntExit             ; call ticks routine
            //没发生任务切换的,执行以下代码
            cmp.b    #0, &OSIntNesting      ; if (OSIntNesting == 0) 
            jne      WDT_ISR_2

            mov.w    &OSTCBHighRdy, R13     ;     restore task stack SP
            mov.w    @R13, SP
                       
WDT_ISR_2
            POPALL                          ; pop all registers
             
            reti                            ; return from interrupt
                                           

;********************************************************************************************************
;                             SAVE AND RESTORE THE CPU'S STATUS REGISTER
;
; Description: These functions are used to implement OS_CRITICAL_METHOD #3 by saving the status register
;              in a local variable of the calling function and then, disables interrupts. 
;
; Notes      : R12 is assumed to hold the argument passed to OSCPUSaveSR() and also, the value returned
;              by OSCPURestoreSR().
;********************************************************************************************************

OSCPUSaveSR
            MOV.W    SR,R12
            DINT
            RETA


OSCPURestoreSR
            MOV.W    R12,SR
            RETA

;********************************************************************************************************
;                                 WD TIMER INTERRUPT VECTOR ENTRY
;
;  Interrupt vectors             
;********************************************************************************************************
            COMMON  INTVEC

            ORG     WDT_VECTOR 
WDT_VEC     DW      WDT_ISR                 ; interrupt vector. Watchdog/Timer, Timer mode

            END

⌨️ 快捷键说明

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