diff --git a/20_input/.vscode/c_cpp_properties.json b/20_input/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..79c6d19a12c235b7345b1cdd14efbde03c2b4f75 --- /dev/null +++ b/20_input/.vscode/c_cpp_properties.json @@ -0,0 +1,50 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "linux-gcc-x64", + "browse": { + "path": [ + "${workspaceFolder}", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ] + } + }, + { + "name": "Win32", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "C:/Qt/Qt5.12.9/Tools/mingw730_64/bin/gcc.exe", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 +} diff --git a/20_input/.vscode/settings.json b/20_input/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..1a2a04ac7a2d6b080404235adcd34b94bc581cb4 --- /dev/null +++ b/20_input/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + } +} \ No newline at end of file diff --git a/20_input/Makefile b/20_input/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6cac2dd391fea48c029d89c6067dd60870160201 --- /dev/null +++ b/20_input/Makefile @@ -0,0 +1,13 @@ +KERNELDIR := ../../../linux-imx-rel_imx_4.1.15_2.1.0_ga +CURRENT_PATH := $(shell pwd) +obj-m := keyinput.o + +build: kernel_modules + +kernel_modules: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules + +clean: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean + + diff --git a/20_input/keyinput.c b/20_input/keyinput.c new file mode 100644 index 0000000000000000000000000000000000000000..b7d9a800e1e6a773d2d0cfaf0070ba50733c9524 --- /dev/null +++ b/20_input/keyinput.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KEYINPUT_CNT 1 +#define KEYINPUT_NAME "keyinput" +#define KEY0VALUE 0X01 +#define INVAKEY 0XFF +#define KEY_NUM 1 + +struct irq_keydesc { + int gpio; /* gpio */ + int irqnum; /* 中断号 */ + unsigned char value; /* 按键对应的值 */ + char name[10]; /* 名字*/ + irqreturn_t (*handler)(int, void *); /* 中断服务函数*/ +}; + + +struct keyinput_dev +{ + dev_t devid; /* 中断号 */ + struct cdev cdev; /* cdev */ + struct class* class; /* 类 */ + struct device* device; + struct device_node* nd; + struct timer_list timer; + struct irq_keydesc irqkeydesc; /* 案件描述组 */ + unsigned char curkeynum; /* 当前的按键号 */ + struct input_dev* inputdev; /* input结构体 */ +}; + +struct keyinput_dev keyinputdev; + + +void timer_function(unsigned long arg) +{ + unsigned char value; + unsigned char num; + struct irq_keydesc* keydesc; + struct keyinput_dev* dev = (struct keyinput_dev*)arg; + + num = dev->curkeynum; + keydesc = &dev->irqkeydesc; + value = gpio_get_value(keydesc->gpio); + + if (value == 0) + { + input_report_key(dev->inputdev, keydesc->value, 1); + input_sync(dev->inputdev); + } + else { /* 按键松开 */ + input_report_key(dev->inputdev, keydesc->value, 0); + input_sync(dev->inputdev); + } + +} + +irqreturn_t key0_handler(int irq, void* dev_id) +{ + struct keyinput_dev *dev = (struct keyinput_dev *)dev_id; + + dev->curkeynum = 0; + dev->timer.data = (volatile long)dev_id; + mod_timer(&dev->timer, jiffies + msecs_to_jiffies(10)); + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void keyio_init(void) +{ + int ret = 0; + keyinputdev.nd = of_find_node_by_path("/key"); + if (keyinputdev.nd == NULL) + { + printk("key node not find!\r\n"); + return -EINVAL; + } + + keyinputdev.irqkeydesc.gpio = of_get_named_gpio(keyinputdev.nd, "key-gpio", 0); + if (keyinputdev.irqkeydesc.gpio < 0) + { + printk("can't get key0"); + } + + /* 初始化key所使用的IO,并且设置成中断模式 */ + memset(keyinputdev.irqkeydesc.name, 0, sizeof(keyinputdev.irqkeydesc.name)); + sprintf(keyinputdev.irqkeydesc.name, "key0"); + gpio_request(keyinputdev.irqkeydesc.gpio, keyinputdev.irqkeydesc.name); + gpio_direction_input(keyinputdev.irqkeydesc.gpio); + keyinputdev.irqkeydesc.irqnum = irq_of_parse_and_map(keyinputdev.nd, 0); + + /* 申请中断 */ + keyinputdev.irqkeydesc.handler = key0_handler; + keyinputdev.irqkeydesc.value = KEY_0; + + ret = request_irq(keyinputdev.irqkeydesc.irqnum, + keyinputdev.irqkeydesc.handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + keyinputdev.irqkeydesc.name, &keyinputdev); + if (ret <0) + { + printk("irq %d request failed !\r\n", keyinputdev.irqkeydesc.irqnum); + return -EFAULT; + } + + /* 创建定时器 */ + init_timer(&keyinputdev.timer); + keyinputdev.timer.function = timer_function; + /* 申请input_dev */ + keyinputdev.inputdev = input_allocate_device(); + keyinputdev.inputdev->name = KEYINPUT_NAME; + keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0); + + /* 注册输入设备 */ + ret = input_register_device(keyinputdev.inputdev); + if (ret) + { + printk("register input device failed!\r\n"); + return ret; + } + return 0; +} + +static __init keyinput_init(void) +{ + keyio_init(); + return 0; +} + +static __exit keyinput_exit(void) +{ + +} + +module_init(keyinput_init); +module_exit(keyinput_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("zhangchaoliang"); diff --git a/20_input/keyinput.code-workspace b/20_input/keyinput.code-workspace new file mode 100644 index 0000000000000000000000000000000000000000..213b97eda2a31e237f92d85a05c7209217d83dfc --- /dev/null +++ b/20_input/keyinput.code-workspace @@ -0,0 +1,14 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.associations": { + "ide.h": "c", + "init.h": "c" + } + + } +} \ No newline at end of file diff --git a/20_input/keyinputApp.c b/20_input/keyinputApp.c new file mode 100644 index 0000000000000000000000000000000000000000..d49d43cd45998e93c00ca8cf7d7c90a7bf1c2d90 --- /dev/null +++ b/20_input/keyinputApp.c @@ -0,0 +1,60 @@ +#include "stdio.h" +#include "unistd.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "fcntl.h" +#include "stdlib.h" +#include "string.h" +#include +#include +#include +#include +#include +#include + +static struct input_event inputevent; + + +int main(int argc, char *argv[]){ + int fd; + int err = 0; + char *filename; + + filename = argv[1]; + + if (argc !=2 ) + { + printf("Error Usage!\r\n"); + return -1; + } + + fd = open(filename, O_RDWR); + if (fd <0) + { + printf("Can't open file %s \r\n", filename); + return -1; + } + + while(1){ + err = read(fd, &inputevent, sizeof(inputevent)); + if (err >0) + { + switch (inputevent.type) + { + case EV_KEY: + if (inputevent.code < BTN_MISC) + { + printf("key %d %s \r\n",inputevent.code, + inputevent.value ? "press" : "release"); + } + break; + + default: + break; + } + }else { + printf("读取数据失败\r\n"); + } + } + return 0; +}