按键驱动程序中,如果不使用read函数中使程序休眠的,而是还是使用查询方式的话,可以使用Poll函数,来控制一定时间内,如果有按键发生,则立即返回键值。
同时,poll也可以同时监控多个(比如说按键,鼠标,等)一旦发生事件则立即返回。
我们在linux查看帮助:
从帮助中的说明得知,
poll, ppoll - wait for some event on a file descriptor
poll就是监控某个设备的事件。
修改驱动程序
1.增加头文件 #include
2.增加key_poll 方法
static unsigned key_poll(struct file *file,poll_table *wait) |
file_opreation中增加:
.poll = key_poll, |
3.在key_poll函数中设置函数不睡眠
4.此时可以把以前的read函数中的中断睡眠代码注释掉
5.编译代码,测试
附上驱动程序。
1 /******************************
2 linux key_query
3 *****************************/
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19
20 #include "mx257_gpio.h"
21 #include "mx25_pins.h"
22 #include "iomux.h"
23
24 #define Driver_NAME "key_interrupt"
25 #define DEVICE_NAME "key_interrupt"
26
27 #define GPIO2_21 MX25_PIN_CLKO
28 #define GPIO3_15 MX25_PIN_EXT_ARMCLK
29 #define GPIO2_10 MX25_PIN_A24
30 #define GPIO2_11 MX25_PIN_A25
31 #define GPIO2_8 MX25_PIN_A22
32 #define GPIO2_9 MX25_PIN_A23
33 #define GPIO2_6 MX25_PIN_A20
34 #define GPIO2_7 MX25_PIN_A21
35 //command
36 #define key_input 0
37 #define version 1
38 //定义各个按键按下的键值
39 struct pin_desc{
40 unsigned int pin;
41 unsigned int key_val;
42 };
43 //当按键按下时,键值分别为 以下值
44 struct pin_desc pins_desc[8] = {
45 {GPIO2_6, 0x01},
46 {GPIO2_7, 0x02},
47 {GPIO2_8, 0x03},
48 {GPIO2_9, 0x04},
49 {GPIO2_10, 0x05},
50 {GPIO2_11, 0x06},
51 {GPIO2_21, 0x07},
52 {GPIO3_15, 0x08},
53 };
54 //定义一个全局变量,用于保存按下的键值
55 static unsigned int key_val;
56
57 //interrupt head
58 static DECLARE_WAIT_QUEUE_HEAD(key_interrupt_wait);
59 static volatile unsigned char ev_press;
60
61 static int major=0;
62
63 //auto to create device node
64 static struct class *drv_class = NULL;
65 static struct class_device *drv_class_dev = NULL;
66
67
68 /* 应用程序对设备文件/dev/key_query执行open(...)时,
69 * 就会调用key_open函数*/
70 static int key_open(struct inode *inode, struct file *file)
71 {
72 printk("<0>function open!nn");
73
74 return 0;
75 }
76
77 /* 中断程序key_irq */
78 static irqreturn_t key_irq(int irq, void *dev_id)
79 {
80 struct pin_desc * pindesc = (struct pin_desc *)dev_id;
81 //发生了中断
82 //printk("<0>function interrupt key_irq!nn");
83 //获取按键键值
84 if(gpio_get_value(IOMUX_TO_GPIO(pindesc->pin))){
85 /* 按下 */
86 key_val = pindesc->key_val;
87 }else{
88 key_val = 0x80 | pindesc->key_val;
89 }
90 printk("<0>get key 0x%x",key_val);
91 ev_press = 1;
92 wake_up_interruptible(&key_interrupt_wait);
93
94 return IRQ_RETVAL(IRQ_HANDLED);
95 }
96
97
98 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
99 {
100 int ret;
101 //如果按键没有按下,没有中断,休眠
102 //wait_event_interruptible(key_interrupt_wait,ev_press);
103
104 ret = copy_to_user(buff,&key_val,sizeof(key_val));
105 if(ret){
106 ;
107 }
108 ev_press = 0;
109 return sizeof(key_val);
110
111 //int cnt=0;
112 //unsigned char key_vals[8];
113
114 /*
115 // reading the pins value
116 key_vals[0] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_6)) ? 1 : 0;
117 key_vals[1] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_7)) ? 1 : 0;
118 key_vals[2] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_8)) ? 1 : 0;
119 key_vals[3] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_9)) ? 1 : 0;
120 key_vals[4] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_10)) ? 1 : 0;
121 key_vals[5] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_11)) ? 1 : 0;
122 key_vals[6] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_21)) ? 1 : 0;
123 key_vals[7] = gpio_get_value(IOMUX_TO_GPIO(GPIO3_15)) ? 1 : 0;
124
125 //printk("<0>%04d key pressed: %d %d %d %d %d %d %d %dn",cnt++,key_vals[0],key_vals[1],key_vals[2],key_vals[3],key_vals[4],key_vals[5],key_vals[6],key_vals[7]);
126 */
127 }
128
129 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
130 {
131 printk("<0>function write!nn");
132
133 return 1;
134 }
135
136 static int key_release(struct inode *inode, struct file *filp)
137 {
138 printk("<0>function release!nn");
139 //释放中断
140 free_irq(IOMUX_TO_IRQ(GPIO2_21), &pins_desc[6]);
141 //free_irq(IOMUX_TO_IRQ(GPIO3_15),&pins_desc[7]);
142 free_irq(IOMUX_TO_IRQ(GPIO2_11), &pins_desc[5]);
143 free_irq(IOMUX_TO_IRQ(GPIO2_10), &pins_desc[4]);
144 free_irq(IOMUX_TO_IRQ(GPIO2_9), &pins_desc[3]);
145 //free_irq(IOMUX_TO_IRQ(GPIO2_8), &pins_desc[2]);
146 free_irq(IOMUX_TO_IRQ(GPIO2_7), &pins_desc[1]);
147 free_irq(IOMUX_TO_IRQ(GPIO2_6), &pins_desc[0]);
148 return 0;
149 }
150
151 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
152 {
153 int ret;
154 printk("<0>function ioctl!nn");
155 switch (command) {
156 case key_input:
157 //设置所有的引脚为输入
158 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21));
159 gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15));
160 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));
161 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));
162 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8));
163 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));
164 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6));
165 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7));
166 printk("<0>have setting all pins to gpio input mod !n");
167 //设置GPIO引脚为上拉模式
168 mxc_iomux_set_pad(GPIO2_6, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
169 mxc_iomux_set_pad(GPIO2_7, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
170 //mxc_iomux_set_pad(GPIO2_8, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
171 mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
172 mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
173 mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
174 mxc_iomux_set_pad(GPIO2_21, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
175 //mxc_iomux_set_pad(GPIO3_15, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);
176
177 //设置GPIO引脚中断 ,下降沿触发
178 request_irq(IOMUX_TO_IRQ(GPIO2_6), key_irq, IRQF_TRIGGER_FALLING, "key_GPIO2_6", &pins_desc[0]);