⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interf.a30

📁 itron操作系统在日本用的很多
💻 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 + -