linux之按键中断

news2024/11/26 15:23:03

查看原理图确认引脚

可以看到按键有两个,分别对应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[] = {
    { .compatible = "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函数输出的信息输出到终端。

按下按键就可以看到打印结果。在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1173272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“宽带中国”工具变量—海拔标准差数据集

参照刘传明&#xff08;2020&#xff09;、金环&#xff08;2021&#xff09;、胡浩然&#xff08;2023&#xff09;等的做法&#xff0c;将地级市-海拔标准差数据&#xff0c;作为“宽带中国”试点政策的工具变量 ➤相关性&#xff1a;地形起伏度会影响网络基础设施建设&…

asp.net 创建docker容器

首先创建asp.net web api 创建完成后如下图 添加docker支持 添加docker支持 添加linux docker支持

SOEM源码解析——ecx_writeeeprom(写EEPROM)

0 工具准备 1.SOEM-master-1.4.0源码1 ecx_writeeeprom函数总览 /** Write EEPROM to slave bypassing cache.&#xff1a;绕过从站缓存写EEPROM数据* param[in] context context struct 句柄* param[in] slave Slave number 从站序号* param[in] eeproma (WORD) …

Voice vlan、ICMP、单臂路由、mux-vlan

目录 一&#xff0c;Voice VLAN Voice vlan配置命令 一&#xff0c;问&#xff1a;已知网络中一台服务器的IP地址&#xff0c;如何找到这太服务器在哪台交换机的哪个接口上​编辑 思路&#xff1a; 二&#xff0c;ICMP协议 三&#xff0c;ICMP案例分析​编辑 四&#xf…

学习c++的第十一天

目录 继承和派生 基类 & 派生类 访问控制和继承 派生类的构造函数 派生类的析构函数 继承类型 多继承 重载运算符和重载函数 函数重载 运算符重载 可重载运算符/不可重载运算符 运算符重载实例 继承和派生 先来说继承&#xff0c;这与现实生活中的继承意思差不…

2023年电工杯数学建模B题人工智能对大学生学习影响的评价求解全过程论文及程序

2023年电工杯数学建模 B题 人工智能对大学生学习影响的评价 原题再现&#xff1a; 人工智能简称AI&#xff0c;最初由麦卡锡、明斯基等科学家于1956年在美国达特茅斯学院开会研讨时提出。   2016年&#xff0c;人工智能AlphaGo 4:1战胜韩国围棋高手李世石&#xff0c;期后波…

【亚马逊云科技产品测评】活动征文|亚马逊云科技AWS之EC2详细测评

引言 &#xff08;授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道&#xff09; 在当前的数字化时代&#xff0c;云服务已…

小饭店点餐系统,小餐馆点餐怎么方便,操作简单的酒店点单软件

小饭店点餐系统&#xff0c;小餐馆点餐怎么方便&#xff0c;操作简单的酒店点单软件 今天给大家分享是 佳易王酒店点餐管理系统软件V16.0版本&#xff0c;点餐界面如下图&#xff0c; 1、开台的桌子醒目显示&#xff0c;结账后或没有开台的桌子为灰色显示。 2、多种点餐方式…

Pytho入门教程之Python运行的三种方式

文章目录 一、交互式编程二、脚本式编程三、方式三关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 一、交互式编…

AMD老电脑超频及性能提升方案及实施

收拾电子元件的时候找到了若干古董的CPU 其中有一个X3 440 是原来同学主板烧了之后给我的&#xff0c;我从网上配了AM2 昂达主板&#xff0c;然后又买了AMD兼容内存&#xff0c;组成了win7 64位电脑&#xff0c;用起来非常不错&#xff0c;我把硬件配置和升级过程说明下&#x…

C++对象模型

思考&#xff1a;对于实现平面一个点的参数化。C的class封装看起来比C的struct更加的复杂&#xff0c;是否意味着产生更多的开销呢&#xff1f; 实际上并没有&#xff0c;类的封装不会产生额外的开销&#xff0c;其实&#xff0c;C中在布局以及存取上的额外开销是virtual引起的…

unittest 通过loadTestsFromName执行多个测试case

这段代码是一个使用unittest模块编写的测试运行程序。它的主要功能是加载其他Python文件中的测试用例并运行这些测试用例。 首先&#xff0c;定义了一个主测试类MainTestCase&#xff0c;该类继承自unittest.TestCase。在这个类中&#xff0c;可以添加各种测试方法来测试不同的…

产品经理入门学习(四):项目立项

参考引用 黑马-产品经理入门基础课程 1. 项目方案 1.1 主要阶段 立项阶段 基本方案&#xff1a;要做个什么项目&#xff0c;为什么要做这个项目&#xff0c;这个项目的作用和价值分别有哪些 上线阶段 设计阶段 运营阶段 开发阶段 总结阶段 测试阶段 2. 可行性分析 可…

Python语言_single_color_共140种--全平台可用

Python语言_single_color_共140种–全平台可用

3、Dockerfile 深入与其他细节

Dockerfile 在 Docker 中创建镜像最常用的方式&#xff0c;就是使用 Dockerfile。Dockerfile 是一个 Docker 镜像 的描述文件&#xff0c;我们可以理解成火箭发射的 A、B、C、D…的步骤。Dockerfile 其内部包含了一 条条的指令&#xff0c;每一条指令构建一层&#xff0c;因此每…

045_第三代软件开发-U盘监测

第三代软件开发-U盘监测 文章目录 第三代软件开发-U盘监测项目介绍U盘监测原理解释源代码 关键字&#xff1a; Qt、 Qml、 USB、 Disk、 文件 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#xff09;和…

1.如何实现统一的API前缀-web组件篇

文章目录 1. 问题的由来2.实现原理3. 总结 1. 问题的由来 系统提供了 2 种类型的用户&#xff0c;分别满足对应的管理后台、用户 App 场景。 两种场景的前缀不同&#xff0c;分别为/admin-api/和/app-api/&#xff0c;都写在一个controller里面&#xff0c;显然比较混乱。分开…

storm安装手册及笔记

图解Storm相关概念 图解storm的并发机制 安装Storm的步骤 1、安装一个zookeeper集群 2、上传storm的安装包&#xff0c;解压 3、修改配置文件storm.yaml #所使用的zookeeper集群主机 storm.zookeeper.servers: - "weekend05" - "weekend06"…

亚马逊 JDK下载地址

下载地址 https://docs.aws.amazon.com/corretto/选择版本 选择操作系统 比如 windows64 位 可以选择安装包或者解压版本 msi 的为安装版 zip 的为解压版

微积分第一章函数与极限

1.正反三角函数的导数 2.常用等价无穷小 3.正反三角函数转化&#xff1a; 1.secx1/cosx 2.cecx1/sinx 3.cotx1/tanx 4.基本数学思想&#xff1a; 1.有限式子与无限式子&#xff1a;在面对无限个式子运算时&#xff0c;大体思路为两个方面&#xff0c;第一个为放缩&#xff…