poll机制

poll机制的作用:使阻塞型函数超时返回,避免一直阻塞。

   

 

实例:

driver.c

1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/fs.h>
4 #include <linux/init.h>
5 #include <linux/delay.h>
6 #include <linux/irq.h>
7 #include <asm/uaccess.h>
8 #include <asm/irq.h>
9 #include <asm/io.h>
10 #include <asm/arch/regs-gpio.h>
11 #include <asm/hardware.h>
12 #include <linux/poll.h>
13
14
15 static int major;
16
17 static struct class *myKey_class;
18 static struct class_device *myKey_class_dev;
19
20 volatile unsigned long *gpfcon;
21 volatile unsigned long *gpfdat;
22
23 volatile unsigned long *gpgcon;
24 volatile unsigned long *gpgdat;
25
26 static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
27 static volatile int ev_press = 0;
28
29 //normal:1; press:0;
30 static unsigned char keyVal = 0;
31
32 struct pin_desc {
33         unsigned int pin;
34         unsigned int key_val;
35 };
36
37 /*
38 * 按键按下键值为0x01,...; 松开键值为0x81,...
39 */
40 struct pin_desc pins_desc[3] = {
41         {S3C2410_GPF0, 0x01},
42         {S3C2410_GPF2, 0x02},        
43         {S3C2410_GPG11, 0x03},        
44 };
45
46
47 static int myKey_open(struct inode *inode, struct file *file);
48 static int myKey_close(struct inode *inode, struct file *file);
49 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
50 static unsigned int myKey_poll(struct file *file, struct poll_table_struct *poll_table_struct);
51
52
53 static struct file_operations myKey_fops = {
54         .open = myKey_open,
55         .read = myKey_read,
56         .owner = THIS_MODULE,
57         .release = myKey_close,
58         .poll = myKey_poll,
59 };
60
61
62 static irqreturn_t handle_buttons(int irq, void *dev)
63 {
64         unsigned int kval;
65         struct pin_desc *pinDesc = dev;
66
67         kval = s3c2410_gpio_getpin(pinDesc->pin);
68         if (kval)        //松开
69         {
70                 keyVal = 0x80 | pinDesc->key_val;
71         }
72         else {                //按下
73                 keyVal = pinDesc->key_val;
74         }
75
76         //唤醒休眠进程
77         ev_press = 1;        //中断发生标志
78         wake_up_interruptible(&button_waitq);
79
80         return IRQ_RETVAL(IRQ_HANDLED);
81 }
82
83
84 static int myKey_open(struct inode *inode, struct file *file)
85 {
86         request_irq(IRQ_EINT0, handle_buttons, IRQT_BOTHEDGE, "S2", &pins_desc[0]);
87         request_irq(IRQ_EINT2, handle_buttons, IRQT_BOTHEDGE, "S3", &pins_desc[1]);
88         request_irq(IRQ_EINT19, handle_buttons, IRQT_BOTHEDGE, "S5", &pins_desc[2]);
89         
90         return 0;
91 }
92
93
94 static int myKey_close(struct inode *inode, struct file *file)
95 {
96         free_irq(IRQ_EINT0, &pins_desc[0]);
97         free_irq(IRQ_EINT2, &pins_desc[1]);
98         free_irq(IRQ_EINT19, &pins_desc[2]);
99
100         return 0;
101 }
102
103
104 static unsigned int myKey_poll(struct file *file, struct poll_table_struct *wait)
105 {
106         unsigned int mask = 0;
107
108         poll_wait(file, &button_waitq, wait);        //不会立即休眠
109
110         if (ev_press)
111         {
112                 mask |= POLLIN | POLLRDNORM;
113         }
114
115         return mask;
116 }
117
118
119 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
120 {
121         //无中断进入休眠
122         wait_event_interruptible(button_waitq, ev_press);
123
124         ev_press = 0;        //清除中断发生标志
125         copy_to_user(buf, &keyVal, 1);
126         return 0;
127 }
128
129 static int __init myKey_init(void)
130 {
131         /* 物理地址映射成虚拟地址 */
132         gpfcon = (volatile unsigned long*)ioremap(0x56000050, 16);
133         gpfdat = gpfcon + 1;
134
135         gpgcon = (volatile unsigned long*)ioremap(0x56000060, 16);
136         gpgdat = gpgcon + 1;
137
138         major = register_chrdev(0, "myKey", &myKey_fops);
139         
140         myKey_class = class_create(THIS_MODULE, "myKeyclass");
141         myKey_class_dev = class_device_create(myKey_class, NULL, MKDEV(major, 0), NULL, "myKey");
142
143         return 0;
144 }
145
146 static void __exit myKey_exit(void)
147 {
148         /* 释放虚拟地址映射 */
149         iounmap(0x56000050);
150         iounmap(0x56000060);
151
152         unregister_chrdev(major, "myKey");
153
154         class_device_unregister(myKey_class_dev);
155         class_destroy(myKey_class);
156         return;
157 }
158
159 module_init(myKey_init);
160 module_exit(myKey_exit);

   

app.c

1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <stdio.h>
5 #include <poll.h>
6
7 int main (void)
8 {
9         int fd;
10         unsigned char keyVal;
11         int ret;
12         struct pollfd fds[1];
13         
14         printf("test app!\n");
15
16         fd = open("/dev/myKey", O_RDWR);
17         if(fd < 0)
18         {
19                 printf("open failed! %d\n", fd);
20                 return -1;
21         }
22
23         fds[0].fd = fd;
24         fds[0].events = POLLIN;
25         
26         while(1)
27         {
28                 ret = poll(fds, 1, 5000);
29                 if (!ret)
30                 {
31                         printf("time out(5s)\n");
32                 }
33                 else {
34                         read(fd, &keyVal, 1);
35                         printf("keyVal: 0x%x\n", keyVal);
36                 }
37         }
38         return 0;        
39 }

   

Makefile

1 KERN_DIR = /work/system/linux-2.6.22.6
2
3 all:
4         make -C $(KERN_DIR) M=`pwd` modules
5

6 clean:
7         make -C $(KERN_DIR) M=`pwd` modules clean
8
        rm -rf modules.order

9
10 obj-m += myKey_pollmcn.o

posted @ 2019-11-17 20:35  Lilto  阅读(526)  评论(0编辑  收藏  举报