android TP驱动移植调试笔记

1. 添加I2C 设备

TP 一般采用的是I2C 作为数据和命令接口,所以TP 驱动也可以归类为I2C 驱动。TP驱动的主要逻辑不在这里,但是了解了Linux 的I2C 体系架构,就可以对整个驱动流程有了

更加清晰的认识,但这里不详细展开讨论I2C 的体系架构,只围绕怎么移植开发TP 驱动展开讨论。

在板级文件中,也就是瑞星微的代码文件board-rk30-sdk.c 中,实例化一个i2c_board_info结构体,该结构抽象描述一个具体的i2c 设备,然后将该实例添加到__i2c_board_list 全局链表中。举个实例:

#if defined (CONFIG_TOUCHSCREEN_PIXCIR)

{

.type = "pixcir_ts",

.addr = 0x5c,

.flags =0,

.irq = RK30_PIN4_PC2,

.platform_data = &pixcir_info,

},

#endif

了解I2C 体系架构的应该都知道,Linux 系统在能成功找到I2C adapter 之后,也就是找到I2C 控制器之后,就会扫描__i2c_board_list 这个链表,每找到一个i2c_board_info,就会生成一个i2c_client,i2c_client 的部分信息来自于i2c_board_info,一部分来自于i2c_adapter。i2c_client 就表示一个真真切切的i2c 设备,因为它既有描述它基本属性的信息,也有描述它行为的方法,通俗的说就是I2C 的传输方法。

现在我们可以回过头来详细说说前面的提到的i2c_board_info结构体中各个成员的意义了。type成员用来赋给后来生成的i2c_client中的name成员,i2c_client中的name就表示这个i2c_client的名字。addr是这个i2c设备的地址,它和I2C控制器一起表示表示这个i2c设备,假如我们的TP是挂载在控制器0上,那么0-005c则表示是这个i2c设备,0-005c我们也可以在sys系统里面找到。Flag是i2c读写的标志,为0表示为写,1表示读。Irq是这个i2c设备的中断脚。Platform_data是在驱动注册时用到。

 

2. 添加I2C驱动

熟悉Linux设备驱动模型的人都了解设备,驱动,总线的关系,上面我们讲的是设备,光有设备不行,还得有驱动。一般TP供应商都会有驱动提供给我们,这里我们以瑞星微SDK中的pixcir_i2c_ts.c来作个例子。

第一步是添加i2c驱动:

i2c_add_driver(&pixcir_i2c_ts_driver);

这里就不展开讨论这个函数了,pixcir_i2c_ts_driver的定义如下:

static struct i2c_driver pixcir_i2c_ts_driver = {

.driver = {

.owner = THIS_MODULE,

.name = "pixcir_i2c_ts_v3.3.09",

#ifdef PIX_DRV_ATTR

.groups = pixcir_drv_grp,

#endif

},

#ifndef CONFIG_HAS_EARLYSUSPEND

.suspend = pixcir_i2c_ts_suspend,

.resume = pixcir_i2c_ts_resume,

#endif

.probe = pixcir_i2c_ts_probe,

.remove = __devexit_p(pixcir_i2c_ts_remove),

.id_table = pixcir_i2c_ts_id,

};

按照Linux设备驱动模型,一旦总线上有新的驱动加入,则系统会自动去搜索挂载在这个总线上的所有设备,然后拿每个设备的name跟驱动的id_table比较,如果两个的名字一样,那么接下来就会执行驱动里面的probe函数。

 

3. TP驱动中的Probe

无论是什么样的TP驱动,在probe中不外乎就做以下几件事情:

1) 申请TP相应的IO口,然后重启一下设备

2) 申请TP中断,熟悉Linux中断的人都应该知道中断的顶半部和底半部机制,于是要申请一个工作队列和初始化一个工作任务。

INIT_WORK(&tsdata->work.work, pixcir_ts_poscheck);

pixcir_wq = create_singlethread_workqueue("pixcir_wq");

TP的数据上报流程是,当人手按下的时候,TP则产生一个中断,在中断服务程序中,将数据读出并且通过输入子系统将数据上报给操作系统。

3) TP在硬件上通过I2C接口告诉人们它的数据,在软件上则是通过输入子系统告诉操作系统它的数据,而使用输入子系统的第一步则是申请一个输入子设备:

input_allocate_device();

这里不详细展开讨论这个函数里面的东西了,输入子系统通信的基本单位是事件,事件有三种属性:类型(type),编码(code),值(value)。输入子系统支持很多种事件,很多种事件编码,所以在使用输入设备前,要先设置这个设备支持何种类型的事件,何种事件编码。

4)一般的TP驱动支持的是以下几种事件

__set_bit(EV_KEY, input->evbit);

__set_bit(EV_ABS, input->evbit);

__set_bit(EV_SYN, input->evbit);

5)确定多点触摸的协议。多点触摸的协议有A协议跟B协议之分。A类在每次报点后加 input_mt_sync(touch_dev->input_dev);

   B类需要在probe中执行input_mt_init_slots(ts->input_dev, ts->max_touch_num);再在每次报点前input_mt_slot(ts->input_dev, index);

6) 向输入子系统注册设备:

input_register_device(ts->input_dev);

 

4. 触摸屏调试常见问题参考:

1)在加载了驱动后,解不了锁。

可以先用USB鼠标解锁。如果可以用adb的话,也可以直接用adb shell input keyevent 82解锁

2)点击屏幕没反应

确定i2c设备供电正常,确定probe被执行了没,如果被执行了,再确定IO有没有先进行初始化,有没有重启设备,再确定I2C通不通,点击屏幕能否进入中断。

3)probe没被执行。检查i2c_board_info终端的type成员定义是否跟i2c_driver中的id_table一样。

4)I2C不通。检查供电正常否,有没有重启设备,i2c地址有没有错误,有的i2c设备是用7位,有的是用8位,8位的则必须右移一位

5)最常发生的问题,TP的报点不对。

这个问题到目前为止还没总结出一个方法论。个人调试经验以为,这个跟LCD的分辨率,TP的分辨率,输入子系统设置都有关系。

先讨论一个对例子确定屏幕的分辨率,假如分辨率为800 * 1280,那么应该是下图的样子:

 

 

  

 

  

图表 1 LCD屏幕表示图

假如TP的分辨率也是800 * 1280

  

  

 

 

  

图表 2 TP分辨率表示图

如上面两幅图所示,LCDTP的分辨率是一样的,并且原点一样,假如这时输入子系统参数设置为:

    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, 800, 0, 0);

    input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, 1280, 0, 0);

那么此时上报的点应该是不用经过任何转换的,也就是说上报的点是对的。

我们再讨论另外一种情况,假如TP的分辨率为:

  

 

 

 

  

图表 3 TP分辨率标示图

 

值得一提的是,TPxy轴可以互换,但是原点是不会变化的。如图3TP跟图1LCD,由于LCD的原点跟TP的原点不一样,那么上报的点则必须经过驱动转换。转换的公式为:

X=800 - y1

Y=x1;

6)如何找LCD原点跟TP原点。

LCD原点应该是在系统没做任何翻转之前,在系统点亮的时候,小企鹅出现的地方

TP的原点,应该是在TP驱动里xy没经过逻辑转换之前,用printk打印出点信息。


  • 0
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是Android TP驱动学习文档: ## 1. 驱动代码原理 Android TP驱动主要涉及以下几个方面: ### 1.1 输入子系统 输入子系统是Android系统中用于处理和管理输入设备的一个子系统,包括设备驱动程序、输入事件的生成和处理、输入设备的注册和注销等功能。输入设备的驱动程序需要实现input_dev结构体中的各个方法,如probe、remove、open、close、ioctl、read、poll、event等。 ### 1.2 触摸屏控制器 触摸屏控制器是一个独立的芯片,通过I2C、SPI或USB等接口与主处理器相连,用于接收触摸屏的输入信号并将其转换成数字信号。触摸屏控制器的驱动程序需要实现input_dev结构体中的event方法,将触摸屏的输入事件发送到输入子系统中。 ### 1.3 触摸屏传感器 触摸屏传感器是一个透明的薄膜,在触摸屏上覆盖一层,用于检测用户的触摸输入,并将其转换成电信号。触摸屏传感器包括电阻式触摸屏、电容式触摸屏、表面声波式触摸屏等多种类型,不同类型的传感器需要不同的驱动程序来处理。 ### 1.4 Linux内核 Android系统基于Linux内核开发,因此TP驱动程序需要在Linux内核中实现。在内核中,可以使用工具链进行编译和调试,通过Kconfig和Makefile文件进行配置和构建。 ## 2. 驱动框图 Android TP驱动的框图如下所示: ``` +---------------------+ +---------------------+ | | | | | Touch Panel Sensor +---+ Touch Panel Control | | | | | +---------------------+ +---------------------+ | | | | v v +---------------------+ +---------------------+ | | | | | Input +---+ Kernel | | Subsystem | | | | | | | +---------------------+ +---------------------+ ``` 其中,输入子系统负责接收来自触摸屏控制器和传感器的输入事件,将其转换成标准的输入事件格式,并发送到内核中。内核负责处理输入事件,将其转发给应用程序或系统服务进行处理。 ## 3. 调试方法 Android TP驱动调试主要包括以下几个方面: ### 3.1 调试工具 在驱动开发过程中,可以使用一些调试工具来帮助定位问题,如printk、dmesg、strace、gdb等。printk可以输出调试信息到内核日志中,dmesg可以查看内核日志中的输出信息,strace可以跟踪应用程序的系统调用,gdb可以对内核进行调试。 ### 3.2 调试方法 在调试过程中,可以使用一些方法来定位问题,如插入断点、输出调试信息、分析内存泄漏、跟踪函数调用栈等。其中,插入断点可以暂停程序执行,输出调试信息可以查看程序的执行过程,分析内存泄漏可以检测程序中的内存问题,跟踪函数调用栈可以查看程序的执行路径。 ## 4. 常见问题解决思路 在TP驱动开发过程中,可能会遇到以下一些常见问题: ### 4.1 触摸屏输入不灵敏 触摸屏输入不灵敏可能是由于触摸屏传感器的灵敏度不足或者触摸屏控制器的配置参数不正确导致的。可以尝试调整控制器的配置参数,如增加采样率、调整滤波算法等,或者更换传感器来解决问题。 ### 4.2 触摸屏输入漂移 触摸屏输入漂移可能是由于传感器的灵敏度不足或者触摸屏控制器的噪声滤波算法不正确导致的。可以尝试调整控制器的噪声滤波算法或者更换传感器来解决问题。 ### 4.3 触摸屏输入失灵 触摸屏输入失灵可能是由于控制器与主处理器之间的通信故障或者控制器硬件故障导致的。可以尝试重新检查控制器与主处理器之间的连接,或者更换控制器硬件来解决问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值