/* __wait_event_interruptible()首先定义并初始化一个wait_queue_t变量__wait,
* 其中数据为当前进程current,并把__wait入队。* 在无限循环中,__wait_event_interruptible()将本进程置为可中断的挂起状态,
*反复检查condition是否成立,如果成立则退出,如果不成立则继续休眠;
*条件满足后,即把本进程运行状态置为运行态,并将__wait从等待队列中清除掉,
*从而进程能够调度运行。如果进程当前有异步信号(POSIX的),则返回-ERESTARTSYS。
*/
wait_event_interruptible(button_waitq, ev_press);}
ev_press = 0;
err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));
return err ? -EFAULT : min(sizeof(key_values), count);
}
/*应用程序对设备文件/dev/buttons执行select(...)时,
*就会调用s3c24xx_buttons_poll函数,作用:判断设备的可读写状态
*/
static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
{
unsigned int mask = 0;
poll_wait(file, &button_waitq, wait);
if (ev_press)
mask |= POLLIN | POLLRDNORM;
return mask;
}
/*这个结构是字符驱动设备程序的核心
*当应用程序操作设备文件时所调用的open,read,write等函数
*最终会调用这个结构中的对应函数
*/
static struct file_operations dev_fops = { //定义dev_fops结构
.owner = THIS_MODULE, /*这是一个宏,指向编译模块时自动创建的__this_module变量*/
.open = s3c24xx_buttons_open,
.release = s3c24xx_buttons_close,
.read = s3c24xx_buttons_read,
.poll = s3c24xx_buttons_poll,
};
static struct miscdevice misc = { //定义名为misc的混杂设备
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
ret = misc_register(&misc); //注册misc混杂设备
printk (DEVICE_NAME"\tinitialized\n");
return ret;
}
static void __exit dev_exit(void)
{
misc_deregister(&misc); //注销misc混杂设备
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");