5.input设备使用分析--2(应用层面)
应用程序打开一个设备(需要包含内核一些头文件.h)---
/*struct input_event
{
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
*/
void main()
{
struct input_event key_event;
int fd = open("/dev/event0", O_RDWR); /*最后执行-->evdev_open;*/
int cnt = 0;
while( (cnt = read(fd, &key_event, sizeof(struct input_event)) > 0) /*最后执行evdev_read*/
{
printf("%d,%d,%d,%d\n", key_event.type, key_event.code, key_event.value);
}
}
/************************接着分析evdev_open******************/
static int evdev_open(struct inode *inode, struct file *file)
{
struct evdev *evdev;
struct evdev_client *client;
int i = iminor(inode) - EVDEV_MINOR_BASE;
unsigned int bufsize;
evdev = evdev_table[i]; /*根据号码取得evdev设备*/
if (evdev)
get_device(&evdev->dev);
bufsize = evdev_compute_buffer_size(evdev->handle.dev); /*构造bufsize和client*/
client = kzalloc(sizeof(struct evdev_client) +
bufsize * sizeof(struct input_event),
GFP_KERNEL);
client->bufsize = bufsize;
client->evdev = evdev;
evdev_attach_client(evdev, client); /*将evdev添加到evdev->client_list链表中-->list_add_tail_rcu(&client->node, &evdev->client_list);*/
if (error)
goto err_free_client;
file->private_data = client; /*将client作为file的私有数据*/
return 0;
}
/********************接着分析evdev_read()***********************************/
static ssize_t evdev_read(struct file *file, char __user *buffer,
size_t count, loff_t *ppos)
{
struct evdev_client *client = file->private_data; /*取得相应的evdev_client*/
struct evdev *evdev = client->evdev;
struct input_event event;
int retval;
while (retval + input_event_size() <= count &&
evdev_fetch_next_event(client, &event)) { /*将client->buffer中的数据放到event中*/
if (input_event_to_user(buffer + retval, &event)) /*将event中的数据拷贝到应用层buffer中*/
return -EFAULT;
retval += input_event_size();
}
return retval;
}