NG102车载信息系统
串口触摸屏设计文档
项目名称:NG102车载信息系统
编 号:
拟 制:
审 核:
批 准:
文件修改控制页
日期 |
版本号 |
修订说明 |
修订人 |
审核人 |
2012-02-01 |
V0.1 |
初稿 |
|
|
2012-02-07 |
V0.2 |
根据评审结果修改 |
|
|
2012-09-26 |
V0.3 |
根据代码的实际结果修改 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1引言 4
1.1背景 4
1.2串口触摸屏驱动简介 4
2设计 4
2.1总体设计 4
2.2需求规定 6
3接口设计 7
3.1和linux系统的input子系统的接口 7
3.2和底层串口的接口 7
4运行设计 7
4.1驱动初始化 7
4.2停止驱动 7
4.3串口号的集成 7
4.4和应用层的接口 7
4.5触摸屏数据分析 8
NG102作为车载信息系统,采用Android2.3操作系统。串口触摸屏驱动作为NG102系统的子模块,连接显示屏幕和载板。本文主要描述串口触摸屏驱动的软件功能设计。
串口触摸屏驱动主要是采用linux系统的input子系统功能,由于Android系统内置采用input输入系统,故串口触摸屏驱动在linux操作系统移植成功后,对android系统将不用任何修改,直接使用。
当然,在串口触摸屏驱动可以使用前,前提就要求底层的串口驱动已经写完而且可以正常工作,否则串口触摸屏驱动就无从谈起了。
Android下的用户输入系统框架
从图中可以看出,android是直接使用linux系统的input子系统的,就是说android的整个触摸屏/键盘的处理框架可以看成是linux系统的一个大的应用程序。
由于linux本身已经支持串口触摸屏驱动的整个框架了,这样我们要做的就是根据我们自己的触摸屏串口数据传输协议,适配到input系统中即可。
linux下的用户输入系统框架
串口触摸屏驱动基于linux现有的input子系统设计,参考原有的串口触摸屏驱动touchit213/touchright/touchwin进行修改,根据我们自己的触摸屏串口协议修改,首先给出整个input子系统的框架图如下:
我们处理的是InputDriver层,在这层适配成我们的触摸屏设备,上面部分都可以使用linux系统自带的(包括android部分),这样可以提高开发速度。
输入子系统数据结构
对于输入子系统,linux提供了完整的框架,其数据结构是完整而且正确的,下面我们给出其数据结构图:
适配我们的触摸屏到linux/android系统的触摸屏驱动中。
采用标准的驱动模型,即用用一个标准的InputDriver层内核模块实现。
采用串行总线(serio_bus,注意不是串口)驱动模型,即注册函数用serio_register_driver,反注册函数用serio_unregister_driver,获取数据用serio_get_drvdata函数,当收到串口数据分析出触摸屏信息后通过input_report_abs函数向上层汇报。
驱动名称直接采用linux内置的touch213驱动,在其基础上进行修改这样可以省去增加配置文件的脚本。
底层串口采用tty模型,驱动通过tty_register_ldisc向tty注册了N_MOUSE行规程处理接口,从而可以通过receive_buf函数收取底层串口读到的数据,再向上层汇报。
简单调用serio_register_driver进行注册。
简单调用serio_unregister_driver进行反注册。
当所有的驱动程序起来后,最后还需要配置一个串口端口作为触摸屏的数据,让这个端口的数据会自己送到触摸屏规程中,从而达到我们的input子系统的驱动层中。
这个功能需要由应用程序完成,目前由于背光调节服务使用了同样的串口,而且其必须长期打开该串口进行工作,故这里把功能放入该模块中完成,使用tty_ioctl(TIOCSETD)来完成对串口端口的规程的切换,从而到达我们input子系统,该程序伪代码如下:
intOpenLdiscChannel(char *pSerialPort)
{
//打开串口端口设备/dev/ttySxx
//设置串口的基本属性(波特率/数据位等)
//调用tty_ioctl(TIOCSETD…)切换规程
return 0;
}
对于在应用层使用input接口的程序(比如android系统)来说,他们是直接使用open打开input文件来使用input接口的,比如open(“/dev/input/mouse0”);
这个接口层的实现,是事件处理层完成的,对于串口触摸屏来说是通过mousedev.c文件来处理的,这个是系统完成的,我们无需修改。但是我们必须和这个功能能可以匹配起来,就是说当用户open(“/dev/input/mouse0”)的时候可以关联到我们的驱动来,这个是通过串行设备匹配表serio_device_id来完成的。详情可以参见input_match_device函数,对于触摸屏来说主要是evbit要加入EV_ABS(绝对坐标),在掩码字段absbit要加上ABS_X/ABS_Y两个掩码值。
由于触摸屏底层串口可能传输多种协议,故而需要定义一个通用的传输层同步头,用分层方式实现串口协议,鉴于触摸屏硬件是我们自己定义的,我们这里触摸屏部分的数据包将参考touch213的协议做微小修改来实现,这样在驱动层的修改会达到最小,而触摸屏芯片的工作量基本不变,下面给出数据分析伪代码:
staticirqreturn_t touchit213_interrupt(struct serio *serio,
unsignedchar data, unsigned int flags)
{
//根据串口传输协议分解出触摸屏部分的数据包
//对触摸屏部分的数据包进行解析,解析触摸屏的x,y坐标
//如果需要,根据linux系统触摸屏定义的协议进行简单的格式转换
//根据input子系统的接口要求调用input_report_abs等函数向上层报告
returnIRQ_HANDLED;
}