按键驱动程序中,如果不使用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]); 



上一篇:【改进信号量】IMX257实现GPIO-IRQ中断按键获取键值驱动程序
下一篇:【改进】IMX257实现GPIO-IRQ中断按键获取键值驱动程序
推荐阅读最新更新时间:2026-03-20 10:58
- 使用 ON Semiconductor 的 FAN2518S 的参考设计
- LTC1530S8、3.3V/3A 稳压器
- 使用 ON Semiconductor 的 ADP3167 的参考设计
- 使用 Analog Devices 的 LT3420EDD 的参考设计
- 基于Kinetis® M的低成本单相电表参考设计
- LTC3708、具有上升/下降轨跟踪功能的 2.5V/15A 和 1.2V/15A 稳压器
- NXQ1TXH5插件板
- 应变仪仪表放大器
- WRL-13287,基于 ESP8266 802.11 无线局域网的 SparkFun Wi-Fi Shield
- 4.1W、3-LED 通用 LED 照明驱动器



嵌入式系统技术与设计
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号