📄 interf.a30
字号:
SYS_IPL .equ 6 ;RTOS中断允许级别
.glb _USP, _INEST ;指向任务堆栈指针的指针,中断嵌套次数
.glb SYS_SP ;系统堆栈指针
;*中断内用中断堆栈,RTOS的系统调用内用系统堆栈,任务内用任务堆栈*
;*中断可以嵌套,但在系统调用内部可以嵌套*
;*系统调用内不能响应OS-dependent中断,但可以响应OS-independent中断*
;进入系统调用
ENTRY .macro
PUSHC FLG ;标志寄存器入栈(任务堆栈)
LDIPL #SYS_IPL ;中断优先级设定为系统优先级
PUSHM R0, R1 ;R0,R1入栈,R0,R1用于计算并将PC,FLG入栈
MOV.W +4[SP], R0 ;R0值为FLG寄存器值
AND.W #0F0FFH, R0 ;8~11位用于存储PC的16~19位,所以先将这4位清零
MOV.W #0, R1 ;R1清零
MOV.B +8[SP], R1H ;R1H=PC高字节(16~23位)
AND.B #0FH, R1H ;屏蔽高4位
OR.W R1, R0 ;将FLG的15~12,PC的16~19,FLG的7~0位写入R0寄存器
MOV.W +6[SP], R1 ;R1=将PC的低16位
MOV.W R1, +5[SP] ;R1(PC的低16位)入栈
MOV.W R0, +7[SP] ;R0(FLG的15~12,PC的16~19,FLG的7~0)入栈
POPM R0, R1 ;R0,R1出栈
ADD.W #1, SP ;调整SP值(FLG和PC结合在一起节省了一个字节)
PUSHM R0,R1,R2,R3,A0,A1,SB,FB ;寄存器入栈(任务堆栈)
STC SP, _USP ;任务堆栈指针保存到任务TCB的堆栈指针中
LDC #SYS_SP, SP ;系统堆栈设定为当前的堆栈指针
.endm
;退出系统调用
EXIT .macro
LDC _USP, SP ;新任务堆栈设定为当前的堆栈指针,USP是新任务堆栈指针的指针
POPM R0,R1,R2,R3,A0,A1,SB,FB ;寄存器出栈(新任务堆栈)
REIT ;中断返回(模拟中断,实质为函数调用),返回到新任务中运行
.endm
;进入中断通知系统调用
IENTRY .macro
PUSHC FLG ;标志寄存器入栈(中断堆栈)
LDIPL #SYS_IPL ;中断优先级设定为系统优先级
FSET U ;使用用户堆栈
STC SP, _USP ;任务堆栈指针保存到任务TCB的堆栈指针中
LDC #SYS_SP, SP ;系统堆栈设定为当前的堆栈指针
PUSHM R1,R2,R3,A0,A1,SB ;寄存器入栈(系统堆栈)
;由于带i的系统调用不会发生任务切换,返回值直接放到R0寄存器中
;所以不用保护R0寄存器的值
.endm
;退出中断通知系统调用
IEXIT .macro
POPM R1,R2,R3,A0,A1,SB ;寄存器出栈(系统堆栈)
LDC _USP, SP ;任务堆栈设定为当前的堆栈指针
FCLR U ;使用ISP
POPC FLG ;标志寄存器出栈(中断堆栈)(函数调用不自动恢复FLG)
RTS ;系统调用返回
.endm
;进入Polling系统调用
PENTRY .macro
PUSHC FLG ;标志寄存器入栈(任务堆栈或者中断堆栈,取决于当时状态(任务还是系统调用中))
LDIPL #SYS_IPL ;中断优先级设定为系统优先级
FSET U ;使用用户堆栈
STC SP, _USP ;任务堆栈指针保存到任务TCB的堆栈指针中
LDC #SYS_SP, SP ;系统堆栈设定为当前的堆栈指针
PUSHM R1,R2,R3,A0,A1,SB ;寄存器入栈(系统堆栈)
.endm
;退出Polling系统调用
PEXIT .macro
.local __pexit
POPM R1,R2,R3,A0,A1,SB ;寄存器出栈(系统堆栈)
LDC _USP, SP ;任务堆栈设定为当前的堆栈指针
CMP.W #0, _INEST ;如果在中断通知处理中则恢复SP为ISP否则保持任务堆栈
JZ __pexit
FCLR U ;使用ISP
__pexit:
POPC FLG ;标志寄存器出栈(任务堆栈或者中断堆栈)
RTS ;系统调用返回
.endm
.section program
.glb _syssta
.glb __syssta
;开始多任务系统运行,这里模拟一次中断返回
_syssta:
JSR.A __syssta
EXIT
.glb _slp_tsk
.glb __slp_tsk
_slp_tsk:
ENTRY
JSR.A __slp_tsk
EXIT
.glb _wup_tsk
.glb $_wup_tsk
_wup_tsk:
ENTRY
JSR.A $_wup_tsk
EXIT
.glb _iwup_tsk
.glb $_iwup_tsk
_iwup_tsk:
IENTRY
JSR.A $_iwup_tsk
IEXIT
.glb _ret_int
.glb _dispatch,_INSET, _DELAY
;从中断通知处理中返回
_ret_int:
LDIPL #SYS_IPL ;中断优先级设定为系统优先级
SUB.W #1, _INEST ;中断嵌套次数减1
JGTU __ret_int_end ;如果中断嵌套次数等于0则激活分发器,否则延迟分发
CMP.W #0, _DELAY ;如果DELAY=0则不用任务切换,直接返回
JZ __ret_int_end ;中断嵌返回
;中断发生时将FLG,PC压入中断堆栈,我们要将它压入任务堆栈用于恢复任务运行
PUSH.W R0 ;R0入栈
MOV.W +4[SP], R0 ;将FLG的15~12,PC的16~19,FLG的7~0位写入R0寄存器
FSET U ;使用任务堆栈
PUSH.W R0 ;R0值入栈
FCLR U ;恢复中断堆栈
MOV.W +2[SP], R0 ;将PC的低16位写入R0寄存器
FSET U ;使用任务堆栈
PUSH.W R0 ;R0值入栈
FCLR U ;恢复中断堆栈
POP.W R0 ;R0出栈
ADD.W #4, SP ;调整中断堆栈指针值(相当于将FLG,PC出栈)
FSET U ;使用任务堆栈
PUSHM R0,R1,R2,R3,A0,A1,SB,FB ;寄存器入栈(任务堆栈)
STC SP, _USP ;任务堆栈指针保存到任务TCB的堆栈指针中
LDC #SYS_SP, SP ;系统堆栈设定为当前的堆栈指针
JSR.A _dispatch ;激活分发器
LDC _USP, SP ;新任务堆栈设定为当前的堆栈指针,USP是新任务堆栈指针的指针
POPM R0,R1,R2,R3,A0,A1,SB,FB ;寄存器出栈(新任务堆栈)
__ret_int_end:
REIT ;中断返回,返回到新任务中运行
.glb _dis_dsp
.glb __dis_dsp
_dis_dsp:
PENTRY
JSR.A __dis_dsp
PEXIT
.glb _ena_dsp
.glb __ena_dsp
_ena_dsp:
ENTRY
JSR.A __ena_dsp
EXIT
.glb _loc_cpu
.glb __loc_cpu,_SYSSTAT,_UIPL
_loc_cpu:
PUSH.W R0
STC FLG, R0
AND.W #7000H, R0
CMP.W #3, _SYSSTAT
JC __loc_cpu_skip
MOV.W R0, _UIPL
__loc_cpu_skip:
POP.W R0
LDIPL #SYS_IPL
STC SP, _USP
LDC #SYS_SP, SP
JSR.A __loc_cpu
LDC _USP, SP
RTS
.glb _unl_cpu
.glb __unl_cpu,_SYSSTAT,_UIPL
_unl_cpu:
PUSHC FLG
LDIPL #SYS_IPL
PUSHM R0, R1
MOV.W +4[SP], R0
AND.W #0F0FFH, R0
CMP.W #3, _SYSSTAT
JNC __unl_cpu_skip
AND.W #0FFFH, R0
OR.W _UIPL, R0
__unl_cpu_skip:
MOV.W #0, R1
MOV.B +8[SP], R1H
AND.B #0FH, R1H
OR.W R1, R0
MOV.W +6[SP], R1
MOV.W R1, +5[SP]
MOV.W R0, +7[SP]
POPM R0, R1
ADD.W #1, SP
PUSHM R0,R1,R2,R3,A0,A1,SB,FB
STC SP, _USP
LDC #SYS_SP, SP
JSR.A __unl_cpu
EXIT
.glb _wai_sem
.glb $_wai_sem
_wai_sem:
ENTRY
JSR.A $_wai_sem
EXIT
.glb _sig_sem
.glb $_sig_sem
_sig_sem:
ENTRY
JSR.A $_sig_sem
EXIT
.glb _isig_sem
.glb $_isig_sem
_isig_sem:
IENTRY
JSR.A $_isig_sem
IEXIT
.glb _preq_sem
.glb $_preq_sem
_preq_sem:
PENTRY
JSR.A $_preq_sem
PEXIT
.glb _rcv_msg
.glb $_rcv_msg
_rcv_msg:
ENTRY
JSR.A $_rcv_msg
EXIT
.glb _snd_msg
.glb $_snd_msg
_snd_msg:
ENTRY
JSR.A $_snd_msg
EXIT
.glb _isnd_msg
.glb $_isnd_msg
_isnd_msg:
IENTRY
JSR.A $_isnd_msg
IEXIT
.glb _prcv_msg
.glb $_prcv_msg
_prcv_msg:
PENTRY
JSR.A $_prcv_msg
PEXIT
.glb _dly_tsk
.glb $_dly_tsk
_dly_tsk:
ENTRY
JSR.A $_dly_tsk
EXIT
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -