我正在尝试为linux内核中的GPIO编写一个简单的中断处理程序。我使用request_threaded_irq
来获取中断上下文处理程序和线程处理程序。
我的问题是线程处理程序完成的工作对调用中断处理程序的时间有很大的影响。
设置中断的代码是:
gpio_request(93, "test")
gpio_direction_input(93);
gpio_request(33, "mirror");
gpio_direction_output(33, 1);
request_threaded_irq(gpio_to_irq(93),
interrupt_handler,
threaded_interrupt_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_TIMER,
"test", NULL);
在这里,我只是要求gpio 93在上升沿和下降沿触发中断。我还要求gpio 33用作镜子,见下文。
(在我的设置中,我在gpio 93上放了一个时钟源。)
中断处理程序的代码是:
static irqreturn_t interrupt_handler(int irq, void *data)
{
int state = gpio_get_value(93);
gpio_set_value(33, state);
return IRQ_WAKE_THREAD;
}
这里,中断处理程序只是将gpio 93输入值镜像为gpio 33的输出值。这样我就可以监视调用interrupt_handler
的有效速率。
最后,线程处理程序:
static irqreturn_t threaded_interrupt_handler(int irq, void *data)
{
/* doing msleep here is apparently problematic... */
msleep(1);
return IRQ_HANDLED;
}
在线程中断处理程序中,调用msleep
(或实际执行工作)是有问题的:通过在gpio输出33处查看范围,我可以看到interrupt_handler
回调率在大幅变化时threaded_interrupt_handler
睡觉或执行太多工作。
如何设置/使用request_threaded_irq()
以便中断处理程序始终被称为“按时”,即使线程处理程序是一项大工作要做?
答案 0 :(得分:6)
我最终明白发生了什么。根据{{3}},中断被屏蔽,同时处理中断和线程中断处理程序。
所以我似乎误解了request_threaded_irq
的观点:应该使用它,以便中断处理在调度程序安排的任务中。
根据我的需要,我真正想要的只是一个wait_queue。我删除了代码的线程中断处理程序,并将中断处理程序更改为:
static wait_queue_head_t wq;
static irqreturn_t interrupt_handler(int irq, void *data)
{
int state = gpio_get_value(93);
gpio_set_value(33, state);
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
现在,中断处理程序以正确的时间调用!