How do I use request_threaded_irq so that the interrupt handler is called when the handler is running with a thread?

I am trying to write a simple interrupt handler for GPIO in linux kernel. I use request_threaded_irq

to get interrupt context handler and thread handler.

My problem is that the work done by the handler with the thread has a big impact on the call times of the interrupt handler.

Code to set up an interrupt:

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);

      

Here I am simply asking gpio 93 to trigger an interrupt on rising and falling edges. I also ask gpio 33 to be used as a mirror, see below.

(In my setup, I set the sync source to gpio 93).

The interrupt handler code is as follows:

static irqreturn_t interrupt_handler(int irq, void *data)
{
    int state = gpio_get_value(93);
    gpio_set_value(33, state);
    return IRQ_WAKE_THREAD;
}

      

Here, the interrupt handler simply mirrors the gpio 93 input as the output for gpio 33. This allows me to control the effective call rate on interrupt_handler

.

Finally, the threaded handler:

static irqreturn_t threaded_interrupt_handler(int irq, void *data)
{
    /* doing msleep here is apparently problematic... */
    msleep(1);
    return IRQ_HANDLED;
}

      

In an interrupt handler with threads, calling msleep

(or actually doing the work) is problematic: looking through the scope in the output of gpio 33, I see that the speed of the callback interrupt_handler

changes drastically when threaded_interrupt_handler

sleeping or doing too much work.

How can I configure / use request_threaded_irq()

so that the interrupt handler is always called "on" even if the thread handler is how big a job?

+3


source to share


1 answer


In the end, I understand what's going on. According to this answer on SO, the interrupt is masked by interrupt handling and an interrupt handler with a thread.

So, it seems I misunderstood the point request_threaded_irq

: it really needs to be used to keep the interrupt handling in the task scheduled by the scheduler.

For my needs, I really wanted to just wait_queue. I am removing the interleaved interrupt handler for my code and changing the interrupt handler to something like:



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;
}

      

The interrupt handler is now called with the correct time!

+3


source







All Articles