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