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

(新手)Linux 输入子系统实战教程 —— 02设备信息查询 + 输入事件读取(阻塞 / 非阻塞模式)

Linux 输入子系统实战教程 —— 设备信息查询 输入事件读取阻塞 / 非阻塞模式完整学习文档本文档基于Linux 输入设备事件读取程序编写包含完整注释源码、核心原理、逐模块解析、真实实验现象、错误原因分析专为嵌入式 Linux 驱动新手打造完全贴合百问网开发板 / 虚拟机实操环境覆盖你实验中出现的read err -1、阻塞 / 非阻塞模式、电源键设备等全部核心内容。一、文档说明本文档讲解的程序在旧版查询设备信息基础上升级新增实时读取输入事件、阻塞 / 非阻塞运行模式切换功能完整包含代码注释、原理讲解、编译运行、实验现象、错误排查所有案例、现象均来自你真实的实验操作可直接对照学习。二、程序核心功能保留旧版功能查询输入设备总线类型、厂商 ID、产品 ID、版本号、支持的事件类型新增核心功能实时读取键盘 / 鼠标 / 电源键的输入事件打印事件类型、编码、状态支持两种运行模式阻塞模式默认无事件时程序卡住等待不打印冗余信息非阻塞模式无事件时read直接返回不等待会出现read err -1兼容所有 Linux 输入设备键盘、鼠标、电源键、触摸屏等。三、核心前置知识新手必学3.1 Linux 标准输入事件结构体struct input_event内核向应用层传递所有输入设备事件统一使用该结构体struct input_event { struct timeval time; // 事件发生的时间戳 __u16 type; // 事件类型如 EV_KEY 按键事件 __u16 code; // 具体按键/坐标编码如回车键、鼠标左键 __s32 value; // 事件状态1按下 0松开 2长按重复 };3.2 阻塞模式 VS 非阻塞模式表格模式打开标志无事件时表现有事件时表现阻塞模式默认O_RDWRread 函数休眠等待程序卡住不打印read 读取事件打印事件信息非阻塞模式O_RDWR | O_NONBLOCKread 立即返回 - 1循环打印read err -1read 读取事件打印事件信息3.3 事件位图机制内核使用 ** 二进制位bit** 表示设备支持的事件类型1支持0不支持程序通过双层循环 位运算解析位图。3.4read函数作用从输入设备文件/dev/input/eventx中读取内核发送的input_event输入事件。四、完整带超详细注释源码// Linux输入子系统核心头文件定义输入事件、结构体、ioctl设备控制命令 #include linux/input.h // Linux系统调用基础头文件 #include sys/types.h #include sys/stat.h #include fcntl.h // 提供 open() 函数用于打开设备文件 #include sys/ioctl.h // 提供 ioctl() 函数设备控制读取硬件信息 #include stdio.h // 提供 printf() 打印函数 #include string.h // 提供 strcmp() 字符串比较函数判断 noblock 参数 #include unistd.h // 提供 read()、close() 函数 /* * 程序功能查询输入设备信息 实时读取输入事件 * 运行命令格式两种模式 * 1. 阻塞模式默认推荐 * sudo ./02_input_read /dev/input/eventx * 2. 非阻塞模式加 noblock 参数 * sudo ./02_input_read /dev/input/eventx noblock * 设备说明event0电源键event1键盘event2~4鼠标 */ int main(int argc, char **argv) { int fd; // 设备文件描述符打开设备后用于操作硬件 int err; // 存储 ioctl 函数返回值判断是否调用成功 int len; // 存储 read/ioctl 读取到的数据长度 int i, bit; // 双层循环计数器用于解析事件类型位图 unsigned char byte; // 存储事件位图的单个字节数据 struct input_id id; // 内核结构体存储设备硬件ID总线/厂商/产品/版本 unsigned int evbit[2]; // 存储事件类型位图2个int 8字节 64位 struct input_event event; // 内核标准结构体存储读取到的输入事件数据 // 事件类型名称数组与内核 EV_XXX 宏一一对应用于打印可读事件名 char *ev_names[] { EV_SYN , // 同步事件内核通知事件发送完成 EV_KEY , // 按键事件键盘、鼠标、电源键的按键操作 EV_REL , // 相对坐标事件鼠标移动 EV_ABS , // 绝对坐标事件触摸屏、游戏摇杆 EV_MSC , // 杂项事件 EV_SW , // 开关事件 NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , EV_LED , // LED灯事件键盘大小写锁定灯 EV_SND , // 声音事件 NULL , EV_REP , // 按键重复事件长按键盘自动重复输入 EV_FF , // 力反馈事件 EV_PWR , // 电源事件 }; // 步骤1参数合法性检查 // 程序运行至少需要2个参数程序名 输入设备路径/dev/input/eventx if (argc 2) { printf(Usage: %s dev [noblock]\n, argv[0]); return -1; } // 步骤2打开设备阻塞/非阻塞模式分支 // 判断传入3个参数且第3个参数为 noblock → 非阻塞模式 if (argc 3 !strcmp(argv[2], noblock)) { // O_NONBLOCK非阻塞标志无事件时read不等待直接返回-1 fd open(argv[1], O_RDWR | O_NONBLOCK); } // 默认情况阻塞模式无事件时read卡住等待直到有事件触发 else { fd open(argv[1], O_RDWR); } // 打开设备失败判断无权限/设备不存在打印错误并退出 if (fd 0) { printf(open %s err\n, argv[1]); return -1; } // 步骤3读取并打印设备硬件ID信息 // EVIOCGID内核ioctl命令获取设备总线、厂商、产品、版本号 err ioctl(fd, EVIOCGID, id); if (err 0) { printf(bustype 0x%x\n, id.bustype ); printf(vendor 0x%x\n, id.vendor ); printf(product 0x%x\n, id.product ); printf(version 0x%x\n, id.version ); } // 步骤4读取并解析事件类型位图 // EVIOCGBIT(0, 大小)内核ioctl命令获取设备支持的事件类型位图 len ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit); if (len 0 len sizeof(evbit)) { printf(support ev type: ); // 第一层循环遍历位图的每一个字节 for (i 0; i len; i) { byte ((unsigned char *)evbit)[i]; // 第二层循环遍历当前字节的每一位0~7 for (bit 0; bit 8; bit) { // 位运算判断当前位1 → 设备支持该事件类型 if (byte (1bit)) { printf(%s , ev_names[i*8 bit]); } } } printf(\n); } // 步骤5无限循环实时读取输入事件 while (1) { // 从设备文件读取内核发送的输入事件存入event结构体 // 阻塞模式无事件 → 卡住等待 // 非阻塞模式无事件 → 立即返回-1实验现象read err -1 len read(fd, event, sizeof(event)); // 读取成功判断读取长度 输入事件结构体大小 if (len sizeof(event)) { // 打印事件信息type事件类型code按键编码value按键状态 // value1按下 value0松开 printf(get event: type 0x%x, code 0x%x, value 0x%x\n, event.type, event.code, event.value); } // 读取失败非阻塞模式无事件 或 设备异常 else { // 非阻塞模式下无事件时read返回-1打印此错误你的核心实验现象 printf(read err %d\n, len); } } // 关闭设备文件while(1)无限循环本行代码永远不会执行 close(fd); return 0; }五、代码逐模块精讲5.1 参数与模式判断模块通过strcmp判断是否传入noblock参数选择阻塞 / 非阻塞打开方式是两种模式的核心分支。5.2 设备信息查询模块使用ioctlEVIOCGID、EVIOCGBIT命令读取设备硬件信息与事件位图保留旧版核心逻辑。5.3 事件读取循环模块while(1)无限循环持续调用read读取事件阻塞模式无事件休眠不占用 CPU非阻塞模式无事件立即返回 - 1高速循环打印read err -1。六、编译与实操运行命令6.1 编译代码gcc 02_input_read.c -o 02_input_read6.2 查看系统输入设备cat /proc/bus/input/devices你的设备event0电源键event1键盘event2~4鼠标6.3 阻塞模式运行默认推荐sudo ./02_input_read /dev/input/event16.4 非阻塞模式运行sudo ./02_input_read /dev/input/event1 noblock七、真实实验现象全解析对应你的实操结果7.1 现象 1非阻塞模式疯狂打印read err -1read err -1 read err -1 ...无限刷屏完全正常不是程序 BUG原因开启O_NONBLOCK非阻塞模式无按键事件时read函数不等待直接返回-1while(1)死循环 → 程序高速打印read err -1。7.2 现象 2读取电源键设备/dev/input/event0bustype 0x19 vendor 0x0 product 0x0 version 0x0 support ev type: EV_SYN EV_KEY设备身份主板虚拟电源按钮无厂商、产品信息bustype 0x19电源总线类型支持事件仅EV_SYN同步、EV_KEY按键按下电源键才会触发事件运行模式阻塞模式无操作时程序卡住等待不打印任何信息。7.3 按键事件正常输出示例plaintextget event: type 0x1, code 0x1c, value 0x1 // 回车键按下 get event: type 0x0, code 0x0, value 0x0 // 同步事件 get event: type 0x1, code 0x1c, value 0x0 // 回车键松开八、常见问题与错误排查表格报错 / 现象原因解决方案read err -1疯狂刷屏非阻塞模式无事件正常现象改用阻塞模式或添加休眠降低刷屏程序卡住不动阻塞模式正常等待按下键盘 / 鼠标 / 电源键触发事件CtrlC 退出open xxx err无权限 / 设备路径错误加 sudo更换正确设备节点event1/event0编译报错 strcmp 未定义缺少头文件添加#include string.h九、核心知识点总结程序完整流程参数检查→打开设备→查询信息→解析位图→循环读事件read err -1是非阻塞模式的正常特征不是错误阻塞模式适合监听输入非阻塞模式适合多任务并发处理Linux 所有输入设备统一使用struct input_event传递事件操作硬件设备必须加sudo获取管理员权限。

相关文章:

(新手)Linux 输入子系统实战教程 —— 02设备信息查询 + 输入事件读取(阻塞 / 非阻塞模式)

Linux 输入子系统实战教程 —— 设备信息查询 输入事件读取(阻塞 / 非阻塞模式)完整学习文档本文档基于Linux 输入设备事件读取程序编写,包含完整注释源码、核心原理、逐模块解析、真实实验现象、错误原因分析,专为嵌入式 Linux …...

Umi-OCR性能调优实战指南:老旧系统文字识别效率提升方案

Umi-OCR性能调优实战指南:老旧系统文字识别效率提升方案 【免费下载链接】Umi-OCR Umi-OCR: 这是一个免费、开源、可批量处理的离线OCR软件,适用于Windows系统,支持截图OCR、批量OCR、二维码识别等功能。 项目地址: https://gitcode.com/Gi…...

DIY USB3.0集线器翻车实录:GL3523芯片的USB3.0死活不认,问题到底出在哪儿?

GL3523芯片USB3.0集线器设计避坑指南:从原理图到PCB的完整解决方案 作为一名硬件爱好者,DIY USB集线器看似简单,实则暗藏玄机。特别是当涉及到USB3.0高速信号时,一个小小的设计疏忽就可能导致整个项目"翻车"。本文将基于…...

芒格思想阅读建议

📚 来源:《穷查理宝典》演讲精华**整理:小橙子 🍊 | 日期:2026-03-27🌟 必读三篇(核心精华) 芒格思想的精华集中在三篇演讲,按以下顺序阅读效果最佳: 阅读顺序…...

百川2-13B-4bits模型微调实战:用OpenClaw日志数据提升任务理解力

百川2-13B-4bits模型微调实战:用OpenClaw日志数据提升任务理解力 1. 为什么需要针对OpenClaw任务做模型微调 去年夏天,当我第一次尝试用OpenClaw自动化处理日常工作报告时,发现一个有趣的现象:当我直接说"帮我整理上周的销…...

数字健康时代的“价值共生“:APP如何用技术重新定义身体数据的意义

一、从"数字佃农"到"价值共创者":健康数据经济的范式转移2024年,全球健康经济规模达到6.8万亿美元,数字健康板块增速领跑全行业。在这场变革中,一个核心命题浮出水面:当我们的身体数据成为驱动AI进…...

扩音器什么牌子音质好?领夹扩音器哪个品牌好性价比高?一次选对!

刚开始带课那几年,我对扩音器的重视程度其实不算高,更多精力都放在备课、安排课堂节奏和处理学生互动上。但课越上越多之后,我越来越清楚一件事:真正左右现场教学效率的,并不是板书有多整齐,也不是课件做得…...

别再只用Topic和Service了!ROS Action在无人机巡检项目中的三大高阶用法

别再只用Topic和Service了!ROS Action在无人机巡检项目中的三大高阶用法 当你在凌晨三点调试无人机代码,发现巡检任务因为一个未处理的异常状态而卡死在空中,而所有日志都淹没在Topic的洪流中时,就会明白为什么ROS Action不是&quo…...

Python金融数据工程:构建高可靠股票数据管道的3种架构方案

Python金融数据工程:构建高可靠股票数据管道的3种架构方案 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 在量化投资和金融数据分析领域,获取稳定、实时的股票数据是每个技…...

5分钟快速上手:使用pose-search实现智能人体姿态检测与搜索

5分钟快速上手:使用pose-search实现智能人体姿态检测与搜索 【免费下载链接】pose-search x6ud.github.io/pose-search 项目地址: https://gitcode.com/gh_mirrors/po/pose-search 你是否曾想过,如何让计算机像人类一样理解人体动作?&…...

别再手动合并代码了!用Docker Compose 5分钟搞定Gitea私有Git服务器(附PostgreSQL配置)

5分钟极速搭建Gitea私有Git服务:Docker Compose与PostgreSQL黄金组合 还在用网盘同步代码?或是把项目文件夹压缩后通过聊天软件传来传去?作为经历过这些"原始管理方式"的开发者,我完全理解手动合并冲突时的崩溃感——上…...

Lychee Rerank MM零基础上手:图文混合Query构建与Document批量上传实操

Lychee Rerank MM零基础上手:图文混合Query构建与Document批量上传实操 1. 什么是Lychee Rerank MM?——多模态重排序的“精准标尺” 你有没有遇到过这样的问题:在图片库中搜索“穿红裙子站在樱花树下的女孩”,返回结果里却混着…...

VTK三维模型导出实战:STL、OBJ与PLY格式的性能对比与应用场景解析

1. 三维模型导出格式概述 第一次接触三维模型导出时,我被各种文件格式搞得晕头转向。STL、OBJ、PLY这些格式到底有什么区别?为什么有的文件特别大,有的又特别小?经过几个项目的实战,我终于摸清了门道。三维模型导出本质…...

Matlab进阶技巧:如何用hatchfill2和legendflex打造专业级纹理柱状图

Matlab数据可视化进阶:用hatchfill2与legendflex打造学术级纹理柱状图 在科研论文或商业报告中,单调的纯色柱状图往往难以清晰传达多维数据的层次关系。当需要区分5种以上的数据类别时,即使用尽所有高对比度颜色,依然会面临辨识度…...

保姆级教程:用Arch Linux为你的旧手机编译LineageOS 21(附LG G8 ThinQ实战记录)

深度实战:在Arch Linux上为LG G8 ThinQ编译LineageOS 21的完整指南 当老旧手机逐渐被厂商放弃系统更新时,自行编译定制ROM成为延长设备寿命的最佳选择。本文将详细记录在Arch Linux环境下为LG G8 ThinQ(代号alphaplus)编译Lineage…...

攻防世界 reverse题GFSJ0810-【crazy】

1.工具:exeinfope、IDA Pro (64-bit)、thonny2.解题:下载附件后,我们先在exeinfope里查壳,如下我们发现是64位无壳文件,然后我们把它放到IDA Pro (64-bit)里分析,我们点击F5先查看伪代码,如下代…...

深度解析Cursor试用重置工具:解决“You‘ve reached your trial request limit“的完整方案

深度解析Cursor试用重置工具:解决"Youve reached your trial request limit"的完整方案 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Youve reached your trial request limit. / Too many free trial accounts used on…...

90% LVGL 新手踩大坑!分不清「父子控件」和「Python 子类」

上面我们说到了 LVGL 采用父子对象模型:所有 UI 元素都是 lv.obj 的子类,通过父子关系构建界面层级(屏幕 → 按钮 → 标签),这是新手最容易混淆的两个「父子 / 子类」概念。 首先要明确:LVGL 里的「父子对…...

用Python+OpenCV给斗地主做个‘外挂’:手把手教你写个桌面记牌器(附源码)

PythonOpenCV实战:打造智能斗地主记牌工具 记得去年宿舍通宵打牌时,室友总抱怨记不住出过的牌。作为计算机系学生,我琢磨着能否用课堂学的OpenCV做个记牌工具。三周后,当这个能自动识别桌面上扑克牌的小程序成功运行时&#xff0c…...

使用ComfyUI可视化工作流构建NLP-StructBERT语义搜索应用

使用ComfyUI可视化工作流构建NLP-StructBERT语义搜索应用 你是不是觉得,要搭建一个能理解你说话、能精准搜索内容的AI应用,得写一堆复杂的代码,还得懂各种框架?其实,现在有更简单的方法了。今天,我就带你用…...

Rustup离线安装完整指南:在没有网络的环境中搭建Rust开发平台

Rustup离线安装完整指南:在没有网络的环境中搭建Rust开发平台 【免费下载链接】rustup The Rust toolchain installer 项目地址: https://gitcode.com/gh_mirrors/ru/rustup 你是否曾经需要在完全隔离的网络环境中安装Rust开发工具链?&#x1f91…...

Windows安全中心总提示驱动不兼容?手把手教你清理老旧驱动,为内存完整性扫清障碍

Windows驱动深度清理指南:彻底解决内存完整性兼容性问题 每次打开Windows安全中心,那个刺眼的"驱动不兼容"提示总让人心烦?这不仅仅是烦人的弹窗问题,更是系统安全与性能的潜在威胁。作为长期使用Windows的资深用户&…...

技术探索:硬件信息伪装的内核级实现方案

技术探索:硬件信息伪装的内核级实现方案 【免费下载链接】EASY-HWID-SPOOFER 基于内核模式的硬件信息欺骗工具 项目地址: https://gitcode.com/gh_mirrors/ea/EASY-HWID-SPOOFER 如何通过驱动级操作实现系统硬件标识的深度修改? 技术解析&#x…...

炸裂实锤!随手乱按挖出编译器「乱码隐藏保留字」编译报错直接封神

文章目录封面文案一、专栏开篇回顾二、初见疑点:反复刷屏的神秘乱码片段三、三层硬核现场取证,逐层锁死真相1. IDE标识实锤:专属K图标 关键字同款高亮2. 编译现场终极定罪:报错和普通未定义变量完全不同对比区分,一眼…...

【java --mybatis-flex】

基本信息 https://mybatis-flex.com/zh/others/codegen.html 基于mybatis,支持 Entity 的增删改查、以及分页查询的同时,MyBatis-Flex 提供了 Db Row^灵活 工具,可以无需实体类对数据库进行增删改查以及分页查询。 与此同时,MyBa…...

国产隔离器信号孤岛保卫战

国产隔离器正以绝缘屏障铸就信号孤岛——当8kV静电在光伏接线盒上炸出刺目蓝光,当10V/m射频噪声如潮水般淹没地铁信号回波,这条工业设备的生死线上,我们以GB/T 17626标准为矛,以-40℃~85℃环境适应性为盾,在电磁风暴与…...

为什么事故复盘总是写到很晚?

这两天和几个做运维/后端的朋友聊了下事故复盘,发现一个很真实的情况: 👉 大家都知道复盘很重要 👉 但几乎没人愿意写 我问了一个问题: “为什么一份复盘总是要写那么久?” 总结下来基本都是这几个原因&…...

如何彻底掌控Windows Defender:终极禁用与启用指南

如何彻底掌控Windows Defender:终极禁用与启用指南 【免费下载链接】defender-control An open-source windows defender manager. Now you can disable windows defender permanently. 项目地址: https://gitcode.com/gh_mirrors/de/defender-control 你是…...

NRBO - Transformer - BiLSTM回归:Matlab实现的数据预测魔法

NRBO-Transformer-BiLSTM回归 Matlab代码 基于牛顿拉夫逊优化算法优化Transformer结合双向长短期记忆神经网络(BiLSTM)的数据回归预测(可以更换为分类/单、多变量时序预测/回归,前私我),Matlab代码,可直接运行,适合小白新手 程序已…...

Z-Image-Turbo LoRA Web服务GPU优化:显存碎片整理与长期运行稳定性保障

Z-Image-Turbo LoRA Web服务GPU优化:显存碎片整理与长期运行稳定性保障 1. 项目概述与核心价值 今天要跟大家分享的是一个基于Z-Image-Turbo模型的图片生成Web服务,重点解决了GPU显存管理和长期稳定运行的关键问题。这个服务不仅支持高质量的图片生成&…...