linux Input驱动子系统源码学习

10 篇文章 0 订阅
1 篇文章 0 订阅

前言

公司要搞什么input子系统介绍,上层应用被人讲完了,花了半天时间看了下源码。
于是乎有了点总结给大家介绍一下input驱动子系统。
总的来说input还算是非常简单的那种类型,阅读过程中没有太大的障碍.

一. 讲解内容介绍

初始化流程

打开与读数据的流程

二. 模块功能划分与介绍

  1. input(input.c):抽象了输入设备驱动与输入设备管理驱动的交互
  2. handler(evdev.c):管理某一类输入设备的驱动
  3. device(gpio_keys.c):特定输入类型的设备驱动

三. input子系统初始化

input初始化

input.c:
初始化级别为5, subsys_initcall

1. class_register: 创建/sys/class/input目录
2. input_proc_init:
	proc_mkdir: 创建/proc/bus/input目录
	proc_create: 创建/proc/bus/input/devices 节点
	proc_create: 创建/proc/bus/input/handler 节点

3. register_chrdev_region: 创建主设备号13,类型为input的设备节点
			次设备号范围为64~(64+32-1)


关注知识点 :*input下的输入设备通过input_register_handler注册到input中*

handler初始化

evdev.c(按键输入的设备类型):
初始化级别为6,module_init

1. 调用input_register_handler注册(struct input_handlers)handlers到input子系统中:
	注册时会查找是否有匹配的(struct input_dev)device(肯定无)

device初始化

keyboard.c:
初始化级别为7,late_initcall

1. 创建(struct input_dev)input_dev,并调用input_register_device将input_dev注册到input子系统中
	注册时会查找是否有匹配的(struct input_handler)handler(肯定有,无则异常)

2. 如果匹配,则会调用handler.connect接口
	evdev_connect接口:
	创建一个(struct evdev)evdev设备。
	evdev中则有一个(struct input_handle)handle成员
	(struct handle)handle成员即保存(struct handler)handler又保存(struct input_dev)device.
	将handle->d_node加入到handle->dev->h_list中
	将handle->h_node加入到handle->handler->h_list中
备注:目的时为了让intput_dev和handler能够通过自身的h_list找到handle,从而通过handle找到绑定的另一方


3. 调用device_initialize和device_add初始化(struct device)evdev->dev设备对象(该dev设备对象依赖于keyboard.c创建的device设备对象input_dev->dev)
4. 调用cdev_init和cdev_add初始化(struct cdev)evdev->cdev字符设备对象,同时添加了设备节点的操作函数
备注:在这里于是会创建/sys/class/input/eventx,/dev/input/eventx节点,若次设备号为64,则对应的时event0

四. 操作流程

open声明:

int open(struct inode *inode, struct file *file);

open实现:

	通过inode->i_cdev的地址获取evdev对象(因为evdev包含cdev对象)
	新建一个evdev_client,并将evdev_client指向evdev,然后file->private_data = evdev_client
	调用evdev_open_device(evdev->handle)去调用keyboard.c中赋值给input_dev->open的函数

read声明:

ssize_t read(struct file *file, char __user *buffer, size_t count, loff_t ppos);

read实现:

	通过file获取到evdev对象
	并调用wait_event_interruptible(evdev->wait)进入等待,等待有数据到来时唤醒

终端产生数据并唤醒:keyboard.c

终端触发以后,获取到evdev对象并调用input_event接口通知input子系统
(input_event内部调用的(struct handler)handler->event函数)
edev_event回调中evdev_pass_value的时候,
evdev_pass_value会调用wake_up_interruptible(evdev->wait)唤醒read中的等待
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值