12.1.6 按键设备驱动读函数
代码清单12.11给出了按键设备驱动的读函数,按键设备驱动的读函数主要提供对按键设备结构体中缓冲区的读并复制到用户空间。当keydev.head ! = keydev.tail时,意味着缓冲区有数据,使用copy_to_user()拷贝到用户空间,否则,根据用户空间是阻塞读还是非阻塞读,分为如下两种情况。
l 若采用非阻塞读,则因为没有按键缓存,直接返回- EAGAIN;
l 若采用阻塞读,则在keydev.wq等待队列上睡眠,直到有按键被记录入缓冲区后被唤醒。
代码清单12.11 按键设备驱动的读函数
1 static ssize_t s3c2410_key_read(struct file *filp, char *buf, ssize_t count,
2 loff_t*ppos)
3 {
4 retry: if (keydev.head != keydev.tail)
5 //当前循环队列中有数据
6 {
7 key_ret = keyRead(); //读取按键
8 copy_to_user(..); //把数据从内核空间传送到用户空间
9 }
10 else
11 {
12 if (filp->f_flags &O_NONBLOCK)
13 //若用户采用非阻塞方式读取
14 {
15 return - EAGAIN;
16 }
17 interruptible_sleep_on(&(keydev.wq));
18 //用户采用阻塞方式读取,调用该函数使进程睡眠
19 goto retry;
20 }
21 return 0;
22 }
|
最后,解释一下代码清单12.9第11行的keyEvent()函数和代码清单12.11的keyRead()函数。在设备驱动的打开函数中,keyEvent被赋值为keyEvent_raw,这个函数完成记录键值,并使用wait_up_interrupt(&(keydev.wq))语句唤醒s3c2410_key_read()第17行所期待的等待队列。而keyRead()函数则直接从按键缓冲区中读取键值。
| 回书目 上一节 下一节 |