一、输入子系统

针对输入设备设计:触摸屏、键盘、按键、传感器、鼠标......

二、每种设备都属于字符设备驱动,程序的写法步骤也相同

1、实现入口函数 xxx_init() 和卸载函数 xxx_exit()

2、申请设备号 register_chrdev() --- 与内核相关

3、创建设备文件(节点) class_create() 和 device_create() --- 与内核相关

4、硬件初始化

  GPIO操作 --- 与硬件相关

  注册中断 --- 与硬件相关

  初始化等待队列 --- 与内核相关

  初始化定时器 --- 与内核相关

5、构建 file_operations 结构,实现操作硬件方法 xxx_open/xxx_read... --- 与硬件相关

三、引入输入子系统:

1、不需要每个步骤都编写,只需要编写部分代码即可

2、不同类的输入设备,编写驱动的方式是一样的

3、应用程序读取输入设备的数据结构是统一的

输入设备按照产生的数据的类型进行分类:

1、产生按键数据 --- 每个按键都是一个整数

  按键、键盘

2、产生绝对数据 --- 每个数据都有最大值和最小值

  触摸屏、传感器

3、产生相对数据 --- 某个收据是相对另一个数据的

  鼠标

四、输入子系统的框架

  -------------------------------------------------------------------------------

  应用层:

  -------------------------------------------------------------------------------

  input handler 层:

    知道如何将数据交给用户,不知道如何从硬件获取数据

    driver/input/evdev.c

  -------------------------------------------------------------------------------

  input core 层:

    维护两个链表,和上下两层交互

    /driver/input/input.c

  -------------------------------------------------------------------------------

  input device 层:

    知道如何从硬件获取数据,不知道如何将数据交给用户

  -------------------------------------------------------------------------------

  硬件:

    触摸屏、键盘、鼠标、按键......

  -------------------------------------------------------------------------------

五、输入子系统的驱动编程方法:

1、构建 input device 对象

2、初始化 input device 对象

3、注册 input device 对象

4、硬件初始化

六、描述一个具体的输入设备对象常用的参数:

struct input_dev {
  const char *name;  // 设备名称
  const char *phys;    // 物理路径
  const char *uniq;    // 设备唯一的识别码
  struct input_id id;    // 设备id,如果有多个输入设备,可以通过此id找到需要的设备
    __u16 bustype;    // 总线类型
    __u16 vendor;      // VID
    __u16 product;      // PID
    __u16 version;      // 版本号
  unsigned long evbit[BITS_TO_LONGS(EV_CNT)];  // 设备支持的事件类型
  unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];  // 此设备具有哪些按键
  unsigned long relbit[BITS_TO_LONGS(REL_CNT)];   // 此设备具有相对坐标
  unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];  // 此设备具有相对坐标
  ... ...
  struct device dev; //父类
  struct list_head  h_list;
  struct list_head  node; //节点
};

evbit 是只有 1 个元素的 long 型数组,总共占 32 位,每种类型占一位,存在的就将对应位置 1

unsigned long evbit[BITS_TO_LONGS(EV_CNT)];

keybit 是含 24 个元素的 long 型数组,总共 768 位,最大支持 768 种按键,每一种按键占一位,存在的就将对应位置 1

unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];

七、常用函数

// 上报按键数据

void 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)

//  同步 (唤醒等待队列  /driver/input/evdev.c -> evdev_event -> wake_up_interruptible(&evdev->wait);)

input_sync(input_key);

input_key_drv.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/irq.h> static struct input_dev *input_key;
static int irqno; irqreturn_t input_key_handler(int irqno, void *dev_id)
{
int value; printk("---%s---\n", __FUNCTION__); value = gpio_get_value(EXYNOS4_GPX1());
// value = gpio_direction_input(EXYNOS4_GPX1(1));
printk("---<DRV>--- %d\n", value);
input_report_key(input_key, KEY_HOME, !value);
input_sync(input_key); return IRQ_HANDLED;
} static int __init input_key_drv_init(void)
{
int ret; input_key = input_allocate_device();
if (input_key == NULL)
{
printk("input_allocate_device fail!\n");
return -ENOMEM;
} input_key->name = "input_key";
input_key->phys = "abcd";
input_key->uniq = "efgh";
input_key->id.bustype = BUS_HOST;
input_key->id.product = 0x1234;
input_key->id.vendor = 0x5678;
input_key->id.version = 0x9ABC; input_key->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
input_key->keybit[BIT_WORD(KEY_HOME)] |= BIT_MASK(KEY_HOME); ret = input_register_device(input_key);
if (ret != )
{
printk("input_register_device fail!\n");
ret = -ENOMEM;
goto input_free;
} irqno = gpio_to_irq(EXYNOS4_GPX1());
ret = request_irq(irqno, input_key_handler, IRQ_TYPE_EDGE_BOTH, "input_eint9", NULL);
if (ret < )
{
printk("request_irq fail!\n");
ret = -EBUSY;
goto input_unregister;
} return ; input_unregister:
input_unregister_device(input_key); input_free:
input_free_device(input_key); return ret;
} static void __exit input_key_drv_exit(void)
{
free_irq(irqno, NULL);
input_unregister_device(input_key);
input_free_device(input_key);
} module_init(input_key_drv_init);
module_exit(input_key_drv_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Aaron Lee");

key_app.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> #include <linux/input.h> struct input_event key_info; int main(void)
{
int fd;
int ret; fd = open("/dev/input/event1", O_RDWR);
if (fd < )
{
perror("open");
exit();
} while ()
{
read(fd, &key_info, sizeof(struct input_event));
if (key_info.type == EV_KEY)
if (key_info.code == KEY_HOME)
printf("---<APP>--- KEY_HOME %s\n", key_info.value ? "down" : "up");
} close(fd); return ;
}

Linux 输入子系统 input的更多相关文章

  1. Linux输入子系统(Input Subsystem)

    Linux输入子系统(Input Subsystem) http://blog.csdn.net/lbmygf/article/details/7360084 input子系统分析  http://b ...

  2. 10. linux输入子系统/input 设备【转】

    转自:https://www.cnblogs.com/crmn/articles/6696819.html 按键事件信息之上报绝对事件信息之上报相对事件信息之上报功能键驱动编写多点触控事件的上报 只产 ...

  3. Linux输入子系统(转)

    Linux输入子系统(Input Subsystem) 1.1.input子系统概述 输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中 ...

  4. linux输入子系统(input subsystem)之evdev.c事件处理过程

    1.代码 input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变. input ...

  5. Linux 输入子系统

    Technorati 标签: Kernel 输入子系统 Input      在Linux中,输入设备(如按键.键盘.触摸屏.鼠标等)是典型的字符设备,其一般的工作机理,是底层在按键.触摸时,触发一个 ...

  6. Linux输入子系统框架分析(1)

    在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...

  7. Linux输入子系统详解

    input输入子系统框架  linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(Input ...

  8. linux输入子系统

    linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputCore)和输入子系统设备驱 ...

  9. linux输入子系统概念介绍

    在此文章之前,我们讲解的都是简单的字符驱动,涉及的内容有字符驱动的框架.自动创建设备节点.linux中断.poll机制.异步通知.同步互斥.非阻塞.定时器去抖动. 上一节文章链接:http://blo ...

随机推荐

  1. 【bzoj5452】[Hnoi2016]大数(莫队)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4542 首先若p=2,5则这题就是道傻逼题,前缀和搞一下没了.如果p为其他质数,那么可以 ...

  2. javascript页面打印

    打印本身比较简单,但要考虑到具体的需求.比如 1. 多浏览器: if (isIE()) { //打印预览 WebBrowser1.execWB(7, 1); } else { window.print ...

  3. VMware与Windows主机交换文件

    1. 安装 VMwareTool ,直接拖拽文件 2. 安装 VMwareTool,然后WMare配置 共享文件夹 3. 通过 U盘 4. for Linux:Windows安装 SSH Client ...

  4. InflateException:Bin file line #19:Error inflating class MyTextView

    InflateException:Bin file line #19:Error inflating class MyTextView 一.错误简介 为了实现TextView的跑马灯效果,我自己写了一 ...

  5. python学习笔记(pip下载安装)

    python有很多扩展模块需要安装 这个时候万能的pip就可以提供帮助 首页进入官网下载压缩包: https://pypi.python.org/pypi/pip#downloads 解压文件 cmd ...

  6. Html工具类

    import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletRespons ...

  7. win8 商店应用 设计风格原则

    共八条: 1,突出内容(数据). a,仅在屏幕上保留最相关的元素:移除线条.框和不必要的图形效果:限制屏幕上持久显示的导航框,如选项卡. b,交互尽量直接在内容上,直接控制内容来完成操作,而不是使用控 ...

  8. 条款14:在资源管理类中小型coping的行为

    首先假设对于一个mutex互斥器对象,有lock以及unlock两个函数可用: void lock(Mutex * pm); void unlock(Mutex * pm); 那么为了防止资源忘记被释 ...

  9. L127

    Biggest Studies on Aspirin Show Risks Outweigh Benefits for Many People Doctors have long recommende ...

  10. Redis 补充

    Redis 补充 Redis 的主要用途 数据库 缓存和消息中间件 相当于一个字典 数据库切换 select 1 (默认36个数据库 默认在0) 1 基本数据类型 字符串 散列 hashes 列表 集 ...