20150303 IMX257 输入子系统(二)之键盘模拟
2015-03-03 李海沿
前面我们已经详细介绍了基本的知识:地址http://www.cnblogs.com/lihaiyan/p/4309329.html
接下来,我们使用IMX257的IO引脚中断+Linux输入子系统实现一个模拟键盘按键。实现的效果是,我们使用IO模拟按键L、按键S和Enter键 这三个按键。
这次我们就不再多废话了,直接上程序,大家看代码:
实验效果图:
如图所示: 我们依次按下三个按键
第一个按键 显示的键值为 38 ,也就是我们的L键
第二个按键 31 自然就是S 键
第三个按键 28 自然就是enter键
驱动代码:
1 /****************************** 2 linux key_inputSystem 3 *****************************/ 4 #include <linux/module.h> 5 #include <linux/init.h> 6 #include <linux/fs.h> 7 #include <linux/interrupt.h> 8 #include <linux/irq.h> 9 #include <linux/sched.h> 10 #include <linux/pm.h> 11 #include <linux/sysctl.h> 12 #include <linux/proc_fs.h> 13 #include <linux/delay.h> 14 #include <linux/input.h> 15 16 #include <mach/hardware.h> 17 18 19 #include "mx257_gpio.h" 20 #include "mx25_pins.h" 21 #include "iomux.h" 22 23 #define Driver_NAME "key_input" 24 25 #define GPIO2_9 MX25_PIN_A23 26 #define GPIO2_10 MX25_PIN_A24 27 #define GPIO2_11 MX25_PIN_A25 28 29 //定义各个按键按下的键值 30 struct pin_desc{ 31 unsigned int pin; 32 char *name; 33 unsigned int key_val; 34 }; 35 //当按键按下时,键值分别为 以下值 36 struct pin_desc pins_desc[3] = { 37 {GPIO2_9, "KEY_L_9", KEY_L}, 38 {GPIO2_10, "KEY_R_10", KEY_S}, 39 {GPIO2_11, "KEY_Enter_11", KEY_ENTER}, 40 }; 41 42 static struct input_dev *key_input_dev;//输入子系统设备结构体 43 static struct timer_list key_timer; //定时器结构体 44 static struct pin_desc *pin_desc_irq; //保存发生中断的引脚信息 45 46 //定时器到时函数 47 static int key_timer_function(unsigned long data){ 48 struct pin_desc *pin_desc_tmp = pin_desc_irq; //发生中断的引脚信息 49 unsigned int pinval_tmp; //按键键值缓冲 50 if(!pin_desc_tmp) 51 return 0; 52 pinval_tmp = gpio_get_value(IOMUX_TO_GPIO(pin_desc_tmp->pin));//获取键值 53 if(pinval_tmp){ 54 //松开 :0 按下:1 55 input_event(key_input_dev,EV_KEY,pin_desc_tmp->key_val ,0); 56 input_sync(key_input_dev); //报告完毕,通知接收者 57 }else{ 58 input_event(key_input_dev,EV_KEY,pin_desc_tmp->key_val ,1); 59 input_sync(key_input_dev); //报告完毕,通知接收者 60 } 61 return 0; 62 } 63 /* 中断程序key_irq */ 64 static irqreturn_t key_irq_function(int irq, void *dev_id) 65 { 66 pin_desc_irq = (struct pin_desc *)dev_id; //获取中断引脚的信息 67 mod_timer(&key_timer,jiffies+HZ/50); //开启定时器,时间20ms 68 69 return IRQ_RETVAL(IRQ_HANDLED); 70 } 71 //初始化函数 72 static int __init key_input_init(void) 73 { 74 printk("<0>\nHello,this is %s module!\n\n",Driver_NAME); 75 76 mxc_request_iomux(GPIO2_9, MUX_CONFIG_ALT5);//设备引脚为GPIO模式 77 mxc_request_iomux(GPIO2_10, MUX_CONFIG_ALT5);//设备引脚为GPIO模式 78 mxc_request_iomux(GPIO2_11, MUX_CONFIG_ALT5);//设备引脚为GPIO模式 79 gpio_request(IOMUX_TO_GPIO(GPIO2_9), "GPIO2_9");//申请IO端口使用 80 gpio_request(IOMUX_TO_GPIO(GPIO2_10), "GPIO2_10");//申请IO端口使用 81 gpio_request(IOMUX_TO_GPIO(GPIO2_11), "GPIO2_11");//申请IO端口使用 82 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));//设备引脚为输入 83 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));//设备引脚为输入 84 gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));//设备引脚为输入 85 //设备引脚为上拉输入 86 mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU); 87 mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU); 88 mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU); 89 //申请中断 90 if(request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq_function, IRQF_TRIGGER_FALLING, "key_GPIO2_9", &pins_desc[0])) 91 return -1; 92 if(request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq_function, IRQF_TRIGGER_FALLING, "key_GPIO2_10", &pins_desc[1])) 93 return -1; 94 if(request_irq(IOMUX_TO_IRQ(GPIO2_11), key_irq_function, IRQF_TRIGGER_FALLING, "key_GPIO2_11", &pins_desc[2])) 95 return -1; 96 97 //input输入子系统设置 98 key_input_dev = input_allocate_device();//分配一个input_dev结构体 99 //设置能产生哪些事件 100 set_bit(EV_KEY, key_input_dev->evbit); //按键事件 101 set_bit(KEY_L, key_input_dev->keybit); // L键 按键 102 set_bit(KEY_S, key_input_dev->keybit); // S键 按键 103 set_bit(KEY_ENTER, key_input_dev->keybit); // ENTER键 按键 104 set_bit(KEY_LEFTSHIFT, key_input_dev->keybit); // LEFTSHIFT键 按键 105 //注册 106 input_register_device(key_input_dev); 107 108 init_timer(&key_timer); //初始化定时器 109 key_timer.function = &key_timer_function; //设置定时器处理函数 110 add_timer(&key_timer); //将该定时器加入内核 111 112 printk("<0>have setting all pins to gpio interrupt mod by IRQF_TRIGGER_FALLING !\n"); 113 printk("Input system initialize successfu!\n\n"); 114 return 0; 115 } 116 //exit 117 static void __exit key_input_exit(void) 118 { 119 printk("<0>\nGoodbye,%s!\n\n",Driver_NAME); 120 /* free gpios */ 121 free_irq(IOMUX_TO_IRQ(GPIO2_9), &pins_desc[0]); 122 free_irq(IOMUX_TO_IRQ(GPIO2_10), &pins_desc[1]); 123 free_irq(IOMUX_TO_IRQ(GPIO2_11), &pins_desc[2]); 124 mxc_free_iomux(GPIO2_9, MUX_CONFIG_ALT5); 125 mxc_free_iomux(GPIO2_10, MUX_CONFIG_ALT5); 126 mxc_free_iomux(GPIO2_11, MUX_CONFIG_ALT5); 127 gpio_free(IOMUX_TO_GPIO(GPIO2_9)); 128 gpio_free(IOMUX_TO_GPIO(GPIO2_10)); 129 gpio_free(IOMUX_TO_GPIO(GPIO2_11)); 130 131 del_timer(&key_timer); //删除定时器 132 input_unregister_device(key_input_dev); //注销驱动 133 input_free_device(key_input_dev); //释放结构体内存 134 printk("Input system unregister successfu!\n\n"); 135 } 136 137 /* 这两行指定驱动程序的初始化函数和卸载函数 */ 138 module_init(key_input_init); 139 module_exit(key_input_exit); 140 141 /* 描述驱动程序的一些信息,不是必须的 */ 142 MODULE_AUTHOR("Lover雪"); 143 MODULE_VERSION("0.1.0"); 144 MODULE_DESCRIPTION("IMX257 key Driver"); 145 MODULE_LICENSE("GPL");
应用程序代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <fcntl.h> 7 #include <termios.h> 8 #include <errno.h> 9 #include <limits.h> 10 #include <time.h> 11 #include <linux/input.h> 12 #include "mx257_gpio.h" 13 14 15 int main(int argc, char **argv) 16 { 17 int fd; 18 int key_value,i=0,count; 19 struct input_event ev_key; 20 21 fd = open("/dev/input/event1",O_RDWR); 22 if(fd < 0){ 23 printf("can't open !!!\n"); 24 exit(1); 25 } 26 printf("open successful!\n"); 27 while(1){ 28 count = read(fd,&ev_key,sizeof(struct input_event)); 29 for(i = 0; i<(int)count/sizeof(struct input_event); i++){ 30 if(EV_KEY == ev_key.type) 31 printf("type: %d ,code: %d ,value: %d \n",ev_key.type, ev_key.code,ev_key.value); 32 if(EV_SYN == ev_key.type) 33 printf("syn event\n\n"); 34 } 35 } 36 close(fd); 37 return 0; 38 }
********************************************
* 博客园: http://www.cnblogs.com/lihaiyan/
* 邮箱:1063385677@qq.com
* QQ: 1063385677
* Copyright ©2014 Lover雪儿
********************************************
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
* 博客园: http://www.cnblogs.com/lihaiyan/
* 邮箱:1063385677@qq.com
* QQ: 1063385677
* Copyright ©2014 Lover雪儿
********************************************
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。