linux之按键中断

编程入门 行业动态 更新时间:2024-10-28 08:17:54

linux之<a href=https://www.elefans.com/category/jswz/34/1768597.html style=按键中断"/>

linux之按键中断

查看原理图确认引脚

可以看到按键有两个,分别对应GPIO5_1和GPIO4_14

配置pinctrl,配置成GPIO模式

1.使用官方工具,配置下引脚

2.将生成的代码复制到设备树里

创建设备节点

生成二进制设备树文件

在工具链表下使用

make dtbs

或者使用

./scripts/dtc/dtc -I dts -O dtb -o tmp.dtb arch/arm/boot/dts/xxx.dts
// 编译 dts 为 dtb

都可以生成二进制设备树文件

#include <linux/module.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>struct gpio_key{int gpio;struct gpio_desc *gpiod;int flag;int irq;
} ;static struct gpio_key *gpio_keys_100ask;static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{struct gpio_key *gpio_key = dev_id;int val;val = gpiod_get_value(gpio_key->gpiod);printk("key %d %d\n", gpio_key->gpio, val);return IRQ_HANDLED;
}/* 1. 从platform_device获得GPIO* 2. gpio=>irq* 3. request_irq*/
static int gpio_key_probe(struct platform_device *pdev)
{int err;struct device_node *node = pdev->dev.of_node;int count;int i;enum of_gpio_flags flag;unsigned flags = GPIOF_IN;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);count = of_gpio_count(node);if (!count){printk("%s %s line %d, there isn't any gpio available\n", __FILE__, __FUNCTION__, __LINE__);return -1;}gpio_keys_100ask = kzalloc(sizeof(struct gpio_key) * count, GFP_KERNEL);for (i = 0; i < count; i++){gpio_keys_100ask[i].gpio = of_get_gpio_flags(node, i, &flag);if (gpio_keys_100ask[i].gpio < 0){printk("%s %s line %d, of_get_gpio_flags fail\n", __FILE__, __FUNCTION__, __LINE__);return -1;}gpio_keys_100ask[i].gpiod = gpio_to_desc(gpio_keys_100ask[i].gpio);gpio_keys_100ask[i].flag = flag & OF_GPIO_ACTIVE_LOW;if (flag & OF_GPIO_ACTIVE_LOW)flags |= GPIOF_ACTIVE_LOW;err = devm_gpio_request_one(&pdev->dev, gpio_keys_100ask[i].gpio, flags, NULL);gpio_keys_100ask[i].irq  = gpio_to_irq(gpio_keys_100ask[i].gpio);}for (i = 0; i < count; i++){err = request_irq(gpio_keys_100ask[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "100ask_gpio_key", &gpio_keys_100ask[i]);}return 0;}static int gpio_key_remove(struct platform_device *pdev)
{//int err;struct device_node *node = pdev->dev.of_node;int count;int i;count = of_gpio_count(node);for (i = 0; i < count; i++){free_irq(gpio_keys_100ask[i].irq, &gpio_keys_100ask[i]);}kfree(gpio_keys_100ask);return 0;
}static const struct of_device_id ask100_keys[] = {{ patible = "100ask,gpio_key" },{ },
};/* 1. 定义platform_driver */
static struct platform_driver gpio_keys_driver = {.probe      = gpio_key_probe,.remove     = gpio_key_remove,.driver     = {.name   = "100ask_gpio_key",.of_match_table = ask100_keys,},
};/* 2. 在入口函数注册platform_driver */
static int __init gpio_key_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = platform_driver_register(&gpio_keys_driver); return err;
}/* 3. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数*     卸载platform_driver*/
static void __exit gpio_key_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&gpio_keys_driver);
}/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */module_init(gpio_key_init);
module_exit(gpio_key_exit);MODULE_LICENSE("GPL");

板子上执行

将生成的设备树文件放到板子上,放到/boot目录里,然后重启以下

安装驱动程序

然后执行echo “7 4 1 7” > /proc/sys/kernel/printk可以将printk函数输出的信息输出到终端。

按下按键就可以看到打印结果。

更多推荐

linux之按键中断

本文发布于:2023-11-16 13:53:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1624055.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:按键   linux

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!