TriCore的中断系统的一个有趣设计

前段时间,一个项目上出现了一个奇怪的现象,本来设计好的10ms周期的CAN消息,测量下来发现周期变成了9ms。这个项目的操作系统是一个1ms的STM中断中累积Tick来驱动的,经过测试发现这个Tick在每隔9ms就会出现一次快速的跳变,如下图-1,因此就造成了触发了10个Tick的时候其实对应的时间只有9.2ms甚至更短,那么问题来了,为什么STM中断会没有按原定的1ms周期发生,而是提前出现了呢。首先我调查了STM中断服务程序中每次重载下次中断发生的比较值,发现及时在发生0.2ms的跳变的时候,重载值也是正确的。继续往下调查,我发现只要将项目中的GPTA0_SRC30的中断关闭,这个问题现象就消失了。

Tick

图-1

下边我们来看一下TriCore的中断处理过程,TriCore中的中断是由ICU(interrupt control units)来控制的,当外设向CPU请求中断以后,该请求对应的中断优先级经过仲裁以后会被推到PIPN中,而CPU接下来的跳转地址,也就是我们所熟悉的中断向量(Interrupt Vector)的计算方式可以从图-2中可以看出,最终的地址=基地址(BIV)+中断优先级(PIPN)<<5。换句话说TirCore中中断向量的位置是于中断优先级有关的,如果两个中断的优先级设置是一样的,那么它们就会跳转到同样的中断向量上去,这似乎就是我们问题的根本原因。

tricore_interrupt_vecotr_calc

图-2

接下来我们来看一下几个寄存器的设置,如图-3,发生这个问题的时候STM的中断优先级(SRPN)是03,GPTA0_SRC30的中断优先级(SRPN)是07,这两个中断的优先级并不相同,难道我们的猜想是错误的?但是经过调试发现把GPTA0_SRC30的SRPN值改成06问题就消失了,而改成07和0F都会复现上文提到的问题,这似乎又在告诉我们,这个问题是跟优先级有关的。

reg_setting_stm_gpta

图-3

我们再留意一下ICR中CARBCYC bit位的值,出现问题的时候这个值是0b11(03030100),我们看一下手册中的描述

tricore_interrupt_arbitration

为了实现系统性能的可配置性,TriCore设计了CARBCYC 这个寄存器值来控制仲裁所消耗的CPU时钟,而它的原理是控制中断仲裁过程中判断的优先级的bit位个数,看完这个,造成我们这个问题的根本原因就显而易见了,系统中使用了CARBCYC=0b11的配置,也就是说SRPN中只有bit0和bit1参与了仲裁,对于系统中目前的配置,SRPN(STM)=03=0b011,SRPN(GPTA0_SRC30)=07=0b111,两者的最低2个bit是一样的都是0b11,由于PIPN最后装载的值是仲裁以后的值,对于STM和GPTA0_SRC30这个值都是0b11,这个中断向量对应的地址其实就是STM中断服务函数的起始地址,这也就是为什么GPTA0_SRC30也会触发STM的中断服务函数的原因。

发表评论

电子邮件地址不会被公开。