我正在编写一个设备驱动程序来处理PCIe卡的中断,该卡目前适用于IRQ线上产生的任何中断向量。
但它有一些可以引发的类型,由Vector寄存器标记。所以现在我需要阅读矢量信息并且有点聪明......
那么,我: -
1 /每个中断类型都有单独的开发节点/dev/int1
,/dev/int2
等,只有int1
用于矢量类型A等的文档?
1.1 /因为每个文件/ char设备都有自己的minor
号码,打开时我会知道哪个是哪个。 我想。
1.2 / ldd3似乎演示了这种方法。
2 /有一个节点/dev/int
(就像我现在这样做)并且有多个进程挂起了相同的read
方法吗? 听起来更棒?!
2.1 /然后只唤醒正确的过程...?
2.2 /我是否使用单独的wait_queue_head_t wait_queue
?或者不同的flag
/测试条件?
在read
方法中: -
wait_event_interruptible(wait_queue, flag);
在处理程序中不是真正的代码!: -
int vector = read_vector();
if vector = A then
wake_up_interruptible(wait_queue, flag)
return IRQ_HANDLED;
else
return IRQ_NONE/IRQ_RETVAL?
编辑:各国人民的评论: -
1)我的用户空间代码mmap
的所有PCIe固件寄存器
2)用户空间代码有几个线程,每个线程在设备驱动程序设备节点上执行阻塞read
,然后在发生中断时从固件返回数据。我需要根据中断类型唤醒正确的线程。
答案 0 :(得分:2)
我不确定我是否理解你对Vector寄存器的意思(指向某些文档的指针可以帮助我精确处理你的情况)。
无论如何,任何PCI设备都会获得一个唯一的中断号(由BIOS或其他架构上的某些固件提供,而不是x86)。您只需在驱动程序中注册此中断即可。
priv->name = DRV_NAME;
err = request_irq(pdev->irq, your_irqhandler, IRQF_SHARED, priv->name,
pdev);
if (err) {
dev_err(&pdev->dev, "cannot request IRQ\n");
goto err_out_unmap;
}
另一件我不太了解的事情是你将中断导出为dev节点的原因:中断肯定需要保留在你的驱动程序/内核代码中。但我想在这里你要导出一个然后在用户空间中访问的设备。我发现 / dev / int 不是一个很好的命名。
关于多个dev节点的问题:如果你的不同中断源提供对不同硬件资源的访问(即使在同一个PCI板上),我会选择1),每个设备都有wait_queue。否则,我会选择2)
由于您的中断来自同一个物理设备,如果您选择了选项1)或选项2),则必须共享中断线,您必须阅读中的向量中断处理程序,用于定义哪个硬件资源引发了中断。
对于选项1),它将是这样的:
static irqreturn_t pex_irqhandler(int irq, void *dev) {
struct pci_dev *pdev = dev;
int result;
result = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &myirq);
if (result) {
int vector = read_vector();
if (vector == A) {
set_flagA(flag);
} else if (vector == B) {
set_flagB(flag);
}
wake_up_interruptible(wait_queue, flag);
return IRQ_HANDLED;
} else {
return IRQ_NONE;
}
对于选项2,它将是类似的,但是在每个不同的中断处理程序中,您将只为每个节点请求一个if子句(对于相应的向量值)。
答案 1 :(得分:1)
如果你有read()
来自不同的chanel,那么你肯定应该使用不同的次要号码。想象一下,你有一个带四个串口的卡,你肯定想要四个/dev/ttySx
但是你的设备适合这种型号吗?
答案 2 :(得分:1)
首先,我假设您没有尝试将代码放入主线内核。如果您是,请期待有关最佳方法的激烈讨论。如果您正在为一张主要由用户空间mmap
驱动的卡写一个简单的中断处理驱动程序,那么有很多方法可以解决这个问题。
如果使用多个设备节点(选项1),还可以实现poll
,以便单个应用程序可以打开多个设备节点并等待选择中断。次要数字足以告诉他们。如果每个向量都有一个唤醒队列,则只能唤醒相关的侦听器。成功poll
后,您需要锁定向量,以确保read
成功。
如果使用单个设备节点(选项2),则需要添加一些额外的魔法,以便线程可以注册他们对特定中断向量的兴趣。您可以使用ioctl执行此操作,或者让线程write
成为设备的中断向量。每个线程都应该打开设备节点以获取自己的文件描述符。然后,您可以将请求的向量列表与每个打开的文件描述符相关联。作为奖励,你可以让应用程序read
来自设备的中断向量,因此它知道发生了哪一个。
您需要考虑如何清除中断。中断处理程序需要删除中断,然后存储结果,以便将其传递给用户空间。您可能会发现kfifo
对此有用而不是等待队列。如果每个打开的文件描述符都有一个fifo,则可以将中断通知分发给每个侦听应用程序。