昨天在做有关Linux input子系统实验的时候,被一个问题困扰了很久,到第二天才发现原因,最后的问题是一个小细节导致实验的失败。

当时的实验代码如下:

static int key_probe(struct platform_device *pdev)  // 按键初始化函数
{int ret = 0;/*...................前面省略初始化GPIO口的代码....................................... *///  申请input_dev 结构体内存keycdev.keyinputdev = devm_input_allocate_device(&pdev->dev);if(NULL == keycdev.keyinputdev){DEBUG_SFLR("devm_input_allocate_devicekeycdev.keyinputdev->name = "key_input_dev";//keycdev.keyinputdev->dev.parent = &pdev->dev;__set_bit(KEY_DOWN ,keycdev.keyinputdev->keybit);  // 设置按键键值为KEY_DOWN__set_bit(EV_KEY, keycdev.keyinputdev->evbit);     // 设置按键类型为EV_KEY// 注册inputdeviceif(input_register_device(keycdev.keyinputdev)){DEBUG_SFLR("input_register_device error\r\n" );ret = -1;goto end;}keycdev.key_timer.function = key_timer_func;keycdev.key_timer.data     = &keycdev;init_timer(&keycdev.key_timer);   // 初始化定时器end:    return ret;}当时实验代码在定时器中断中上报键值
void key_timer_func(unsigned long arg)
{struct key_dev_type *pdata = (struct key_dev_type *)arg;int value = 0;value = gpio_get_value(pdata->gpio);if(0 == value)   // 当按键按下时上报事件{input_report_key(pdata->keyinputdev,KEY_0,0);  // 上报事件input_sync(pdata->keyinputdev);}}

但是当把驱动加载到内核之后,按下按键内核并没有把键值上报到应用层。反复检查了很多遍都没有找到是什么问题。后来再次认真检查一遍,终于发现了问题所在。原来是在按键初始化函数中向内核注册的按键键值为KEY_DOWN,但是在定时器中断函数中向内核上报按键的键值却是KEY_0,这就导致了内核注册的键值与上报的键值不一致,导致上报失败

至于为什么当内核注册的按键键值与上报的键值不一致会导致上传失败,这需要在内核中找答案

static void input_handle_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)
{int disposition;disposition = input_get_disposition(dev, type, code, &value);if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)dev->event(dev, type, code, value);if (!dev->vals)return;if (disposition & INPUT_PASS_TO_HANDLERS) {struct input_value *v;if (disposition & INPUT_SLOT) {v = &dev->vals[dev->num_vals++];v->type = EV_ABS;v->code = ABS_MT_SLOT;v->value = dev->mt->slot;}v = &dev->vals[dev->num_vals++];v->type = type;v->code = code;v->value = value;}if (disposition & INPUT_FLUSH) {if (dev->num_vals >= 2)input_pass_values(dev, dev->vals, dev->num_vals);dev->num_vals = 0;} else if (dev->num_vals >= dev->max_vals - 2) {dev->vals[dev->num_vals++] = input_value_sync;input_pass_values(dev, dev->vals, dev->num_vals);dev->num_vals = 0;}}

input_handle_event函数负责处理上报的内容,其中函数input_get_disposition负责检测键值的有效性

static int input_get_disposition(struct input_dev *dev,unsigned int type, unsigned int code, int *pval)
{int disposition = INPUT_IGNORE_EVENT;int value = *pval;switch (type) {/*****************前后省略其他的事件****************************/case EV_KEY:if (is_event_supported(code, dev->keybit, KEY_MAX)) {/* auto-repeat bypasses state updates */if (value == 2) {disposition = INPUT_PASS_TO_HANDLERS;break;}if (!!test_bit(code, dev->key) != !!value) {__change_bit(code, dev->key);disposition = INPUT_PASS_TO_HANDLERS;}}break;/********************************************************************/*pval = value;return disposition;
}

在input_get_disposition函数中我们选择EV_KEY来分析,在函数被执行时disposition预先被设置为INPUT_IGNORE_EVENT,也就是预先设置为忽略事件。is_event_supported负责判断上报的键值是否与内核注册的键值一致,如果一致就将disposition设置为INPUT_PASS_TO_HANDLERS并往后选择一个input事件处理层来处理事件,如果不相等就直接退出,不进行事件上报

所以这就是为什么当内核注册的按键键值与上报键值不一致时会导致数据没有上报的原因。最后将定时器中断函数中需要上报的键值修改为KEY_DOWN,与注册的键值一致就能上报成功

void key_timer_func(unsigned long arg)
{struct key_dev_type *pdata = (struct key_dev_type *)arg;int value = 0;value = gpio_get_value(pdata->gpio);if(0 == value)   // 当按键按下时上报事件{input_report_key(pdata->keyinputdev,KEY_DOWN);  // 上报事件input_sync(pdata->keyinputdev);}}

Linux input子系统上报键值失败问题相关推荐

  1. Linux input子系统上报事件讲解(以重力传感器lis2dw12驱动为例)

    input子系统背景 以前我们写一些输入设备(键盘.鼠标等)的驱动都是采用字符设备.混杂设备处理的.问题由此而来,Linux内核为了能够处理各种不同类型的输入设备,(比如 触摸屏 ,鼠标 , 键盘 , ...

  2. 三个子系统_「正点原子Linux连载」第五十八章Linux INPUT子系统实验(一)

    1)实验平台:正点原子Linux开发板 2)摘自<正点原子I.MX6U嵌入式Linux驱动开发指南> 关注官方微信号公众号,获取更多资料:正点原子 第五十八章Linux INPUT子系统实 ...

  3. 【Linux】Linux input子系统之Input event codes

    文章目录 前言 正文 附件 参考文章 前言 在阅读和修改Linux kernel中Touch相关驱动代码时经常可以见到形如INPUT_PROP_DIRECT EV_SYN BTN_TOUCH之类的In ...

  4. Linux input 子系统详解

    1. 模块概述 1.1.相关资料和代码研究 drivers/input/ include/uapi/linux/input-event-codes.h 2. 模块功能 linux核心的输入框架 3. ...

  5. 高通驱动实现 GPIO 中断上报键值

    高通驱动实现 GPIO 中断上报键值 一. 确认keycode值,同步修改上层键值映射表 Tips 1: 选择一个好的键值的好处 Tips 2: 如何确认驱动代是否ok 二. 驱动代码编写 三.代码调 ...

  6. 31 Linux input子系统按键驱动--4IO驱动16按键

    31.1 前言 按键是设备中是最常见的人机交互方式,本节中将学习两部分. (1)如何4个GPIO 16个按键的实现: (2)Linux input按键驱动开发实例编程: 31.2 4个IO驱动16按键 ...

  7. Linux input子系统 io控制字段【转】

    转自:http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html http://blog.csdn.net/guoshaobei/arc ...

  8. linux input子系统分析--主要函数

    linux input子系统分析--主要函数 一. 各种注册函数 因为分析一所讲的每种数据结构都代表一类对象,所以每种数据结构都会对应一个注册函数,他们都定义在子系统核心的input.c文件中.主要有 ...

  9. platform框架--Linux MISC杂项框架--Linux INPUT子系统框架--串行集成电路总线I2C设备驱动框架--串行外设接口SPI 设备驱动框架---通用异步收发器UART驱动框架

    platform框架 input. pinctrl. gpio 子系统都是 Linux 内核针对某一类设备而创建的框架, input子系统是管理输入的子系统 pinctrl 子系统重点是设置 PIN( ...

最新文章

  1. Intel Developer Forum 2010英特尔信息技术峰会第二天小记
  2. 用Tableau制作滚动时间轴(上)
  3. 【模型解读】network in network中的1*1卷积,你懂了吗
  4. python填写excel内容_python实现数据写入excel表格
  5. excel操作练习_你见过最好的Excel教程有哪些?
  6. 怎样用谷歌network调试接口_前端-chromeF12 谷歌开发者工具详解 Network篇
  7. ELK收集日志到mysql
  8. 动机才是需求,问题只是现象
  9. Word2007中公式和文字混排,文字和公式总是没法对齐
  10. c盘python27文件夹可以删除嘛_c盘哪些目录可以删除
  11. Vlookup实现多条件匹配
  12. 主流营销渠道O2O营销平台特质有哪些
  13. QQ坦白说查看好友方法攻略
  14. uva 10066 The Twin Towers (最长公共子序列)
  15. 范数规则化(一):L0、L1与L2范数
  16. 自定义线程池拒绝策略缓解高并发下线程池压力
  17. AMD 宣布开源 Linux 显卡驱动与 GPUOpen 工具
  18. 虚幻四学习笔记(2)—— 学习途径
  19. 电大计算机专业英语形成性考试,电大资源网《管理英语1》形成性考核册作业题目和答案2018年...
  20. 大学“电路分析基础”试题合集第六章(文末附PDF文档与Word文档)

热门文章

  1. ArcGIS之多个GDB批量导出shp至特定文件夹20201228
  2. 服务器和网页接口,WebApi架构详解,WebApi接口搭建与部署WebApi服务器
  3. 录屏工具ScreenToGif功能总结
  4. 华为鲲鹏+银河麒麟v10 安装 docker-ce
  5. 《数据库原理》实验六 SQL数据查询实验
  6. 沉浮70年,人工智能2018年将走向何方?
  7. 淘宝电商数据分析-Python
  8. 设置CRT使用Console连接网络设备
  9. 【转】软件测试面试题(一)
  10. 投资笔记4-投资风险认知