安卓外挂红外触摸屏的软件设计
许海燕, 黄贤立
(淮阴师范学院计算机科学与技术学院 江苏 淮安 223300)
【 摘 要】基于 Android 输入系统开发了 安卓外挂红外触摸屏的驱动软件。 USB 接口的红外触摸屏连接到 A83T 开
发板上,触摸点数据通过安卓 Input 子系统上报。 本文描述了 触摸系统的硬件架构和安卓输入系统的编程体系,给出了 触
屏驱动的主要设计和实现过程。
【关键词】安卓;触摸屏;驱动设计
1 开发背景
红外触摸技术是一种自然的人机交互技术, 利用了 LCD 屏
边沿的红外对管矩阵来检测触摸位置。 红外管发出的脉冲形成
格栅, 手指触摸屏幕会阻断光束, 接收电路探测到光束的损失
便可确定 X 轴与 Y 轴的坐标值。 对于两点以上触摸, 可通过多
轴扫描来处理, 实现真 2 点以上触摸感知。
相比电阻、电容等触摸屏, 红外触摸屏的特点是透光性好,
性价比高, 稳定性好, 对触摸物体无力度、导电等特殊要求。 红
外触摸屏常用接口有 COM 串口和 USB, 其中 USB 接口使用比
较灵活, 可插拔使用。 普通显示器只要外挂一个尺寸相当的触
摸屏, 安装好驱动程序即可使用。
市场上的触摸展示机大多采用 Windows 系统, 其优点是软
件兼容性好, 系统性能较强, 缺点是功耗大, 散热不好, 系统造
价高。 若采用安卓系统, 可克服上述缺点, 大大降低系统造价,
提高系统的稳定性。 安卓系统的触摸系统适合用在对系统性能
要求不高, 功能相对单一的场合。 本文外挂触摸屏选用了 22
寸的 USB 接口触摸屏, 支持 2 点触摸和 USB-HID 规范, Win-
dows7 以上可直接驱动, 不需要专门的驱动程序。 系统主板采用
了全志 A83T 开发板, 安卓版本为 4.4, linux 内核版本为 3.1。 整
个触摸系统架构如图 1 所示。
2 安卓驱动架构
Android 驱动 主要分两种类型: Android 专用驱动 和 An-
droid 使用的设备驱动 (linux), 触摸屏属于 Event 输入设备驱
动。 输入 Input 驱动程序的主设备号是 13, 次设备号是(Event
queue):64~95, 最多有 32 个。Input 子系统的结构如图 2 所示, 分
为三层: 硬件驱动层, 子系统核心层, 事件处理层。
(1) 硬件驱动层负责具体的硬件设备驱动, 本层代码放在
内核中, 是开发工作的核心内容, 按照 GPL 协议, 这部分需要开
源。
(2) 安卓框架部分是上下两个层之间的纽带, 向上提供事
件处理层的接口, 向下提供驱动层的接口, 本部分一般不用修
改。
(3) 最上层应用层负责与用户程序打交道, 将下层传来的
事件报告给用户程序。
3 触屏驱动设计
安卓的 linux3.1.10 版本的内核中自带了 USB 触摸屏驱动,
位置是:
/kernel /drivers /input /touchscreen /usbtouchscreen.c, 添加
的专用触摸驱动也放在这个目录。
3.1 USB 驱动注册
插入 USB 触屏后, 首先进行 USB 设备注册, 入口是:
module_init(usbirtouch_init);
static int __init usbirtouch_init(void)
{
return usb_register(&usbirtouch_driver);
}
这里调用了 USB 注册函数, 需要传入一个 usb_driver 结构
体指针:
static struct usb_driver usbirtouch_driver = {
.name = "USBIRTOUCH",
.probe = usbirtouch_probe, .disconnect = usbir-
touch_disconnect,
.id_table = usbirtouch_id_table,
};
USB 设备驱动 usb_generic_driver 会和 USB 设备交互, 进
行描述符的匹配, 匹配成功后将调用上述结构体中 probe 域中
指定的 probe 函数。 其中的匹配表由 usbirtouch_id_table 指定。
然后将每个接口定义成 device, 加载到 USB 总线。
static struct usb_device_id usbirtouch_id_table[] = {
{USB_DEVICE_HID_CLASS(0x0abf, 0x0011), .driver_info
= DEVTYPE_IGNORE},
{USB_DEVICE_HID_CLASS(0x0abf, 0x0012), .driver_info
= DEVTYPE_IGNORE},
…
};
USB_DEVICE_HID_CLASS 中两个参数, 第 1 个代表厂商
(Vendor)ID, 第 2 个代表产品(Product) ID.
在 probe 函数中, 需要通过 set_bit ()告知 input 子系统可以
报告的事件并初始化触屏参数:
input_dev->evbit [0] = BIT(EV_KEY) | BIT(EV_ABS);
set_bit(BTN_TOUCH, input_dev->keybit);
input_dev->absbit[0] = BIT(ABS_MT_POSITION_X) | BIT
(ABS_MT_POSITION_Y);
set_bit(ABS_MT_PRESSURE, input_dev->absbit);
EV_KEY 表示按键事件, EV_ABS 表示触摸的绝对坐标值,
使用下面 3 个函数进行触屏参数初始化。
input_set_abs_params (input_dev, ABS_MT_PRESSURE,
0,255,0,0);//压力范围和精度
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
32767, 0, 0);//X 值范围和精度
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
32767, 0, 0);//Y 值范围和精度
3.2 触摸数据的上报
利用 urb 上报进行数据上报。 上报前使用 usb_fill_int_urb(
)回调 usbirtouch_irq( )函数进行数据段填充。 主要代码如下:
input_report_abs(dev,ABS_MT_POSITION_X, x);//X 轴
坐标值
input_report_abs(dev,ABS_MT_POSITION_Y, y);//Y 轴
坐标值
input_report_key(dev,BTN_TOUCH,1);//单击
input_mt_sync(dev);
在每个点上报后需要紧跟一句 input_mt_sync()用于不同点
的间隔, 本批触摸点上报完毕使用 input_sync(dev)表示本批次
上报结束。
4 驱动的编译
编写好的需要对内核重新编译, 主要步骤如下 :
(1) 将驱动程序复制到 kernel/driver/input/touchscreen 目 录
下;
(2) 修改 kernel/driver/input/touchscreen 目 录下的 Makefile,
添加
"obj-$(CONFIG_TOUCHSCREEN_USBIRTOUCH_DT)
+= usbirtouchusb-hy.o";
(3) 修改 kernel/driver/input/touchscreen 目 录下的 Kconfig
文件, 增加如下代码
config TOUCHSCREEN_USBIRTOUCH_HY
tristate "IRTOUCH USB Touchscreen Driver For single
point"
depends on USB_ARCH_HAS_HCD
select USB
help
Say Y here if you have a USBIRTOUCH based touch-
screen controller.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called usbirtouch.
(4) 运行 make menuconfig 选择 TOUCHSCREEN_USBIR-
TOUCH_HY 重建内核;
(5)打开目 录/system/core/rootdir 目 录下的 ueventd.rc 文件,
该文件设置驱动挂载到/dev 目录下时的权限和所有者。 添加如
下内容:
/dev/usbirtouch 0666 root root
第 5 步的作用是增加程序访问驱动的权限。 经过上述步骤
编译的内核包含了新 USB 触屏驱动。 如果安卓系统版本高于
4.0, 还要需要将输入设备配置文件(idc)复制到/system/usr/idc 目
录下。
5 触摸屏的校准
由于外挂屏采用了绝对坐标, 安装时也不可能与 LCD 高精
度对准, 需要软件算法进行校准, 其目 标是将物理坐标值转换
为屏幕坐标。 常用的校准算法是 3 点、4 点与 5 点校准, 原理类
似。 校准的数据保存在/dev/usbirtouch 目录下, 但需要此目录的
读写权限。 对于 3 点校准算法使用方程组(1)来表示触摸点的绝
对坐标值与显示设备上匹配点的关系:
X t = (A*X o + B*Y o + C)
Y t = (D*X o + E*Y o + F) (1)
其中(X t , Y t )为转换后得到的显示屏坐标, (X o , Y o )为原始的
触摸屏坐标, A、B、C、D、E、F 为该线性算法的 6 个参数。 代入至
少三个不同点的坐标值 (X o1 ,Y o1 ),(X o2 ,Y o2 ),(X o3 ,Y o3 ),(X t1 ,Y t1 ),(X t2 ,Y t2 ),
(X t3 ,Y t3 )到方程组(2), 得到 6 个方程。
X t1 = (A*X o1 + B*Y o1 + C)
X t2 = (A*X o2 + B*Y o2 + C)
X t3 = (A*X o3 + B*Y o3 + C)
Y t1 = (D*X o1 + E*Y o1 + F)
Y t2 = (D*X o2 + E*Y o2 + F)
Y t3 = (D*X o3 + E*Y o3 + F) (2)
求解方程确定 6 个参数后, 即可利用方程组(1) 计算触摸
点对应的屏幕点的坐标。 将 6 个参数值存入指定文件, 触摸屏
初始化时如果读到校准文件就不需要校准了, 否则提示用户运
行程序校准。 校准程序限制于篇幅不再赘述。
6 结语
本文主要对基于安卓的外挂式红外触摸屏进行了驱动设
计, 实现了 2 点触摸操作, 设计思想可用于其它大屏尺寸的触
摸驱动开发。 由于 Input 输入子系统涉及的知识较多和篇幅受
限, 细节没有过多展开, 未来打算在触摸防抖、抗干扰和提高分
辨率等方面做进一步研究。
参考文献:
[1]许荣斌,谢莹,朱永红.触摸屏校准常用 算法分析[J].工业控制 计算
机,2006. 19(4):77~ 78.
[2]於琪建,张海峰. Linux 输入子系统在触摸屏驱动上的实现[J]. 机电
工程, 2009,26 (3):32~ 34
[3] 王振丽等.Android 底层开发技术实战详解—— —
内 核、移植和驱动[M]. 北京:电子工业出版社,2015.3
[4]石坚, 白瑞林, 邹骏宇, 马涛. Android 多 点触摸屏输入系统的设计
与实现[J]. 计算机工程与应用. 2012(28)
作者简介:
许海燕(1970-),男(汉族),江苏省淮安人,副教授,硕士,研究方向
为物联网和嵌入式开发;黄贤立(1977-),男(汉族),安徽省砀山县人,
副教授,硕士,主要研究方向为机器学习、人机用户界面和生物信息学。