Search code examples
craspberry-pikernel-moduleraspberry-pi4

RPi 4 GPIO Interrupt on Rising and Falling trigger not working in C


Beginner here learning to code linux kernel modules.

I want to write a kernel module for my RPi 4 in C language.

I want to use interrupts to light on a LED when I push a button. As long as the button is pushed, the LED is on and when I release it, the LED is supposed to turn off.

I use the function request_irq() so that my function handling the interrupt is called on the rising edge and on the falling edge of my button by indicating "IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING". I formerly used the function gpio_to_irq(BUTTON_PIN).

request_irq(button_irq, button_ih, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "button_irq", NULL);

The function is called when I push the button but not when I release it. It is coded as seen below :

static irqreturn_t button_ih(int irq, void *data)
{
    int state;
    
    state = gpio_get_value(BUTTON_PIN);

    printk(KERN_INFO "Actual state of the button : %d", state);
    
    //Debounce condition
    if(jiffies - last_interrupt_time > msecs_to_jiffies(200))
    {
        if(state)
        {
            gpio_set_value(LED_PIN, 1);
        }else
        {
            gpio_set_value(LED_PIN, 0);
        }
    }
    last_interrupt_time = jiffies;

    return IRQ_HANDLED;
}

I check whether the value of the button is 1 (pressed) or 0 (released) and want to turn on/off the LED accordingly.

When I try different GPIOs, sometimes, the value of my button is 1 even though I haven't pushed it yet(by printing a message from the init function) and sometimes it's 0. So I don't understand if I'm doing something wrong. I don't think the GPIOs are already used cause I can request them with the function gpio_request_one().

So when the button already has the value 1, the LED turn on but won't switch off when I release the button.

And when the value is already 0, the button value doesn't change to become 1 when I enter the interrupt handler function (and the LED obviously doesn't turn on).

Could you tell me what's wrong with it please?


Solution

  • Ok so thanks for all the comments/answers.

    It was indeed because I wasn't using any pull-up or pull-down resistor properly.

    So I changed my circuit as following: Circuit