当前位置: 首页 > news >正文

Linux系统驱动(十四)输入子系统

文章目录

  • 一、输入子系统
    • (一)输入子系统框架结构
    • (二)输入子系统的API
  • 二、实现两个按键的驱动
    • (一)实现思路
    • (二)代码实现

一、输入子系统

在linux系统中使用输入子系统驱动上报鼠标,键盘,触摸屏,游戏摇杆等输入类设备上报的事件。当输入子系统驱动被安装到linux内核之后就会在"/dev/input/eventX"节点,如果想要获取上报的输入事件的值直接从这个文件中读取input_event结构类型的数据即可。

(一)输入子系统框架结构

在这里插入图片描述

(二)输入子系统的API

1.分配对象
struct input_dev *key_dev;
struct input_dev  *input_allocate_device(void);
//void input_free_device(struct input_dev *dev);
功能:申请input_dev结构体内存
参数:@无
返回值:成功返回首地址,失败返回NULL2.对象初始化set_bit(EV_KEY, key_dev—>evbit);  //设置事件类型set_bit(KEY_L, key_dev—>keybit); //可以上报l键set_bit(KEY_S, key_dev—>keybit); //可以上报s键set_bit(KEY_ENTER, key_dev—>keybit); //可以上报enter键3.注册int input_register_device(struct input_dev *dev)4.注销void input_unregister_device(struct input_dev *dev)5.上报数据
void input_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
//上报数据 参数1:inpu_dev结构体指针,参数2:类型,参数3:那个键,参数4:值
以下的函数都是在input_event函数基础上做的封装input_report_key(struct input_dev *dev, unsigned int code, int value)void input_report_rel(struct input_dev *dev, unsigned int code, int value)void input_report_abs(struct input_dev *dev, unsigned int code, int value)void input_sync(struct input_dev *dev)

二、实现两个按键的驱动

(一)实现思路

  1. 分配对象
  2. 初始化对象
  3. 注册对象
  4. 注销
  5. 上报数据

(二)代码实现

#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
// mykeys{
//     interrupt-parent = <&gpiof>;
//     interrupts = <9 0>,<7 0>,<8 0>;
//     keys_no = <&gpiof 9 0>,<&gpiof 7 0>,<&gpiof 8 0>;
// };
enum {KEYL,KEYS,KEYEN,
};
struct device_node* node;
unsigned int irqno[3];
int gpiono[3];
struct timer_list mytimer;
struct input_dev* key_dev;void key_irq_timer_func(struct timer_list* timer)
{int i;for (i = 0; i < ARRAY_SIZE(gpiono); i++) {if (!gpio_get_value(gpiono[i])) {switch (i) {case KEYL:input_report_key(key_dev,KEY_L,1);input_report_key(key_dev,KEY_L,0);input_sync(key_dev);break;case KEYS:input_report_key(key_dev,KEY_S,1);input_report_key(key_dev,KEY_S,0);input_sync(key_dev);break;case KEYEN:input_report_key(key_dev,KEY_ENTER,1);input_report_key(key_dev,KEY_ENTER,0);input_sync(key_dev);break;}}}
}
// 中断处理函数
irqreturn_t keys_irq_handle(int irq, void* dev)
{mod_timer(&mytimer, jiffies + 1); // 再次启动定时器return IRQ_HANDLED;
}
static int __init mykeys_init(void)
{int ret, i;// 1.获取节点node = of_find_node_by_name(NULL, "mykeys");if (node == NULL) {pr_err("of_find_node_by_name error\n");ret = -ENODATA;goto err1;}for (i = 0; i < 3; i++) {// 2.获取gpio号gpiono[i] = of_get_named_gpio(node, "keys_no", i);if (gpiono[i] < 0) {pr_err("of_get_named_gpio error\n");ret = gpiono[i];goto err1;}// 3.解析得到软中断号irqno[i] = irq_of_parse_and_map(node, i);if (irqno[i] == 0) {pr_err("irq_of_parse_and_map error\n");ret = -EAGAIN;goto err1;}}// 4.初始化并注册输入子系统key_dev = input_allocate_device();if (!key_dev) {pr_err("input_allocate_device error\n");ret = -ENOMEM;goto err1;}set_bit(EV_KEY, key_dev->evbit); // 设置键盘类事件set_bit(KEY_L, key_dev->keybit); // 可以上报键盘中的L键set_bit(KEY_S, key_dev->keybit); // 可以上报键盘中的S键set_bit(KEY_ENTER, key_dev->keybit); // 可以上报键盘中的ENTER键ret = input_register_device(key_dev);if (ret) {pr_err("input_register_device error\n");goto err2;}// 5.初始化并定时器mytimer.expires = jiffies + 1; // 10mstimer_setup(&mytimer, key_irq_timer_func, 0);add_timer(&mytimer);for (i = 0; i < 3; i++) {// 6.注册中断ret = request_irq(irqno[i], keys_irq_handle,IRQF_TRIGGER_FALLING, "key", NULL);if (ret) {pr_err("request_irq error\n");goto err3;}}return 0;
err3:for (--i; i >= 0; i--) {free_irq(irqno[i], NULL);}del_timer(&mytimer);input_unregister_device(key_dev);key_dev = NULL;
err2:input_free_device(key_dev);
err1:return ret;
}
static void __exit mykeys_exit(void)
{int i;for (i = 0; i < 3; i++) {free_irq(irqno[i], NULL);}del_timer(&mytimer);input_unregister_device(key_dev);
}
module_init(mykeys_init);
module_exit(mykeys_exit);
MODULE_LICENSE("GPL");

相关文章:

Linux系统驱动(十四)输入子系统

文章目录 一、输入子系统&#xff08;一&#xff09;输入子系统框架结构&#xff08;二&#xff09;输入子系统的API 二、实现两个按键的驱动&#xff08;一&#xff09;实现思路&#xff08;二&#xff09;代码实现 一、输入子系统 在linux系统中使用输入子系统驱动上报鼠标&…...

力扣(2024.08.12)

1. 98&#xff1a;验证二叉搜索树 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def isValidBST(self, r…...

最新版的AutoGPT,我搭建好了

最近AutoGPT不是更新了嘛 安装 我按照官方的教程 在本地搭建好了 改动 可见的改动&#xff0c;主要是把原来的纯命令行改成前后端的形式 看下前端界面 界面比较简单&#xff0c;主要分3个大块 监控 第一个是监控 主要是看你在 build 里构建的Agents的运行情况 build 第一个是Ag…...

[SWPUCTF 2021 新生赛]PseudoProtocols(构造伪协议)

打开题目所给的环境我们可以看到这样一句话&#xff1a; 这里我先尝试访问/hint.php &#xff0c;但是发现什么都没有发生&#xff0c; F12查看源代码也并没有发现什么&#xff0c;到这里来看的话似乎没有思路了&#xff0c;但是这个题的题目已经给了我们很明显的提示&#xff…...

基于STM32开发的智能语音助手系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 智能家居控制个人语音助理常见问题及解决方案 常见问题解决方案结论 1. 引言 随着人工智能技术的发展&#xff0c;智能语音助手已经逐渐进入了人们的日常生活。…...

基于python的图像去雾算法研究系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…...

自定义 View 可以播放一段视频

请实现一个自定义 View 的核心代码&#xff0c;核心要求可以响应如下事件&#xff1a; // - 要求自定义 View 可以播放一段视频 / - 在 view 左侧区域上下滑动&#xff0c;可以提高减少音量 / / - 在 view 右侧区域上下滑动可以提高减少屏幕亮度 // - 在 view 左右滑动可以…...

LVS负载均衡集群部署之—NAT模式的介绍及搭建步骤

一、环境准备 1.准备三台rhel9服务器 服务器名称 主机名 ip地址备注LVS调度服务器lvs.timinglee.org eth0:172.25.254.100&#xff08;外网&#xff09; eth1:192.168.0.100(内网) 关闭selinux和防火墙webserver2网站服务器webserver1.timinglee.orgeth0&#xff1a;192.168.…...

【算法】浅析哈希算法【附代码示例】

哈希算法&#xff1a;数据存储与检索的基石 1. 引言 在计算机科学中&#xff0c;哈希算法是一种用于将数据&#xff08;如文件、网络地址或数据库记录&#xff09;转换为固定长度的哈希值的过程。哈希值通常是一个较短的数字或字符串&#xff0c;用于快速检索原始数据或验证数…...

2024.8.12

2024.8.12 【梦最让我费解的地方在于&#xff0c;明明你看不清梦里人们的脸&#xff0c;却清晰地知道他们是谁。】 Monday 七月初九 序理论 最小链覆盖&最长反链长度 我们设定一个二元关系符R和一个集合A 我们设定<A,R>这样一个类群&#xff0c;那么对于任意 a i…...

使用Python解析pdf、docx等格式文件。

针对不同类型的文件&#xff0c;需要采取特定的访问与解析策略来有效获取其中蕴含的知识。下面我们将介绍对于不同数据源数据的获取方式。 1 解析Docx文档 1.1 获取Docx文档中文本 from docx import Document # pip install python-docx # python-docx 0.8.11 filename xx…...

Linux网络通信基础API

这篇文章只有Linux网络通信基础API大参数信息&#xff0c;和返回值&#xff0c;这篇文章并没有这些基础API的参数类型介绍。accept的第二个参数可以查看客户端信息。 创建socket #include <sys/types.h> /* See NOTES */#include <sys/socket.h>int sock…...

Python爬虫:下载4K壁纸

&#x1f381;&#x1f381;创作不易&#xff0c;关注作者不迷路&#x1f380;&#x1f380; 目录 &#x1f338;完整代码 &#x1f338;分析 &#x1f381;基本思路 &#x1f381;需要的库 &#x1f381;提取图片的链接和标题 &#x1f453;寻找Cookie和User-Agent &…...

2024年【北京市安全员-B证】新版试题及北京市安全员-B证免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【北京市安全员-B证】新版试题及北京市安全员-B证免费试题&#xff0c;包含北京市安全员-B证新版试题答案和解析及北京市安全员-B证免费试题练习。安全生产模拟考试一点通结合国家北京市安全员-B证考试最新大纲…...

python爬取B站视频实验

实验17&#xff1a;爬虫2 文章目录 实验17&#xff1a;爬虫21.实验目标及要求2. 实验主要内容3.实验小结 1.实验目标及要求 &#xff08;1&#xff09;掌握有关爬虫的包 &#xff08;2&#xff09;掌握爬虫方法 &#xff08;3&#xff09;爬取B站卡塔尔世界杯若干视频 2. 实验…...

10步搞定Python爬虫从零到精通!

学习Python网络爬虫可以分为以下几个步骤&#xff0c;每一步都包括必要的细节和示例代码&#xff0c;以帮助你从零开始掌握这一技能。 第一步&#xff1a;理解网络爬虫基础 什么是网络爬虫&#xff1f; 网络爬虫是一种自动化程序,用来从互联网上收集数据.它通过发送 HTTP 请求…...

SpringMVC学习笔记---带你快速入门和复习

一、初识SpringMVC 1.1、什么是SpringMVC 1.1.1、什么是MVC MVC是一种软件架构模式&#xff08;是一种软件架构设计思想&#xff0c;不止Java开发中用到&#xff0c;其它语言也需要用到&#xff09;&#xff0c;它将应用分为三块&#xff1a; M&#xff1a;Model&#xff0…...

Linux系统编程 day09 线程同步

Linux系统编程 day09 线程同步 1.互斥锁2.死锁3.读写锁4.条件变量&#xff08;生产者消费者模型&#xff09;5.信号量 1.互斥锁 互斥锁是一种同步机制&#xff0c;用于控制多个线程对共享资源的访问&#xff0c;确保在同一时间只有一个线程可以访问特定的资源或执行特定的操作…...

Vue快速入门(四)——Vue3及组合式API(一)

文章目录 一、认识Vue31. Vue2 选项式 API vs Vue3 组合式API2. Vue3的优势二、使用create-vue搭建Vue3项目1、认识create-vue2. 使用create-vue创建项目三、组合式API - setup选项1. setup选项的写法和执行时机2. setup中写代码的特点3. `<script setup>`语法糖4.小结四…...

vue项目名修改、webstorm和idea创建的项目重命名、重构项目、修改项目名称

一、需求 就是创建了一个项目&#xff0c;后期需要重命名&#xff0c;怎么办&#xff1f;----> 直接修改&#xff1f;肯定不行&#xff0c;因为里面有些配置也需要修改&#xff0c;假如你只改文件夹名称的话&#xff0c;里面配置都没修改&#xff0c;后期可能会出问题。 二…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...