UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

取消
显示结果 
搜索替代 
您的意思是: 
Observer keep
Observer
1,123 次查看
注册日期: ‎09-21-2018

如何获取设备驱动中断号

    在设备驱动程序编写中,用request_irq()注册申请中断时,第一个参数,即中断号,如何获取?

    我想编写ZYNQ  MIO按键中断的驱动程序,从手册上得到GPIO0的硬件中断号为52,但是request_irq (52, ......)不成功,返回-EINVAL

    考虑到可能会有32的偏移值,于是尝试了request_irq(20, ......),同样返回-EINVAL,而且,通过在板级系统中cat /proc/interrupts,看到20号中断已经被arm-pmu占据了。

    现在的问题就是,ZYNQ外设的中断号究竟是如何确定的?是硬件中断号还是有偏移值?或者别的方法可以得到中断号?

0 项奖励
5 条回复5
Xilinx Employee
Xilinx Employee
1,107 次查看
注册日期: ‎03-27-2013

回复: 如何获取设备驱动中断号

建议使用PetaLinux工具或者直接用DTG(Device Tree Generator)生成DTS, PS部分的外设在DTS中对应的node就找到这个值。

Best Regards,
Jason
-----------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
-----------------------------------------------------------------------------------------------
0 项奖励
Observer keep
Observer
1,101 次查看
注册日期: ‎09-21-2018

回复: 如何获取设备驱动中断号


@jasonwu  已写:

建议使用PetaLinux工具或者直接用DTG(Device Tree Generator)生成DTS, PS部分的外设在DTS中对应的node就找到这个值。


感谢回复。

刚刚确认了一下,petalinux生成的system.dts中,GPIO0的interrupts=<0x0 0x14 0x4>,即中断号为20,但是之前已经尝试过了request_irq(20, ...),未能成功

请教一下,驱动中所用的中断号就是设备树中节点对应的中断号吗?也即硬件中断号减去32的偏移值?

0 项奖励
Xilinx Employee
Xilinx Employee
1,086 次查看
注册日期: ‎03-27-2013

回复: 如何获取设备驱动中断号

Hi Keep,

是的,有一个偏移值,你的理解没有问题。

另外建议找一个比较简单的可以工作的例子/模板修改尝试下看看,建议使用PetaLinux中带的module模板,调用petalinux-create -t modules生成,具体参考UG1144),这个模板会注册中断,使用的中断号应该就是前面说的DTS中的那个。

 

 

Best Regards,
Jason
-----------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if the information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
-----------------------------------------------------------------------------------------------
0 项奖励
Xilinx Employee
Xilinx Employee
1,057 次查看
注册日期: ‎08-01-2007

回复: 如何获取设备驱动中断号

同意 Jason 说的用 petalinux-create -t modules 建一个模板参考一下就比较清楚了。

另外,关于创建中断的分析,可以参考这篇文章:http://www.zynqnotes.com/pl-ps-interrupt

/* Get IRQ for the device */
   r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
   if (!r_irq) {
      dev_info(dev, "no IRQ found\n");
      dev_info(dev, "mymodule at 0x%08x mapped to 0x%08x\n",
         (unsigned int __force)lp->mem_start,
         (unsigned int __force)lp->base_addr);
      return 0;
   }
   lp->irq = r_irq->start;
   rc = request_irq(lp->irq, &mymodule_irq, 0, DRIVER_NAME, lp);
   if (rc) {
      dev_err(dev, "testmodule: Could not allocate interrupt %d.\n",
         lp->irq);
      goto error3;
   }

通过 platform_get_resource 动态获取 IRQ 号码,然后用 request_irq 连接中断。

0 项奖励
Highlighted
Observer keep
Observer
903 次查看
注册日期: ‎09-21-2018

回复: 如何获取设备驱动中断号


@rickys  已写:

同意 Jason 说的用 petalinux-create -t modules 建一个模板参考一下就比较清楚了。

另外,关于创建中断的分析,可以参考这篇文章:http://www.zynqnotes.com/pl-ps-interrupt

/* Get IRQ for the device */
   r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
   if (!r_irq) {
      dev_info(dev, "no IRQ found\n");
      dev_info(dev, "mymodule at 0x%08x mapped to 0x%08x\n",
         (unsigned int __force)lp->mem_start,
         (unsigned int __force)lp->base_addr);
      return 0;
   }
   lp->irq = r_irq->start;
   rc = request_irq(lp->irq, &mymodule_irq, 0, DRIVER_NAME, lp);
   if (rc) {
      dev_err(dev, "testmodule: Could not allocate interrupt %d.\n",
         lp->irq);
      goto error3;
   }

通过 platform_get_resource 动态获取 IRQ 号码,然后用 request_irq 连接中断。


感谢回复。

参考petalinux生成的模板,目前中断注册问题已解决,只是还遗留有一些问题,这里做个简单的总结。

1、较新版本的linux内核采用了动态分配虚拟中断号的方法,即注册中断时所传入的虚拟中断号与硬件中断号不再是固定的映射关系,因此,传统的驱动写法以及platform_device中指定中断号的方法不再适用;

2、采用设备树描述硬件中断资源,需要自行在dts文件中添加节点,指明父中断控制器、中断编号、中断触发方式,内核会根据dtb解析出对应的device,并分配对应的虚拟中断号;

3、驱动程序中通过of_match_table匹配设备树节点与驱动,执行驱动中的probe函数;

4、调用platform_get_resource()获取硬件资源,request_irq()申请中断,这部分和传统写法基本一致。

目前遗留的问题:

platform_get_resource(pdev, IORESOURCE_IRQ, 0)始终返回空指针,无法得到设备树中指定的中断属性,后来改为platform_get_irq(pdev, 0)成功获取到了虚拟中断号。虽然问题得到了解决,但是并不明白原因在哪,为什么会返回空指针呢?