Новичок здесь учится программировать модули ядра Linux.
Я хочу написать модуль ядра для своего RPi 4 на языке C.
Я хочу использовать прерывания для включения светодиода, когда я нажимаю кнопку. Пока кнопка нажата, светодиод горит, а когда я ее отпускаю, светодиод должен погаснуть.
Я использую функцию request_irq(), чтобы моя функция, обрабатывающая прерывание, вызывалась по переднему фронту и по заднему фронту моей кнопки, указав IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING. Раньше я использовал функцию gpio_to_irq(BUTTON_PIN).
request_irq(button_irq, button_ih, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "button_irq", NULL);
Функция вызывается, когда я нажимаю кнопку, но не когда я ее отпускаю. Он закодирован, как показано ниже:
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;
}
Я проверяю, равно ли значение кнопки 1 (нажато) или 0 (отпущено), и хочу соответственно включить/выключить светодиод.
Когда я пробую разные GPIO, иногда значение моей кнопки равно 1, хотя я еще не нажимал ее (распечатывая сообщение из функции инициализации), а иногда это 0. Поэтому я не понимаю, делаю ли я это. Что-то не так. Я не думаю, что GPIO уже используются, потому что я могу запросить их с помощью функции gpio_request_one().
Поэтому, когда кнопка уже имеет значение 1, светодиод включается, но не выключается, когда я отпускаю кнопку.
И когда значение уже равно 0, значение кнопки не меняется на 1, когда я вхожу в функцию обработчика прерывания (и светодиод, очевидно, не включается).
Не могли бы вы сказать мне, что с ним не так, пожалуйста?