这学期一直在忙项目的事情,没什么时间写博客,最近过年闲下来,会把之前欠的内容补上。
目录
(本文的基础是FPGA能向DSP发送doorbell类型的包。)
从上一节
FPGA+DSP SRIO通信(三)——基于LSU的数据传输我们已经了解到了如何将数据通过SRIO,以LSU的方式传输。而现实的数据传输任务中除了传输数据,还需要传输中断。例如,使用FPGA将一段视频传输给DSP,除了需要传输数据,还需要在传输一帧数据之后,向DSP发送中断,以告知CPU——
“DSP的存储空间中数据已经存在,请及时读取”。这便是中断最常用的场景。
1、6678的中断系统
1.1、系统事件
在谈SRIO的中断系统之前,先说一说6678DSP中断系统。
C6678的CPU中断是由
C66x CorePac Interrupt Controller配置的。该中断控制器(
C66x CorePac Interrupt Controller),下文直接称
66x中断控制器。
66x中断控制器允许将最多128个
系统事件映射到12个
CPU中断上(CPUINT4 - CPUINT15),或映射到
CPU异常,或映射到
高级仿真逻辑上。。
上面说的CPU异常和高级仿真逻辑都不是今天的重点,我们最重要的,要理解的概念是——
系统事件,系统事件包括
核上产生的事件以及
片级事件(也就是 外设产生的中断事件)。
额外的系统事件被路由到每个C66x CorePac,以提供额外的芯片级事件,因为CPU中断/异常作为仿真事件被路由到中断控制器,所以额外的系统事件也可以走这条路 。此外,错误类事件或不常使用的事件也通过系统事件路由器路由,以减轻C66x CorePac中断选择器的负担。 这是通过
芯片级中断控制器(CIC)块完成的,CIC使用的时钟是CPU主频的六分之一。
事件控制器由简单的组合逻辑组成,为每个C66x CorePac提供附加事件,加上EDMA3CC,CIC0和CIC1为每个C66x CorePac提供17个附加事件和8个广播事件,CIC2提供26个和24个附加事件给 EDMA3CC1和EDMA3CC2,CIC3分别为EDMA3CC0和HyperLink提供8个和32个附加事件。
芯片级别上有大量的事件。 芯片级CIC提供了一种灵活的方式来组合和重新映射这些事件。 多个事件可以通过芯片级CIC组合到单个事件中。 但是,组合事件的输出只有一个。 芯片级CIC还允许编程者通过内存写入来触发系统事件。
到C66x CorePacs的广播事件可用于多个核心之间的同步或处理器间的通信目的等。(这对咱们以后研究多核之间的通信有所帮助)
6678的中断系统可用下面Figure7-29来解释:
可以从图中看到,
CIC0和CIC1为每个C66x CorePac提供17个附加事件和8个广播事件,其余结论也可以从图中看到,作为开发者,我们需要知道的是:“
片级中断控制器CIC能够将片级事件映射(或组合映射)到任意CPU核心,这就为我们的SRIO中断映射提供了方法”
综上所述,我们得到的结论是:
1、CPU中断只有12个,为CPUINT4 - CPUINT15。而CPU中断是由C66x CorePac Interrupt Controller配置的,也就是很多资料中写的cpIntc。
2、片级中断控制器CIC能够将系统事件映射到CPU中断。
伴随着该结论的还有两个问题:
1、SRIO中断和系统事件有什么关系呢?怎样将这两者联系映射起来呢?
2、cpIntc怎样将系统事件和CPU中断映射起来呢?(下篇博客讲)
6678的中断映射路径大致图1-1所示:
图1-1
看完这张图,我们来解释一下上面的两个问题。
1.2、SRIO中断和系统事件有何关系?怎样将这两者联系映射起来?
SRIO中的中断配置方式非常多,我就不一一列举(其实是我只探索出来一种方式哈哈哈)。我所使用的中断方式是:
FPGA以DIO的传输方式传输DOORBELL类型的SRIO 包。
DIO传输doorbell类型的包(使用LSU)的最重要的组成就是doorbell_info域,该域由16bit构成,每个bit代表一个标志位,例如我doorbell_info域写0x3,那我就会向DSP发出bit0和bit2所对应的系统事件。
但是!doorbell_info的每个bit对应的系统事件并不是固定的,而是可以根据你的配置指向不同的系统事件。
在了解具体什么寄存器影响着doorbell_info bit到系统事件的映射之前,我们先了解三种寄存器的名称和其作用。
1、Interrupt Condition Routing Register (ICRR):这种寄存器的作用就是配置doorbell_info bit映射向不同的系统事件(当然也可以相同)。
2、 Interrupt Condition Status Register (ICSR)::这种寄存器的作用就是可以在ICSR寄存器中读到能够触发中断的系统事件是什么。
3、Interrupt Condition Clear Register (ICCR):这种寄存器的作用就是清除系统事件,来确保我们每一次收到的中断不是前一个中断。
这样我们就发现可以通过配置ICRR寄存器,来将特定的doorbell_info映射到特定的系统事件。也可以通过ICSR来观察映射的结果。在每次接收到中断之后,可以在ISR(中断服务程序)中使用ICCR清除之前的中断,以确保收到最新的中断。
1.3、doorbell_info bit到系统事件的映射
我们在图1-1中猜测到:6678的doorbell_info bit与系统事件一一对应,现在看来并不是。
具体映射配置应该由两部分构成:
1、中断映射表
选择中断映射表的寄存器是INTERRUPT_CTL,可以在文末的参考文件SRIO User Guide中找到,我这里就不贴该寄存器的具体内容了,只在这里说明一下,中断映射表有两个:
当INTERRUPT_CTL寄存器的第0bit为1时,映射表如下:
图中的
ICRx代表的就是doorbell_bit_info,如ICR5代表doorbell_bit_info为0101b;INTDST
i为系统事件。
当INTERRUPT_CTL寄存器的第0bit为0时,映射表如下:
没有特殊要求的情况下,情况1能够满足我们的要求,所以将INTERRUPT_CTL的第0bit置1,CSL函数为:
CSL_SRIO_SetDoorbellRoute(hSrio, 1);
2、doorbell_info bit到系统事件的映射
既然选择了中断映射表1,我们就要通过ICRR将doorbell_info的bit与ICRx联系起来。官方文档给了下面的示例:
ICRR和ICRR2是一组寄存器,4bit映射doorbell_bit的一位。我再贴上ICRR和ICRR2的寄存器图更好理解。
注意Figure3-25和Figure3-26的标题都标错了,应该是ICRR而不是ICCR,这是官方文档的错误。
ICSR寄存器表示doorbell_info 的哪一位为1,就产生一个中断。ICSR寄存器图:
通过以上三幅图可以看到:
FPGA向DSP发送doorbell中断产生系统事件的流程如下:
以上讲了寄存器级别的doorbell_info转系统事件,下面贴上具体代码:
CSL_SRIO_SetDoorbellRoute(hSrio, 1);
for (i = 0; i < 16; i++)
{
CSL_SRIO_RouteDoorbellInterrupts(hSrio, 0, i, i);
}
通过这个流程,我们可以产生系统事件,这为产生真正的中断奠定了基础,下一篇博客将说明如何配置系统事件和主机中断,使其建立映射关系。
参考文献
http://www.ti.com/cn/litv/pdf/sprugw1b
PS:欢迎大家与我讨论文章中的问题,包括反对我的观点。