接下来,我们使用IMX257的IO引脚中断+Linux输入子系统实现一个模拟键盘按键。实现的效果是,我们使用IO模拟按键L、按键S和Enter键 这三个按键。
这次我们就不再多废话了,直接上程序,大家看代码:
实验效果图:
如图所示: 我们依次按下三个按键
第一个按键 显示的键值为 38 ,也就是我们的L键
第二个按键 31 自然就是S 键
第三个按键 28 自然就是enter键
驱动代码:
1 /******************************
2 linux key_inputSystem
3 *****************************/
4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 16 #include 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!nn',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!nn'); 114 return 0; 115 } 116 //exit 117 static void __exit key_input_exit(void) 118 { 119 printk('<0>nGoodbye,%s!nn',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!nn'); 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 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 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 eventnn'); 34 } 35 } 36 close(fd); 37 return 0; 38 }
上一篇:块设备驱动程序
下一篇:IMX257 输入子系统
推荐阅读最新更新时间:2024-11-21 18:59
设计资源 培训 开发板 精华推荐
- SiM3L1xxLCD-B-DK,统一开发平台(UDP)依赖于SiM3L1XX LCD MCU卡
- 铝基板热床 Bed 1-0.127-100
- 使用 IXYS 的 CPC9909 的参考设计
- LTC1261LCS8 5V 输入、-4V 输出 GaAs FET 偏置发生器的典型应用电路
- 使用 MIC4575 的典型应用电路,可切换电池组充电器
- FPAB30BH60前端整流智能功率模块(SPM)典型应用电路
- MDB-JS Board:自动售货机物联网改造板
- ADP2504-5.0-EVALZ,用于 ADP2504ACPZ-5.0-R7、1A、5V 降压升压转换器的评估板
- TWR-P1025,用于 P1025 QorIQ P1 MPU 处理器的开发塔式系统模块,具有网络和工业连接以及协议卸载引擎
- 使用 ON Semiconductor 的 NCP100 的参考设计