转:http://blog.csdn.net/longshan_2009/article/details/9981975
poll机制也是一种查询的机制,它可以等待一个时间段,比如按键,如果在这个时间段之后,按键没有按下的话,poll机制就会让应用程序处于休眠状态。
我们可以在指定的时间内查询是否有按键按下。poll机制所耗费的资源也比较低。超时时间又应用程序poll函数决定。
关于poll机制的具体分析可以参考韦东山分析文档
示例如下:
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <asm/uaccess.h>
- #include <linux/device.h>
- #include <asm/io.h>
- #include <linux/interrupt.h>
- #include <mach/regs-gpio.h>
- #include <linux/gpio.h>
- #include <linux/poll.h>
- struct class *buttons_class;
- struct device *buttons_dev;
- static DECLARE_WAIT_QUEUE_HEAD(button_waitq);//定义休眠队列
- static volatile int ev_press = 0; //初始值为0,处于休眠状态
- static unsigned char key_val;
- struct pin_desc{
- unsigned int pin;
- unsigned int key_val;
- };
- struct pin_desc pins_desc[4] = {
- {S3C64XX_GPN(0),0x01},
- {S3C64XX_GPN(1),0x02},
- {S3C64XX_GPN(2),0x03},
- {S3C64XX_GPN(3),0x04},
- };
- static irqreturn_t button_irq_handle(int irq, void *devid)
- {
- printk("irq = %d\n",irq);
- struct pin_desc * pindesc = (struct pin_desc *)devid;
- unsigned int pinval;
- pinval = gpio_get_value(pindesc->pin);
- if (pinval)
- {
- key_val = 0x80 | pindesc->key_val;
- printk("songkai\n");
- }
- else
- {
- key_val = pindesc->key_val;
- printk("anxia\n");
- }
- ev_press = 1; //唤醒
- wake_up_interruptible(&button_waitq);
- return IRQ_HANDLED;
- }
- static int buttons_drv_open(struct inode *inode, struct file *file)
- {
- printk("buttons_drv_open \n");
- request_irq(IRQ_EINT(0),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD1", &pins_desc[0]);
- request_irq(IRQ_EINT(1),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD2", &pins_desc[1]);
- request_irq(IRQ_EINT(2),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD3", &pins_desc[2]);
- request_irq(IRQ_EINT(3),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD4", &pins_desc[3]);
- return 0;
- }
- static ssize_t buttons_drv_read( struct file *file,
- char __user *buffer,
- size_t len,
- loff_t *offset )
- {
- if (len != 1)
- return -EINVAL;
- wait_event_interruptible(button_waitq, ev_press);//进入睡眠
- ev_press = 0;
- copy_to_user(buffer, &key_val, 1);
- return 1;
- }
- int buttons_drv_release(struct inode *inode, struct file *file)
- {
- free_irq(IRQ_EINT(0),&pins_desc[0]);
- free_irq(IRQ_EINT(1),&pins_desc[1]);
- free_irq(IRQ_EINT(2),&pins_desc[2]);
- free_irq(IRQ_EINT(3),&pins_desc[3]);
- return 0;
- }
- static unsigned int buttons_drv_poll(struct file *file, poll_table *wait)
- {
- unsigned int mask = 0;
- poll_wait(file, &button_waitq, wait);//到这里还没有进入休眠
- if (ev_press)
- mask |= POLLIN | POLLWRNORM;//mask是返回应用程序poll的返回值,mask一定要和应用程序中的events相对应,不然还会进行超时
- return mask;
- }
- static struct file_operations buttons_fops = {
- .owner = THIS_MODULE,
- .open = buttons_drv_open,
- .read = buttons_drv_read,
- .release = buttons_drv_release,
- .poll = buttons_drv_poll,
- };
- int major;
- static int __init buttons_drv_init(void)
- {
- printk("buttons_drv_init \n");
- major = register_chrdev(0,"buttons",&buttons_fops);
- buttons_class = class_create(THIS_MODULE,"buttons");
- buttons_dev = device_create(buttons_class,NULL,MKDEV(major,0),NULL,"buttons");
- return 0;
- }
- static void __exit buttons_drv_exit(void)
- {
- device_destroy(buttons_class,MKDEV(major,0));
- class_destroy(buttons_class);
- unregister_chrdev(major,"buttons");
- }
- module_init(buttons_drv_init);
- module_exit(buttons_drv_exit);
- MODULE_LICENSE("GPL");
应用测试程序:
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <poll.h>
- /* thirddrvtest
- */
- int main(int argc, char **argv)
- {
- int fd;
- unsigned char key_val;
- int ret;
- static int time = 5000;
- struct pollfd fds[1];
- fd = open("/dev/buttons", O_RDWR);
- if (fd < 0)
- {
- printf("can't open!\n");
- }
- fds[0].fd = fd;
- fds[0].events = POLLIN;
- while (1)
- {
- ret = poll(fds,1,time);//poll函数的使用可以man poll来查看
- if(ret == 0){
- printf("Time out !!!\n");
- }else{
- read(fd, &key_val, 1);
- printf("key_val = 0x%x\n", key_val);
- }
- }
- return 0;
- }
使用poll函数也可以对CPU资源的使用很低,如下所示:
- 上一篇:6410之中断处理编写代码(1)