我试图在内核模块中设置一个由gpio中断触发的中断处理程序,但是我似乎没有正确地使用request_irq()-function .我正在通过gpio_to_irq()获得我的irq号码,这似乎是可行的。那我就打电话
request_irq(irqNumber, handler, 0, "GPIO_Test", NULL);但是它返回-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;
}»irq_handler_t«期望,但参数具有类型?enum irqreturn_t (* (*)(int,void *))(int,void *)
使用...and时:
void handler (int irq, void *dev_id, struct pt_regs *regs){/*interrupt-handling*/}»irq_handler_t«期望,但参数具有类型-- void (*)(int,void *,struct pt_regs *)
(谢谢你的支持;)
发布于 2016-08-10 02:33:09
这个问题(-EINVAL)不是由handler引起的,因为内核无法在运行时确定它的签名。
而且,在通过handler请求IRQ时,不会调用request_irq() (除非定义了CONFIG_DEBUG_SHIRQ_FIXME,并且使用了错误的签名,这只会导致参数验证后的未定义行为,而不是在此之前,因此此时不太可能返回-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) 之前调用 request_irq(),您可以很容易地排除这一点。handler -将检查handler是否为NULL。在你的情况下,事实并非如此。因此,基本上您只有两种可能导致问题的检查,其中一种可以在调用request_irq()之前排除使用request_irq(),但不幸的是,这在模块下是不可能的,因为can_request_irq符号是不导出的。
但是,如果您有耐心和时间,您可以使用内置的代码构建一个新映像,只需查看can_request_irq()检查是否通过即可。如果是这样的话,导致问题的唯一检查是irq_to_desc(),这意味着irq无效。
我不能再扩展这个答案了,因为我无法从你的问题中得到更多的信息,但我希望它能帮助你进入正确的轨道。
顺便提一下,在这种情况下,只需指出typedef of irq_handler_t就可能有用:
include/linux/interrupt.h:92 (在4.5棵树上):
typedef irqreturn_t (*irq_handler_t)(int, void *);发布于 2021-03-17 15:13:53
如果您的中断行是嵌套的,并且需要一个线程处理程序,request_any_context_irq API (补丁)将自动处理这个情况。因为您不能从模块访问irq_settings_can_request,所以在添加工具之前,这是值得使用的。
此调用分配中断资源,并启用中断行和IRQ处理。它根据上下文选择hardirq或线程处理方法。 如果失败,则返回一个负值。成功后,它将返回IRQC_IS_HARDIRQ或IRQC_IS_NESTED。
https://stackoverflow.com/questions/38853849
复制相似问题