📄 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 <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 + -