Doc*_*lle 6 c interrupt linux-kernel
我正在尝试在由 gpio 中断触发的内核模块中设置一个中断处理程序,但似乎我没有request_irq()
正确使用-function...我正在通过以下方式获取我的 irq-numbergpio_to_irq()
这似乎有效。然后我打电话
request_irq(irqNumber, handler, 0, "GPIO_Test", NULL);
Run Code Online (Sandbox Code Playgroud)
但它返回-22,无效参数。我认为它可能是处理程序函数,因为我不确定它的签名 - 有时它被定义为void handler (int irq, void *dev_id, struct pt_regs *regs)
,有时被定义为static irqreturn_t handler(int irq, void *data)
- 在这种情况下使用哪个是正确的,为什么有这两种完全不同的变体?我都试过,但总是得到相同的无效参数错误。
编译器给我一个关于我的处理程序函数的返回类型的警告:使用时:
static irqreturn_t handler(int irq, void *data)
{
/*interrupt-handling*/
return IRQ_HANDLED;
}
Run Code Online (Sandbox Code Playgroud)
»irq_handler_t« 预期,但参数类型 »enum irqreturn_t (* (*)(int, void *))(int, void *)«
...当使用:
void handler (int irq, void *dev_id, struct pt_regs *regs){/*interrupt-handling*/}
Run Code Online (Sandbox Code Playgroud)
»irq_handler_t« 预期,但参数类型 »void (*)(int, void *, struct pt_regs *)«
感谢您的支持 ;)
问题 ( -EINVAL
) 不是由 引起的handler
,因为内核无法在运行时确定其签名。
另外,handler
在请求 IRQ via 时永远不会调用request_irq()
(除非已定义,并且[使用错误的签名]只会在参数验证之后而不是之前导致未定义的行为,因此此时CONFIG_DEBUG_SHIRQ_FIXME
不太可能返回 an )。-EINVAL
在正确设置 IRQ 之前,需要验证 4 个关键点:
irqflags
- 你还没有设置,通过检查。irq_to_desc()
irq_desc_tree
- 将执行查找irq
. -EINVAL
如果没有找到就会返回。否则,返回指向 irq 描述符结构的指针 ( struct irq_desc *
)irq_settings_can_request()
- 检查是否可以请求 IRQ。int can_request_irq(unsigned int irq, unsigned long irqflags)
您可以通过调用before 轻松排除这种情况request_irq()
。handler
- 将检查是否handler
是NULL
。就你而言,事实并非如此。所以基本上你只有两种可能导致问题的检查,其中之一你可以在can_request_irq()
调用之前排除使用request_irq()
,但不幸的是,这不可能在模块下执行,因为can_request_irq
符号没有导出。
但如果您有耐心和时间,您可以使用内置代码构建一个新映像,只需查看can_request_irq()
检查是否通过即可。如果确实如此,则导致问题的唯一检查是irq_to_desc()
,这意味着该irq
检查无效。
无法进一步扩展这个答案,因为我无法从您的问题中获得更多信息,但我希望它可以帮助您走上正确的轨道。
顺便说一句,只是指出在这种typedef
情况irq_handler_t
下它可能有用:
include/linux/interrupt.h:92
(在 4.5 树上):
typedef irqreturn_t (*irq_handler_t)(int, void *);
Run Code Online (Sandbox Code Playgroud)