当前位置: 首页 > news >正文

嵌入式触摸屏适配全链路排障复盘:从设备树到 Qt 输入层

一、背景与目标

在一块野火 NPi-nyika(i.MX6ULL,Debian 系统,内核 4.19.35-imx6)开发板上,需要让一块 5 寸 GT9157 电容触摸屏正常工作。目标不仅是驱动层跑通,还要让板子上预装的 Qt 应用能够响应触摸。

整个排障过程跨越了设备树(Device Tree)→ 内核驱动 → 用户态输入框架(evdev/tslib)→ Qt 应用层四个层次,几乎覆盖了嵌入式 HMI 开发中最典型的所有坑。本文按时间线复盘,逐层拆解每个报错的根因与解法。


二、问题演进全景

阶段 现象 根因层 关键结论
1 new_device 手动创建设备报 request IRQ failed: -22 设备树 手动创建的设备没有 DT 节点,驱动拿不到 irq-gpios
2 dtc 报 syntax error(宏行) 设备树 用了 GPIO_ACTIVE_LOW 等宏但没包含头文件
3 dtc 报 #include syntax error 工具链 dtc 不处理 C 预处理器语法,需先 cpp
4 编译成功但满屏 Warning (reg_format) 设备树 overlay 的已知误报,可忽略
5 dmesg 出现 ID 1158 + input/input2 驱动 驱动跑通,中断注册成功
6 触摸能用了,但 Qt 程序不响应 Qt 应用层 驱动通 ≠ Qt 能读,两套独立机制
7 环境变量设了仍无效 进程环境 脚本有独立环境,终端 export 对其无效
8 改 run.sh 后定位真正根因 厂商脚本 变量 typo + tslib/evdev 混用

三、第一层:设备树 overlay 的编译坑

3.1 宏未定义导致的 syntax error

最初写了使用 GPIO_ACTIVE_LOW、IRQ_TYPE_EDGE_FALLING 宏的设备树,dtc 在第 10 行(reset-gpios 那行)报 syntax error。

根因:这些是定义在头文件里的宏,不 #include 宏定义所在头文件,dtc 根本不认识它们,直接当成语法错误。这是设备树最典型的坑之一。

解法 A(补 include + cpp 预处理):#include 是 C 预处理器语法,dtc 本身不处理,必须先用 cpp 预处理再交给 dtc:

cpp -nostdinc -I /usr/include -undef -x assembler-with-cpp \/tmp/touch-fix.dts > /tmp/touch-fix.tmp.dts
dtc -@ -I dts -O dtb -o /tmp/touch-fix.dtbo /tmp/touch-fix.tmp.dts

如果报 dt-bindings/gpio/gpio.h: No such file,说明板子上没装内核头文件,走解法 B。

解法 B(零宏,纯数字,推荐):直接用数字代替宏,彻底绕开头文件依赖:

宏 数值
GPIO_ACTIVE_LOW 1
GPIO_ACTIVE_HIGH 0
IRQ_TYPE_EDGE_FALLING 2
IRQ_TYPE_LEVEL_LOW 8

最终可用的 overlay(注意去掉了猜测的 pinctrl-0 标签,避免 undefined label):

/dts-v1/;
/plugin/;&i2c1 {gtxx_tsc@14 {compatible = "goodix,gt911", "goodix,gt9xx";reg = <0x14>;reset-gpios = <&gpio3 4 1>;irq-gpios = <&gpio5 9 0>;interrupt-parent = <&gpio5>;interrupts = <9 2>;status = "okay";};
};

3.2 满屏 reg_format 警告——可忽略的误报

编译成功后出现大量 Warning (reg_format)、pci_device_reg、simple_bus_reg 等警告。

为什么无害:overlay 里 dtc 拿不到父节点(i2c1)的 #address-cells/#size-cells,于是按默认值 #address-cells=2, #size-cells=1 校验,期望 reg 是 12 字节,而 reg = <0x14> 只有 4 字节。但实际 I2C 总线是 #address-cells=1, #size-cells=0,4 字节完全正确。这是 overlay 的已知误报,后面的 Failed prerequisite 警告都是 reg_format 的连带失败,全部忽略。

3.3 为什么必须走设备树,不能手动 new_device

回顾最初的 request IRQ failed: -22:手动 new_device 创建的设备没有设备树节点,驱动拿不到 irq-gpios 信息,申请了无效中断号。所以必须走设备树这条路,把中断配置一起写进节点——这是整条链路的起点认知。


四、第二层:驱动跑通的验证

部署 overlay 并重启后,dmesg | grep -iE 'goodix|gt9' 出现三行关键日志:

Goodix-TS 0-0014: ID 1158, version: 0100
Falling back to syfs fallback for: goodix_1158_cfg.bin
input: Goodix Capacitive TouchScreen as .../i2c-0/0-0014/input/input2

判断标准:

  • ID 1158, version: 0100 → 芯片通信正常,I2C 地址 0x14 正确
  • input: ... input2 → 输入设备注册成功
  • 没有 request IRQ failed: -22 → 中断注册成功(设备树补上了中断信息)

中间的 Falling back to ... goodix_1158_cfg.bin 不是错误,只是驱动优先去 /lib/firmware/ 找厂商配置文件没找到,回退使用设备树里的 goodix,cfg-group0 数组。

/proc/bus/input/devices 确认 Handlers=kbd event2、PROP=2(支持多点触控),设备节点为 /dev/input/event2。用 evtest /dev/input/event2 实测触摸事件,坐标正常 → 驱动层完全跑通。


五、第三层:Qt 应用层的输入配置(真正的难点)

驱动通了,触摸能用,但预装 Qt 程序不响应。这是两套独立的东西:evtest 能读到事件只证明内核层 OK,Qt 还需要被告知去读哪个设备节点。

5.1 排除权限问题

ls -l /dev/input/event2   # crw-rw---- root input
sudo chmod 666 /dev/input/event2   # 临时验证

权限不是根因(排除)。

5.2 环境变量必须加在进程实际读取的地方

在终端 export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=... 对预装程序完全无效——通过 ps aux 发现程序是 /usr/local/qt-app/run.sh 脚本拉起的(bash 380 → App 540)。脚本有自己独立的环境,终端里 export 的变量对它无效。同理,环境变量加在 /etc/profile 对 systemd 服务也无效。

5.3 阅读厂商脚本,定位三个致命问题

run.sh 里发现:

问题 1:变量名 typo,设备路径是空的

export TSLIB_TSDEVICE=/dev/input/$event    # 少了 x!上面定义的是 eventx

导致 TSLIB_TSDEVICE 实际是 /dev/input/,tslib 根本打不开设备。

问题 2:tslib 与 evdev 混用,互相冲突
脚本同时设了 QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS(evdev 路线)、QT_QPA_GENERIC_PLUGINS=tslib:... 和 QT_QPA_FB_TSLIB=1(tslib 路线)。tslib 面向单点(电阻屏),调用 handleMouseEvent;evdev 面向多点(电容屏),生成真正的 QTouchEvent。两者同时开启会导致坐标错乱甚至完全无响应。

问题 3:电容屏却用 tslib 配置
QT_QPA_GENERIC_PLUGINS 写成了 tslib,而 GT9157 电容屏应该用 evdevtouch。

5.4 libinput 的隐性干扰

Qt 的 eglfs/linuxfb 插件默认优先用 libinput,只有 libinput 不可用或显式禁用时才回退到 Qt 自带的 evdev 处理程序。系统若装了 libinput,它可能抢先接管但没读对设备。强制走 evdev:

export QT_QPA_FB_NO_LIBINPUT=1     # linuxfb
# 或 export QT_QPA_EGLFS_NO_LIBINPUT=1   # eglfs

六、最终修复方案(evdev 路线)

修改 /usr/local/qt-app/run.sh(先备份):

  1. 修变量名:export TSLIB_TSDEVICE=/dev/input/$eventx
  2. 注释掉所有 tslib 相关行:QT_QPA_GENERIC_PLUGINS=tslib:...、QWS_MOUSE_PROTO=tslib、QT_QPA_EGLFS_TSLIB=1、QT_QPA_FB_TSLIB=1、TSLIB_CONFFILE、TSLIB_CALIBFILE
  3. 改用 evdev 配置(在启动行之前):
export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/$eventx:rotate=0
export QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/$eventx
export QT_QPA_FB_NO_LIBINPUT=1
export QT_LOGGING_RULES=qt.qpa.input=true

重启程序后通过日志判断:

日志现象 结论
Using device + min X: 0 max X: 799 读到了;若仍无响应是程序代码问题
Adding device 但无 Using device 设备被其他进程独占
完全没有 evdevtouch 脚本没生效,确认改的是同一文件

坐标镜像/旋转用 rotate=90/180/270 或 invertx/inverty 单轴翻转修正。

备选(若 App 只认鼠标事件,必须走 tslib):彻底关掉 evdev,unset QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS,并 export QT_QPA_FB_DISABLE_INPUT=1 禁用 evdev 避免冲突,且必须先跑 ts_calibrate 生成 /etc/pointercal。


七、通用诊断方法论沉淀

  1. 分层定位,逐层验证:设备树 → 驱动 → evdev → Qt,每一层用对应工具验证(dtc / dmesg / evtest / QT_LOGGING_RULES),确认一层通了再往下走,避免跨层瞎猜。
  2. QT_LOGGING_RULES=qt.qpa.input=true 是 Qt 触摸排障的黄金开关:能直接看出 Qt 是否读到设备、是否 Using device、坐标范围是否异常。
  3. 区分驱动层与应用层:evtest 能读事件 ≠ Qt 能响应,这是两个独立世界,绝大多数"触摸不灵"卡在这里。
  4. 警惕进程环境隔离:脚本、systemd 服务都有独立环境,终端 export 和 /etc/profile 未必生效,必须改在进程真正读取的地方。
  5. tslib 与 evdev 不可混用:电容屏走 evdev(多点、真 QTouchEvent),电阻屏走 tslib(单点、鼠标事件),混用必出问题。
  6. overlay 的 reg_format 警告是误报:看到 #address-cells==2 相关警告时,先想是不是 overlay 拿不到父节点 cells,而不是真的写错 reg。
  7. 手动 new_device 缺中断信息:需要中断的设备尽量走设备树,把 irq-gpios/interrupts 一起写进去。

八、一句话总结

这次适配真正的难点从来不在驱动,而在厂商预置脚本本身是为电阻屏(tslib)写的、且带一个变量名 typo——它把"电容屏 + evdev"这条正确路径,用一堆 tslib 配置和空设备路径堵死了。能定位到这一层,靠的不是技术直觉,而是"逐层验证 + 读源码 + 开日志"的方法论。


http://www.cnnetsun.cn/news/64498.html

相关文章:

  • 规划参考:香港DSE升学指导全流程的升学路径、备考节奏、录取规则怎么影响录取 - 优质品牌中立测评推荐
  • 从升学路径、备考节奏、课程安排入手,理解留学申请的差别(11月14日整理) - 互联网科技品牌测评
  • 香港DSE升学指导报名合前后:升学路径、课程安排、师资匹配怎么安排 - 优质品牌中立测评推荐
  • 留学申请:升学路径、备考节奏、课程安排先理清 - 互联网科技品牌测评
  • 从经验驱动到数据驱动:学校为何必须建设智慧校园管理系统?
  • 用AI写代码到用开源代码
  • leetcode 607. 销售员
  • 从“标题改到第8版”到一篇拆三个平台:一个制造业新媒体运营的AI内容流水线
  • 电子音乐游戏哪些人气高 十大必玩电子音乐游戏精选
  • 推理游戏哪些人气高 人气高的推理游戏排行
  • 即时含暂停游戏有哪些好玩 十大经典即时含暂停游戏排行榜前十
  • 指向 & 点击游戏推荐哪个 十大必玩指向 & 点击游戏推荐
  • 心理恐怖游戏哪个最好玩 十大经典心理恐怖游戏推荐
  • 牌组构建游戏下载 热门牌组构建游戏盘点
  • 原声音乐游戏有哪些 十大必玩原声音乐游戏精选
  • 暴力游戏哪些好玩 热门暴力游戏排行榜前十
  • 人工智能游戏大全 高人气人工智能游戏推荐
  • 海盗游戏哪个好玩 最热海盗游戏推荐
  • 生存游戏有哪些好玩 2024生存游戏盘点
  • 大型多人在线角色扮演游戏哪些好玩 热门大型多人在线角色扮演游戏盘点
  • 拼字游戏哪些人气高 十大耐玩拼字游戏盘点
  • 平台游戏游戏大全 最新平台游戏游戏排行
  • 策略游戏推荐哪个 十大必玩策略游戏盘点
  • 消除游戏推荐哪个 十大必玩消除游戏排行榜前十
  • 重制游戏哪个好玩 最热重制游戏排行
  • 西部风格游戏哪些好玩 人气高的西部风格游戏盘点
  • 程序生成游戏下载 十大必玩程序生成游戏精选
  • 冷战游戏哪个最好玩 十大必玩冷战游戏排行
  • 第三人称游戏哪些人气高 热门第三人称游戏排行
  • 血腥游戏哪些人气高 好玩的血腥游戏排行榜