转自:http://www.cnblogs.com/lcw/p/3802617.html

【1.input子系统框架(drivers\input)】

如何得出某个驱动所遵循的框架?
    1) 通过网络搜索
    2) 自己想办法跟内核代码!
         2.1 定位此驱动是属于哪种类型的(触摸屏驱动为字符设备)
         2.2 搜索register_chrdev得到,input.c
         2.3 分析input.c文件

/*入口函数*/
 subsys_initcall(input_init); 
 input_init
  /*1.创建一个设备类*/
  class_register(&input_class);
  /*2.申请主设备号,注册操作方法,注册字符设备*/
  register_chrdev(13, "input", &input_fops);
  
  static const struct file_operations input_fops = {
   .owner = THIS_MODULE,
   .open  = input_open_file,
  };

2.4 分析如何来用input子系统

   app:  open("/dev/xxx",...)
   =============================
   vfs:  sys_open
    ...
    ...
   input.c struct file_operations input_fops
     .open = input_open_file,
      
      /*1.根据次设备号,从input_table数组中,取出一个input_handler结构体*/
      handler = input_table[iminor(inode) >> 5];   //2
      /*2.取出input_handler里面的操作方法*/
      if (handler)
       new_fops = fops_get(handler->fops);      //evdev_fops
      old_fops = file->f_op;
      file->f_op = new_fops;       //file中的f_op覆盖了
      /*3.执行底层的open函数*/
      new_fops->open(inode, file);   //事件处理层的操作方法里面的open函数evdev_open
      evdev_open

2.5 根据handler = input_table[iminor(inode) >> 5];
            猜测,有某段代码将input_handler放入了input_table[iminor(inode) >> 5]
            搜索input_table,看在哪里放了

   module_init(evdev_init);
   evdev_init    //driver/input/evdev.c
    /*注册一个handler*/
    input_register_handler(struct input_handler *handler)
     
     /*将input_handler放入input_table数组中*/
     input_table[handler->minor >> 5] = handler;
   static struct input_handler evdev_handler = {
    .event   = evdev_event,
    .connect  = evdev_connect,
    .disconnect  = evdev_disconnect,
    .fops   = &evdev_fops,
    .minor   = EVDEV_MINOR_BASE,
    .name   = "evdev",
    .id_table   = evdev_ids,
   };

【input子系统框架讲解】

1.input子系统的核心层(input.c)
    功能:1)给用户提供接口(register_chrdev,cdev,file_operations结构体)
         2)给用input子系统内部组件提供接口,建立三者之间的联系

/*入口函数*/
subsys_initcall(input_init); 
input_init
 /*1.创建一个设备类*/
 class_register(&input_class);
 /*2.申请主设备号,注册操作方法,注册字符设备*/
 register_chrdev(13, "input", &input_fops);
 
 static const struct file_operations input_fops = {
  .owner = THIS_MODULE,
  .open = input_open_file,
 };

2.input子系统的事件处理层(evdev.c)
    功能:专门用来为设备驱动层上报事件的

/*入口函数*/
module_init(evdev_init);
evdev_init    //driver/input/evdev.c
 /*注册一个handler*/
 input_register_handler(struct input_handler *handler)
  
  /*将input_handler放入input_table数组中*/
  input_table[handler->minor >> 5] = handler;   //64/32 =2
static struct input_handler evdev_handler = {  //表示事件处理句柄
 .event   = evdev_event,     //上报事件的时候,会调用此函数
 .connect  = evdev_connect,    //建立连接的时候,会调用此函数
 .disconnect  = evdev_disconnect,
 .fops   = &evdev_fops,     //事件处理方法(xxx_read)
 .minor   = EVDEV_MINOR_BASE,    //64
 .name   = "evdev",
 .id_table  = evdev_ids,
};
static const struct file_operations evdev_fops = {
 .owner   = THIS_MODULE,
 .read   = evdev_read,      //当应用程序来读数据的时候,便会调用此函数
 .write   = evdev_write,
 .poll   = evdev_poll,
 .open   = evdev_open,
 .release  = evdev_release,
 .unlocked_ioctl = evdev_ioctl,
 .fasync   = evdev_fasync,
 .flush   = evdev_flush
};

3.input子系统的设备驱动层(s3c2410_ts.c为例子)(是驱动工作人员的主要任务)
    功能:1)跟硬件交互,操作硬件,获取硬件的外部事件
         2)提交事件给事件处理层

/*入口函数*/
module_init(s3c2410ts_init);
 s3c2410ts_init
  /*注册一个平台驱动*/
  platform_driver_register(&s3c_ts_driver);
static struct platform_driver s3c_ts_driver = {
 .driver         = {
  .name   = "samsung-ts",
  .owner  = THIS_MODULE,
#ifdef CONFIG_PM
  .pm = &s3c_ts_pmops,
#endif
 },
 .id_table = s3cts_driver_ids,
 .probe  = s3c2410ts_probe,
 .remove  = __devexit_p(s3c2410ts_remove),
};
/*匹配成功,则调用平台驱动中的probe函数*/
s3c2410ts_probe
 /*猜测*/
 /*1.获取资源*/
 /*1.1 获取平台数据*/
 info = pdev->dev.platform_data;
 /*1.2 使能时钟*/
 ts.clock = clk_get(dev, "adc");
 clk_enable(ts.clock);
 /*1.3 获取中断资源*/
 ts.irq_tc = ret = platform_get_irq(pdev, 0);
 /*1.4 获取IO内存资源*/
 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 /*1.5 映射*/
 ts.io = ioremap(res->start, resource_size(res));
 /*1.6 注册中断*/
 ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
     "s3c2410_ts_pen", ts.input);
 /*2. 申请ADC服务*/
 /*3. 初始化硬件(初始化触摸屏控制器)*/
 /*4. 构建一个struct input_dev结构体*/
 struct input_dev *input_dev;                //表示一个输入设备
 /*4.1 设置input_dev*/
 /*4.2 注册input_dev,注册到子系统(input子系统中)*/
 input_register_device(ts.input);

【input子系统里面涉及的几个重要结构体】

struct input_dev     //用来表示一个输入设备
{
 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 input_handler   //用来表示一个事件处理句柄
{
 /*上报事件*/
 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
 /*建立连接的*/
 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
 const struct file_operations *fops;
 ...
}

struct input_handle    //用来建立input_dev与input_handler的连接的
{
 ...
 struct input_dev *dev;
 struct input_handler *handler;
 struct list_head d_node;
 struct list_head h_node;
}

struct input_event    //用来表示一个输入事件
{
 struct timeval time;  //事件产生的时间
 __u16 type;     //事件类型 EV_KEY
 __u16 code;     //事件码   KEY_A KEY_B
 __s32 value;    //事件值   1-按下 0-松开
}

【input子系统中涉及的重要函数:(input.c)】

/*注册一个事件处理句柄*/
int input_register_handler(struct input_handler *handler)
void input_unregister_handler(struct input_handler *handler)
/*注册一个输入设备*/
int input_register_device(struct input_dev *dev)
void input_unregister_device(struct input_dev *dev)
/*提交事件到事件处理层*/
void input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)
/*提交按键类事件*/
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)
/*提交同步类事件,每上报完一次事件后,都必须要上报一个同步事件*/
void input_sync(struct input_dev *dev)
/*分配一个input_dev结构体*/
struct input_dev *input_allocate_device(void)
/*设置input_dev,设置它能产生哪类事件,设置它能产生哪些*/
方法一:BIT_MASK(事件类型)  事件类型都在:linux/input.h
例如:
ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
方法二:set_bit
例如:
set_bit(EV_KEY,ts.input->evbit);
set_bit(EV_ABS,ts.input->evbit);
set_bit(BIN_TOUCH,ts.input->keybit);

【input子系统框架】

【input子系统框架完整版】

@成鹏致远

(email:wwwlllll@126.com)

(qq:552158509)

【Linux高级驱动】input子系统框架【转】的更多相关文章

  1. 【Linux高级驱动】input子系统框架

    [1.input子系统框架(drivers\input)] 如何得出某个驱动所遵循的框架?    1) 通过网络搜索    2) 自己想办法跟内核代码!         2.1 定位此驱动是属于哪种类 ...

  2. Linux 驱动框架---input子系统框架

    前面从具体(Linux 驱动框架---input子系统)的工作过程学习了Linux的input子系统相关的架构知识,但是前面的学习比较实际缺少总结,所以今天就来总结一下输入子系统的架构分层,站到远处来 ...

  3. input子系统框架

    废话不多说,直接进入主题.在驱动insmod后,我们应用层对input设备如何操作?以下以全志a64为实例. 在/dev/input/eventX下(X的形成为后续会分析),是内核把接口暴露给应用层, ...

  4. 网络驱动移植之解析Linux网络驱动的基本框架

    内核源码:linux-2.6.38.8.tar.bz2 概括而言,编写Linux网络驱动其实只要完成两件事即可,一是分配并初始化网络设备,二是注册网络设备. 1.分配并初始化网络设备 动态分配网络设备 ...

  5. 【Linux高级驱动】rtc驱动开发

    [1.分层思想] 1.1 rtc-dev.c   //设备接口层,功能:给用户提供接口 subsys_initcall(rtc_init);   , RTC_DEV_MAX, "rtc&qu ...

  6. 【Linux高级驱动】linux设备驱动模型之平台设备驱动机制

    [1:引言: linux字符设备驱动的基本编程流程] 1.实现模块加载函数  a.申请主设备号    register_chrdev(major,name,file_operations);  b.创 ...

  7. ARM Linux 驱动Input子系统之按键驱动测试

    上一篇已经谈过,在现内核的中引入设备树之后对于内核驱动的编写,主要集中在硬件接口的配置上了即xxxx.dts文件的编写. 在自己的开发板上移植按键驱动: 1.根据开发板的原理图 确定按键的硬件接口为: ...

  8. 【Linux高级驱动】I2C驱动框架分析

    1.i2c-dev.c(i2c设备驱动组件层) 功能:1)给用户提供接口 i2c_dev_init  //入口函数 /*申请主设备号*/ register_chrdev(I2C_MAJOR(), &q ...

  9. 【Linux高级驱动】LCD驱动框架分析

    1.framebuffer接口层(fbmem.c) 功能:给用户提供接口 fbmem_init  ),"fb",&fb_fops)  /*2.创建一个设备类*/ fb_cl ...

随机推荐

  1. “吃神么,买神么”的第一个Sprint计划(结束)

    “吃神么,买神么”项目Sprint计划 ——5.28  星期四(第八天)第一次Spring计划结束   第一阶段Spring的目标以及完成情况: 时间:5月21号~5月28号(7天) 目标:第一阶段结 ...

  2. 第二次spring冲刺第1天

    今天,我们开会讨论了,觉得现阶段的四则运算还不够完善,功能也过于简单,没有太多能吸引人的地方,因次提出以下几点作为后续的修改: 1.计时器,如果具有计时功能,那么就可以增加趣味性. 2.页面跳转,现阶 ...

  3. [BUG随想录] 看不见的分隔符: Zero-width space

    今天在调试一段代码的时候,有一个输入不能为空的库函数抛出了异常(为空就会抛出异常,就是这么傲娇).自己暗骂了自己一番,怎么这么大意,于是追溯源头,开始寻找输入控制的地方.但是当我找到时我惊呆了,我明明 ...

  4. 12th 对礼物挑选小工具的WBS功能分解

    WBS功能分解: 功能 一级子功能 二级子功能 预计用时(分钟) 主页 进入相应页面 1.如果用户已处于登录状态,则返回用户登录时的主页 10 2.如果用户处于未登录状态,则返回用户预览主页. 10 ...

  5. [windows]转帖 windows 版本的含义

    1.N是None的意思,由于欧洲反垄断法不让系统捆绑浏览器ie和播放器.LTSB全称为Long Term Support Branch,意思为长期支持分支,是给Windows 10企业用户的一个更新选 ...

  6. GS 服务器端开启webservice 远程调试的方法

    1. 修改 安装目录下 web.config的文件. 一般目录为: C:\Program Files\GenerSoft\bscw_local\web.config 为了保证安全想把文件备份一下. 2 ...

  7. 平时在PHP编码时有没有注意到这些问题

    编出一手好代码,这个是需要你在平时开发中日积月累的,平时如果你有注意到以下的那些代码的编码,那么祝贺你,你在技能提升这方面已经垫下了一些基础,编写出一手好代码,说白了就是你特么注意到性能这块的问题,代 ...

  8. BZOJ 3516 国王奇遇记加强版(乱推)

    题意 求\(\sum_{k=1}^{n}k^mm^k (n\leq1e9,m\leq1e3)\) 思路 在<>中有一个方法用来求和,称为摄动法. 我们考虑用摄动法来求这个和式,看能不能得到 ...

  9. BZOJ4589 Hard Nim(博弈+FWT)

    即使n个数的异或为0.如果只有两堆,将质数筛出来设为1,做一个异或卷积即可.显然这个东西满足结合律,多堆时直接快速幂.可以在点值表示下进行. #include<iostream> #inc ...

  10. WebService 检测到有潜在危险的 Request.Form 值

    在web.config 的 <system.web> <pages validateRequest="false" /> <httpRuntime r ...