一、使用struct pin_desc 管理按键的值
1.定义结构体
2.将前面我们申请中断时写的(void *)1修改为 &pins_desc[n]
在ioctl中,设置中断中修改
在key_release中释放中修改
3.在中断程序中利用我们定义的struc pins_desc判断并得到按键的值
4.得到按键键值后,唤醒程序,在read函数中返回键值
附上驱动源程序:
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 19 #include 'mx257_gpio.h' 20 #include 'mx25_pins.h' 21 #include 'iomux.h' 22 23 #define Driver_NAME 'key_interrupt' 24 #define DEVICE_NAME 'key_interrupt' 25 26 #define GPIO2_21 MX25_PIN_CLKO 27 #define GPIO3_15 MX25_PIN_EXT_ARMCLK 28 #define GPIO2_10 MX25_PIN_A24 29 #define GPIO2_11 MX25_PIN_A25 30 #define GPIO2_8 MX25_PIN_A22 31 #define GPIO2_9 MX25_PIN_A23 32 #define GPIO2_6 MX25_PIN_A20 33 #define GPIO2_7 MX25_PIN_A21 34 //command 35 #define key_input 0 36 #define version 1 37 //定义各个按键按下的键值 38 struct pin_desc{ 39 unsigned int pin; 40 unsigned int key_val; 41 }; 42 //当按键按下时,键值分别为 以下值 43 struct pin_desc pins_desc[8] = { 44 {GPIO2_6, 0x01}, 45 {GPIO2_7, 0x02}, 46 {GPIO2_8, 0x03}, 47 {GPIO2_9, 0x04}, 48 {GPIO2_10, 0x05}, 49 {GPIO2_11, 0x06}, 50 {GPIO2_21, 0x07}, 51 {GPIO3_15, 0x08}, 52 }; 53 //定义一个全局变量,用于保存按下的键值 54 static unsigned int key_val; 55 56 //interrupt head 57 static DECLARE_WAIT_QUEUE_HEAD(key_interrupt_wait); 58 static volatile unsigned char ev_press; 59 60 static int major=0; 61 62 //auto to create device node 63 static struct class *drv_class = NULL; 64 static struct class_device *drv_class_dev = NULL; 65 66 67 /* 应用程序对设备文件/dev/key_query执行open(...)时, 68 * 就会调用key_open函数*/ 69 static int key_open(struct inode *inode, struct file *file) 70 { 71 printk('<0>function open!nn'); 72 73 return 0; 74 } 75 76 /* 中断程序key_irq */ 77 static irqreturn_t key_irq(int irq, void *dev_id) 78 { 79 struct pin_desc * pindesc = (struct pin_desc *)dev_id; 80 //发生了中断 81 //printk('<0>function interrupt key_irq!nn'); 82 //获取按键键值 83 if(gpio_get_value(IOMUX_TO_GPIO(pindesc->pin))){ 84 /* 按下 */ 85 key_val = pindesc->key_val; 86 }else{ 87 key_val = 0x80 | pindesc->key_val; 88 } 89 printk('<0>get key 0x%x',key_val); 90 ev_press = 1; 91 wake_up_interruptible(&key_interrupt_wait); 92 93 return IRQ_RETVAL(IRQ_HANDLED); 94 } 95 96 97 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp) 98 { 99 int ret; 100 //如果按键没有按下,没有中断,休眠 101 wait_event_interruptible(key_interrupt_wait,ev_press); 102 103 ret = copy_to_user(buff,&key_val,sizeof(key_val)); 104 if(ret){ 105 ; 106 } 107 ev_press = 0; 108 return sizeof(key_val); 109 110 //int cnt=0; 111 //unsigned char key_vals[8]; 112 113 /* 114 // reading the pins value 115 key_vals[0] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_6)) ? 1 : 0; 116 key_vals[1] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_7)) ? 1 : 0; 117 key_vals[2] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_8)) ? 1 : 0; 118 key_vals[3] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_9)) ? 1 : 0; 119 key_vals[4] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_10)) ? 1 : 0; 120 key_vals[5] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_11)) ? 1 : 0; 121 key_vals[6] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_21)) ? 1 : 0; 122 key_vals[7] = gpio_get_value(IOMUX_TO_GPIO(GPIO3_15)) ? 1 : 0; 123 124 //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]); 125 */ 126 } 127 128 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) 129 { 130 printk('<0>function write!nn'); 131 132 return 1; 133 } 134 135 static int key_release(struct inode *inode, struct file *filp) 136 { 137 printk('<0>function release!nn'); 138 //释放中断 139 free_irq(IOMUX_TO_IRQ(GPIO2_21), &pins_desc[6]); 140 //free_irq(IOMUX_TO_IRQ(GPIO3_15),&pins_desc[7]); 141 free_irq(IOMUX_TO_IRQ(GPIO2_11), &pins_desc[5]); 142 free_irq(IOMUX_TO_IRQ(GPIO2_10), &pins_desc[4]); 143 free_irq(IOMUX_TO_IRQ(GPIO2_9), &pins_desc[3]); 144 //free_irq(IOMUX_TO_IRQ(GPIO2_8), &pins_desc[2]); 145 free_irq(IOMUX_TO_IRQ(GPIO2_7), &pins_desc[1]); 146 free_irq(IOMUX_TO_IRQ(GPIO2_6), &pins_desc[0]); 147 return 0; 148 } 149 150 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg) 151 { 152 int ret; 153 printk('<0>function ioctl!nn'); 154 switch (command) { 155 case key_input: 156 //设置所有的引脚为输入 157 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21)); 158 gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15)); 159 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10)); 160 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11)); 161 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8)); 162 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9)); 163 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6)); 164 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7)); 165 printk('<0>have setting all pins to gpio input mod !n'); 166 //设置GPIO引脚为上拉模式 167 mxc_iomux_set_pad(GPIO2_6, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 168 mxc_iomux_set_pad(GPIO2_7, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 169 //mxc_iomux_set_pad(GPIO2_8, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 170 mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 171 mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 172 mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 173 mxc_iomux_set_pad(GPIO2_21, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 174 //mxc_iomux_set_pad(GPIO3_15, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU); 175 176 //设置GPIO引脚中断 ,下降沿触发 177 request_irq(IOMUX_TO_IRQ(GPIO2_6), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_6', &pins_desc[0]); 178 request_irq(IOMUX_TO_IRQ(GPIO2_7), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_7', &pins_desc[1]); 179 request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_9', &pins_desc[3]); 180 request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq, IRQF_TRIGGER_FALLING, 'key_GPIO2_10', &pins_desc[4]);
上一篇:【改进Poll定时查询】IMX257实现GPIO-IRQ中断按键获取键值驱动程序
下一篇:IMX257实现GPIO-IRQ中断按键驱动程序
推荐阅读最新更新时间:2024-11-02 15:04
设计资源 培训 开发板 精华推荐
- LTC2946IMS 电源、电荷和能量监视器在 -48V 恶劣环境中的典型应用,使用 INTVCC 并联稳压器来耐受 200V 瞬态
- 使用 ON Semiconductor 的 ADP3156 的参考设计
- LTC3521 的典型应用 - 1A 降压-升压型 DC/DC 和双路 600mA 降压型 DC/DC 转换器
- DC1996A-C,使用 LTC2323 双通道、14 位、2 Msps 串行高速 SAR ADC 的演示板
- EVB-EP5352QI,带有集成电感器的 EP5352QI 500mA PowerSoC 同步降压稳压器评估板
- 【训练营_基础班】基于STM32F103RBT6的单片机学习板
- Tzduino
- DER-720 - 使用带集成二极管的 HiperPFS-4 的 275 W PFC 前端
- LTC3105EDD 演示板、250mV 启动、升压型 DC/DC 转换器,具有最大电源点控制
- 使用 Semtech 的 EZ1083 的参考设计