【问题标题】:How to use request_threaded_irq so that the interrupt handler is called while the threaded handler works?如何使用 request_threaded_irq 以便在线程处理程序工作时调用中断处理程序?
【发布时间】:2014-11-21 16:37:57
【问题描述】:

我正在尝试为 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() 以便始终“按时”调用中断处理程序,即使线程处理程序是一项大工作?

【问题讨论】:

  • 在 ISR 和线程处理程序之间设置信号量。只使用IRQ_WAKE_THREAD,如果线程的人已经给出了信号量并且没有更多的工作要做。也就是说,这很奇怪。您没有提供内核版本或任何您可能已经调查过问题发生原因的来源。
  • 应该使用信号量来保护数据,但这里不涉及数据。内核版本是 3.13。我试图把问题说清楚:为什么线程中断处理程序会改变中断处理程序的时序?
  • 信号量可以保护任何东西。如果您在中断处理程序中执行“尝试”但失败,则返回IRQ_HANDLED。如果通过,则返回IRQ_WAKE_THREADthread 接受信号量(或任何你喜欢的无锁原语)。 atomic_t 可能会起作用。

标签: c linux-kernel arm interrupt


【解决方案1】:

我终于明白发生了什么。根据this answer on SO中断被屏蔽同时处理中断线程中断处理程序。

所以看来我误解了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;
}

现在,以正确的时间调用中断处理程序!

【讨论】:

    猜你喜欢
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多