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;
}