?? os_cpu_a.s43
字號:
;********************************************************************************************************
; 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 + -