?? os_cpu_a.asm
字號(hào):
;/*
;*********************************************************************************************************
;* uC/OS-II
;* 實(shí)時(shí)內(nèi)核
;*
;* (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
;* 版權(quán)所有
;*
;* MCU-51 專用代碼
;* KEIL C51大模式編譯
;*
;* 文件名 : OS_CPU_A.ASM
;* 作者 : Jean J. Labrosse
;*********************************************************************************************************
;*/
;偽指令詳細(xì)用法請(qǐng)查A51.PDF文件
;程序結(jié)構(gòu)詳見《uC/OS-II》193-198頁(yè)
;不用此語(yǔ)句!!! $CASE ;標(biāo)號(hào)和變量名區(qū)分大小寫
$NOMOD51
EA BIT 0A8H.7
SP DATA 081H
B DATA 0F0H
ACC DATA 0E0H
DPH DATA 083H
DPL DATA 082H
PSW DATA 0D0H
TR1 BIT 088H.6
TH1 DATA 08DH
TL1 DATA 08BH
TF2 BIT 0C8H.7
NAME OS_CPU_A ;模塊名
;定義重定位段
?PR?OSStartHighRdy?OS_CPU_A SEGMENT CODE
?PR?OSCtxSw?OS_CPU_A SEGMENT CODE
?PR?OSIntCtxSw?OS_CPU_A SEGMENT CODE
?PR?OSTickISR?OS_CPU_A SEGMENT CODE
?PR?_?serial?OS_CPU_A SEGMENT CODE
;聲明引用全局變量和外部子程序
EXTRN DATA (?C_XBP) ;仿真堆棧指針用于重入局部變量保存
EXTRN IDATA (OSTCBCur)
EXTRN IDATA (OSTCBHighRdy)
EXTRN IDATA (OSRunning)
EXTRN IDATA (OSPrioCur)
EXTRN IDATA (OSPrioHighRdy)
EXTRN CODE (_?OSTaskSwHook)
EXTRN CODE (_?serial)
EXTRN CODE (_?OSIntEnter)
EXTRN CODE (_?OSIntExit)
EXTRN CODE (_?OSTimeTick)
;對(duì)外聲明4個(gè)不可重入函數(shù)
PUBLIC OSStartHighRdy
PUBLIC OSCtxSw
PUBLIC OSIntCtxSw
PUBLIC OSTickISR
;分配堆棧空間。只關(guān)心大小,堆棧起點(diǎn)由keil決定,通過標(biāo)號(hào)可以獲得keil分配的SP起點(diǎn)。
?STACK SEGMENT IDATA
RSEG ?STACK
OSStack:
DS 40H
OSStkStart IDATA OSStack-1
;定義壓棧出棧宏
PUSHALL MACRO
PUSH PSW
PUSH ACC
PUSH B
PUSH DPL
PUSH DPH
MOV A,R0 ;R0-R7入棧
PUSH ACC
MOV A,R1
PUSH ACC
MOV A,R2
PUSH ACC
MOV A,R3
PUSH ACC
MOV A,R4
PUSH ACC
MOV A,R5
PUSH ACC
MOV A,R6
PUSH ACC
MOV A,R7
PUSH ACC
;PUSH SP ;不必保存SP,任務(wù)切換時(shí)由相應(yīng)程序調(diào)整
ENDM
POPALL MACRO
;POP ACC ;不必保存SP,任務(wù)切換時(shí)由相應(yīng)程序調(diào)整
POP ACC ;R0-R7出棧
MOV R7,A
POP ACC
MOV R6,A
POP ACC
MOV R5,A
POP ACC
MOV R4,A
POP ACC
MOV R3,A
POP ACC
MOV R2,A
POP ACC
MOV R1,A
POP ACC
MOV R0,A
POP DPH
POP DPL
POP B
POP ACC
POP PSW
ENDM
;子程序
;-------------------------------------------------------------------------
RSEG ?PR?OSStartHighRdy?OS_CPU_A
OSStartHighRdy:
USING 0 ;上電后51自動(dòng)關(guān)中斷,此處不必用CLR EA指令,因?yàn)榈酱颂庍€未開中斷,本程序退出后,開中斷。
LCALL _?OSTaskSwHook
OSCtxSw_in:
;OSTCBCur ===> DPTR 獲得當(dāng)前TCB指針,詳見C51.PDF第178頁(yè)
MOV R0,#LOW (OSTCBCur) ;獲得OSTCBCur指針低地址,指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù)
INC R0
MOV DPH,@R0 ;全局變量OSTCBCur在IDATA中
INC R0
MOV DPL,@R0
;OSTCBCur->OSTCBStkPtr ===> DPTR 獲得用戶堆棧指針
INC DPTR ;指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù)
MOVX A,@DPTR ;.OSTCBStkPtr是void指針
MOV R0,A
INC DPTR
MOVX A,@DPTR
MOV R1,A
MOV DPH,R0
MOV DPL,R1
;*UserStkPtr ===> R5 用戶堆棧起始地址內(nèi)容(即用戶堆棧長(zhǎng)度放在此處) 詳見文檔說明 指針用法詳見C51.PDF第178頁(yè)
MOVX A,@DPTR ;用戶堆棧中是unsigned char類型數(shù)據(jù)
MOV R5,A ;R5=用戶堆棧長(zhǎng)度
;恢復(fù)現(xiàn)場(chǎng)堆棧內(nèi)容
MOV R0,#OSStkStart
restore_stack:
INC DPTR
INC R0
MOVX A,@DPTR
MOV @R0,A
DJNZ R5,restore_stack
;恢復(fù)堆棧指針SP
MOV SP,R0
;恢復(fù)仿真堆棧指針?C_XBP
INC DPTR
MOVX A,@DPTR
MOV ?C_XBP,A ;?C_XBP 仿真堆棧指針高8位
INC DPTR
MOVX A,@DPTR
MOV ?C_XBP+1,A ;?C_XBP 仿真堆棧指針低8位
;OSRunning=TRUE
MOV R0,#LOW (OSRunning)
MOV @R0,#01
POPALL
SETB EA ;開中斷
RETI
;-------------------------------------------------------------------------
RSEG ?PR?OSCtxSw?OS_CPU_A
OSCtxSw:
PUSHALL
OSIntCtxSw_in:
;獲得堆棧長(zhǎng)度和起址
MOV A,SP
CLR C
SUBB A,#OSStkStart
MOV R5,A ;獲得堆棧長(zhǎng)度
;OSTCBCur ===> DPTR 獲得當(dāng)前TCB指針,詳見C51.PDF第178頁(yè)
MOV R0,#LOW (OSTCBCur) ;獲得OSTCBCur指針低地址,指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù)
INC R0
MOV DPH,@R0 ;全局變量OSTCBCur在IDATA中
INC R0
MOV DPL,@R0
;OSTCBCur->OSTCBStkPtr ===> DPTR 獲得用戶堆棧指針
INC DPTR ;指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù)
MOVX A,@DPTR ;.OSTCBStkPtr是void指針
MOV R0,A
INC DPTR
MOVX A,@DPTR
MOV R1,A
MOV DPH,R0
MOV DPL,R1
;保存堆棧長(zhǎng)度
MOV A,R5
MOVX @DPTR,A
MOV R0,#OSStkStart ;獲得堆棧起址
save_stack:
INC DPTR
INC R0
MOV A,@R0
MOVX @DPTR,A
DJNZ R5,save_stack
;保存仿真堆棧指針?C_XBP
INC DPTR
MOV A,?C_XBP ;?C_XBP 仿真堆棧指針高8位
MOVX @DPTR,A
INC DPTR
MOV A,?C_XBP+1 ;?C_XBP 仿真堆棧指針低8位
MOVX @DPTR,A
;調(diào)用用戶程序
LCALL _?OSTaskSwHook
;OSTCBCur = OSTCBHighRdy
MOV R0,#OSTCBCur
MOV R1,#OSTCBHighRdy
MOV A,@R1
MOV @R0,A
INC R0
INC R1
MOV A,@R1
MOV @R0,A
INC R0
INC R1
MOV A,@R1
MOV @R0,A
;OSPrioCur = OSPrioHighRdy 使用這兩個(gè)變量主要目的是為了使指針比較變?yōu)樽止?jié)比較,以便節(jié)省時(shí)間。
MOV R0,#OSPrioCur
MOV R1,#OSPrioHighRdy
MOV A,@R1
MOV @R0,A
LJMP OSCtxSw_in
;-------------------------------------------------------------------------
RSEG ?PR?OSIntCtxSw?OS_CPU_A
OSIntCtxSw:
;調(diào)整SP指針去掉在調(diào)用OSIntExit(),OSIntCtxSw()過程中壓入堆棧的多余內(nèi)容
;SP=SP-4
MOV A,SP
CLR C
SUBB A,#4
MOV SP,A
LJMP OSIntCtxSw_in
;-------------------------------------------------------------------------
CSEG AT 002BH ;OSTickISR
LJMP OSTickISR ;使用定時(shí)器2
RSEG ?PR?OSTickISR?OS_CPU_A
OSTickISR:
CLR TF2
USING 0
PUSHALL
LCALL _?OSIntEnter
LCALL _?OSTimeTick
LCALL _?OSIntExit
POPALL
RETI
;-------------------------------------------------------------------------
CSEG AT 0023H ;串口中斷
LJMP SerialISR ;工作于系統(tǒng)態(tài),無任務(wù)切換。
RSEG ?PR?_?serial?OS_CPU_A
SerialISR:
USING 0
PUSHALL
CLR EA
LCALL _?serial
SETB EA
POPALL
RETI
;-------------------------------------------------------------------------
END
;-------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -