2025-03-12
监听GPIO引脚变化是嵌入式开发的基础知识。在Linux驱动中监听GPIO电平变化也是很方便的。下面的例子就演示了如何监听GPIO引脚电平变化?
raspberry pi3b
Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
// simple.c
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
static unsigned int irq_number = 0;
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) {
pr_info("simple_gpio_irq_handler\n");
return (irqreturn_t)IRQ_HANDLED;
}
static int __init simple_init(void) {
pr_info("simple_init\n");
if (gpio_request(17, "rpi-gpio-17")) {
pr_err("gpio_request 17 error\n");
return -1;
}
if (gpio_direction_input(17)) {
pr_err("gpio_direction_input 17 error\n");
return -1;
}
irq_number = gpio_to_irq(17);
if (request_irq(irq_number, (irq_handler_t)gpio_irq_handler,
IRQF_TRIGGER_RISING, "my_gpio_irq", NULL) != 0) {
pr_err("request_irq 17 error\n");
gpio_free(17);
return -1;
}
return 0;
}
static void __exit simple_exit(void) {
pr_info("simple_exit\n");
free_irq(irq_number, NULL);
gpio_free(17);
}
module_init(simple_init);
module_exit(simple_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("heng30");
MODULE_VERSION("v0.0.1");
MODULE_DESCRIPTION("A simple kernel module");
#!/bin/sh
top-dir = $(shell pwd)
kernel-version = $(shell uname -r)
kernel-dir ?= /lib/modules/$(kernel-version)/build
obj-m += simple.o
all:
make -C $(kernel-dir) modules M=$(top-dir)
clean:
rm -f *.o *.ko *.mod *.mod.c *.order *.symvers *.dtbo
make -C $(kernel-dir) clean m=$(top-dir)
安装gpio
工具:sudo apt install gpiod
查看gpio设备:gpiodetect
gpiochip0 [pinctrl-bcm2835] (54 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
编译程序:make
安装驱动:insmod simple.ko
查看中断:cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
...
184: 0 0 0 0 pinctrl-bcm2835 17 Edge my_gpio_irq
...
移除驱动:rmmod simple.ko
查看输出:dmesg