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

📄 os_cpu_a.asm

📁 uCOS-II在MSP430上的移植程序包
💻 ASM
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                              (c) Copyright 2002, Micrium, Inc., Weston, FL
;                                          All Rights Reserved
;
;                                               TI MSP430
;
;
; File         : OS_CPU_A.ASM
; By           : Alley Zhou (zzy@lierda.com)
;                Jean J. Labrosse
;********************************************************************************************************

#include   <msp430x44x.h>


;********************************************************************************************************
;                                           //宏定义
;********************************************************************************************************

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

#MACRO	POPALL
            pop      r15
            pop      r14
            pop      r13
            pop      r12
            pop      r11
            pop      r10
            pop      r9
            pop      r8
            pop      r7
            pop      r6
            pop      r5
            pop      r4          
            #ENDM
            
;********************************************************************************************************
;                                  //声明公共变量和外部变量
;********************************************************************************************************

            .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

;********************************************************************************************************
;                                  //最高优先级任务开始函数
;
; //说明: OSStart()调用本函数,调度运行优先级最高的任务
;
; //OSStartHighRdy()应完成以下三条:
; //                 a) 调用函数OSTaskSwHook(),
; //                 b) 置OSRunning 标志,
; //                 c) 切换到优先级最高的任务
;********************************************************************************************************

            .pseg code,common                ; //可重定位段,下面汇编可重定位
            
            
            
            				 

_OSStartHighRdy
            call     #_OSTaskSwHook

            mov.b    #1, &_OSRunning         ; //置内核运行标志

            mov.w    SP, &_OSISRStkPtr       ; //保护中断堆栈              

            mov.w    &_OSTCBHighRdy, R13     ; //载入最高优先级任务堆栈
            mov.w    @R13, SP

            POPALL                          ; //从堆栈弹出任务对应的所有寄存器
             
            reti                            ; //效仿一次中断返回
 

;********************************************************************************************************
;                                     //任务级任务切换
;
; //说明: 函数OS_Sched() 调用本函数作一次任务切换
;
; //函数OSCtxSw() 应完成:
; //                a) 保存当前任务的所有寄存器到任务堆栈
; //                b) 保存SP到当前任务的任务控制块
; //                c) 调用OSTaskSwHook()
; //                d) 复制OSPrioHighRdy 到 OSPrioCur
; //                e) 复制 OSTCBHighRdy 到 OSTCBCur
; //                f) 把OSTCBHighRdy->OSTCBStkPtrLoad 载入到SP
; //                g) 从高优先级任务堆栈弹出所有寄存器
; //                h) 执行一次中断返回
;********************************************************************************************************

_OSCtxSw
            push      sr                    ; //保存SR,效仿一次中断
            PUSHALL                         ; //所有当前任务的寄存器压入堆栈          
             
            mov.w     &_OSTCBCur, R13        ; OSTCBCur->OSTCBStkPtr = SP
            mov.w     SP, 0(R13)

            call      #_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                          ; //弹出高优先级任务的寄存器
             
            reti                            ; //效仿中断返回


;********************************************************************************************************
;                                       //中断级任务切换
;
; //说明: 函数OSIntExit() 调用本函数执行一次中断级任务切换
;
; //函数OSIntCtxSw() 应完成:
; //                a) 调用OSTaskSwHook()
; //                b) 复制 OSPrioHighRdy 到 OSPrioCur
; //                c) 复制 OSTCBHighRdy 到 OSTCBCur
; //                f) 把OSTCBHighRdy->OSTCBStkPtrLoad 载入到SP
; //                g) 从高优先级任务堆栈弹出所有寄存器
; //                h) 执行一次中断返回
;********************************************************************************************************

_OSIntCtxSw
             
            call      #_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                          ; //弹出高优先级任务的寄存器
             
            reti                            ; //中断返回


;********************************************************************************************************
;                                              //时钟节拍中断服务程序
;
; //说明: 看门狗定时器作为时钟节拍原
;
; //备注      : 1) 下面的这段C伪码表示中断执行过程
;
;                 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) 用户在调用函数OSIntExit()应先关闭总中断,因为有可能当函数OSIntExit()返回时中断发生,
; //                如果这样的话,新的中断将保存中断堆栈的的堆栈指针,而不是任务堆栈的堆栈指针,这样系
; //                统就会崩溃 
;                 
;
;********************************************************************************************************

_WDT_ISR                                     ; //看门狗定时器中断服务程序
            PUSHALL                         ; //保护所有寄存器             
             
            bic.b    #0x01, IE1             ; //关闭看门狗定时器中断
             
            cmp.b    #0, &_OSIntNesting      ; if (OSIntNesting == 0)  
            jne      WDT_ISR_1
                               
            mov.w    &_OSTCBCur, R13         ; //保存任务堆栈
            mov.w    SP, 0(R13)

            mov.w    &_OSISRStkPtr, SP       ; //载入中断堆栈             

WDT_ISR_1
            inc.b    &_OSIntNesting          ; OSIntNesting++
            bis.b    #0x01, IE1             ; //开看门狗定时器中断
             
            EINT                            ; //开中断允许中断嵌套

            call     #_OSTimeTick            ; //调用节拍处理函数             

            DINT                            ; //这一点非常重要,调用函数OSIntExit()前关闭中断

            call     #_OSIntExit             ; //调用退出中断函数

            cmp.b    #0, &_OSIntNesting      ; if (OSIntNesting == 0) 
            jne      WDT_ISR_2

            mov.w    &_OSTCBHighRdy, R13     ; //恢复任务堆栈
            mov.w    @R13, SP
                       
WDT_ISR_2
            POPALL                          ; //恢复所有寄存器
             
            reti                            
                                           

;********************************************************************************************************
;                             //保存和恢复状态寄存器SR
;
;********************************************************************************************************

_OSCPUSaveSR
            MOV.W    SR,R12
            DINT
            RET


_OSCPURestoreSR
            MOV.W    R12,SR
            RET

;********************************************************************************************************
;                                 //看门狗定时器中断向量
;
; //AQ430头文件定义的是各中断向量的偏移量,故看门狗中断向量为0xFFE0+WDT_VECTOR
;********************************************************************************************************
            .pseg wdt_vector,abs=0xFFE0+WDT_VECTOR
            .data _WDT_ISR		

            END

⌨️ 快捷键说明

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