吴志勇,刘继平,郭元兴
(中国电子科技集团公司第三十研究所,四川 成都 610041)
在嵌入式系统中,CPU与外设交互数据主要有3种方式:查询、中断和DMA。查询方式是由CPU周期性地执行查询指令来读取外设的状态寄存器,根据设备的状态来交互数据。这种方式效率低下,当CPU连接的外设数量较多时,外设的数据无法得到实时处理。中断和DMA方式克服了查询方式的缺点,提高了CPU的效率和数据处理的实时性。其中,DMA方式同样需要使用中断机制来实现。
然而,CPU的中断资源有限。当系统中连接CPU的外设数量多于CPU的中断管脚数量时,需要采取某种方式将多个外设的中断信号进行复用。采用Intel 8259A等芯片可以实现中断信号的复用,但在使用前需要CPU对其进行配置。然而,将32路中断信号复用成1路中断信号需要使用5片8259A芯片级联,占用了较大的PCB板面积,也增加了系统设计的复杂性[1-2]。
此外,部分CPU在进入中断服务程序后或处于中断屏蔽状态时,无法通过中断管脚继续接收外设给入的中断信号,有可能导致数据的丢失。
因此,设计一种适用于多外设系统,能够将多路中断信号复用且不受CPU中断状态影响的中断控制器具有较高的实用价值。本文利用FPGA具有的研制周期短、设计成本低、设计灵活性高等特点,设计了一种基于FPGA的中断控制器。
中断是指CPU在执行当前程序的过程中,当出现某些异常事件或某种外部请求时,CPU暂时停止执行当前程序,转去执行外设的服务程序。当外设的服务程序执行完毕后,再返回被暂停执行的程序处继续执行。CPU对中断响应的流程如图1所示[3]。
图1 CPU对中断响应的流程
CPU一般至少有一个中断信号输入管脚,在每条指令的最后一个机器周期对中断管脚的输入信号进行采样,并对中断做出响应。根据不同的触发方式,中断可以分为电平触发中断和边沿触发中断。电平触发方式用一段持续的高电平或低电平表示中断请求,要求中断请求信号要有足够长的保持时间,要保持到当前指令的最后一个机器周期,以确保CPU采样时中断请求有效。边沿触发方式是以一个信号的上跳沿或下跳沿表示中断请求,CPU对这个中断请求进行锁存。
中断控制器的作用是在有多个中断源的系统中,可同时接受多个外部的中断请求,进行一定判别后,选中当前优先级最高的中断请求送至CPU的中断输入端。当CPU响应中断并进入中断处理程序后,该控制器仍负责对外部中断的管理[4]。
本文采用Verilog HDL语言,设计了一种能够将32路中断信号复用成1路中断信号的控制器,其系统结构如图2所示。
图2 中断控制器的系统结构
中断控制器主要包含了中断信号计数模块、中断信号产生模块和中断信号清除模块。INT_i[31:0]为32路外设产生的中断信号,其中INT_i[0]的优先级最高,INT_i[31]的优先级最低。控制器输出的中断信号INT_o接CPU的中断管脚,CPU通过mask信号来设置当前中断管脚是否处于中断屏蔽状态。如果CPU当前处于中断屏蔽状态,INT_o将不会输出有效中断信号。CPU接收到INT_o中断信号后,在中断服务程序中需要读取flag[4:0]标志,以确定当前中断的中断源。CPU在执行完毕中断服务程序后,需通过clear信号清除当前中断。中断控制器能够根据flag[4:0]的值来自动确定需要清除的中断源。
中断信号计数模块主要由32个相同的计数器构成,将中断信号INT_i进行同步处理后输入给计数器。计数器在有中断信号INT输入时执行加计数,在清除中断信号decrease到来时执行减计数,从而实现对当前中断信号有效个数的锁存。当有效中断信号个数大于0时,通过valid信号输出高电平,其流程如图3所示。
图3 中断信号计数器流程
中断信号产生模块首先判断mask信号是否有效,如果有效,表示CPU当前正处于中断屏蔽状态,此时中断信号产生模块不应该输出中断信号INT_o给CPU。当mask信号无效时,进一步判断计数器模块的输出值valid[31:0]是否有效。只要valid[31:0]中的某个比特有效,说明有中断源需要处理,中断信号产生模块则输出中断信号INT_o到CPU的中断管脚,同时对valid[31:0]信号中有效位的优先级进行判决,将优先级最高的输入中断信号INT_i对应的编码输出到flag[4:0]总线上,以便CPU获取当前中断信号对应的中断源。中断信号产生模块在中断清除信号clear有效后回到初始状态,其流程如图4所示。
图4 中断信号产生模块流程
CPU在跳出中断服务程序前需要通过clear信号清除当前中断,否则中断信号产生模块将一直处于等待clear信号有效的状态,无法进行下一个中断源的处理。同时,中断信号计数模块也需要clear的有效信号进行减计数,以确保在当前中断源处理完毕后,中断计数模块中锁存的值始终为尚未处理的中断源个数。中断信号清除模块通过读取flag[4:0]的值来获取当前优先级最高的中断源,并产生相应的脉冲信号给中断计数模块,其流程如图5所示。
图5 中断信号清除模块流程
本文在Xilinx的XC6SLX150T-3FGG676I FPGA上验证设计的中断控制器。在FPGA中,例化了32个模块。这些模块作为CPU的外设通过EMIF总线与CPU进行数据交互。模块产生的数据存储于各自内部的FIFO中,每产生一帧数据,会给出一个中断信号通知CPU读取。只要各外设模块产生的中断信号不丢失,CPU就能够正确读取这些外设模块产生的数据帧。多外设系统应用的框图如图6所示。
在图6的多外设系统应用中,32个外设模块产生的中断信号通过中断控制器复用成1路中断信号输出给CPU。它仅占用CPU的1个中断输入管脚,其余信号均占用的是资源相对较丰富的GPIO。当CPU正在中断服务程序中处理某个外设模块的数据帧或者CPU正处于中断屏蔽状态时,中断控制器能够继续接收外设模块产生的中断信号,然后计数并锁存这些中断信号,避免了由于中断信号的丢失而导致数据帧的丢失,使得这些外设模块能够并发工作,提高了CPU和外设的工作效率。
经过验证,CPU能够正确接收FPGA中32个外设模块并发产生的数据帧,说明中断控制器能够正确工作,达到了预期效果。
图6 多外设系统应用
针对多外设系统的中断复用问题,本文设计了一种能够将32路中断信号复用成1路中断信号的中断控制器,并在实际项目中进行了应用验证,其具有如下特点:
(1)上电后可直接使用,无需CPU对该中断控制器进行配置;
(2)使用CPU的1个中断输入管脚及若干个GPIO,就能够实现对多个外设中断信号的响应,减少了对CPU中断资源的占用;
(3)具备中断信号锁存功能,当CPU进入中断服务程序中或正处于中断屏蔽状态时,中断控制器能够继续接收外设的中断信号并记录这些中断信号的个数,待CPU能够接收中断信号后,将锁存的中断信号继续发送给CPU,避免了外设中断信号的丢失;
(4)采用Verilog硬件描述语言设计,当需要复用更多路数的外设中断信号时,仅需修改少量的代码就可实现,同时可将该中断控制器封装成IP核移植到多个FPGA平台上,具有良好的推广应用价值。