判断通关:
实验现象截图,并上传代码
/* 设备树文件: key_int_node{ compatible = "test_key"; interrupt-parent = <&gpx1>; interrupts = <2 0>; }; */ #include <linux/init.h> #include <linux/module.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/of.h> #include <linux/of_irq.h> #include <asm/io.h> #define GPX1CON_ADDR 0x11000c20 #define GPX1_SIZE 8 struct input_dev *pInputdev; int irqno; void* reg_virt_base; int get_irqno_from_node(void) { //获取到设备树中的节点 struct device_node *np = of_find_node_by_path("/key_int_node"); if(np){ printk("find node ok\n"); } else{ printk("find node failed\n"); return 0; } //通过节点去获取到中断号码 irqno = irq_of_parse_and_map(np,0); printk("irqno = %d\n",irqno); return irqno; } irqreturn_t input_key_irq_handler(int irqno, void *devid) { unsigned int GPX1DAT; printk("--------------%s------------------\n",__FUNCTION__); GPX1DAT = readl(reg_virt_base + 4); printk("----------GPX1DAT = %d-----------\n",GPX1DAT); if( GPX1DAT &= 0x1<<2 ){//抬起 printk("__KERN__:Enter up\n"); input_event(pInputdev,EV_KEY,KEY_POWER,0); //上报数据 input_sync(pInputdev); //上报数据结束 } else{//按下 printk("__KERN__:Enter down\n"); input_event(pInputdev,EV_KEY,KEY_POWER,1); //上报数据 input_sync(pInputdev); //上报数据结束 } return IRQ_HANDLED; } static int __init simple_input_dev_init(void) { /* 1,分配一个input device对象 2,初始化input device对象 3,注册input device对象 */ int ret ; pInputdev = input_allocate_device(); if(pInputdev == NULL) { printk(KERN_ERR "input_allocate_device error"); return -ENOMEM; } //当前设备能够产生“按键”类型数据 __set_bit(EV_KEY,pInputdev->evbit); //当前设备能够产生power按键值 __set_bit(KEY_POWER,pInputdev->keybit); pInputdev->name = "button_dev";//随便取个名字 不然会报错 ret = input_register_device(pInputdev); if(ret != 0) { printk(KERN_ERR "input_register_device error"); goto err0; } irqno = get_irqno_from_node(); ret = request_irq(irqno, input_key_irq_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "IRQ_EINT10", NULL); if(ret != 0) { printk("request_irq ERROR!\n"); goto err1; } reg_virt_base= ioremap(GPX1CON_ADDR, GPX1_SIZE); return 0; err1: input_unregister_device(pInputdev); err0: input_free_device(pInputdev); return ret; } static void __exit simple_input_dev_exit(void) { free_irq(irqno,NULL); input_unregister_device(pInputdev); input_free_device(pInputdev); } module_init(simple_input_dev_init); module_exit(simple_input_dev_exit); MODULE_LICENSE("GPL");
[root@farsight ]# ls /dev/input/ event0 [root@farsight ]# insmod simple_input_dev.ko [ 51.361454] simple_input_dev: loading out-of-tree module taints kernel. [ 51.367989] input: button_dev as /devices/virtual/input/input1 [root@farsight ]# ls /dev/input/ event0 event1 [root@farsight ]# [ 24.691143] ----------GPX1DAT = 0----------- [ 24.695394] __KERN__:Enter down [ 24.850114] --------------input_key_irq_handler------------------ [ 24.854734] ----------GPX1DAT = 4----------- [ 24.858985] __KERN__:Enter up
#include <stdio.h> #include <stdlib.h> #include <linux/input.h> #include <fcntl.h> struct input_event *pEvent; int main(int argc, char *argv[]) { int fd,ret; fd = open("/dev/input/event1",O_RDWR); // 地址以及设备文件名需要按实际情况修改 if(fd < 0) { perror("open"); exit(1); } while(1){ ret = read(fd, (void*)pEvent, sizeof(struct input_event)); if(pEvent->type == EV_KEY) //如果产生的是“按键”类型数据 if(pEvent->code == KEY_POWER) //如果按键值是POWER if(pEvent->value) //如果传输的数据大于0 { printf("____APP____:Key up\n"); } else { printf("____APP____:Key down\n"); } } close(fd); return 0; }
[ 5238.782829] --------------input_key_irq_handler------------------ [ 5238.787451] ----------GPX1DAT = 0----------- [ 5238.791703] __KERN__:Enter down [ 5239.004857] --------------input_key_irq_handler------------------ [ 5239.009476] ----------GPX1DAT = 4----------- [ 5239.013728] __KERN__:Enter up [ 5242.390972] --------------input_key_irq_handler------------------ [ 5242.395588] ----------GPX1DAT = 0----------- [ 5242.399839] __KERN__:Enter down [ 5242.609469] --------------input_key_irq_handler------------------ [ 5242.614089] ----------GPX1DAT = 4----------- [ 5242.618341] __KERN__:Enter up