📄 os_cpu_a.asm
字号:
//**********************************************************************************************************
//* uC/OS-II
//* 实时内核
//*
//* (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
//* 版权所有
//*
//* unSP 专用代码
//*
//* 文件名 : OS_CPU_a.asm
//* 作者 : Jean J. Labrosse
//* 改编 : 牟联树 lianshu@sunnorth.com.cn 北京北阳电子技术有限公司
//**********************************************************************************************************/
//程序结构详见《uC/OS-II》193-198页
//不用此语句!!! $CASE ;标号和变量名区分大小写
.INCLUDE Spmc75_regs.inc
.DEFINE OS_CRITICAL_METHOD 2
//.EXTERNAL _C_XBP //仿真堆栈指针用于重入局部变量保存
.EXTERNAL _OSTCBCur
.EXTERNAL _OSTCBHighRdy
.EXTERNAL _OSRunning
.EXTERNAL _OSPrioCur
.EXTERNAL _OSPrioHighRdy
.EXTERNAL _OSTaskSwHook
.EXTERNAL _OSIntEnter
.EXTERNAL _OSIntExit
.EXTERNAL _OSTimeTick
//对外声明4个不可重入函数
.PUBLIC _OSStartHighRdy
.PUBLIC _OSCtxSw
.PUBLIC _OSIntCtxSw
.PUBLIC _OSTickISR
//分配堆栈空间。只关心大小,堆栈起点由keil决定,通过标号可以获得keil分配的SP起点。
.DEFINE OSStkStart 0x07fd
//定义压栈出栈
PUSHALL:.MACRO
push r1,r5 to [sp]
.ENDM
POPALL: .MACRO
pop r1,r5 from [sp]
.ENDM
.CODE
//-------------------------------------------------------------------------
_OSStartHighRdy:
call _OSTaskSwHook
OSCtxSw_in:
//OSTCBCur ===> DPTR 获得当前TCB指针,详见C51.PDF第178页
bp = [_OSTCBCur] //获得OSTCBCur指针
r2 = [bp] //r2中为用户堆栈指针
r1 = [r2] //用户堆栈长度
r3 = OSStkStart //恢复现场堆栈内容
restore_stack:
r4 = [r2 --]
[r3 --] = r4
r1 -= 1
jnz restore_stack
r3 += 1 //恢复堆栈指针SP
sp = r3
r1 = 1 //OSRunning=TRUE
[_OSRunning] = r1
POPALL
int irq
reti
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
_OSIntCtxSw:
sp -= 2 //调整SP指针去掉在调用OSIntExit(),OSIntCtxSw()过程中压入堆栈的多余内容 SP=SP-2
.if OS_CRITICAL_METHOD == 3
r1 = [_C_XBP] //调整使用关中断方法3调用OSIntExit()
r1 += 1
[_C_XBP] = r1
.endif
r1 = SP //获得堆栈长度和起址
r1 -= OSStkStart //获得堆栈长度 r1 中
r2 = [_OSTCBCur] //获得当前TCB指针,详见C51.PDF第178页,r2中
r3 = [r2] //获得用户堆栈指针 r3 中
[r3 ++] = r1 //保存堆堆栈长度
r4 = OSStkStart //获得堆栈起址 r4中
save_stackA:
r2 = [r4 ++]
[r3 ++] = r2
r1 -= 1
jnz save_stackA
CALL _OSTaskSwHook //调用用户程序
r1 = [_OSTCBHighRdy] //OSTCBCur = OSTCBHighRdy
[_OSTCBCur] = r1
r2 = [_OSPrioHighRdy] //OSPrioCur = OSPrioHighRdy 使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。
[_OSPrioCur] = r2
r2 = [r1] //r2中为用户堆栈指针
r1 = [r2] //用户堆栈长度
r3 = OSStkStart //恢复现场堆栈内容
restore_stk:
r4 = [r2 ++]
[r3 ++] = r4
r1 -= 1
jnz restore_stk
r3 -= 1 //恢复堆栈指针SP
sp = r3
r1 = 1 //OSRunning=TRUE
[_OSRunning] = r1
POPALL
retf
.TEXT
.PUBLIC _BREAK
_BREAK:
_OSCtxSw:
PUSHALL
OSIntCtxSw_in:
r1 = OSStkStart //获得堆栈长度和起址
r1 -= SP //获得堆栈长度 r1 中
r2 = [_OSTCBCur] //获得当前TCB指针,详见C51.PDF第178页,r2中
r3 = [r2] //获得用户堆栈指针 r3 中
[r3 ++] = r1 //保存堆堆栈长度
r4 = OSStkStart //获得堆栈起址 r4中
save_stack:
r2 = [r4 --]
[r3 --] = r2
r1 -= 1
jnz save_stack
CALL _OSTaskSwHook //调用用户程序
r1 = [_OSTCBHighRdy] //OSTCBCur = OSTCBHighRdy
[_OSTCBCur] = r1
r2 = [_OSPrioHighRdy] //OSPrioCur = OSPrioHighRdy 使用这两个变量主要目的是为了使指针比较变为字节比较,以便节省时间。
[_OSPrioCur] = r2
r2 = [r1] //r2中为用户堆栈指针
r1 = [r2] //用户堆栈长度
r3 = OSStkStart //恢复现场堆栈内容
restore_stkA:
r4 = [r2 --]
[r3 --] = r4
r1 -= 1
jnz restore_stkA
r3 += 1 //恢复堆栈指针SP
sp = r3
r1 = 1 //OSRunning=TRUE
[_OSRunning] = r1
POPALL
reti
.PUBLIC _FIQ
_FIQ:
reti
//-------------------------------------------------------------------------
// INTERRUPT
//-------------------------------------------------------------------------
.PUBLIC _IRQ0
_IRQ0:
PUSHALL
CALL _OSIntEnter
CALL _OSIntExit
POPALL
reti
//-------------------------------------------------------------------------
.PUBLIC _IRQ1
_IRQ1:
reti
//-------------------------------------------------------------------------
.PUBLIC _IRQ2
_IRQ2:
PUSHALL
CALL _OSIntEnter
CALL _OSIntExit
POPALL
reti
//-------------------------------------------------------------------------
.PUBLIC _IRQ3
_IRQ3:
PUSHALL
CALL _OSIntEnter
CALL _OSIntExit
POPALL
reti
//-------------------------------------------------------------------------
.PUBLIC _IRQ4
_IRQ4:
PUSHALL
CALL _OSIntEnter
CALL _OSIntExit
POPALL
reti
//-------------------------------------------------------------------------
.PUBLIC _IRQ5
_IRQ5:
PUSHALL
CALL _OSIntEnter
CALL _OSIntExit
POPALL
reti
//-------------------------------------------------------------------------
.PUBLIC _IRQ6
_IRQ6:
reti
.PUBLIC _IRQ7
_IRQ7:
_OSTickISR:
PUSHALL
r1 = [P_CMT_Ctrl_ADDR]
r2 = r1&0x8000
jz IRQ7_Exit
[P_CMT_Ctrl_ADDR] = r1
CALL _OSIntEnter
CALL _OSTimeTick
CALL _OSIntExit
IRQ7_Exit:
POPALL
reti
.END
//-------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -