实验12 触摸屏驱动
一、实验目的
1.了解CE下本地设备驱动程序的加载过程 2.掌握WinCE下本地设备驱动程序的设计方法 3.实现本地设备驱动程序的接口函数
二、实验环境
1.软件:PB5.0, UltraEdit文本编辑器 2.硬件:PC,2410实验平台
三、实验内容
1.分析触摸屏驱动程序
2.将现有的触摸屏驱动程序添加进2410的BSP5.0包 3.修改代码,以适用于其他尺寸屏幕的驱动 4.在PB中调试驱动程序代码
四、预备知识
1.熟悉各种配置文件:.reg、.bib、.def、sources、makefile等 2.熟悉PB的使用
3.掌握驱动程序的基本知识
五、实验原理
1. 硬件采样原理(三星自带ADC控制器/触摸屏控制器)
触摸屏一般由4层薄膜组成,其中最主要的就是X层和Y层的薄膜。在点击触摸屏时,X层和Y层会在点击处连接,由此形成了测量通路。如图1所示:
图1:触摸屏原理
当测量X方向电压时(即触摸中断产生时),触摸屏控制器(同时产生触摸中断)控制内部测量电路的切换,在X层形成从X+到X-方向的均匀电势场,而Y层无外加电压。X层在点击处形成电阻分压状态,并与下面的Y层连接形成通路。此时,就可以通过测量Y+或Y-管脚,得到点击处的X方向的电压。反之,可以测量到Y轴方向的电压。于是,形成了坐标点(X,Y)。
2410自带ADC控制器和触摸控制器,A/D通道直接与触摸屏相连。如图2所示:
图2:2410触摸采样原理
触摸控制器切换测量电路,并产生中断;ADC控制器进行采样通道选择。
2.驱动分层
触摸屏驱动程序属于本地设备驱动程序,经过编译生成一个DLL库,并由GWES加载。在WinCE系统中,触摸屏驱动也是一种分层驱动,上层是模型设备驱动程序MDD,下层是依赖平台的驱动程序PDD。如图3所示:
GWESDDI函数设备驱动程序MDD层DDSI函数PDD层图3:驱动分层
当系统访问硬件时,首先通过使用DDI函数与驱动程序交互,然后在驱动程序内部,MDD再通过DDSI函数与PDD进行交互,PDD完成真正的硬件访问操作: DDI接口函数 TouchPanelGetDeviceCaps TouchPanelSetMode TouchPanelSetCalibration TouchPanelCalibrateAPoint TouchPanelPowerHandler TouchPanelEnable TouchPanelDisable TouchPanelReadCalibrationPoint TouchPanelReadCalibrationAbort 3.驱动程序的整体框图
触摸屏驱动的整体框图如图4所示:
初始化DDSI接口(需要填充) DdsiTouchPanelAttach DdsiTouchPanelDetach DdsiTouchPanelDisable DdsiTouchPanelEnable DdsiTouchPanelGetDeviceCaps DdsiTouchPanelGetPoint DdsiTouchPanelGetPoint 需要校准吗?是否校准触摸操作图4:驱动流程整体框图
触摸驱动被加载后,GWES首先执行相关的初始化操作,然后创建一个线程,用来判断采集的点是校准点还是普通的触摸点。无论是校准点还是普通的触摸点,都会把点的坐标和状态信息通过回调函数返回给GWES。GWES根据这些信息,可能进行校准运算(校准点),也可能直接通过消息机制把信息发送给应用程序(非校准点)。 4.初始化
驱动程序的执行,第一步就是初始化,其过程如图5所示:
GWES保存回调函数TouchPanelEnable•调用DdsiTouchPanelEnable 为寄存器分配虚拟地址 申请触摸中断和定时器中断的逻辑中断号•创建事件并关联•创建IST线程并设置优先级线程阻塞,等待中断图5:驱动初始化过程
保存回调函数,以方便返回触摸点的坐标信息和状态信息。接着进入MDD层的TouchPanelEnable函数,在这里检查并初始化所需的gIntrTouch(触摸屏中断)和gIntrTouchChanged(定时器中断),并将中断关联到事件hTouchPanelEvent,当gIntrTouch和gIntrTouchChanged中断产生时都将触发hTouchPanelEvent事件。
初始化阶段的最后一步,就是创建一个IST线程。这个线程是整个驱动程序的唯一事件,用来处理触摸坐标。此线程的主要流程如图6所示:
IST线程触摸事件等待采样换算否校准事件?是回调函数校准处理GWES通信图6:IST线程流程
线程等待触摸事件,判断采集的坐标是否需要校准。同时,利用GWES提供的回调函数,把坐标点和坐标信息返回给GWES。其中,需要与GWES保持通信,一方面可得知采样点是否为校准点,另外一方面可以通知GWES保存校准点数据。 5.GWES处理
GWES读取校准点坐标和信息,进行校准处理。其流程如图7所示:
GWES获取设备信息长和宽光标坐标读取校准点坐标阻塞校准事件直至校准事件触发调用校准函数通信IST
图7:GWES读取校准点坐标和信息
GWES依次显示5个光标,进行校准引导。每次采样一个点。待5点全部采样完成,就开始调用校准函数,求解校准系数。当然,GWES也可以读取非校准状态下采集的点。前提是,这个采样点已经经过换算处理(使用已经求得的校准系数)。 6.触摸处理
驱动中采用了触摸屏中断以及定时器中断两个中断源,不仅可以监控触摸笔按下和抬起状态,而且可以检测触摸笔按下时的拖动轨迹。如果检测到触摸笔按下将产生中断并触发一个事件通知一个工作线程开始采集数据。同时,驱动将打开一个硬件定时器,只要检测到触摸笔仍然在按下状态将定时触发同一个事件通知工作线程采集数据,直到触摸笔抬起后关闭该定时器,并重新检测按下状态。
程序中定义了三个变量,它们分别为:
1) TouchIrq为静态变量或全局变量,且初始值为TRUE,该变量必须在触摸屏按下并产生触摸屏中断时设置为FALSE;
2) InterruptType为静态变量或全局变量,且初始值为SYSINTR_NOP,当在处理触摸屏中断时设置为SYSINTR_TOUCH,在处理定时器中断时设置为
SYSINTR_TOUCH_CHANGED,其余设置为SYSINTR_NOP,且在处理完毕后必须将其作为参数传入InterruptDone函数以清除中断;
3) g_NextExpectedInterrupt为静态变量或全局变量,该变量表示下一个希望产生的中断,初始状态为PEN_DOWN,也就是触摸笔在抬起状态,因此希望下一个产
生的中断为PEN_DOWN。当触摸屏中断产生以及定时器中断产生时该变量为PEN_UP_OR_TIMER,也就是下一个可能产生的状态为触摸笔抬起状态或者触摸笔按下但定时器中断产生。
在DdsiTouchPanelGetPoint中,每个点采样3次,抛弃其中离另两点最远的点,然后求剩下两点平均值。假设采样的三个x方向的值分别为x1、x2、x3,在三个值都小于x方向最大量程前提下,有|x1-x2|、|x2-x3|、|x3-x1|。
if (|x1-x2| < |x2-x3|) {x = x1 + ( (|x3-x1| < |x1-x2|) ? x3 : x2} else {x = x3 + ( (|x3-x1| < |x2-x3|) ? x1 : x2 )} x >>= 1
7.主要函数及主要数据结构 (1)TOUCH_PANEL_SAMPLE_FLAGS
getTouchCoordinate( unsigned channel, unsigned short &sample ) 注释:(回调函数)TOUCH_PANEL_SAMPLE_FLAGS数据结构表示返回到系统的坐标值的属性。函数参数channel表示X坐标、Y坐标或压力值的选择,函数参数&sample表示返回测得的电压值。 (2)extern \"C\" BOOL
TouchDriverCalibrationPointGet( TPDC_CALIBRATION_POINT *pTCP ) 注释:利用屏幕的高和宽来确定中心和四周的坐标值。如果采用不同分辨率的 屏,应该在此修改。
涉及TPDC_CALIBRATION_POINT结构体:
struct TPDC_CALIBRATION_POINT
{
INT PointNumber; INT cDisplayWidth; INT cDisplayHeight; INT CalibrationX; INT CalibrationY; };
参数*pTCP表示结构体变量。
返回值为TRUE代表成功,FALSE表示失败。 (3)extern \"C\" BOOL
DdsiTouchPanelGetDeviceCaps( INT iIndex, LPVOID lpOutput )
注释:查询触摸屏设备的采样频率(决定定时器间隔),并确定校准所需坐标样本数。函数参数iIndex表示查询的项目,函数参数lpOutput表示指向存放返
回信息的内存区域,类型与iIndex对应。 返回值为TRUE代表成功,FALSE表示失败。 其中,调用TouchDriverCalibrationPointGet。 (4)BOOL DdsiTouchPanelEnable( void )
注释:初始化(寄存器分配内存或逻辑中断号申请) (5)void DdsiTouchPanelGetPoint
( TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,INT *pUncalX,INT *pUncalY )
注释:实现对触摸屏数据的采样,获取当前触摸屏位置和状态信息。 调用SampleTouchScreen函数,对三次采样得到的值进行评估,抛弃误差较大的采样数据(见前面的介绍)。
参数pTipStateFlags依然与TOUCH_PANEL_SAMPLE_FLAGS结构有关,记录采样状态。参数pUncalX和pUncalY表示返回原始的坐标电压值。
六、实验步骤(添加驱动代码到BSP包)
1.\\WINCE500\\PLATFORM\\SMDK2410A\\Src\\Drivers下添加Touch文件夹,加入驱动程序源代码文件。同时加入
●SOURCE文件:
TARGETNAME=s3c2440a_touch // 生成的目标文件名
RELEASETYPE=PLATFORM // 使用该类型将使得生成的文件受平台控制 TARGETTYPE=DYNLINK // 生成.dll文件
DLLENTRY=TouchPanelDllEntry // 驱动入口
DEFFILE=$(_COMMONOAKROOT)\\inc\ouch.def // DLL文件的def文件名 TARGETLIBS=$(_COMMONSDKROOT)\\lib\\$(_CPUINDPATH)\\coredll.lib
SOURCELIBS= \\
$(_COMMONOAKROOT)\\lib\\$(_CPUINDPATH)\ch_cal.lib \\ // 校准模块 $(_COMMONOAKROOT)\\lib\\$(_CPUINDPATH)\chmdd.lib // 驱动上层代码
SOURCES=s3c2410_touch.cpp PREPROCESSDEFFILE=1
INCLUDES=$(_TARGETPLATROOT)\\src\\inc;
●MAKEFILE文件
不用修改:!INCLUDE $(_MAKEENVROOT)\\makefile.def
●touch.def文件:指定了需要导出的函数名称
EXPORTS
STDAPI(TouchPanelGetDeviceCaps, 8); STDAPI(TouchPanelEnable,4); STDAPI(TouchPanelDisable,0); STDAPI(TouchPanelSetMode, 8);
STDAPI(TouchPanelReadCalibrationPoint, 8); STDAPI(TouchPanelReadCalibrationAbort, 0); STDAPI(TouchPanelSetCalibration, 20); STDAPI(TouchPanelCalibrateAPoint, 16); STDAPI(TouchPanelPowerHandler, 4);
2.修改\\WINCE500\\PLATFORM\\SMDK2410\\Src\\Drivers下的dirs文件:
DIRS= touch \\ // 增加此项,提示编译touch目录
3.修改\\WINCE500\\PLATFORM\\SMDK2410下的smdk2410.bat文件:
“set BSP_NOTOUCH =1” 改为“set BSP_NOTOUCH = ”,使得SOURCE文件有效。
4.修改\\WINCE500\\PLATFORM\\SMDK2440A\\Files下的platform.bib文件
BIB文件定义操作系统运行时映像中都包括哪些模块和文件,同时,MAKEIMG使用BIB文件来决定如何将这些模块和文件加载到目标设备的存储器中。
●加载驱动模块,即把touch.dll添加到NK镜像中:
MODULES
; Name
Path Memory Type
-----------
; -------------- ----------------------------- IF BSP_NOTOUCH !
touch.dll $(_FLATRELEASEDIR)\ouch.dll NK SH ENDIF BSP_NOTOUCH !
即BSP_NOTOUCH为0时,名为touch.dll的驱动模块被加载进内核。 ●加载校准应用程序
FILES
; Name Path Memory Type ; --------- ------------------------- ----------- calib.exe $(_FLATRELEASEDIR)\\calib.exe NK U
5.修改\\WINCE500\\PLATFORM\\SMDK2410Files下的platform.reg注册表文件
[HKEY_LOCAL_MACHINE\\ControlPanel]
“InputConfig” = dword : 3 // 3 => keybd and touch screen
[HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\TOUCH]
“DriverName” = “touch.dll”
“MaxCalError” = dword : 10 //允许校准次数
“CalibrationData”=“1274,908 2192,171 331,173 346,17 2186,17”
若不想进行触摸校准,可在硬件环境中准确测量到这些值,然后填入。 6.在PB中调试驱动程序
经过以上各种文件的操作和相关的设置,我们可以在PB的“FileView”窗口下看到“touch文件”已经加入:
(a)双击“s3c2410_touch.cpp”文件,在“文本编辑区”看到打开的源代码程序:
(b)编译整个BSP包
(c)修改源代码文件并保存。
注意:如果是“release”版本,请使用“RETAILMSG”函数打印输出调试信息。 (d)编译修改后的文件
右键点击选择“build current project”。 (e)生成镜像(XIP格式)
在PB的“build os”下选择“open release directory”,弹出命令行界面,输入“romimage ce.bib”:
回车后,生成镜像。
在“\\WINCE500\\PBWorkspaces\\s3c2410\\RelDir\\smdk2410_ARMV4I_Release”下可以找到我们需要的各种镜像文件。
(f)下载到开发平台,如果出现错误,则重复以上步骤。
七、实验参考资料
1.基于最小二乘原理建立坐标系方法的研究与实现 2.常用的坐标定位方法 3. S3C2410数据手册
八、实验思考
1.阅读触摸处理相关的代码,给出处理流程。
2.本实验中所涉及的配置文件操作都是必需的吗?为什么?