Linux 输入子系统 input 子系统

 input 子系统

Linux系统提供了input子系统,按键、触摸屏、鼠标等输入型设备都可以使用input接口函数模型来设计设备驱动,通过这些设备Linux能够获取到一些按键键值、坐标等信息。

input子系统模型。



系统由3部分组成,1driver驱动程序(工程师需要完成)2input core 3:事件处理Event Handler,这两者内核已提供。我们只需按照input core接口规范实现驱动程序。

当一个事件发生时,如鼠标移动,键盘按下,事件首先进入driver层,然后driver把事件传给input core,再把时间传给event handler,然后把事件反馈到设备文件(用户空间)。

input体系结构

驱动层:把底层的硬件输入转化成input子系统规定的统一事件形式,向input core汇报。

input core: 把事件交给event handler处理。

Event Handler:主要作用同用户空间应用程序交互,把事件交给用户空间。

 

input驱动程序设计

设备用input_dev结构描述,驱动核心工作是向系统报告按键、触摸屏、键盘、鼠标等输入事件(event,通过input_event结构体描述),不再需要关心文件操作的接口file_operation,用为input子系统已经完成文件操作的接口。

int input_register_device struct input_dev *dev) 注册输入设备的函数

void input_unregister_device  (struct input_dev  *dev )  注销输入设备的函数

驱动的实现 :

设备驱动通过set_bit()告诉input子系统它支持那些事件,那些按键等

set_bit(EV_KEY,  button_dev.evbit)  第二的参数button_devstruct input_dev类型,有两个成员evbit:事件类型,keybit:按键类型,告诉设备支持按键。

事件类型:

EV_RST  Reset EV_KEY  按键 EV_REL  相对坐标

EV_ABS 相对坐标   EV_MSC  其他       EV_LED  LED

EV_SND 声音       EV_REP   Repeat     EV_FF    力反馈

当事件类型为EV_KEY时,还需指明按键类型,设置进keybit

BTN_LEFT:鼠标左键  BTN_0:数字0键    BTN_1:数字1

BTN_RIGHT:鼠标右键 BTN_MIDDLE:鼠标中键

当事件发生时,比如按键按下或弹起,应往input子系统报告这些事件,应使用input_report_keystruct input_dev *devunsigned int code,  int value)报告EV_KEY事件,  

code:如果按下按键,code记录按下的是那个键,如果事件类型是EV_KEY,改代码则为设备的键盘代码,例如键盘上的按键代码值为0~127,鼠标按键代码为0x110~0x116,其中0x110(BTN_LEFT)为鼠标左键,0x111BTN_RIGHT)为鼠标右键,0x112(BTN_MIDDLE)为鼠标中键,其他代码参照include/linux/input.h

value:事件的值。如果事件的类型为EV_KEY,当按键按下时值为1,松开时值为0

报告结束后通过input_sync()告诉input子系统整个事件报告完了。

在触摸屏驱动程序,一次点击坐标信息的整个报告过程:

input_report_abs (input_dev,  ABS_X, x) ;  //X坐标

input_report_abs (input_dev,  ABS_Y, y) ;  //Y坐标

input_report_abs (input_dev,  ABS_pressure, 1) ;  //按下or弹起

input_sync(input_dev) ;  //报告结束

 

按键驱动程序的改写

static int __init  button_init (void ) { //模块初始化函数

if(request(BUTTON_IRQ, button_interrupt, 0, “button”,  NULL)) //申请中断

return -EBUSY ;

set_bit(EV_KEY, button_dev.evbit); 

//设备button_dev支持的集合里包含按键EV_KEY事件,放evbit

set_bit(BTN_0, button_dev.keybit); //设置支持那些按键,放keybit

set_bit(BTN_1, button_dev.keybit); //设备支持两个键

input_register_device(&button_dev); //注册input设备

}

//在按键中断中报告事件,支持的每个键都要报

static  void button_interrupt (int irq,  void  *dummy,  struct pt_regs  *fp) {

input_report_key(&button_dev,  BTN_0,  inb(BUTTON_PART0)) ;

//通过读取寄存器BUTTON_PART0得到0号按键状态

input_report_key(&button_dev,  BTN_1,  inb(BUTTON_PART1));

input_sync(&button_dev);

}

剩下的工作,input core event handler 收集报告的事件,形成相应的数据,放到file_operation、字符文件相关的buffer里,供用户空间读取,在用户空间看到的还是字符设备,input子系统简化程序设计,两步,先初始化,后报告。

按键驱动程序的应用程序改写:

  #include<fcntl.h>
  #include<sys/select.h>
  #include<sys/time.h>
  #include<errno.h>
  #include<linux/input.h>
  
  int  main (void) {
  int buttons_fd ;
  int key_value, i=0, count ;
  struct input_event ev_key ;
  button_fd = open(“/dev/	event0”,  O_RDWR) ;
  for (; ;) {
  count = read(buttons_fd,  &ev_key,  sizeof(struct input_event)) ;
  //访问输入型设备读取的是一个struct input_event结构,包含了发生的事件
  
  for(i  =  0; i  <  (int)count/sizeof(sizeof(struct input_event));  i++)
  if(EV_KEY  ==  ev_key.type)
  printf(“type: %d  code: %d, value: %d\n”, ev_key.type, ev_key.code,  ev_key.value) ;
  if(EV_SYN == ev_key.type)
  printf(“syn event\n\n”) ;
  }
  close(button_fd) ;
  return 0 ;
  }
  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值