www.pudn.com > FULL_TI-MSP430-FOR-uCOS-II-V252.rar > Os_cpu_a.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    
 
 
;******************************************************************************************************** 
;                                           //宏定义 
;******************************************************************************************************** 
 
#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