📄 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 <msp430x14x.h>
;********************************************************************************************************
; //宏定义
;********************************************************************************************************
PUSHALL MACRO
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
POPALL MACRO
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) 切换到优先级最高的任务
;********************************************************************************************************
RSEG CODE ; //可重定位段,下面汇编可重定位
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
;********************************************************************************************************
;======================================================
COMMON INTVEC ;Interrup vector
;======================================================
ORG WDT_VECTOR
DW WDT_ISR
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -