用C语言编写复杂的中断干扰处理器

作者在 2008-09-26 14:34:48 发布以下内容
    当从外部的硬件或者处理器向CPU发出异常信号的时候,中断就会发生了。CPU通过传递执行流来响应中断服务程序,其中CPU响应的过程是这样的:首先对事件进行处理,处理之后再返回中断代码。
ISR本质上是一个不设任何参数和不返回任何值得函数。但是,和一般的规则函数不一样,你几乎可以在任何情况下调用ISR函数,因此在调用的时候要特别小心,特别是登陆和退出ISR函数时,要严格按照特定的执行规则和执行顺序来执行。
一些编译器用#pragma或者不规则的关键字为中断提供了内置支持,这种内置支持会在相应的终端函数处,让编译器产生ISR登陆和退出代码的序列。如下面的例子所示:
interrupt void ISR(void)
{
       /*中断处理*/
}
在这样处理过之后,你就可以安心的把这些函数作为ISR使用了。如果你的编译器提供这种支持,务必确保检查所产生的登陆和退出代码是相对应的。你的运行环境可能会和你预先设想的环境稍有不同。
如果你的编译器没设立中断的内置支持,你可以把ISR部分放到C函数中并且把那个ISR汇编程序包调用到这个函数中。你应该建立一个ISR汇编程序包。它负责在调用C函数的时候执行专门的寄存器和退出代码。
那么哪些纪录必须被保存并返回呢?你怎样才能把它调用到高级的C语言环境中去呢?在编译文件中你通常会遇到这样的问题。在调用规定中,你要从下面两个问题入手,找寻到这样一段,它是汇编程序的接口,或者一些类似的文件:
这和CPU的状态,处理器的型号或者记录值有着密切的关系。
一旦你有了这些信息,你就可以编写汇编程序包了。下面是一个为命名80386的C_汇编程序的例子。该汇编程序的的文件如下所示:
--- isr.asm ---
; 用作ISR来调用C函数的汇编程序包
; 返回地址被保存在ISR1堆栈的入口
ISR1:                    
              push    eax                ; 进栈占
              push    ds  
              push    es
              mov     ax,DGROUP          ; 准备调用C…
              mov     ds,ax              ; DS = DGROUP
              mov     es,ax              ; ES = DGROUP
              cld                        ; 清除地址标记
              call    _ISR1Handler       ; 调用C函数
              pop     es                 ; 恢复记录
              pop     ds
              pop     eax
             iretd               ; 中中断中返回(同时恢复标记)
--- isr.c ---
/* 干扰处理,也就是被汇编程序包调用的部分 */
void ISR1Handler(void)
{
       /* 干扰处理 */
}
在用这种方法对ISR进行处理的时候可能会出现一些特别的编译处理,但是如果你编译的是一个复杂的终端干扰处理,那么这样的过程就会显得微不足道。我们的目的是通过编译器优化使中断处理更加有效进行。
技术 | 阅读 5331 次
文章评论,共0条
游客请输入验证码
浏览1970330次