写一个能在树莓派加载的按键驱动
时间: 2024-03-20 11:39:42 浏览: 17
好的,以下是一个简单的树莓派按键驱动的实现示例:
```c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#define BUTTON_GPIO_PIN 17 // 使用 GPIO17 作为按键输入引脚
#define BUTTON_IRQ_NUM gpio_to_irq(BUTTON_GPIO_PIN)
MODULE_LICENSE("GPL");
static int irq_number; // 中断号
static bool button_state = false; // 按键状态
// 中断处理函数
static irqreturn_t button_interrupt(int irq, void *dev_id)
{
button_state = !button_state; // 取反当前按键状态
printk(KERN_INFO "Button state: %d\n", button_state);
return IRQ_HANDLED;
}
static int __init button_init(void)
{
int ret;
// 申请 GPIO 引脚
if (!gpio_is_valid(BUTTON_GPIO_PIN)) {
printk(KERN_INFO "Invalid GPIO pin\n");
return -ENODEV;
}
ret = gpio_request(BUTTON_GPIO_PIN, "Button");
if (ret < 0) {
printk(KERN_INFO "Unable to request GPIO pin %d\n", BUTTON_GPIO_PIN);
return ret;
}
// 配置 GPIO 引脚为输入模式,并设置中断处理函数
gpio_direction_input(BUTTON_GPIO_PIN);
irq_number = gpio_to_irq(BUTTON_GPIO_PIN);
ret = request_irq(irq_number, button_interrupt, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "Button", NULL);
if (ret < 0) {
printk(KERN_INFO "Unable to request IRQ number %d\n", irq_number);
gpio_free(BUTTON_GPIO_PIN);
return ret;
}
printk(KERN_INFO "Button driver initialized\n");
return 0;
}
static void __exit button_exit(void)
{
// 释放中断和 GPIO 引脚资源
free_irq(irq_number, NULL);
gpio_free(BUTTON_GPIO_PIN);
printk(KERN_INFO "Button driver exited\n");
}
module_init(button_init);
module_exit(button_exit);
```
在上面的代码中,我们使用了 GPIO17 作为按键输入引脚,使用 `gpio_request` 申请 GPIO 引脚资源,并使用 `gpio_direction_input` 将 GPIO 引脚配置为输入模式。然后使用 `gpio_to_irq` 将 GPIO 引脚转换为中断号,使用 `request_irq` 注册中断处理函数。
中断处理函数会在按键按下或松开时触发,通过取反当前按键状态并使用 `printk` 打印出来。
最后,在模块初始化函数中调用 `module_init` 注册初始化函数,在模块退出函数中调用 `module_exit` 注册退出函数,即可将该驱动编译为内核模块并加载到树莓派中运行。