?? os_cpu_a.asm
字號:
//************************************************************
// 單位: 華中科技大學光電子工程系
// 作者: 張利
// 文件: OS_CPU_A.asm for unsp
//*************************************************************
.include hardware.inc
.external _OSTCBCur
.external _OSTCBHighRdy
.external _OSRunning
.external _OSPrioCur
.external _OSPrioHighRdy
.external _OSTaskSwHook
.external _OSIntEnter
.external _OSIntExit
.external _OSTimeTick
.public _OSStartHighRdy
.public _OSIntCtxSw
.public _OSCtxSw
.public _OSTickISR
PUSHALL: .MACRO
PUSH R5 to [sp]
PUSH R4 to [sp]
PUSH R3 to [sp]
PUSH R2 to [sp]
PUSH R1 to [sp]
.ENDM
POPALL: .MACRO
POP R1 from [sp]
POP R2 from [sp]
POP R3 from [sp]
POP R4 from [sp]
POP R5 from [sp]
.ENDM
.isram
OSStack: .dw 50 dup(?)
.define OSStkStart OSStack+50
//**************************************************************
// 堆棧結構:
// 任務堆棧: 系統堆棧: OSStkStart -> | | |
// ---------- SP -> ----------
// |OSTCBCur| /---->| | |
// ---------- | ----------
// | |
// | |
// \---->|OSTCBCur->OSTCBStkPtr| |
// ----------------------- |
// | |
// | ---------- |
// | | | |<-----
// | ----------
// \---------->| 長度 | 低地址
// ----------
//****************************************************************
.code
_OSStartHighRdy:
CALL _OSTaskSwHook
OSCtxSw_in:
// OSTCBStrPtr -->R1
// OSTCBStrPtr 是TCB結構的第一項,所以就是OSTCBCur指想的內存單元
// R1為任務堆棧的頭指針
R1=[_OSTCBCur]
// R2中為任務堆棧頭地址存放的第一條內容,是堆棧的長度
R1=[R1]
R2=[R1]
// R3為系統堆棧的高位地址+1
R3=OSStkStart
restore_stack:
R1+=1
R3-=1
R4=[R1]
[R3]=R4
R2-=1
JNZ restore_stack
// 調整堆棧指針
R3-=1
SP=R3
// OSRunning =TRUE
R1=0x0001
[_OSRunning]=R1
POPALL
INT FIQ
INT IRQ
RETI
//***************************************************************
_OSCtxSw:
// 將所有寄存器壓棧
PUSHALL
OSIntCtxSw_in:
// 求出系統堆棧的長度 ,并將其存入 R2
R1=SP
R2=OSStkStart
R1+=1
R2=R2-R1
// R1 <-- OSTCBStkPtr
// R1 為任務堆棧的頭指針
R1=[_OSTCBCur]
// 首先將系統堆棧長度保存在任務堆棧中
R1=[R1]
[R1]=R2
// 得到堆棧的起始地址
R3=OSStkStart
// 保存系統堆棧到任務堆棧
save_stack:
R3-=1
R1+=1
R4=[R3]
[R1]=R4
R2-=1
JNZ save_stack
CALL _OSTaskSwHook
// OSTCBCur = OSTCBHighRdy
R1=[_OSTCBHighRdy]
[_OSTCBCur]=R1
// OSPrioCur = OSPrioHighRdy
R1=[_OSPrioHighRdy]
[_OSPrioCur]=R1
JMP OSCtxSw_in
//*********************************************************************
// 僅需調整SP指針,然后進行任務切換
//*********************************************************************
_OSIntCtxSw:
R1=SP
R1+=0x0007 //多壓棧的偏移量,由于不懂凌陽編譯器的編譯原理,該量是
// 郁悶了 n 久才調出來的,嗚嗚~~~
SP=R1
JMP OSIntCtxSw_in
//********************************************************************
// 打開SPACE061A的時間基準信號中斷
//********************************************************************
_OSTickISR:
R1=0x0001
[P_INT_Ctrl]=R1
RETF
//********************************************************************
// 該中斷采用SPACE061A的時間基準信號產生調度信號
// 注意要 在程序開始前對該中斷初始化
//********************************************************************
.text
.public _IRQ6
_IRQ6:
nop
PUSHALL
R1=0x0001
test R1,[P_INT_Ctrl]
JZ OUT
R1=0x0001
[P_INT_Clear]=R1
CALL _OSIntEnter
CALL _OSTimeTick
CALL _OSIntExit
OUT:
R1=0x0001
[P_INT_Clear]=R1
POPALL
RETI
//**********************************************************************
// 用戶函數寫在下面
//
//**********************************************************************
.public _SerialInit
_SerialInit:
R1=0x0480
[P_IOB_Attrib]=R1
R1=0x0400
[P_IOB_Dir]=R1
R1=0x0000
[P_UART_BaudScalarLow]=R1
R1=0x0005
[P_UART_BaudScalarHigh]=R1
R1=0x0000
[P_UART_Command1]=R1
R1=0x00c0
[P_UART_Command2]=R1
retf
.public _Output
_Output:
INT OFF
bp=sp
R1=[bp+3]
R2=[bp+4]
TxRDY:
R4=[P_UART_Command2]
r4&=0x0040
JZ TxRDY
R3=[R1]
[P_UART_Data]=R3
R1+=1
R2-=1
JNZ TxRDY
INT FIQ
INT IRQ
retf
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -