FPGA+Linux触摸屏驱动实战:从硬件链路到Qt交互
发布时间:2026/9/18 4:30:54 作者:尧图编辑部 阅读量:1,286

1. 这个教程到底在做什么从整体架构理解触摸屏驱动先聊一个很现实的问题一提到FPGA Linux 触摸屏很多刚接触SoC FPGA的同学第一反应是——触摸屏驱动不就写个内核模块吗这跟FPGA有什么关系实际上关系很大。黑金这套7寸触摸屏驱动教程本质上是带你走通一条完整的硬件-软件协同链路FPGA里通过逻辑实现LCD时序控制器把RGB信号送到屏幕触摸屏控制器通过I2C或USB接口把触摸坐标数据传给ARM核Linux内核里的触摸屏驱动负责把硬件上报的原始坐标翻译成标准的input_event事件最终让Qt应用、tslib这些上层组件直接拿到可用的触摸点。换句话说驱动本身可能只有几百行代码难的是把那几百行代码嵌进正确的体系里。你先得知道你这块FPGA芯片内部到底有哪些资源硬核ARM和软核NIOS II怎么选触摸控制器挂在哪个总线上设备树该怎么改内核里该开哪些配置项。这些全串起来触摸屏才能真正点得动。这篇教程面向的人是已经能用FPGA写一些基本逻辑比如数码管、UART通信但还没在FPGA上跑过完整Linux系统的开发者。如果你想搞明白FPGA跑Linux跟普通ARM开发板到底有什么不同或者你手里正好有一块黑金或类似平台的SoC FPGA开发板想在上面点亮一块带触摸的屏幕这篇东西就是给你的。先做一个简单的概念约定。这套方案里的核心处理方式有两种路线一种是Zynq/SoC FPGA硬核ARM Linux另一种是纯FPGA逻辑 MicroBlaze软核本身不太擅长跑Linux更多是裸机方案。黑金云课堂里讲的主流路线是前者这也是行业里最通用的做法。以下所有内容基于这个前提。2. 硬件平台认知你的触摸屏数据到底从哪条路进来在碰代码之前我强烈建议你先花时间把开发板上的硬件通路捋一遍。这一步在做教程的时候容易被一带而过但恰恰是后面排查问题的分水岭。2.1 屏幕的显示通路FPGA逻辑做时序ARM只管喂数据7寸屏通常是一个RGB接口的LCD面板30到40根信号线包括RGB888或RGB666颜色数据线、行场同步信号HSYNC/VSYNC、像素时钟DCLK、有效数据使能DE。这块屏本身不具备显卡功能它必须被持续不断地以固定刷新率扫描否则画面就会闪、花甚至直接不显示。在SoC FPGA方案里这部分工作由FPGA逻辑承担。你在Vivado或Quartus里搭一个Video Timing Controller IP生成符合屏幕规格书要求的时序再用一个简单的FIFO或VDMA做数据缓存。ARM核里的Linux系统把图像内容写到DDR指定地址FPGA侧通过AXI总线把数据读出来按照时序送给屏幕。这一步跟触摸屏驱动的关系在于你用fbset或者modetest能看到的那个framebuffer设备就是ARM和FPGA逻辑之间的数据接口。驱动里的坐标转换要考虑到屏幕的实际分辨率而分辨率本身就来自framebuffer的配置。常见7寸屏是1024x600或800x480代码里凡是硬编码这两个数字的地方你都得留个心眼。2.2 触摸的通路电容屏I2C、电阻屏SPI、红外屏USB触摸屏的传感方式决定了你的驱动路线。这里我按最常见的几种类型给你拆开讲电容触摸屏最常见触摸控制芯片通常是GT911、FT5x06、Goodix系列接口是I2C。芯片挂在你板子上的某个I2C控制器下Linux内核里对应的驱动是goodix.c或edt-ft5x06.c。驱动做的事情是在I2C总线上发现这个芯片地址读回设备的ID寄存器确认身份然后申请一个input_dev设备把触摸坐标报给系统。电阻触摸屏老一代设备喜欢用接口通常是SPI或ADC控制器如TSC2007、ADS7846。在内核里对应tsc2007或ads7846驱动。这种屏需要校准后面我会专门讲tslib的部分。红外触摸屏对应热词里的touchkit屏框四周布满红外发射接收对管手指遮挡光线来定位。这种屏的数据接口多数是USB HID在内核里直接用usbhid通用驱动就能认出来设备会枚举成一个event节点。触摸行为上它更像一个绝对坐标的鼠标。在教程对应的开发板场景里最常见的是第一种——电容触摸屏走I2C。所以我在后面的章节会以GT911为例展开同时提一下USB红外触摸屏的适配思路。2.3 中断和复位引脚这两个GPIO决定驱动能不能稳定工作GT911这类触摸芯片有两个引脚必须接对中断脚INT和复位脚RST。芯片内部有个上电时序要求RST拉低再拉高、保持一段时间后INT脚的电平状态会被芯片采样用来决定I2C设备地址是0x5D还是0x14。这个细节在做裸机的时候很多人不在乎但在Linux驱动里就麻烦了。goodix驱动的probe流程是获取中断GPIO、获取复位GPIO、按文档要求的时序做复位、等芯片就绪、发起I2C读取。如果你的设备树里中断号写错了或者复位引脚没配成GPIO模式最常见的现象就是系统启动日志里出现goodix-ts 0-005d: I2C read failed: -5 goodix-ts: probe of 0-005d failed with error -5这个-5是-EIO大概率不是I2C控制器坏了而是芯片处于未复位状态根本没起来响应总线。所以原理上先搞清楚设备树里的interrupts、reset-gpios、irq-gpios这三个属性分别对应什么能省掉一晚上的调驱动时间。3. 环境准备交叉编译链、内核源码与设备树的关系很多人第一步就卡在环境上。我这里不贴一键脚本因为每个板卡厂商的内核版本、编译工具链路径可能是不同的但整体的准备逻辑是一致的。你把逻辑顺明白了换到任何一块板子都能自己搞定。3.1 交叉编译链你是用x86机器去编ARM程序SoC FPGA的ARM核在板子上你不能直接在板子上跑make性能不够也没必要。你在PC上装一个针对ARM Cortex-A9架构的交叉编译工具链比如黑金教程里常用的arm-linux-gnueabihf-gcc或者Xilinx/Intel官方提供的linaro工具链。装好之后必须验证一件事arm-linux-gnueabihf-gcc -v能正常打印版本信息同时arm-linux-gnueabihf-gcc -dumpmachine显示目标平台是arm-linux-gnueabihf。如果这两步没问题你才能继续内核编译。工具链版本和内核版本要匹配太老的gcc编新的内核会报一些诡异的语法错误这类问题别去查内核代码先换工具链。3.2 内核源码你不是从零编是在官方内核基础上加补丁SoC FPGA供应商会维护一个带板级补丁的Linux内核仓库。不要自己去kernel.org拉一个干净内核来编因为你还得手动移植厂商的设备树文件、BSP驱动补丁工作量大到足以让人放弃。正确做法是获取厂商提供的内核源码压缩包黑金是提供配套bsp的解压后先看一眼目录里有没有该板卡对应的*.dts或*.dtsi设备树文件。找到它后面的触摸屏设备树改动就是在这个文件的基础上做加法而不是重写。编译前先执行export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf- make xilinx_zynq_defconfig make menuconfig make dtbs make zImage注意make menuconfig这一步它不是让你把整个内核选项都过一遍而是开发板厂的默认配置里大多已经启用了I2C、input subsystem、framebuffer。你需要手动确认的触摸无关配置项我放到第4章专门讲。3.3 设备树内核里描述硬件的接线图设备树DeviceTree对Linux驱动来说就是一张描述硬件怎么接线的清单。你把触摸芯片挂在哪个I2C控制器上、中断接在哪个GPIO、复位接在哪个GPIO、设备地址是多少全部写成设备树节点。驱动代码里不硬编码这些信息而是运行时通过设备树拿。打个容易理解的比方驱动是一个通用插座设备树是告诉你这个插座该插在哪堵墙上、插座上有几个孔。同一个goodix驱动你不用改一行C代码只需要修改设备树里的地址和中断引脚就能适配不同板卡上不同接法的GT911。设备树文件的修改逻辑是这个教程里的重头戏。后面我会详细拆一个节点给你看。4. 内核配置触摸屏驱动能工作的前提选项这一步经常被教程一句话带过但实际是新手最容易踩坑的地方。你设备树写得再对如果内核编译时压根没把需要的子系统编进去驱动就是加载不起来而且报错信息往往很隐晦。4.1 必须开启的配置项清单进make menuconfig之后按下面这几个路径逐项确认。这边用GT911goodix驱动举例Device Drivers Input device support [*] Generic input layer (needed for keyboard, mouse, touchscreen) [*] Event interface [*] Input event debugging [*] Touchscreens * Goodix I2C touchscreen如果你的触摸屏不是goodix而是FT5x06就把Touchscreens下的Focaltech ft5x06 touchscreen编进去。建议全都编成*而不是M因为触摸屏驱动通常要在系统启动早期就完成probe如果编成模块还得靠rootfs里管理模块加载顺序很容易起不来。4.2 I2C子系统和GPIO配置触摸驱动走I2C所以你还要确认Device Drivers [*] I2C support I2C Hardware Bus support [*] Xilinx I2C controller (Zynq specific)同时GPIO子系统是中断和复位引脚控制的底层依赖Device Drivers [*] GPIO Support [*] /sys/class/gpio/... (sysfs interface)对于中断请求你还得确认CONFIG_GPIO_CDEV是开启的。新内核里GPIO用户态接口改成了字符设备方式老板子的BSP里可能还开着deprecated的sysfs接口如果你用的内核版本较新而tslib或者你的测试工具还是用老接口来访问GPIO也会失败。4.3 确认你的配置真的生效配置完保存退出执行编译之后有一个检查动作特别重要。用grep CONFIG_TOUCHSCREEN_GOODIX .config看到CONFIG_TOUCHSCREEN_GOODIXy才说明编进了内核。如果看到的是# CONFIG_TOUCHSCREEN_GOODIX is not set那前面menuconfig里肯定有哪一步没保存。make menuconfig退出时选Save别选Exit直接走了这种情况我见过好多次编出来的内核没触摸驱动还在那儿查设备树查了半天。5. 设备树实操给GT911挂到正确的I2C总线上现在进入正题。我直接给一个经过验证的设备树节点模板然后逐行解释它的含义。黑金这块板子的Zynq平台GT911通常是挂在I2C0或I2C1上。具体挂哪个看你原理图上PS端的MIO引脚分配。5.1 示例节点逐行拆解在i2c0节点下加上i2c0 { status okay; clock-frequency 100000; tps651323e { compatible ti,tps65132; reg 0x3e; }; goodix_ts5d { compatible goodix,gt911; reg 0x5d; interrupt-parent pio; interrupts 18 IRQ_TYPE_EDGE_FALLING; irq-gpios pio 18 GPIO_ACTIVE_HIGH; reset-gpios pio 17 GPIO_ACTIVE_HIGH; touchscreen-size-x 1024; touchscreen-size-y 600; touchscreen-inverted-x; touchscreen-inverted-y; }; };看着长但你只需要理解五类信息第一类I2C总线归属。i2c0表示这个触摸芯片挂在内核I2C子系统编号为0的控制器的总线上。clock-frequency决定I2C时钟频率GT911支持100kHz普通模式用100000最稳。有些屏的触摸芯片对400kHz快速模式支持不好跑起来会偶发丢坐标先别图快等稳定后再试400kHz不迟。第二类compatible匹配。goodix,gt911这个名字必须与驱动代码里of_match_table中的字符串完全一致。你打开内核源码drivers/input/touchscreen/goodix.c搜索gt911能看到{ .compatible goodix,gt911 }这样一个条目。名字对不上驱动根本不会probe你的设备。第三类I2C地址。reg 0x5d是GT911的7位I2C地址。前面提到过这个地址由INT引脚在复位上升沿时刻的电平决定。黑金板子的原理图上如果INT上拉就是0x5D如果下拉就是0x14。如果probe时总是报address not available或者no such device先查这一位电平而不是怀疑I2C控制器坏了。第四类中断和复位引脚。interrupt-parent指定中断控制器interrupts是中断号跟触发方式irq-gpios和reset-gpios是触屏驱动的GPIO控制句柄。这里最坑的是这四行里的引脚编号必须和你的FPGA工程里PS端MIO的引脚号一一对应而且这个状态是由硬件工程师定的不是代码决定的。如果你在把硬件设计从旧板卡换到新板卡新旧板子的触摸引脚换了位置你只改设备树就可以了内核源码不用动。这是设备树机制的便利也是你必须重新梳理硬件接线的理由。第五类屏幕参数。touchscreen-size-x 1024表示触摸面板水平方向最大坐标值。注意这个坐标值不是像素值GT911芯片输出的坐标是一个跟触摸屏物理感应区域成比例的无符号整数范围一般是0到芯片固件配置的一个最大值。如果这个最大值设得跟实际屏幕分辨率不匹配触摸点跟画面错位会很严重看起来就像指针歪了一样。5.2 容易忽略的dtsi还是dts差异设备树文件有dtsi和dts之分。dtsi是公共的、可以被多个板型引用的头文件式定义dts是某个具体板型的最终文件。触摸屏的差异跟具体板型强相关所以应该加到板型的.dts文件里不要加到.dtsi里。如果你在多个板型共用的.dtsi里加了带有特定pin信息的触摸节点别的板型在编译设备树时会遇到冲突比如同一个引脚被两个节点占用这种问题排查起来非常费劲。一台板子一处硬件差异就在对应的.dts里改别图省事。5.3 编译并反编译验证修改完dts后用make dtbs编译然后强烈建议反编译回文本格式确认改动都进去了dtc -I dtb -O dts -o zynq-7000.dts arch/arm/boot/dts/zynq-7000.dtb grep -A 20 goodix zynq-7000.dts这一步能立刻发现语法错误或节点放置位置错误。设备树的语法错误有时候编译不报错比如i2c0这个名字写错了编译器只是找不到父节点而把这个片段丢弃在你启动板子后才发现触摸设备根本没有注册。反编译检查是最快的方式。6. USB红外触摸屏的适配思路touchkit这类设备怎么接热词里那几个关于touchkit红外触摸屏驱动、Linux设备驱动、input子系统的搜索说明很多人在做的是红外触摸屏方向。这类屏跟GT911走I2C不一样数据路径是USB Host人际交互也更简单——它本身就是一个USB HID设备。6.1 为什么USB红外屏几乎不用写驱动当你把USB红外触摸屏接到FPGA开发板上的USB Host口Linux内核的usbhid驱动会自动识别它。你打开/dev/input/目录会看到多出一个eventX节点。用hexdump读取能看到屏幕上报的坐标数据流。这类设备在内核里已经现成支持了。大多数时候你不需要去改任何驱动代码只需要做两件事确认内核里CONFIG_HID和CONFIG_USB_HID是启用的然后在应用层让tslib或Qt事件库正确识别到这个eventX设备。6.2 但用户态环境变量经常配错红外触摸屏真正的问题在用户态配环境变量。常见的一种现象是cat /dev/input/event3有数据但Qt程序触摸没反应。原因是程序默认打的设备节点跟实际的不一致。常见的解决做法是建立一个稳定的符号链接而不是去记那一串会变的event号udevadm info -a -p /sys/class/input/event3从输出里找到ATTRS{name}eGalax Inc. USB TouchController之类的信息然后在/etc/udev/rules.d/里写一条规则把这类触摸设备固定映射成/dev/input/touchscreen。然后设置export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS/dev/input/touchscreen export QT_QPA_PLATFORMlinuxfb先让Qt直接打开这个符号链接跑起来后面再做坐标校准。6.3 红外屏常见的坐标翻转问题红外触摸屏的坐标原点默认在左上角物理安装位置如果是从上往下而不是从正面安装的坐标就有可能是翻转的。在tslib或Qt层面做翻转很容易TSLIB_CALIBFILE/etc/pointercalts_calibrate会交互式地让你点屏幕上的十字靶点然后生成校准文件。但有一个坑是红外的坐标本身就是线性的它跟电阻屏不一样很多时候根本不需要做完整的五点校准。如果你做了校准反而引入误差这时候删掉/etc/pointercal设置环境变量TSLIB_RAWINPUT为no系统直接透传设备坐标效果反而准确。这个经验是实际项目里换了几种校准策略对比出来的。结论是搞清楚你的触摸屏类型再决定要不要做校准不要套用一个固定模版。7. 驱动加载后的验证与调试从内核日志到实际触摸所有配置做完、烧写到板子上启动后真正的调试才刚刚开始。我一直觉得这块是最锻炼人的地方因为你面对的问题已经不是代码能不能编过这个层面了而是硬件和软件在同一个系统里能不能好好配合。7.1 查看probe是否成功启动完成后先看内核日志dmesg | grep -i -E goodix|i2c|input正常情况会看到类似这样的一段goodix-ts 0-005d: I2C TouchScreen GT911 detected input: Goodix GT911 TouchScreen as /devices/platform/amba/amba:pl011/i2c0/0-005d/input/input2 input: Goodix GT911 TouchScreen as /dev/input/event2这两行的信息量很大第一行表示触控芯片被识别到了型号都对上了第二行表示内核给它创建了一个input设备节点/dev/input/event2是你后续测试要用的节点名。如果只看到第一行没有第二行说明input子系统注册失败了通常是input_allocate_device或input_register_device环节出错查一下内核配置里的CONFIG_INPUT和CONFIG_INPUT_EVDEV是否开启。如果第一行都看不到那就是probe之前就失败了按上一章的-EIO排查链路去查。7.2 用evtest和hexdump直接看坐标数据流evtest是排查input子系统问题最常用的工具。安装后运行evtest /dev/input/event2然后用手指点击屏幕终端里会持续输出Event: time 1234.567890, type 3 (EV_ABS), code 0 (ABS_X), value 500 Event: time 1234.567890, type 3 (EV_ABS), code 1 (ABS_Y), value 234 Event: type 1, code 330, value 1 Event: type 1, code 330, value 0ABS_X和ABS_Y是触摸点的绝对坐标code 330是BTN_TOUCHvalue 1/0表示手指按下和抬起。如果evtest里完全没有输出但触摸屏的背光、显示都正常问题大概率在设备树的中断配置上——芯片数据没触发中断内核就永远等不到数据。把interrupts里的IRQ_TYPE_EDGE_FALLING改成IRQ_TYPE_LEVEL_LOW试试GT911的INT脚默认行为是低电平有效部分芯片版本存在边沿丢失的情况。7.3 坐标范围和方向的检查方式用evtest多点击几个位置把坐标值跟屏幕分辨率对照。比如屏幕分辨率是1024x600你在屏幕左上角点一下ABS_X应该接近0ABS_Y接近0右下角点一下ABS_X接近1024ABS_Y接近600。如果左下和右上对调了那就是touchscreen-inverted-x和touchscreen-inverted-y这两个设备树属性该加没加。如果坐标范围倒挂比如横屏坐标出现在竖屏数值上则是touchscreen-size-x和touchscreen-size-y设置反了交换过来就行。这类问题都改设备树即可改完重新编译dtb烧录不需要改驱动源码。8. Qt应用层坐标适配与性能优化触摸屏驱动跑到这步/dev/input/event2已经有数据了系统层面也能用。但对大多数做产品的人来说最后一步是让Qt程序能正常响应并且触摸的跟手速度、精度都过关。8.1 用-plugin evdevtouch还是linuxfb跑QtQt在嵌入式Linux下访问触摸屏有两条路直接的evdev插件或tslib插件。配置方法取决于Qt的编译参数。如果你的Qt是用-qt-linuxfb -evdev编的运行时设置export QT_QPA_PLATFORMlinuxfb export QT_QPA_FB_DRM1 export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS/dev/input/event2如果你的Qt是用tslib支持编译的则要设置export QWS_MOUSE_PROTOtslib:/dev/input/event2 export TSLIB_TSDEVICE/dev/input/event2 export TSLIB_CALIBFILE/etc/pointercal两条路的差异在于evdev插件直接读内核input事件响应链路短、延时低tslib插件中间多一层坐标过滤和校准可以消除触摸芯片的一些毛刺抖动但会引入一点点额外延时。对GT911这类比较成熟的电容屏我个人建议直接走evdev开发阶段排错简单产品阶段延时更低。8.2 触摸抖动和抖动问题调试Qt应用时最常见的两个投诉一是触摸点发抖二是滑动时线条不连续。发抖一般是电源噪声或触摸屏信号受干扰。先在硬件上查屏的供电是否稳定FPGA开发板上很多屏幕的VCC是直接从5V转出来的纹波大了触摸芯片的坐标跳动会非常明显。软件上可以用tslib的滤波模块export TSLIB_PLUGINDIR/usr/lib/ts export TSLIB_CONSOLEDEVICEnone export TSLIB_FBDEVICE/dev/fb0 export TSLIB_TSDEVICE/dev/input/event2然后在tslib配置里启用median和lowpass滤波插件但注意滤波会带来坐标滞后滑块移动时尤其明显。具体要做多大滤波得根据你实际的噪声水平调没有一个万能值。线条不连续多数是设备树里的分辨率配得不对。GT911的touchscreen-size-x如果配小了坐标值会全部超过屏幕范围Qt收到坐标后换算出来就是跳跃的。这个我之前踩过一次配反了坐标范围Qt里画线就是一段一段的当时还以为是性能问题查了半天才发现是size-x和size-y填反了。8.3 使用tslib校准还是直接用内核坐标GT911这类电容屏在产线上制造时每一块屏出来的坐标原点可能有微小差异但一般不会超过一两个像素。如果是做工业触摸产品建议接上tslib做5点校准把校准结果存到/etc/pointercal。但如果你的屏幕是标准7寸1024x600模组没有太大的坐标系偏移直接透传内核坐标完全没有问题。理解透传的原理后你还会遇到“光标位置跟手指实际触摸位置上下左右错位”的调试场景这时候不要一开始就怀疑代码先用手量一下错位规律。上下翻转、左右翻转、对角翻转这三种情况分别对应设备树里的三个旋转属性这个知识点在上升到产品阶段时非常实用。9. 常见问题排查我把黑金平台上能踩的坑汇总到这里东西写到最后我把这些年调试SoC FPGA触摸屏驱动时遇到的高频问题集中列出来并说清楚它们的排查路径。这里面有几个坑的定位过程很曲折希望你能直接跳过。9.1 触摸屏有响应但坐标整体偏移这种现象是设备树里touchscreen-size-x或touchscreen-size-y和屏幕实际分辨率不匹配导致的。比如屏幕上实际是1024x600但你写的size是800x480触摸芯片上报的物理坐标经过内核换算后跟framebuffer的像素对不上整个坐标系被压缩或者拉伸了。直接改设备树里这两参数重新编译dtb启动后evtest确认坐标到达的范围。如果对不上还可能是屏幕上用于坐标映射的固件配置不同那就需要查屏厂的手册了。9.2 触摸设备在dmesg里probe成功但evtest没任何输出查中断配置。用cat /proc/interrupt看注册的中断有没有触发计数。如果你看到IRQ编号一直在增长但evtest没数据那就是事件上报链路出问题了检查CONFIG_INPUT_EVDEV是否开启。如果中断计数根本没变化那就是GPIO中断配置不对。先确认设备树里的interrupt-parent是否正确然后确认FPGA工程里该MIO引脚的上下拉状态是否跟设备树里的GPIO_ACTIVE_HIGH/GPIO_ACTIVE_LOW一致。这两处是对应关系不是独立的。9.3 触摸有时灵有时不灵尤其在系统启动初期这是GT911的复位时序问题。芯片要求RST拉低后至少等10ms再拉高然后等待100ms以上才能访问I2C。Linux内核里的goodix驱动本身有这个延时处理但如果你的复位引脚同时还被别的设备共用时序就被破坏了。用示波器抓一下RST脚的波形确认有没有毛刺或异常拉低。如果没有示波器可以在设备树里把reset-gpios去掉改成上电后软件手动复位一次试试。9.4 Qt应用可以触摸但滑动过程不流畅刷新率瓶颈通常不在触摸驱动而在图形显示链路。FPGA侧的VDMA数据读回速度、framebuffer的格式RGB565还是RGB888都会影响画面刷新流畅度。触摸事件其实一直没丢是画面更新跟不上手指看起来像卡顿。把framebuffer像素格式从RGB888改成RGB565带宽减少三分之一画面刷新率有明显改善。代价是色彩精度降低但工业界面够用了。这个方法跟触摸驱动的优化没直接关系却是整个系统体验最直观的优化点。9.5 USB红外屏插上后没有任何设备节点排除法先插到一个正常的Linux PC上如果PC上也没反应那屏本身或USB线有问题如果PC上有反应说明开发板内核的USB HID配置或USB驱动有问题。确认内核里Device Drivers HID support [*] HID bus support [*] USB HID transport layer再检查USB PHY的驱动Zynq平台需要开启CONFIG_USB_DWCOTG。10. 最后给新手的一个动手建议根据我个人的经验第一次做FPGA Linux触摸屏驱动千万别一上来就对着教程抄设备树、编译内核。先把开发板附带的手册和原理图打开用笔在纸上画出这条链路PS端ARM → I2C控制器 → 触摸芯片引脚 → 中断GPIO → Linux内核input子系统 → evtest → Qt事件循环。你能把这条链路上的每一环都标出来再去看代码和教程内容效率会高非常多。这套技术路线到今天已经相对成熟但内部关联的知识点仍然比较散FPGA逻辑、Linux设备树、I2C协议、input子系统、Qt平台抽象每一个都能单独写一本书。以触摸屏驱动为切入点去串这些知识点是性价比很高的一种学习方式一个项目跑通之后后续什么MIPI摄像头、SPI外设的Linux驱动你就都敢碰了。