1、中断系统IR模块介绍
在计算机原理中,中断是一种用于打破正常程序执行流程看的机制,中断允许计算机在执行程序的过程中临时暂停当前任务,转而处理其它优先级更高或需要立即处理的事件。广义的中断概念包括以下
几个关键要素:
1、中断请求(Interrupt Request,IRQ):外部设备或系统内部产生中断时,会向计算机发送中断请求
每个中断源通常由一个唯一的IRQ号。
2、中断向量表(Interrupt Vector Table,IVT):计算机维护一个中断向量表,其中存储了每个可能中断的处理程序看的地址。当中断发生时,计算机通过查找中断向量表找到相应中断的处理程序
3、中断服务程序(Interrupt Service Routine,ISR):中断服务程序是一段特定的代码,用于处理特定中断类型。当中断发生时,控制权会转移到相应中断的ISR,执行相关操作。
4、中断控制器(Interrupt Controller):中断控制器负责管理和协调各个中断源,确保按照优先级处理中断。常见的中断控制器包括PIC(Programmable Interrupt Controller)和APIC(Advanced Programmable Interrupt- Controller)。
中断的引入提高了计算机系统的响应性和并发性,允许系统在处理一些紧急事件时快速做出响应。中断机制是操作系统和硬件之间协调的重要手段确保系统能够高效地处理各种事件。
TC3xx系列中断采用了中断路由的方式,将硬件中断源和CPU、DMA进行灵活的连接,并且有着稳定可靠高效的硬件上下文保存机制,具有较高的中断实时性。
2.1、IR中断系统
TC3xx系列的中断系统涉及外设、中断控制器、CPU、DMA等的交互,每个模块内部都有与中断相关的控制寄存器,因而这里称其为中断系统。TC3xx系列的CPU接收中断信号后直接跳转到中断向量表,在中断向量表中每个中断由最多32字节的代码空间,一般是在向量表中放跳转指令,跳转到实际执行的中断服务例程中。下图是TC3xx中断系统的硬件框图:
由图可知整个中断系统包含来自软硬件的中断源,一个中断路由器IR,和对应的服务提供者,服务提供者可以是CPU或者DMA,所以在这里中断请求的术语称之为Service Request,服务请求,因为它可能触发一个CPU中断,也可能是触发一个DMA转换。
它的响应流程是这样的:当外部中断源如ADC等模块产生了服务请求信号,会发送给IR,IR根据配置的优先级进行仲裁,并将胜出的服务请求路由至对应的服务提供者,如果服务提供者是CPU则是中断服务,如果是DMA则是某路DMA通道的转换使能信号。
2.2、中断源
中断源是由外设模块、软件模块等进行的服务请求,每个外设模块都有不同的请求事件,比如ADC模块当某个Group的转换完成之后会发出对应的服务请求,CAN或Eth模块在收到外部数据时会发出接收服务请求。具体资源情况由硬件固定,使用时需要查询对饮模块的说明。
一般情况下,外设的中断信号没有开关,对应的事件发生之后就会向IR发送请求,而中断的控制逻辑由后续的IR模块和CPU来负责。
2.3、中断路由器IR
中断路由器负责接收系统的服务请求,然后进行优先级仲裁,并将仲裁胜出的请求路由至对应的服务提供者。它的输入是各个外设模块,输出则是CPU或DMA模块。IR模块主要包括服务请求节点(SRN)、中断控制单元(ICU)、和外设总线接口(BPI)。IR有很多的SRN,每个SRN对应一个硬件的服务请求,例如ADC0有4个服务请求,则在IR中就有与其对应的4个SRN。中断控制单元负责与对应的服务提供者进行连接。外设总线接口负责外设总线的连接。
2.3.1、服务请求节点SRN
每个SRN对应一个硬件的服务请求,外设模块的服务请求信号在硬件上一般是直接连接到其对应的SRN的,具体的中断控制如优先级、使能、状态查询等都是在SRN中进行的。每个SRN有一个服务请求控制寄存器(SRC)、如SRC_VASC_G3_SR0表示ADC3的SRC寄存器。
SRC寄存器中包含了这个服务请求的控制和状态量,如下图:
SRPN:服务请求优先级,即中断优先级。数值越大优先级越高。它决定了服务请求IR中仲裁的结果;同时它也是和CPU中断向量表对应。当路由的对象是DMA时,它指示对应的DMA通道。
SRE:中断使能位,若使能中断则需要打开,决定IR是否将该请求路由到对应的服务提供者,若使能位未打开,也可以通过软件轮询SRR中断状态来执行对应服务例程。
TOS:服务类型,即选择将服务路由到哪个ICU中,CPU0、CPU1、或者DMA。
SRR:中断标志位,该位在服务提供者响应服务的时候会自动清除,所以在TC3xx中不需要软件取清除中断标志位,但若SRE位为打开使用轮询去执行服务,则需要在每次执行后用CLRR清除中断标志位。
CLRR:中断标志清除位,用来清除SRR,读的话一直是0;
SETR:软件中断请求位,可以通过软件来请求一次中断。
IOV:中断溢出标志位,若一个中断没有被接收或者清除,又进行了一次触发,该位会置位。
IOVCLR:中断溢出标志清除位,清除中断溢出标志,读的话一直是0;
SWS:软件请求粘滞位,若设置过SETR位进行软触发,则该位会置位直到清除。
SWSCLR:软件请求粘滞清除位,用来清除SWS。
2.3.2、ICU功能介绍
每个SRN的服务请求会路由到一个ICU中,一个ICU连接一个CPU或者DMA,每个ICU内部进行服务请求的仲裁,并将仲裁的结果发送到连接的服务提供者。ICU中一般不需要配置,与CPU和DMA的连接相对比较固定。可以通过查询ICU寄存器查看仲裁或路由情况,包括LASRx、ECRx等。这些寄存器一般只读。
2.4、CPU as Interrupt Service Provider
当服务请求被路由到CPU的时候,CPU会接收IR的信号并作应答,然后执行对应的服务例程,这就是中断。若从CPU的角度介绍中断的处理流程。首先介绍两个重要的寄存器,中断向量表基址指针(Base Interrupt Vector Table Pointer,BIV)和ICU中断控制寄存器(ICU Interrupt Control Register,ICR)。这两个寄存器属于CPU寄存器。在多核系统中,每个核都有一套自己的CPU寄存器,所以会存在CPU0_ICR、CPU1_ICR,而前面提到的IR模块寄存器属于外设寄存器,一个系统只有一套。CPU寄存器不能直接读写,需要通过ENABLE、DISABLE、MTCR、MFCR等内核指令访问。如下图:
由图可知中断向量表基址指针寄存器,包括中断向量表基址BIV核向量空间选择位VSS。
BIV:中断向量表基址,TC3xx的中断向量表是存放在Flash中的连续地址,因此需要该寄存器来表示向量表继地址
VSS:向量空间选择位,该位表示每个中断向量所占的内存空间,0表示每个中断向量占据32字节,1表示8字节,默认为32字节。
ICR是CPU主要的中断控制寄存器,其中包括全局中断使能位IE,当前CPU中断优先级位CCPN和等待中断优先级位PIPN。
IE:全局中断使能位,我们所使用的关闭所有中断操作,就是将该位置0,因为每个CPU是独立的,也有自己的ICR控制器,所以IE只控制当前核的中断开关;
CCPN:当前CPU中断优先级,在非中断程序执行时,该位为0,进入中断时,该位会被硬件设置为所触发中断的优先级;
PIPN:等待中断优先级,表征当前CPU收到IR路由但还未处理的中断优先级。
2.4.1、中断向量表
向量中断的核心是由硬件进行中断入口的查找和跳转,这样可以大大降低中断的响应时间,达到真正的高实时性。
TC3xx的中断向量表存放在Pflash(代码段)中的一段连续地址中,默认一个向量的存储空间是8word(32字节),通过BIV指向其基地址。这里有个巧妙的逻辑,中断向量的位置是和中断优先级绑定的,也就是前文IR模块中的SRC.SRPN,例如优先级为80的中断,它的向量地址就是基址加上偏移为 BIV+80*32,CPU在接收该中断信号后第一运行的代码也就是这个位置。这种设计省去了从中断源到中断入口地址的链接开销,只需在编译过程中对中断向量表进行编址,CPU在接收IR中断信号之后直接按照对应的优先级进行跳转。中断向量表在内存中的结构如下图:
由上图可知,向量表是支持跨越优先级占用的。因为一般情况下32字节放不下中段服务例程,只能放跳转指令,但若代码量不那么大,可以通过占有多优先级的方式,省去一次跳转。上图优先级2--5放置了一个中断,通过优先级2的中断源触发,这里因为3---5被占据,所以要注意不能给其它中断使用。
2.4.2、CPU中断控制策略
前面提到,IR模块中有SRC.SRE位表征到达IR的服务请求信号是否会被路由,但是路由到CPU之后也并非能够直接执行,还需要判断相关的条件。
我们都知道,系统在运行过程中有时需要进入临界区时,防止中断程序或者OS调度程序破坏数据一致性。而根据数据的保护需求,对于临界区的实现可能是关闭所有中断,或者关闭OS中断(也就是关闭某一优先级以下中断)。
对于TC3xx来说,若要关闭所有中断,那么操作方法就是将ICR.IE置0,此时所有路由到该CPU的中断都处于Pending状态,不会被接收。而若要关闭OS中断,将所有OS优先级以下的中断全部屏蔽,则可将ICR.CCPN设置为目标门槛优先级,小于或等于该优先级的中断都将被屏蔽。
所以当中断信号到达CPU的时候,若ICR.IE为1,且该中断优先级大于ICR.CCPN中指示的当前CPU中断优先级,CPU会接收该中断,向IR发出ACK信号,则IR中的中断标志位SRC.SRR会被硬件清除,然后CPU开始执行中断响应步骤。
2.5、DMA as Interrupt Server Provider
除了CPU接收IR的服务请求信号执行中断响应程序以外,TC3xx的中断系统还有一个特色,那就是将服务请求信号路由到DMA中,硬件触发一次DMA转换。这种连接,我们只需要将SRC.TOS设置为DMA,然后将SRC.SRPN设置为目标DMA通道号,即可实现路由。
TC3xx中实现了将外设的中断信号连接到DMA中,我们可以通过设计外设触发链路,不经过CPU就能完成外设数据的处理。例如通过ADC中断触发DMA,能够直接将ADC采样数据取到RAM中;通过将SPI的中断信号路由到DMA,就能完成后台异步SPI发送。
2.6、CPU中断处理流程
CPU对于中断的响应和退出流程如下:
在中断决定响应中断时,并不是直接按照向量表执行其中中断服务例程,而是先由硬件执行一系列操作进行上下文保存,也就是保护现场,而在退出中断之后也需要加载上下文,也就是恢复现场。下面我们先详细介绍CPU对于中断的硬件响应步骤:
1、第一步是保存上部分上下文,TC3xx系列芯片中存在硬件CSA机制,分为上、下两部分上下文,主要包括通用寄存器和链接地址等信息,其中上部分是由中断或者异常时由硬件自动保存,并在退出时使用RFE指令加载回来,上图为CSA结构图。
2、保存返回地址寄存器A[11],也就是常说的链接寄存器。
3、若此时CPU的中断栈使能开关PSW.IS没有打开,则硬件会将栈寄存器A[10](SP指针)指向中断栈指针ISP,以使用中断的栈,同时将PSW.IS置位。
4、将I/O模式(外设访问权限)设置为Supervisor模式。
5、将当前保护寄存器集设置为PSW.PRS=000B,TC3xx每个核有6套内存保护的设置集,如果使用了内存保护则这里表示会切换到PSW.PRS=000指向的保护策略。
6、调用深度计数器PSW.CDC清零,并且调用深度限制被设置为64;
7、调到深度检查打开:PSW.CDE=1;
8、PSW安全位被设置为SYSCON中的值:PSW.S = SYSCON.IS;
9、全局地址寄存器A[0],A[1],A[8],A[9]的写入会被禁用:PSW.GW=0;
10、当全局中断使能位ICR.IE被保存到PCXI链接字寄存器中的先前全局中断使能位PCXI.PIE中,然后将ICR.IE置0,关闭所有中断;
11、当前中断优先级ICR.CCPN被保存到PCXI链接字寄存器中的先前中断优先级位PCXI.PCPN(PCXI在上部分上下文中,第一步已经保存到CSA中了,因此在嵌套处理时,此处PCXI可以写入,以实现中断嵌套);
12、等待中断优先级位ICR.PIPN被写入到当前CPU中断优先级位ICR.CCPN;
13、从中断向量表中取第一条指令,然后开始执行中断服务函数,至此硬件的处理流程结束。
整个中断响应流程,其实CPU在响应中断的时候,主要做的事情就是保护上下文、切换系统模式、切换中断环境,这在任何一个系统中都是必需的,而TC3xx得益于其独特的硬件上下文自动保存机制,省去了软件压栈的时间,对中断的实时性有较好的优化作用。
中断执行完毕之后自然需要退出中断,退出中断需要使用RFE指令,然后硬件会执行相应的步骤:
1、将链接字寄存器中的先前中断优先级位PCXI.PCPN写入到ICR.CCPN中,这样就恢复了中断进入之前的系统中断优先级门槛;
2、将链接字寄存器中的PCXI.PIE被恢复到ICR.IE中;
3、从CSA中加载进入中断时保存的上部分上下文。
从中断退出流程我们可以看到,其实主要的硬件处理还是处理上下文和中断环境。TC3xx的中断是可以直接嵌套的,我们可以直接在中断服务例程中使能全局打断,打开嵌套,得益于其完善的硬件上下文保存机制,软件不需要像ARM一样执行系统模式切换和额外的上下文保存工作,从而提升了系统执行效率。
2.7、不可屏蔽中断NMI
TC3xx还提供了一种不可屏蔽中断机制(Non-Maskable Interrupt,NMI),一般是SMU模块或者外部ESR0/ESR1引脚触发,用于响应紧急事件。这种机制虽然叫不可屏蔽中断,但是它的本质走的是Trap系统,而不是本文中的中断系统,因此IR模块或CPU的中断控制位都不会对其响应产生影响,从而实现不可屏蔽中断的响应逻辑。
3.1、MACL配置/ETAS配置及代码
1、首先我们来到EB工具中的Irq模块中,可以找到IrqCanCatConfig页面进行配置,这里我们找到CAN0,将Catogary配置为CAT2/CAT1(CAT2为OS中断),然后设置中断优先级,这里使用1,然后TOS选CPU0,由CPU0执行中断函数;如下图:
3.2、ETAS工具配置
3.3、代码
1、若使用ETAS工具中的OS模块管理中断,需要将设置为CAT2类的中断,工具会生成如下图的中断向量表:
2、当触发了中断时会通过OS_ISRWrapper0调用相对的中断函数,如下图: