06.输入系统第:10课第19节_输入系统_多点触摸驱动程

该小节我们开始讲解多点触摸屏的驱动层。我们的驱动只需要上报多个触点的位置就可以了。

应用程序一般会使用open,read,write,ioctl等访问驱动程序,最简单的方法就是我们在驱动程序中也实现对应的函数,在linux中存在一个输入子系统,以上的函数,在驱动层,其已经帮我们实现了,我们只需要实现硬件相关的那比部分即可。

比如有数据时,上报数据(上报给输入子系统)。前面提到驱动程序需要提供open,read,write,ioctl等函数,那么在输入子系统中,谁来提供该函数呢?其核心在SDK/kernel/input.c与SDK/kernel/evedv.c(内核源码)文件中。

在evedv.c文件中:

static const struct file_operations evdev_fops = {
	.owner		= THIS_MODULE,
	.read		= evdev_read,
	.write		= evdev_write,
	.poll		= evdev_poll,
	.open		= evdev_open,
	.release	= evdev_release,
	.unlocked_ioctl	= evdev_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= evdev_ioctl_compat,
#endif
	.fasync		= evdev_fasync,
	.flush		= evdev_flush,
	.llseek		= no_llseek,
};

我们可以找到以上文件描述符,那么这个文件描述符是在哪里注册的呢?在文中查找evdev_fops,可以找到:

/*当有输入设备接入的时候,调用该函数*/
static int evdev_connect(struct input_handler *handler, struct input_dev *dev,const struct input_device_id *id)
	/*获取一个新的次设备号*/
	minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
	/*绑定文件描述符*/
	cdev_init(&evdev->cdev, &evdev_fops);
	/*生成设备节点*/
	error = device_add(&evdev->dev);

这样就完成了input驱动设备的注册。那么evdev_fops中的函数,他怎么获得数据呢?这些就是和硬件相关的操作了,也就是我们需要去编写的驱动程序

一般来说步骤如下:
1.构造input_device
2.设置input_device
3.注册input_device
4.有数据时,调用input_event函数上报数据,该函数会把数据放到evdev_fops->read的buffer中。

假设应用程序调用open函数,打开了某个输入设备节点,然后其read函数被调用,在没有数据的时候,其会处于阻塞状态。当我们按下,或者点击触摸屏的时候,会产生某个中断,在中断中,从硬件获取数据,调用input_event上报,input_event会把数据放在read的buffer中,同时唤醒休眠的应用程序。

下面我们来对比一下单点触摸(电阻屏),和多点触摸(电容屏)的区别。

单点触摸(电阻屏):
	按下上报:BTN_TOOCH,1
	滑动:循环上报ABS_X(X坐标),ABS_Y(Y坐标),ASB_PRESSORE(压力值),BTN_TOOCH为1。
	松开上报:BTN_TOOCH,1
多点触摸:
	在一个时刻有几个点,就上报几个点(即在循环上报所有触点位置)。一般来说,有两中上报方式:
	a:直接上报触电
	b.上报触电,以及触点之间的关系(如是否为同一划痕)

下面是设置多点触摸上报事件类型设定,以及上报数据的例子:
类型设定:

	input_set_abs_params(input_device,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
	input_set_abs_params(input_device,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
	input_set_abs_params(input_device,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
	input_set_abs_params(input_device, ABS_MT_PRESSURE, 0, 255, 0, 0);

上报数据:

扫描二维码关注公众号,回复: 5708639 查看本文章
	input_report_abs(ts->input, ABS_MT_PRESSURE, id);//id可以理解为是否为同一划痕
	input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 1);
	input_report_abs(ts->input, ABS_MT_POSITION_X, x);
	input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
	input_mt_sync(ts->input);

光说不练是没有作用的,下小节我们开始进入实战,编写电容屏驱动程序的框架。

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/88592990