最近ZYNQ的项目需要,调试了PL中断PS的部分,下面将其中了解到信息记录下来,以防遗忘,如图一,图二所示,PL到PS的中断分为16个共享中断(SPI)和4个私有中断(PPI)。本文用到了共享中断,着重介绍SPI中断。
图一
图二
PL 侧16个SPI中断硬件中断号为6168,8491.支持高电平触发和上升沿触发两种触发方式。以下内容摘抄自
https://blog.csdn.net/weixin_40640020/article/details/92159687
PL中断PS触发方式可以在PS端编程控制对应寄存器设置为高电平触发和上升边缘触发。在这个我们认为中断源的满足中断和不满足中断分别用1和0表示。高电平就是中断的条件满足了,表现为逻辑1。上升边缘触发表示之前从中断没有发生到中断发生的这个跳变,也就是从逻辑0到逻辑1的跳变。在Z7系统中允许设置PL的中断触发方式。
当设置电平触发时候,只要中断条件一直满足,也就是中断请求线上电平是高,则触发处理器产生中断。当设置上升边缘触发时候,当且仅当中断条件从不满足到满足的跳变上,也就是中断请求线表现成了一个上升边缘,并且保持高电平至少2个CPU_2X3X周期(也就是说4个以上处理器的时钟周期)。就会产生触发处理器产生中断。边缘触发方式下高电平最少保持处理器时钟周期的两倍,一般建议时间长一些,20NS。
这两种中断触发方式强调的侧重点不一样,电平触发强调的是 特定中断事件之要没有撤销就要反复进行处理。比方说在具体应用中一个来自外界的报警信号,只要报警信号存在说明危险没有被消除,需要继续中断处理器,继续处理。上升缘触发方式强调特定中断事件发生了,对于这个此次特定发生的中断事件,处理器只要做一次处理就可以。如果外设还要再次请求中断处理器,则需要将中断再次产生一个上升边缘进行进行请求。
摘抄完毕,继续写自己遇到的问题,在Linux下调试PL到PS侧的中断,在整个系统中,对于一个PL中断源,存在三个中断号,拿PL侧的第一个SPI中断为例,ZYNQ的硬件中断号为61,在设备树里面,此中断的中断号记录为61-32=29,在linux系统内的逻辑中断号则又不同,在linux下调用int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)时,第一个输入参数irq为何值,经过测试,此irq应为Linux分配的逻辑中断号。那么问题来了,在linux下,如何获得61硬件中断号对应的逻辑中断号呢,此时就要用到设备树和驱动的配合来获得。
设备树里面对中断的主要描述如下:
irq: [email protected]{
compatible = “hello,irq”;
interrupt-parent = <&intc>;
interrupts = <0 29 2>;
};
compatible = “hello,irq”;这条语句在驱动里面与platform架构的驱动匹配时需要用到,interrupt-parent = <&intc>;指明父节点,interrupts = <0 29 2>;第一个参数0代表是SPI中断还是PPI中断,0代表SPI中断,1代表PPI中断。29代表中断号,经过观察发现,这个地方所填的数值与硬件中断号的关系为:当中断为SPI中断时,为硬件中断号-32;当为PPI中断时,为硬件中断号-16。第三个参数2代表触发方式,2代表高电平触发,1代表上升沿触发。Linux读取设备树的信息,然后为此中断分配一个逻辑中断号,以前注册中断号是通过手工在 C 代码中填入中断号,现在这种方法不可行了,请使用虚拟中断号的方法。
另外,在https://blog.csdn.net/u013457167/article/details/80682926 这篇文章里看到这段话,如图三所示,经过查看,应该是写反了,SPI中断加32,非SPI中断加16。
图三
设备树里描述好中断的信息后,再涉及到修改自己的Linux驱动了。Linux驱动要改为platform架构方式,具体的platform架构方式,网上查资料有很多,时间太紧,我也没完全搞清楚,按照架构自己套了一个,
参照https://blog.csdn.net/h244259402/article/details/83993524这篇文章,
图四
如图四所示,这里一定要与设备树里面中端部分的.compatible属性对应起来,驱动就是通过设备树的这个属性来进行匹配并获得Linux分配的逻辑中断号的,通过irq=platform_get_irq函数获得逻辑中断号后,就可以将逻辑中断号代入rquest_irq函数申请中断了。