这几天在android上移植了sensor(compass+gsensor),虽然以前TP也是input系统,但只在driver处理,而sensor除了在driver处理还要在HAL处理,HAL处于input subsystem的上层,通过看HAL,对input子系统有了更全面的认识。sensor的数据流是sensor ic ---》driver---》input system----》HAL,其中,input system是由linux系统提供的,我们要完成driver和HAL。这里主要说一下input device在用户空间的接口,主要有三个位置分别如下

1.设备结点

/dev/input

crw-rw---- root input 13, 682012-03-28 16:16 event4

crw-rw---- root input 13, 702012-03-28 16:16 event6

crw-rw---- root input 13, 692012-03-28 16:16 event5

crw-rw---- root input 13, 672012-03-28 16:16 event3

crw-rw---- root input 13, 662012-03-28 16:16 event2

crw-rw---- root input 13, 652012-03-28 16:16 event1

crw-rw---- root input 13, 642012-03-28 16:16 event0

这些全是字符设备,通过这些字符设备节点可以在用户空间导出了原生event,转化成input_event,允许用户程序操作任何event,不会遗失任何信息。要读取相应inputdevice的数据,首先你必须获得input设备的文件描述符。获取方法如下

//这里的inputName必须与driver中注册input设备时制定的name一致,通过这个name就可以找到fd

//从而读取数据

//注册时定义data->input_dev_compass->name= "ami30x_compass";

int SensorBase::openInput(const char*inputName) {

int fd = -1;

const char *dirname = "/dev/input";

char devname[PATH_MAX];

char *filename;

DIR *dir;

struct dirent *de;

dir = opendir(dirname);

if(dir == NULL)

return -1;

strcpy(devname, dirname);

filename = devname +strlen(devname);

*filename++ = '/';

while((de = readdir(dir))) {

if(de->d_name[0] == '.' &&

(de->d_name[1] =='\0' ||

(de->d_name[1]== '.' && de->d_name[2] == '\0')))

continue;

strcpy(filename, de->d_name);

fd = open(devname, O_RDONLY);

if (fd>=0) {

char name[80];

//通过给设别结点发送ioctrl来获取相应的name,如果匹配则查找到

if (ioctl(fd,EVIOCGNAME(sizeof(name) - 1), &name) < 1) {

name[0] = '\0';

}

if (!strcmp(name,inputName)) {

strcpy(input_name,filename);

break;

} else {

close(fd);

fd = -1;

}

}

}

closedir(dir);

LOGE_IF(fd<0, "couldn'tfind '%s' input device", inputName);

return fd;

}

只要得到了这个fd,就可以与设备交互了,一般有3个接口可以使用

1IOCTRL

系统提供的IOCTRL如下

include/linux/input.h

#define EVIOCGVERSION _IOR('E',0x01, int) /* get driver version */

#define EVIOCGID _IOR('E', 0x02,struct input_id) /* get device ID */

#define EVIOCGREP _IOR('E',0x03, int[2]) /* get repeat settings */

#define EVIOCSREP _IOW('E',0x03, int[2]) /* set repeat settings */

#define EVIOCGKEYCODE _IOR('E',0x04, int[2]) /* get keycode */

#define EVIOCSKEYCODE _IOW('E',0x04, int[2]) /* set keycode */

#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */

#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */

#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */

#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */

#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */

#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */

#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */

#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */

#define EVIOCGABS(abs) _IOR('E',0x40 + abs, struct input_absinfo) /* get abs value/limits */

#define EVIOCSABS(abs) _IOW('E',0xc0 + abs, struct input_absinfo) /* set abs value/limits */

#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send aforce effect to a force feedback device */

#define EVIOCRMFF _IOW('E',0x81, int) /* Erase a force effect */

#define EVIOCGEFFECTS _IOR('E', 0x84,int) /*Report number of effects playable at the sametime*/

#define EVIOCGRAB _IOW('E',0x90, int) /* Grab/Release device */

值得一提的是EVIOCGNAME,通过ioctl命令EVIOCGNAME,能获取dev/input/event*对应的DeviceName,如ioctl(fd,EVIOCGNAME(sizeof(name)), name)

注意这个一般只是从系统中获取inputdevice的注册信息,不会与硬件通信。

2)获取设备的event通过char设备的read function

rb=read(fd,ev,sizeof(structinput_event)*64)

3)给设备发送信息通过write(如点亮键盘的numlock led

 write(fd, &ev, sizeof(struct input_event));

这些ioctrlreadwirte系统都已经实现,我们只要注册后,通过fd就可以使用,不需要在driver再实现fops

2.查看input class 信息

/sys/devices/virtual/input/input*

自己进去看看好了

3.查看设备信息

/proc/bus/input/

# cat /proc/bus/input/devices

I: Bus=0018 Vendor=0000 Product=0000Version=0000

N: Name="ft5xxx"

P: Phys=

S:Sysfs=/devices/i2c-0/0-0038/input/input4

U: Uniq=

H: Handlers=event4 cpufreq

B: EV=b

B: KEY=400 0 4 0 0 0 0 0 0 0 0

B: ABS=2650000 3

I: Bus=0000 Vendor=0000 Product=0000Version=0000

N: Name="msm7627_sku2_keypad"

P: Phys=

S: Sysfs=/devices/virtual/input/input5

U: Uniq=

H: Handlers=kbd event5 cpufreq

B: EV=3

B: KEY=c0000 0 0 0

参考:

Input event驱动

Linux input 子系统 (1)(翻译国外的一篇文章,讲的很好)

linux内核input子系统解析

闲聊linux中的input设备(1)Linux中的设备大家族

(这是一个系列的文章,以akm的comapss 为例,正好我是在看android的sensor这块,风格有点像linnux那些事)

强烈建议看一看,看完以上三篇文章,基本对input subsystem会有比较全面的认识,包括driver层如何注册,input core如何处理及APP层如何处理接受到的event。




更多相关文章

  1. Android中如何获取IMEI号码
  2. android中判断sim卡状态和读取联系人资料的方法
  3. adb wifi连接手机
  4. 检索Android的图片库,并显示
  5. Android打包时我们如何选择平台(ABI)
  6. Linux下添加Android设备
  7. 利用Dumpsys做系统诊断
  8. Android(安卓)获取运营商信息(完整版)-解决高通,MTK等双卡问题
  9. 11.3、Libgdx的音频之播放PCM音频

随机推荐

  1. 【移动安全】Android(安卓)App Smail代码
  2. Android抖动动画
  3. Android中使用GridView实现标签效果源码
  4. 百度地图中android获取经纬度和地方名称
  5. Failed to create directory C:\ Progra
  6. Android使用Retrofit请求WebService
  7. Android(安卓)联系人选择Widget
  8. Android中判断网络连接是否可用
  9. 如何正常关闭android应用程序
  10. android dex工具打包Could not reserve e