700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 8.input子系统基础之按键

8.input子系统基础之按键

时间:2019-08-22 03:22:58

相关推荐

8.input子系统基础之按键

转自 /lecturer/505 朱老师物联网大讲堂

《5.linux驱动开发-第5部分-5.8.input子系统基础之按键》

第一部分、章节目录

5.8.1.什么是input子系统

5.8.2.input设备应用层编程实践1

5.8.3.input设备应用层编程实践2

5.8.4.input子系统架构总览1

5.8.5.input子系统架构总览2

5.8.6.输入核心层源码分析1

5.8.7.输入核心层源码分析2

5.8.8.输入事件驱动层源码分析

5.8.9.输入设备驱动层源码分析1

5.8.10.输入设备驱动层源码分析2

5.8.11.中断方式按键驱动实战1

5.8.12.中断方式按键驱动实战2

第二部分、章节介绍

5.8.1.什么是input子系统

本节全面介绍input子系统的概念和来源、解决的主要问题,目的是让大家对linux中输入类设备有一个全面了解

5.8.2.input设备应用层编程实践1

本节实践编写应用层程序,操作键盘和鼠标这些常见input类设备,目的是让大家先学会使用输入类设备,后面再来分析驱动。

5.8.3.input设备应用层编程实践2

本节接着上节对读上来的数据进行解析,分析其规律并且和设备本身特性进行关联分析。

5.8.4.input子系统架构总览1

本节详细介绍input子系统的三层结构以及各层的功能特点。

5.8.5.input子系统架构总览2

本节介绍input子系统下编写驱动的路线和方法。

5.8.6.输入核心层源码分析1

本节分析输入核心层,主要是模块装载和开放给其他层的接口的分析。

5.8.7.输入核心层源码分析2

本节接着分析输入核心层,主要是handler和device的匹配、安装部分的源码分析。

5.8.8.输入事件驱动层源码分析

本节对输入事件层源码分析,主要以evdev.c为例分析了event handler的安装函数、数据上报函数的实现。

5.8.9.输入设备驱动层源码分析1

本节分析输入设备驱动层,以x210自带的按键驱动为例进行分析。

5.8.10.输入设备驱动层源码分析2

本节接着分析按键驱动,主要是一些源码细节探究。

5.8.11.中断方式按键驱动实战1

本节开始按键驱动实战,先找到内核提供的模版,并且对模版程序进行分析讲解。

5.8.12.中断方式按键驱动实战2

本节以模版驱动为基础,结合x210开发板的情况进行驱动移植、编译、测试、修改。

第三部分、随堂记录

5.8.1.什么是input子系统

5.8.1.1、何为输入设备

5.8.1.2、linux中输入设备的编程模型

(1)命令行界面的输入类设备应用接口

(2)GUI界面带来的麻烦、不同的输入类设备也会带来麻烦

(3)struct input_event

5.8.1.3、input子系统简介

(1)linux的input子系统解决了什么问题

(2)input子系统分4个部分:应用层 + input event + input core + 硬件驱动

(3)input子系统如何工作

(4)事件驱动型GUI框架,如QT、VC等。

5.8.2.input设备应用层编程实践1

5.8.2.1、确定设备文件名

(1)应用层操作驱动有2条路:/dev目录下的设备文件,/sys目录下的属性文件

(2)input子系统用的/dev目录下的设备文件,具体一般都是在 /dev/input/eventn

(3)用cat命令来确认某个设备文件名对应哪个具体设备。我在自己的ubuntu中实测的键盘是event1,而鼠标是event3.

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <linux/input.h>#include <string.h>#define DEVICE_KEY"/dev/input/event1"#define DEVICE_MOUSE"/dev/input/event3"int main(void){int fd = -1, ret = -1;struct input_event ev;// 第1步:打开设备文件fd = open(DEVICE_KEY, O_RDONLY);if (fd < 0){perror("open");return -1;}while (1){// 第2步:读取一个event事件包memset(&ev, 0, sizeof(struct input_event));ret = read(fd, &ev, sizeof(struct input_event));if (ret != sizeof(struct input_event)){perror("read");close(fd);return -1;}// 第3步:解析event包,才知道发生了什么样的输入事件printf("%s.\n", (unsigned char *)&ev);}// 第4步:关闭设备close(fd);return 0;}

5.8.2.2、标准接口打开并读取文件

5.8.2.3、解析struct input_event

5.8.3.input设备应用层编程实践2

5.8.3.1、解析键盘事件数据

5.8.3.2、解析鼠标事件数据

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <linux/input.h>#include <string.h>#define DEVICE_KEY"/dev/input/event1"#define DEVICE_MOUSE"/dev/input/event3"#define X210_KEY"/dev/input/event1"int main(void){int fd = -1, ret = -1;struct input_event ev;// 第1步:打开设备文件fd = open(X210_KEY, O_RDONLY);if (fd < 0){perror("open");return -1;}while (1){// 第2步:读取一个event事件包memset(&ev, 0, sizeof(struct input_event));ret = read(fd, &ev, sizeof(struct input_event));if (ret != sizeof(struct input_event)){perror("read");close(fd);return -1;}// 第3步:解析event包,才知道发生了什么样的输入事件printf("-------------------------\n");printf("type: %hd\n", ev.type);printf("code: %hd\n", ev.code);printf("value: %d\n", ev.value);printf("\n");}// 第4步:关闭设备close(fd);return 0;}

5.8.4.input子系统架构总览1

5.8.4.1、input子系统分为三层

(1)最上层:输入事件驱动层,evdev.c和mousedev.c和joydev.c属于这一层

(2)中间层:输入核心层,input.c属于这一层

(3)最下层:输入设备驱动层,drivers/input/xxx 文件夹下

5.8.4.2、input类设备驱动开发方法

(1)输入事件驱动层和输入核心层不需要动,只需要编写设备驱动层

(2)设备驱动层编写的接口和调用模式已定义好,驱动工程师的核心工作量是对具体输入设备硬件的操作和性能调优。

(3)input子系统不算复杂,学习时要注意“标准模式”四个字。

5.8.5.input子系统架构总览2

5.8.6.输入核心层源码分析1

5.8.6.1、核心模块注册input_init

(1)class_register文件夹class那一块,还有udev那一块

(2)input_proc_init文件系统proc那一块

(3)register_chrdev注册字符设备驱动

5.8.6.2、设备驱动层的接口函数

(1)input_allocate_device分配设备号

(2)input_set_capability

(3)input_register_device向上注册

5.8.7.输入核心层源码分析2

5.8.7.1、handler和device的匹配

(1)input_attach_handler

input_match_device 匹配device和handler

handler->connect(handler, dev, id) 连接device和handler

5.8.7.2、事件驱动层的接口函数

(1)input_register_handler这个是dev的爸爸,一个handler匹配或者被匹配多个dev

(2)input_register_handle它负责连接dev和handlr,让父子相认

5.8.8.输入事件驱动层源码分析

5.8.8.1、input_handler

5.8.8.2、evdev_connect

5.8.8.3、evdev_event

5.8.9_10.输入设备驱动层源码分析1_2

5.8.9.1、先找到bsp中按键驱动源码

(1)锁定目标:板载按键驱动

(2)确认厂家提供的BSP是否已经有驱动

(3)找到bsp中的驱动源码

5.8.9.2、按键驱动源码初步分析

(1)模块装载分析

(2)平台总线相关分析

(3)确定重点:probe函数

5.8.9.3、源码细节实现分析

(1)gpio_request

(2)input_allocate_device

(3)input_register_device

(4)timer

5.8.11.中断方式按键驱动实战1

5.8.11.1、模板

(1)input类设备驱动模式非常固定,用参考模版修改即可

(2)新建驱动项目并粘贴模版内容

5.8.11.2、模板驱动的解析

5.8.11.3、着手移植驱动

#include <linux/input.h> #include <linux/module.h> #include <linux/init.h>#include <asm/irq.h> #include <asm/io.h>#include <mach/irqs.h>// arch/arm/mach-s5pv210/include/mach/irqs.h#include <linux/interrupt.h>#include <linux/gpio.h>/** X210:** POWER -> EINT1 -> GPH0_1* LEFT -> EINT2 -> GPH0_2* DOWN -> EINT3 -> GPH0_3* UP-> KP_COL0 -> GPH2_0* RIGHT -> KP_COL1 -> GPH2_1* MENU -> KP_COL3 -> GPH2_3 (KEY_A)* BACK -> KP_COL2 -> GPH2_2 (KEY_B)*/#define BUTTON_IRQIRQ_EINT2static struct input_dev *button_dev;static irqreturn_t button_interrupt(int irq, void *dummy) {int flag;s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0));// input模式flag = gpio_get_value(S5PV210_GPH0(2));s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));// eint2模式input_report_key(button_dev, KEY_LEFT, !flag);input_sync(button_dev);return IRQ_HANDLED; }static int __init button_init(void) {int error;error = gpio_request(S5PV210_GPH0(2), "GPH0_2");if(error)printk("key-s5pv210: request gpio GPH0(2) fail");s3c_gpio_cfgpin(S5PV210_GPH0(2), S3C_GPIO_SFN(0x0f));// eint2模式if (request_irq(BUTTON_IRQ, button_interrupt, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "button-x210", NULL)) {printk(KERN_ERR "key-s5pv210.c: Can't allocate irq %d\n", BUTTON_IRQ);return -EBUSY; }button_dev = input_allocate_device();if (!button_dev) {printk(KERN_ERR "key-s5pv210.c: Not enough memory\n");error = -ENOMEM;goto err_free_irq; }button_dev->evbit[0] = BIT_MASK(EV_KEY);button_dev->keybit[BIT_WORD(KEY_LEFT)] = BIT_MASK(KEY_LEFT);error = input_register_device(button_dev);if (error) {printk(KERN_ERR "key-s5pv210.c: Failed to register device\n");goto err_free_dev; }return 0;err_free_dev:input_free_device(button_dev);err_free_irq:free_irq(BUTTON_IRQ, button_interrupt);return error; }static void __exit button_exit(void) {input_unregister_device(button_dev); free_irq(BUTTON_IRQ, button_interrupt); }module_init(button_init); module_exit(button_exit); MODULE_LICENSE("GPL");MODULE_AUTHOR("aston <1264671872@>");MODULE_DESCRIPTION("key driver for x210 button.");

5.8.12.中断方式按键驱动实战2

5.8.12.1、驱动移植细节

5.8.12.2、驱动实践

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。