拓冰建站拓冰建站
首页 / 资讯中心 / 正文

FPGA工程师调试Linux触摸屏驱动全链路指南

屏幕点亮了Linux起来了QT界面也显示出来了手指点上去图标纹丝不动。这个场景我在不少FPGA转嵌入式的朋友那里见过太多回几乎每个人第一时间都怀疑是内核驱动的问题然后陷入改驱动、重新编译、烧写、再试的循环里一折腾就是好几天。实际上7寸触摸屏驱动这件事90%的问题根本不在驱动代码本身而是整条数据链路没有通。从手指按到屏幕上的那一刻起触摸IC要完成电容变化采样、坐标计算、通过I2C总线送数、SoC的中断控制器上报、内核驱动读取坐标、input子系统分发给应用层再到QT或Weston做出响应任何一环断了现象都一样没反应。FPGA工程师的优势恰恰是能一路测上来但如果不懂这条链路优势也发挥不出来。这篇文章我就以黑金ZYNQ系列开发板配7寸触摸屏为背景把从硬件连接到内核驱动、再到设备树和实际调试的完整过程讲透。1. 先搞清楚触摸屏驱动的完整链路再谈写代码很多人把触摸屏驱动理解成写几个C文件编进内核这个理解太窄了。触摸屏驱动在Linux里是一个典型的输入设备驱动但它同时挂在I2C子系统的底下。也就是说它既是I2C客户端驱动又是input设备驱动一脚踩两个子系统。这种双重身份决定了它的工作模式probe时通过I2C总线跟触摸IC对话运行时就通过中断引脚感知有人摸了然后去读坐标最后通过input子系统把坐标事件送出去。在开始碰代码之前你必须把整条链路画出来否则后面遇到的问题根本无从下手。1.1 7寸屏上那颗触摸IC决定了后面所有工作量市面上7寸RGB电容触摸屏模组触摸部分基本都是一个独立的触摸IC贴在屏幕玻璃上。主流的控制器就两大家族汇顶的GT911/GT9271和敦泰的FT5206/FT5316。很多开发板把这两类芯片都兼容因为模组供应商有时候会根据采购批次换料排线接口一样但寄存器地址和初始化流程完全不一样。参数GT911FT5316/FT5206I2C地址0x5D部分批次为0x140x38最多触摸点数5点2到5点坐标寄存器0x8150起始每点8字节0x02起始每点4字节中断行为有触摸时INT拉低读坐标后恢复有触摸时INT拉低读坐标后恢复内核已有驱动goodix.cedt-ft5x06.c这个选型对后续工作影响很大。拿到一块屏第一步就是确认上面的触摸IC型号最简单的办法是看丝印或者直接查开发板原理图和BSP里自带的驱动。黑金的大多数7寸屏资料里GT911和FT5316两种情况都覆盖了但如果你是自行采购的模组一定要先确认清楚。用错驱动、compatible字符串对不上设备树写得再漂亮也白搭。1.2 坐标从手指传到应用层中间要经过几道关卡完整的链路是这样的手指触摸 - 触摸屏感应层电容变化 - 触摸IC内部完成坐标计算 - INT引脚拉低通知SoC - 内核驱动在中断处理中通过I2C读取坐标寄存器 - 调用input子系统API上报ABS_MT_POSITION_X/Y等事件 - 内核把事件写入/dev/input/eventX -应用层QT、GTK、Weston通过evdev接口读取 - UI做出响应。应用层根本不关心你用的是GT还是FT它只从event设备节点读标准事件。这里有个常见误区很多FPGA工程师拿到触摸屏第一反应是写一个驱动把坐标printk出来结果即使打印出了坐标QT界面还是不响应于是又开始怀疑QT配置。其实原因很简单图形框架走的是evdev只认input子系统注册的标准事件不会去读你的printk。所以驱动里必须做input设备注册和事件上报这一步绕不过去。1.3 硬件连接检查单SCL、SDA、INT、RST各就各位触摸屏的软排线一般引出6根信号SCL、SDA、INT、RST、VCC、GND。翻车点几乎全在这几根线上。VCC有些模组是3.3V供电有些是2.8V直接接3.3V有时候会出现读ID正常但坐标异常的问题建议查一下模组丝印或规格书。RST必须由SoC的GPIO可控不能直接硬接到VCC。GT911对复位时序有要求后面我会详细讲。INT不能随便接一个普通IO就完事必须接到能触发中断的引脚而且设备树里中断触发方式也要写对。SCL/SDAI2C是开漏结构必须有上拉电阻。很多扩展板只把SDA/SCL引脚引出来板上没有上拉电阻这是i2cdetect扫不到设备的第一大原因。排线方向也别小看。触摸排线的金手指方向是朝屏幕玻璃面插入的插反了一般不会烧但会导致接触不良表现为时通时断特别难排查。我见过不少驱动加载失败的案例最后发现就是排线松了或插反了。2. FPGA/SoC侧要先解决的三个基础问题复位时序、I2C通路、中断信号很多教程直接跳到内核驱动和设备树但实际上Linux起来之前硬件侧有三件事必须提前确认好。FPGA/SoC侧不准备好驱动写得再完美都是空中楼阁。2.1 GT911的复位时序说多了都是泪GT911这颗IC对复位时序是有点矫情的。它的要求大致是上电后等待一段时间拉低RST保持至少1ms再拉高释放后等待几十毫秒触摸IC才完成初始化I2C才会正常应答。如果你只是简单地把RST拉高不管或者复位信号跳变太快触摸IC可能一直处于异常状态表现为I2C扫描不到设备或者能扫描到但读寄存器超时。FT5316相对宽容一些上电后给个低脉冲再拉高基本就行。但如果你用的是GT911复位时序不规范后面会吃大亏。如果用的是内核自带的goodix.c驱动设备树里把reset-gpios和irq-gpios都配好驱动probe的时候自己会控制复位时序不需要你在应用层额外操作。但问题在于有些硬件设计为了省事把RST引脚直接通过电阻拉到高电平靠RC上电延时实现复位。这种电路如果RC参数不对时序就可能不满足要求。我建议在Linux跑起来之前先用一个最简单的裸机I2C读ID程序或者直接在uboot里I2C探测一下确认触摸IC有应答再往下走。2.2 I2C总线怎么选MIO还是EMIO差别很大ZYNQ的PS自带两个I2C控制器I2C0和I2C1。这两个控制器可以配置到两组引脚上一组是固定的MIO引脚另一组是EMIO引脚通过PL侧的可配置IO引出。配置方式引脚位置电平范围优点缺点MIOPS固定引脚由MIO Bank电压决定通常3.3V或1.8V不需要PL参与启动即用引脚固定扩展不方便EMIOPL侧引脚由PL Bank电压决定常见3.3V引脚灵活可约束到扩展口需要PL逻辑配置好涉及管脚约束黑金开发板上的7寸屏扩展接口触摸的I2C信号通常接到PL侧扩展引脚上所以你需要在Vivado里把PS的I2C控制器通过EMIO引出来分配好管脚位置。这个过程不复杂在Block Design里把I2C1或者I2C0的接口使能选择EMIO然后会生成两个顶层端口在XDC里约束到具体引脚并设置IO标准即可。关键是别漏了管脚约束否则PL侧引脚悬空I2C控制器自然不通。另外提醒一下I2C时钟频率不要上来就配400kHz触摸屏FPC排线长了之后抗干扰能力会下降高速率下容易出现ACK异常。先从100kHz跑通稳定后再考虑提速。2.3 用FPGA的ILA工具去抓I2C波形这一步比任何调试都管用FPGA工程师做这事的最大优势就是可以把ILA集成逻辑分析仪直接挂到EMIO引出的SCL、SDA、INT信号上在硬件层面看到真实的波形。这个手段Linux开发者通常没有但我们可以。具体做法是在Vivado里添加ILA IP把I2C的SCL、SDA还有触摸INT引脚都接进去采样深度设置大一点。然后运行Linux执行i2cdetect或者让驱动probe回头查看ILA波形。如果能看到SCL/SDA上有正常的地址字节和ACK位说明物理链路没问题如果根本没波形或者波形畸形、幅度不对问题就在管脚约束、上拉电阻或者排线连接上。这一步能帮你把物理层和软件层彻底隔离排查效率翻倍。2.4 纯FPGA方案怎么玩AXI IIC或者自己写I2C主机如果你的平台不是ZYNQ这种带ARM硬核的SoC而是纯FPGA想上Linux最常见的路线是MicroBlaze软核。这种情况下Xilinx提供了AXI IIC IP核你可以直接在Block Design里拖出来用它实现了I2C主机功能Linux内核里有对应的i2c-xiic驱动设备树里按常规I2C控制器节点写就行。当然也可以完全用Verilog/VHDL自己写一个I2C主机挂在AXI总线上。但除非你是想练手或者对面积/性能有特殊要求否则没必要重复造轮子。AXI IIC这个IP已经非常成熟配合Linux标准驱动稳定性是有保障的。MicroBlaze跑Linux本身就已经够折腾了I2C这种基础外设就别再给自己加戏了。3. Linux内核驱动从probe到坐标上报到底要做什么先说明一个重要观点如果你用的触摸IC是GT911或者FT5x06这种主流型号内核里已经有现成驱动你根本不需要自己写。你需要做的是把设备树配好、把内核配置项打开然后验证功能。自己写驱动的场景一般是拿到了冷门触摸IC或者你想彻底理解驱动的工作原理。但无论哪种情况理解驱动内部的工作流程都对调试有巨大帮助。3.1 内核自带的goodix.c是怎么工作的以goodix.c为例它的工作流程大致是设备树匹配I2C子系统的核心层扫描总线上的设备如果发现设备树的compatible字符串和驱动里of_match_table匹配就调用驱动的probe函数。复位触摸IC驱动读取设备树里的reset-gpios按照GT911要求的时序拉低再拉高完成一次硬件复位。检测设备通过I2C读取触摸IC的ID寄存器确认设备在线且型号正确。GT911的检测过程会尝试0x5D和0x14两个地址所以你会发现即使你的屏是0x14地址驱动也能识别。初始化input设备设置设备支持的事件类型、坐标轴范围、多点触摸协议等。请求中断注册中断处理函数中断触发方式通常是下降沿。这里值得多说一句的是GT911在复位释放的瞬间INT引脚的电平状态决定了I2C地址。INT拉高对应一个地址拉低对应另一个地址。这个设计让很多人在一开始栽跟头因为手动写裸机I2C程序时如果你在复位期间没处理好INT状态读到的地址就跟预期不一样。而内核的goodix.c通过自动探测两个地址规避了这个问题。3.2 edt-ft5x06.c的基本逻辑FT5316对应的内核驱动是edt-ft5x06.c它的probe流程跟goodix类似但寄存器操作更简单。FT5316的坐标读取是从0x02寄存器开始每个触摸点占4个字节数据格式是高字节在前还是低字节在前寄存器手册里写得很清楚。这个驱动早期也支持通过设备树配置是否交换X/Y轴、是否翻转坐标属性名大概是touchscreen-inverted-x之类的后面调试章节我会具体说。3.3 如果必须自己写抓住四个核心点就够了自己写触摸驱动的场景不多但理解核心点能让你在调试现成驱动时更有底气。四个核心点分别是i2c_driver结构体、坐标读取、input子系统上报、中断处理。先看一个最小骨架#include linux/i2c.h #include linux/input.h #include linux/interrupt.h #include linux/module.h #include linux/of_device.h struct ts_priv { struct i2c_client *client; struct input_dev *input; }; static int ts_read_coord(struct ts_priv *ts, int *x, int *y, bool *touch) { u8 buf[8]; struct i2c_msg msg[2]; int ret; /* 以GT911为例先写寄存器地址0x8150再连续读8字节 */ /* 这里省略具体I2C传输实现重点是数据格式 */ ret i2c_smbus_read_i2c_block_data(ts-client, 0x81, 8, buf); if (ret 0) return ret; *touch (buf[0] 0x80) ? true : false; if (*touch) { *x buf[1] | (buf[2] 8); *y buf[3] | (buf[4] 8); } return 0; } static irqreturn_t ts_irq_handler(int irq, void *dev_id) { struct ts_priv *ts dev_id; int x, y; bool touch; int ret; ret ts_read_coord(ts, x, y, touch); if (ret 0) return IRQ_HANDLED; if (touch) { input_report_key(ts-input, BTN_TOUCH, 1); input_report_abs(ts-input, ABS_X, x); input_report_abs(ts-input, ABS_Y, y); } else { input_report_key(ts-input, BTN_TOUCH, 0); } input_sync(ts-input); return IRQ_HANDLED; } static int ts_probe(struct i2c_client *client) { struct device *dev client-dev; struct ts_priv *ts; struct input_dev *input; int ret; ts devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; ts-client client; input devm_input_allocate_device(dev); if (!input) return -ENOMEM; input-name 7inch-touchscreen; input-id.bustype BUS_I2C; __set_bit(EV_KEY, input-evbit); __set_bit(EV_ABS, input-evbit); __set_bit(BTN_TOUCH, input-keybit); input_set_abs_params(input, ABS_X, 0, 1023, 0, 0); input_set_abs_params(input, ABS_Y, 0, 767, 0, 0); ts-input input; ret devm_request_threaded_irq(dev, client-irq, NULL, ts_irq_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 7inch_ts, ts); if (ret) return ret; ret input_register_device(input); if (ret) return ret; return 0; } static const struct of_device_id ts_of_match[] { { .compatible myvendor,7inch-ts, }, { } }; MODULE_DEVICE_TABLE(of, ts_of_match); static struct i2c_driver ts_driver { .probe ts_probe, .id_table ts_id_table, .driver { .name 7inch_ts, .of_match_table ts_of_match, }, }; module_i2c_driver(ts_driver); MODULE_LICENSE(GPL);这个骨架省略了很多细节比如GT911多点触摸需要按B协议上报用input_mt_init_slots初始化槽位然后input_mt_slot、input_mt_report_slot_state配合使用。但核心逻辑已经清楚probe里注册input设备、请求中断中断里读坐标、上报事件。理解了这四件事你再去看内核自带的goodix.c和edt-ft5x06.c会发现它们再怎么复杂也是在这个框架里打转。3.4 中断处理还是轮询别在这个问题上犯懒触摸屏驱动有两种工作模式中断驱动和轮询。中断驱动是正道。手指按下时触摸IC的INT引脚拉低SoC收到中断驱动去读坐标。这种方式实时性好、CPU占用低、触摸跟手。缺点是中断引脚必须配置正确设备树里interrupts属性一旦写错要么中断不触发要么中断风暴。轮询模式适合验证硬件不适合做产品。如果你只是想先确认触摸IC能读到坐标可以在内核线程里每10ms读一次printk打印出来看看。但如果你把这个方案用到QT界面里触摸滑动会明显丢点、卡顿用户体验很差。所以我的建议是验证阶段可以轮询正式方案必须中断。设备树里interrupt-parent和interrupts这两个属性就是为中断模式准备的后面专门讲。4. 设备树与内核配置一个字节就能决定驱动能不能加载硬件链路确认没问题内核驱动也编进去了接下来就是设备树。这一节是最容易翻车的地方因为设备树写错不会报编译错误只会静默地导致驱动无法加载或者中断行为异常排查起来特别费劲。4.1 设备树节点怎么写GT911和FT5316各来一份设备树的核心作用是把硬件信息告诉内核总线上挂了什么设备、地址是多少、中断引脚是哪个、复位引脚是哪个。GT911的设备树节点通常这样写i2c1 { status okay; clock-frequency 100000; gt9115d { compatible goodix,gt911; reg 0x5d; interrupt-parent gpio0; interrupts 54 IRQ_TYPE_EDGE_FALLING; irq-gpios gpio0 54 GPIO_ACTIVE_HIGH; reset-gpios gpio0 55 GPIO_ACTIVE_HIGH; }; };FT5316的设备树节点类似i2c1 { status okay; clock-frequency 100000; ft531638 { compatible edt,edt-ft5316, edt,edt-ft5x06; reg 0x38; interrupt-parent gpio0; interrupts 54 IRQ_TYPE_EDGE_FALLING; reset-gpios gpio0 55 GPIO_ACTIVE_HIGH; touchscreen-size-x 1024; touchscreen-size-y 768; }; };这里有几个关键点reg必须是触摸IC实际应答的I2C地址GT911可能是0x5D也可能是0x14跟硬件复位时序有关。interrupt-parent和interrupts决定中断信号从哪个GPIO进内核。ZYNQ的EMIO GPIO在设备树里通常挂在gpio0节点下中断号从54开始对应EMIO引脚。如果你对自己的GPIO编号没把握去查Vivado生成的设备树文件.dtsi不要凭记忆写。reset-gpios、irq-gpios这些GPIO描述属性goodix.c和edt-ft5x06.c驱动都会解析分别用于复位和中断配置。GPIO编号同样要跟实际约束一致。IRQ_TYPE_EDGE_FALLING表示下降沿触发。大多数电容触摸IC在有触摸时INT从高拉低所以下降沿是常见配置。如果你的硬件设计把INT反相了触发方式也要相应调整否则中断要么不触发要么触发后一直在处理。4.2 中断号和GPIO编号怎么确认别靠猜ZYNQ平台的EMIO中断号是有规律可循的但规律很容易记错。最稳妥的办法是在Vivado里做完管脚约束后导出XSA文件然后在Linux的BSP配套设备树文件里找gpio和interrupt相关的定义。黑金的BSP资料里一般都有现成的设备树参考直接对照着改就行。如果你是从零开始没有参考可以先把设备树里中断号随便填一个启动后用dmesg看kernel打印驱动会报出实际的中断申请情况。或者用一个最简单的GPIO中断测试模块逐个试出有效的中断号。这个过程虽然笨但可靠。我在实际项目中见过太多人因为interrupts写错一个数字卡了整整一天。4.3 内核配置选项这两项必须编进内核触摸驱动有两种编法编成模块.ko或者直接编进内核。对于开发板调试编进内核更省事不用考虑模块加载顺序和文件系统路径问题。配置路径在Device Drivers - Input device support - Touchscreens需要选中的项Goodix touchscreen对应CONFIG_TOUCHSCREEN_GOODIXEDT EETI touchscreen对应CONFIG_TOUCHSCREEN_EDT_FT5X06如果你用的是其它触摸IC就在这个菜单下找对应的驱动。理论上讲触摸屏驱动都是这个目录下的子项。有些老内核可能没有GT911驱动那就需要从新内核移植或者用驱动源码自己编这个另说。4.4 编译烧写后怎么确认设备树和驱动真的在干活Linux起来之后用几个简单命令确认状态# 确认I2C总线上能看到触摸设备 i2cdetect -y 1 # 查看内核日志中触摸驱动的打印 dmesg | grep -i goodix dmesg | grep -i edt # 查看input设备列表 cat /proc/bus/input/devices # 查看中断是否注册成功 cat /proc/interrupts | grep 7inch如果dmesg里能看到goodix_ts_probe或者I2C Communication with touch device failed之类的信息说明驱动已经加载。如果/proc/bus/input/devices里有触摸设备并且事件名为7inch-touchscreen或类似名字说明input设备注册成功。后面就是用evtest测试坐标了。这一步最容易出现的问题是设备树改了、烧写了、也重启了但dmesg里没有任何触摸相关的输出。这种情况九成是compatible字符串不匹配或者I2C地址不对导致驱动probe被跳过。优先检查这两项。5. 实测调试坐标翻转、漂移、偶发死机的完整排查链路驱动和设备树都配置好了触摸屏能动了但别高兴太早。实测阶段最少会遇到三类问题坐标方向不对、触摸点漂移抖动、偶发失去响应。下面把排查思路完整过一遍。5.1 第一步永远是i2cdetect先看设备在不在不管现象是什么第一步永远是确认I2C设备还在总线上。执行i2cdetect -y 1这里的1对应I2C控制器序号要根据你的设备树实际配置确认。如果能扫描到设备地址比如0x5D或0x38说明硬件链路正常问题在驱动或设备树。如果扫描不到按这个顺序排查现象可能原因排查手段扫描不到任何设备SDA/SCL无上拉电阻检查扩展板原理图补上拉扫描不到任何设备复位时序不对触摸IC没起来用ILA检查RST引脚波形扫描地址是0xFFSDA线被拉低或总线挂死检查SDA是否有异常电平时有时无排线接触不良重新插拔检查金手指方向扫描到但读寄存器失败I2C速率太高或干扰降速到100kHz再试如果扫描正常但驱动没加载问题基本锁定在设备树。重点检查compatible字符串、reg地址、以及status属性是否为okay。5.2 坐标翻转和镜像设备树属性一行搞定触摸屏装到设备上X轴Y轴方向经常跟屏幕显示方向不一致。有的是左右镜像有的是上下颠倒有的是X/Y交换。解决办法有两个。如果是内核自带的edt-ft5x06驱动设备树里有现成属性touchscreen-inverted-x; touchscreen-inverted-y; touchscreen-swapped-x-y;goodix驱动同样支持这些属性。加上之后重新编译设备树重启即可生效。这个方法比在驱动代码里手动改坐标要干净得多也更容易维护。注意一点坐标翻转不只是正负号问题。如果你的屏默认X范围是0到1023翻转后应该变成1023减去原始值再上报。内核驱动的属性已经处理好了这一步不需要你手动做减法。如果用的GT911并且想做屏幕旋转360度可以配置驱动里的axis映射或者直接改设备树加touchscreen-swapped-x-y。5.3 触摸点漂移和乱跳先查供电和地再动软件触摸点十几个像素范围内轻微抖动是正常现象但如果触摸点乱跳、无操作时也上报事件那就是硬件问题为主了。优先检查三件事供电是否稳定。触摸IC的VCC如果纹波大采样结果会异常。用示波器看VCC引脚的纹波必要时加一个10uF电容和0.1uF电容。接地是否可靠。触摸屏排线的GND和开发板的GND如果存在较大阻抗电磁干扰会让触摸IC读出假坐标。这也是为什么触摸排线要选用屏蔽线的原因。排线是否完全插入。FPC排线插不到位会导致部分信号线虚接表现就是触摸时断时续、坐标乱跳。如果硬件检查完没问题再去软件层做滤波。比如在驱动里记录上次坐标如果新坐标和上次坐标的跳变超过一定阈值比如200像素丢弃这次数据。这个方法简单有效但要注意不能过滤掉正常快速滑动。更好的做法是检查触摸IC的寄存器配置GT911内部有几个寄存器可以调节灵敏度适当降低灵敏度可以缓解抖动。5.4 触摸用着用着就不动了大概率是中断或I2C总线问题偶发死机的现象一般是触摸屏刚上电好用用几分钟后完全没反应但屏幕显示正常。这个时候先别重启按下面顺序排查。先看中断状态cat /proc/interrupts | grep 7inch记录中断计数然后用手指反复触摸如果计数不动说明中断没有触发。这时候有两类原因一是触摸IC挂死了需要复位二是中断配置本身有问题。再查I2C总线状态i2cdetect -y 1如果扫描不到设备了说明I2C总线上的触摸IC失联。这种失联到底是IC内部跑飞还是I2C总线被拉死可以用ILA抓波形判断。如果SDA被从设备拉低不放就是I2C总线挂死常见原因是从设备进入异常状态需要拉低RST复位。还有一种很隐蔽的原因中断处理函数里做了可能导致睡眠的操作。Linux中断上下文不能调用msleep、i2c_transfer等可能睡眠的函数但如果用了request_threaded_irq并加了IRQF_ONESHOT标志中断处理是在内核线程里执行的就可以放心调用I2C传输函数。这个细节在自写驱动时特别重要搞错了就会出现一触摸就死机的怪现象。5.5 FPGA工程师独有的终极调试手段ILA抓全波形前面已经提过ILA这里再展开说一下。当问题复杂到软件层面已经看不到头绪时把ILA的采样信号设置为触摸屏I2C的SCL、SDA、INT、RST。然后触发条件可以设置为INT下降沿这样每次触摸都会捕获从INT拉低到驱动读坐标完成的完整I2C波形。通过波形你能看到中断之后SoC是否真的发起了I2C读操作读操作的目标地址是否正确从设备是否回了ACK读出来的数据是否有规律如果一切波形正常但应用层还是没反应问题就在驱动和input子系统那一段。如果波形不正常问题就在硬件连接或触摸IC本身。这种硬件波形软件日志双重定位的方式能把排查时间从几天压缩到几个小时强烈建议每个做FPGALinux的人都掌握。5.6 用evtest做最终验证别再用printk看坐标驱动跑起来之后最终验证工具推荐evtest。在开发板文件系统里执行evtest /dev/input/event0然后手指在屏幕上移动能看到类似这样的输出Event: time 1234.567890, type 3 (EV_ABS), code 0 (ABS_X), value 320 Event: time 1234.567890, type 3 (EV_ABS), code 3 (ABS_X), value 240 Event: time 1234.567890, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 1234.567890, type 0 (EV_SYN), code 0 (SYN_REPORT), value 0看到EV_ABS和BTN_TOUCH事件持续输出并且数值随手指移动变化说明从硬件到驱动到input子系统的链路已经全部打通。这个时候再启动QT程序或者其他GUI应用触摸就能直接用了。如果到这里还不响应那问题就在应用层的触摸屏配置上比如QT的QWS_MOUSE_PROTO或环境变量设置那就属于另一篇文章的内容了。最后分享一点个人经验这套东西做下来我个人最大的体会是触摸屏驱动在难度上并不高但它是一个典型的链路问题跨了硬件、FPGA逻辑、内核驱动、设备树、应用层五个层面。FPGA工程师做这件事有天然优势因为我们可以用ILA抓波形这一点比纯软件开发者强太多。但反过来如果一上来就埋头看驱动源码不看波形、不扫描I2C、不确认中断就会陷入盲目改代码的泥潭。我建议任何碰到触摸问题的朋友严格按这个顺序排查先查排线和上拉用万用表量出SCL/SDA/INT/复位电平是否正常再用ILA或者示波器抓一遍上电复位时序和I2C波形然后在Linux里i2cdetect确认设备在线接着看dmesg确认驱动加载最后evtest验证input事件。按照这个顺序走90%的问题在第一轮就能定位。剩下10%的疑难杂症往往是硬件偶发问题需要反复抓波形对比这时候保持耐心比掌握什么高深技巧更重要。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门