0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

驱动之路#11:Input子系统数据上报流程

BSP调试从0到1 来源:嵌入式分享 作者:嵌入式分享 2026-03-10 08:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

题图:日本东京有一家专门生产电梯按钮的公司,该公司把生产过的1000多种电梯按钮,做成了一面展示墙,按上去每个都会亮。孩子们和大人都很喜欢。

欢迎关注,每周更新!☞

本合集分享的是,我当初学习Linux驱动的来时路——《《驱动之路》开篇:自序&前言》。

正文

Input 子系统框架的复杂程度有三四层楼那么高。幸运的是,复杂那部分代码大佬前辈们已经实现,我们只需搞懂 Input 子系统的框架,然后套用框架实现具体输入设备 driver 端驱动程序即可。因此,可以说 ai 时代搞懂框架比理解每行代码更重要。

但是对于 Input 子系统这样复杂的框架,要彻底理解从硬件底层到用户空间的数据上报流程谈何容易,必须要找到一个抓手作为切入点。

然而,分析gpio_keys.c驱动正是掌握 Linux Input 子系统数据上报流程的绝佳途径,因为它是一个典型且相对简单的 Input 驱动实例。

在分析前,请先回顾《驱动之路#01:Hello World!》和 Input 子系统的三层架构:驱动层、核心层以及事件处理层。

wKgZO2mvZN2AbU7PAAIG2CMGLgw758.png

下面是一个 step-by-step 的指南,带你从gpio_keys.c出发,彻底理解 Input 子系统的工作机制。

特别说明:本文重点在于理解 Input 子系统数据上报流程,而非gpio_keys.c驱动分析。

从module_init开始:驱动入口函数

阅读一个字符设备驱动程序从入口函数开始,在 gpio_keys.c 中可以看到 gpio_keys_init 注册了 gpio_keys_device_driver。当 driver 与 device 匹配后,gpio_keys_probe 函数就会被调用,接下来重点分析gpio_keys_probe 函数。

wKgZO2mvZN2AO6OtAAFAxbsqrOc979.png

驱动层到核心层

驱动核心: gpio_keys_probe 函数分析

probe函数在驱动与设备匹配成功后被调用,可以看到 probe函数有 4 步关键操作。

步骤 1:获取设备配置信息

首先通过dev_get_platdata(dev)从平台设备中获取静态定义的平台数据。如果没有静态平台数据,则再通过gpio_keys_get_devtree_pdata(dev)从设备树中解析配置。总之,无论是设备树还是传统平台数据,最终都解析到pdata中。

wKgZO2mvZN2AeJ07AAEDJMVRvDE707.png

步骤 2:分配和初始化struct input_dev

通过devm_input_allocate_device()创建一个输入设备对象input_dev,这是驱动层与核心层交互的第一步。

wKgZO2mvZN6ASV88AAESzXXDnpA111.png

步骤 3:申请 GPIO 和中断

probe 函数没有直接包含中断处理函数的实现,而是通过调用 gpio_keys_setup_key() 完成了中断函数的注册、中断触发方式等配置。

wKgZO2mvZN6Abl0WAAA-eoy6v4c995.png

步骤 4:注册输入设备

通过 input_register_device()将 input_dev 注册到 Input 子系统核心层,调用此函数后,Input 核心层会接手管理这个输入设备并尝试为它匹配合适的事件处理器(Handler),如 evdev。

注册成功后,用户空间就可以看到/dev/input/eventX 设备节点了。

wKgZO2mvZN6AQLLqAABLPDcqWHY584.png

以上是 probe 函数关键操作的分析。

中断处理函数分析

中断处理函数是数据上报流程的起点,当用户按下或松开按键时,GPIO 电平变化触发中断,此函数被执行。

经过前面分析知道,中断服务函数相关配置在gpio_keys_setup_key() 中完成,接下来分析 gpio_keys_setup_key() 。

可以看到有两种IRQ函数

gpio_keys_gpio_isr:设备树中的用gpios描述引脚时调用;

gpio_keys_irq_isr:设备树中的用interrupts描述引脚时调用。

它们有各自的优缺点,但不是本文的重点,这里不展开分析。

wKgZO2mvZN6AGUc_AANaoLNwqDQ103.png

我们分析相对简单的 gpio_keys_irq_isr 中断函数的处理流程,其中,

核心:调用input_event(input, EV_KEY, *bdata->code,1)和input_sync(input)进行上报数据。

input_event():向 Input 核心层上报一个原始事件。这个事件包含了事件类型(EV_KEY)、事件码(如 KEY_POWER)和值(1 或 0)。

input_sync():上报一个同步事件,告诉核心层 “这一组事件已经完整上报完毕”。

wKgZO2mvZN6AMdO2AATY92t5pNQ363.png

至此,数据已经从硬件驱动层上报到核心层。

核心层到事件层数据流

数据从核心层传递到事件层函数调用关系比较复杂,调用关系如下。

其中,input_handle_event函数是 Input 核心层的事件分发中心,它会将事件传递给所有与该input_dev关联的input_handler(事件处理器)。

而数据从核心层传递到事件层,是调用evdev_events 函数来实现,然后通过evdev_pass_values函数被分发到各个客户端。

wKgZO2mvZN-AZFU2AAWPtQGk01k574.png

当用户空间读取/dev/input/eventX时,实际上是从对应客户端的环形缓冲区中读取数据。数据最后保存在每个打开设备文件的进程所对应的evdev_client的环形缓冲区中。

wKgZO2mvZN-AaTuOAAGpAHHV4Kw875.png

数据流:gpio_keys.c驱动->input_event -> input_handle_event -> input_pass_values -> evdev_events -> evdev_pass_values ->写入evdev_client的 buffer ->用户空间read读取。

总结整个流程

硬件:用户按下按键 -> GPIO 电平变化 -> 触发中断。

驱动层 (gpio_keys.c):

gpio_keys_irq_isr 或gpio_keys_gpio_isr 中断服务程序被调用。

调用input_event()和input_sync()向上层(核心层)上报事件。

核心层 (input.c):

input_event()->input_handle_event()接收事件。

核心层将事件分发给所有匹配的 input_handler。

事件处理层 (evdev.c):

evdev_event()接收事件。

将事件打包成struct input_event并写入内核缓冲区(buffer)。

唤醒正在等待数据的用户空间应用程序。

用户空间:应用程序的 read()调用返回,读取到 struct input_event 数据并进行解析。

看完本文,可自行阅读源码分析,关键代码阅读顺序:

drivers/input/keyboard/gpio_keys.c- 具体输入设备驱动程序

drivers/input/input.c- 核心框架

drivers/input/evdev.c- 事件处理

include/linux/input.h- 数据结构和 API

(完)

本人专注 Linux 驱动 & Linux/Android BSP 开发调试,可接外包项目/技术支持/问题定位。有需求或交个朋友可加微信:【Chen_WeChat2026】。

更多原创技术文章:《README 2026》。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 驱动
    +关注

    关注

    12

    文章

    1989

    浏览量

    88684
  • 子系统
    +关注

    关注

    0

    文章

    116

    浏览量

    13570
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    驱动之路#20:Pinctrl 在手,引脚复用很顺手

    : 步骤 2:内核解析设备树,初始化引脚配置 Linux 内核启动时,Pinctrl 子系统会执行以下操作: 解析i2c0)绑定,等待驱动使
    的头像 发表于 04-07 21:18 444次阅读
    <b class='flag-5'>驱动</b><b class='flag-5'>之路</b>#20:Pinctrl 在手,引脚复用很顺手

    AirCloud 协议:物联网设备数据上报实现与实操指南

    物联网设备开发过程中,便捷实现云端接入、保障数据稳定传输是两大核心诉求。LuatOS 的 AirCloud 物联网云服务通信协议,可高效实现设备数据上报核心功能,还支持七类数据的定期或
    的头像 发表于 03-25 12:34 139次阅读
    AirCloud 协议:物联网设备<b class='flag-5'>数据</b><b class='flag-5'>上报</b>实现与实操指南

    LuatOS:AirCloud 云协议——物联网设备数据上报实操详解

    物联网设备开发中,便捷上云与稳定数传是核心需求,LuatOS 的 AirCloud 物联网云服务通信协议可实现数据上报核心功能,支持七类数据的定期 / 触发式上报。本文将讲解该协议相关
    的头像 发表于 03-19 18:23 151次阅读
    LuatOS:AirCloud 云协议——物联网设备<b class='flag-5'>数据</b><b class='flag-5'>上报</b>实操详解

    RDMA设计37:RoCE v2 子系统模型设计

    子系统模型并将其整合到验证平台中,使得 RoCE v2 高速数据传输系统能够进行复杂网络环境下的仿真验证。RoCE v2 子系统模型包含两个 AXIS 总线接口、一个虚拟内存管理器、
    发表于 02-06 16:19

    4G工业网关实现PLC数据采集与HTTP协议上报

    HTTP(超文本传输协议)是互联网最基础的应用层协议,在工业物联网(IIoT)中也被广泛用于设备上云、数据上报系统集成通信,其标准化、跨平台和易实现的特点,使其成为工业网关与云平台之间的重要桥梁
    的头像 发表于 12-23 10:22 430次阅读
    4G工业网关实现PLC<b class='flag-5'>数据</b>采集与HTTP协议<b class='flag-5'>上报</b>

    驱动隔离芯片:电子系统的安全与效能守护者

    在当今科技飞速发展的时代,电子系统的复杂性和集成度不断提升,对信号传输的安全性、稳定性和高效性提出了前所未有的挑战。从工业自动化的精密控制到新能源汽车的动力管理,从通信网络的高速数据传输到医疗设备的精准监测,驱动隔离芯片作为电
    的头像 发表于 10-25 15:19 769次阅读

    基于 ROS + ADI 芯片方案 的 人形机器人子系统级BOM清单(以腿部子系统为例)

    基于 ROS + ADI 芯片方案 的 人形机器人子系统级BOM清单 (以 腿部子系统 为例),包括核心感知、执行与通信模块,配合主控系统通过 ROS2 实现分布式控制与状态反馈。 一、腿部
    的头像 发表于 06-17 17:06 2245次阅读

    迅为RK3568开发板新增topeet子系统-在产品中新增子系统

    build/subsystem_config.json文件中增加名为topeet的子系统,在3.4节已经新建了topeet 文件夹存放子系统代码。添加 topeet 子系统进行一个登记,说明
    发表于 06-16 10:43

    RK3568驱动指南|第十二篇 GPIO子系统-第130章 GPIO的调试方法

    RK3568驱动指南|第十二篇 GPIO子系统-第130章 GPIO的调试方法
    的头像 发表于 06-03 11:32 1432次阅读
    RK3568<b class='flag-5'>驱动</b>指南|第十二篇 GPIO<b class='flag-5'>子系统</b>-第130章 GPIO的调试方法

    迅为RK3568开发板驱动指南GPIO子系统GPIO子系统API函数的引入

    迅为RK3568开发板驱动指南GPIO子系统GPIO子系统API函数的引入
    的头像 发表于 05-29 14:05 1162次阅读
    迅为RK3568开发板<b class='flag-5'>驱动</b>指南GPIO<b class='flag-5'>子系统</b>GPIO<b class='flag-5'>子系统</b>API函数的引入

    迅为RK3568驱动指南GPIO子系统 GPIO操作函数实验

    迅为电子RK3568开发板驱动指南GPIO子系统 GPIO操作函数实验
    的头像 发表于 05-28 15:24 1489次阅读
    迅为RK3568<b class='flag-5'>驱动</b>指南GPIO<b class='flag-5'>子系统</b> GPIO操作函数实验

    迅为RK3568开发板驱动指南GPIO子系统三级节点操作函数实验

    迅为RK3568开发板驱动指南GPIO子系统三级节点操作函数实验
    的头像 发表于 05-26 15:39 1659次阅读
    迅为RK3568开发板<b class='flag-5'>驱动</b>指南GPIO<b class='flag-5'>子系统</b>三级节点操作函数实验

    RK3568驱动指南|第十二篇 GPIO子系统-第135章 GPIO子系统与pinctrl子系统相结合实验

    RK3568驱动指南|第十二篇 GPIO子系统-第135章 GPIO子系统与pinctrl子系统相结合实验
    的头像 发表于 05-23 13:47 1189次阅读
    RK3568<b class='flag-5'>驱动</b>指南|第十二篇 GPIO<b class='flag-5'>子系统</b>-第135章 GPIO<b class='flag-5'>子系统</b>与pinctrl<b class='flag-5'>子系统</b>相结合实验

    迅为RK3568驱动指南GPIO子系统实战:实现动态切换引脚复用功能

    迅为RK3568驱动指南GPIO子系统实战:实现动态切换引脚复用功能
    的头像 发表于 05-22 14:27 2324次阅读
    迅为RK3568<b class='flag-5'>驱动</b>指南GPIO<b class='flag-5'>子系统</b>实战:实现动态切换引脚复用功能

    一文带你了解KaihongOS标准系统的技术架构、子系统系统应用、典型特性以及支持的设备类型

    硬件之间的交互,从而实现了对周边设备对应硬件的控制和数据传输。硬件资源池化基于驱动接口(HDI)完成硬件虚拟化,服务层各个业务子系统可以像使用本机硬件一样使用分布式硬件。 注意: 使用分布式特性(分布式
    发表于 04-23 07:17