STM32MP1 + GT911 触摸显示系统开发笔记
- [一. 触摸屏基础](#一. 触摸屏基础)
-
- [1. 触摸技术原理](#1. 触摸技术原理)
- [2. 硬件连接与数据流](#2. 硬件连接与数据流)
- [二. 驱动分析](#二. 驱动分析)
-
- [1. 设备树](#1. 设备树)
-
- 1>从设备地址
- [2> 设备树文件](#2> 设备树文件)
- [3> 配置内核](#3> 配置内核)
- [4> 重启开发板测试](#4> 重启开发板测试)
- [三. TS_Lib移植与配置](#三. TS_Lib移植与配置)
- 常见问题排查
本文系统梳理从触摸屏基础、硬件连接、Linux 输入子系统驱动到 tslib 移植以及内核启动流程的关键要点。目标是帮助开发者快速搭建 STM32MP1 平台的 LCD+触摸系统,并掌握调试和排障方法。
c
本文介绍了基于 STM32MP1 平台 和 GT911 触摸芯片的LCD触摸系统开发全流程。主要内容包括:
硬件部分:
解析电容式触摸屏原理和GT911芯片工作方式
详细说明I2C接口连接及设备树配置方法
驱动开发:
分析Linux输入子系统框架
详解GT911驱动架构和事件上报流程
提供内核配置和编译指南
软件集成:
介绍tslib移植步骤和常见问题解决
说明应用层事件处理流程
调试方法:
提供设备节点检测和功能验证方法
包含详细的设备树配置示例
该文档为开发者提供了从硬件连接到软件集成的完整参考,帮助快速实现STM32MP1平台的触摸显示系统开发。
gt911 设备树节点:

显示管线:SoC LTDC → DSI Host → MIPI DPHY → LCD Panel
触摸管线:GT911 触控 IC 将电容触摸矩阵转换为 I²C 数据,通过 Linux 输入子系统驱动上传事件
用户态:可使用 tslib 完成滤波、校准,再由上层图形栈(X.Org、Qt、Wayland/libinput 等)获取稳定的触摸事件。
gt911 驱动框架:

GT911 驱动框架解析:
- 平台层:
platform_bus匹配i2c2控制器 →i2c_adapter驱动(drivers/i2c/busses/i2c-stm32f7.c)注册。 - I²C 子系统:设备树节点
touchscreen@5d→i2c_client→ 匹配drivers/input/touchscreen/goodix.c。 - 输入子系统:
goodix_probe()解析 GPIO、复位 GT911、读取固件信息。- 注册
input_dev,设置多点触控BTN_TOUCH、ABS_MT_POSITION_X/Y等。 - 请求中断,在
goodix_irq_handler()中通过 I²C 读取坐标缓冲区,调用input_mt_report_slot_state()、input_sync()上报。
- 应用层:
evdev、libinput、tslib等通过/dev/input/eventX接收事件。
建议熟悉 drivers/input/touchscreen/goodix.c,理解寄存器布局、坐标分辨率、手势扩展等。
一. 触摸屏基础
1. 触摸技术原理
| 类型 | 检测方式 | 典型特点 |
|---|---|---|
| 电阻式 | 两层导电薄膜接触后测量电阻变化 | 成本低、可戴手套操作、易磨损 |
| 电容式 | 扫描 X/Y 电极阵列的电荷变化 | 精度高、支持多点触控、需导电体 |
电阻触摸屏: 上下两个面,分别测量对方的电阻,根据电阻计算出坐标。

电容触摸屏: 不断扫描x,y轴上小电容的电荷变化,得到x,y坐标。

GT911 属于电容式控制器,内部处理原始电容数据后输出触点坐标和压力信息。
2. 硬件连接与数据流
触摸屏玻璃、ITO 电极、FPC → 控制板(触控 IC) → I²C 连接到主控,坐标采样与滤波由触控芯片完成,驱动层主要负责 I²C 读写和事件上报。
坐标如何获取,如何保存都是触控芯片自动完成的,对于产品开发的驱动工程师而言,就是 I2C 获取数据。



I²C 从地址:
GT911 支持 0x5D(0xBA/0xBB 去掉 R/W 位)与 0x14(0x28/0x29 去掉 R/W 位)两组地址,通过 RESET/INT 上电时序选择(GT911 数据手册摘录,见上图示)。
二. 驱动分析
1. 设备树
1>从设备地址

从上面可知,带读写位的地址为:0xBA/0XBB,转为二进制: 10111010/10111011 ,去掉最右边的读写位从设备地址: 1011101-->0x5d
2> 设备树文件
参考文件:
devicetree/bindings/input/touchscreen/goodix.txt
修改 arch/arm/boot/dts/stm32mp157a-fsmp1a.dts 文件,在文件末尾增加如下内容:
c
&i2c2 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c2_pins_a>;
pinctrl-1 = <&i2c2_pins_sleep_a>;
i2c-scl-rising-time-ns = <100>;
i2c-scl-falling-time-ns = <7>;
status = "okay";
/delete-property/dmas;
/delete-property/dma-names;
touchscreen@5d {
compatible = "goodix,gt911";
reg = <0x5d>;
irq-gpios = <&gpiog 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
reset-gpios = <&gpiog 8 GPIO_ACTIVE_HIGH>;
interrupt-parent = <&gpiog>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
status = "okay";
// touchscreen-inverted-x;
touchscreen-inverted-y;
// touchscreen-swapped-x-y;
};
};
//编译,并更新
make ARCH=arm dtbs LOADADDR=0xC2000040
cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb /tftpboot/
3> 配置内核
bash
Device Drivers --->
Graphics support --->
<*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) --->
<*> DRM Support for STMicroelectronics SoC Series
Display Interface Bridges --->
<*> Silicon Image sii902x RGB/HDMI bridge
-> Device Drivers -> Input device support
-> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y]) -> Touchscreens (INPUT_TOUCHSCREEN [=y])
Goodix I2C touchscreen
重新编译内核,并更新
make ARCH=arm -j4 uImage LOADADDR=0xC2000040
cp arch/arm/boot/uImage /tftpboot/
4> 重启开发板测试
bash
[root@fsmp1a ~]# ls -l /dev/input/event0
crw-r----- 1 root root 13, 64 Jan 1 1970 /dev/input/event0
root@fsmp1a ~]# ls /sys/class/input/event0/
dev device power subsystem uevent
[root@fsmp1a ~]# cat /sys/class/input/event0/device/name
Goodix Capacitive TouchScreen
三. TS_Lib移植与配置
bash
源码下载:git clone https://github.com/kergoth/tslib
1.拷贝tslib-1.4.tar.gz到ubutun的工作目录,如:\\192.168.60.6\peter\fsmp1\tools
2.解压缩
tar -xvf tslib-1.4.tar.gz
//进入解压后的目录
cd tslib-1.21/
3.配置
sudo apt-get install autoconf libtool
./autogen.sh
mkdir tmp
echo "ac_cv_func_mallo_0_nonnull=yes">arm-ostl-linux-gnueabi.cache
./configure --host=arm-ostl-linux-gnueabi --prefix=$(pwd)/tmp --cache-file=arm-ostl-linux-gnueabi.cache
4.编译
make
make的时候会出现如下错误:
ts_test.c:(.text+0x1e4): undefined reference to `rpl_malloc'
解决方法:将config.h.in里的 #undef malloc屏蔽掉
5.安装
make install
6.将tmp目录中生成的相关库文件拷贝到开发板的文件系统中
例如:cp -af tmp/* /opt/myrootfs/
7.cd /opt/myrootfs/lib
mkdir ts (如果已经存在报错那么就不管他)
8.进入到tslib的源码目录,拷贝plugins 到/opt/myrootfs/lib/ts/
例如:
farsight@ubuntu:~/mp157/tools/tslib-1.21$ cp -af plugins/ /opt/myrootfs/lib/ts/
9.修改/opt/myrootfs/etc/ts.conf第一行(去掉#号和第一个空格)
#module_raw input
改为
module_raw input
10.修改/myrootfs/etc/profile文件
vi/opt/myrootfs/etc/profile
在文件末尾添加如下代码
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=/dev/tty
export TSLIB_FBDEVICE=/dev/fb0
11.启动开发板
//运行ts_calibrate,并根据提示进行校准
例如:
[root@fsmp1a ~]# ts_calibrate
xres = 480, yres = 854
Took 2 samples...
Top left : X = 117 Y = 234
Took 1 samples...
Top right : X = 294 Y = 759
Took 1 samples...
Bot right : X = 217 Y = 153
Took 1 samples...
Bot left : X = 388 Y = 481
Took 1 samples...
Center : X = 16 Y = 403
184.463776 -0.121675 0.198645
515.863647 1.542433 -1.003010
Calibration constants: 12089018 -7974 13018 33807640 101084 -65733 65536
//运行ts_test,点击draw按钮,可以自由画图
[root@fsmp1a ~]# ts_test
948309974.279720: 181 583 255
948309974.397848: 181 583 0
948309975.249617: 228 550 255
948309975.357378: 228 550 255
948309975.368241: 228 549 255
948309975.378880: 229 546 255
948309975.389606: 231 540 255
948309975.400481: 233 535 255
948309975.411218: 235 533 255
948309975.422009: 237 534 255
948309975.432781: 237 539 255
948309975.443556: 237 545 255
948309975.454308: 237 551 255
948309975.465094: 236 559 255
如果要修改触摸屏输入设备节点 为/dev/event1
需要修改
1./opt/rootfs/etc/profile
2.tslib库tests目录下的ts_test.c的源码
结合官方仓库(https://github.com/libts/tslib)的最新说明,推荐使用较新的版本(例如 1.24),以下步骤以通用流程为参考。
- 源码准备与编译
bash
git clone https://github.com/libts/tslib.git
cd tslib
./autogen.sh
mkdir build && cd build
../configure --host=arm-ostl-linux-gnueabi --prefix=$(pwd)/install \
--cache-file=arm.cache
make
make install
如果使用历史版本(如 1.21),可能需要屏蔽 config.h 中对 malloc 的重定义。新版本通常无需此工作。
- 拷贝文件到目标根文件系统
bash
cp -a install/etc /opt/myrootfs/
cp -a install/bin /opt/myrootfs/
cp -a install/lib /opt/myrootfs/
cp -a install/share/tslib /opt/myrootfs/share/
mkdir -p /opt/myrootfs/lib/ts
cp -a install/lib/ts/*.so /opt/myrootfs/lib/ts/
- 配置
ts.conf
确保首行启用 module_raw input:
bash
# /etc/ts.conf
module_raw input grab_events=1
module median depth=3
module dejitter delta=100
module linear
更多可选滤波模块详见官方文档(median、iir、lowpass、crop、evthres等)。
- 环境变量设置
在 /etc/profile 或专用脚本中添加:
bash
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=/dev/tty
export TSLIB_FBDEVICE=/dev/fb0
tslib 默认会自动探测设备。若事件号可能变动,可结合 udev 规则创建固定符号链接(参考 README 中的 ts_uinput_start.sh 和 98-touchscreen.rules)。
- 校准与测试
bash
ts_calibrate # 按提示点击五个校准点
ts_test # 单点触控测试
ts_test_mt # 多点触控测试
校准后会生成 /etc/pointercal,不要手工编辑。
如果需要为上层 GUI 提供过滤后的 evdev 设备,可使用:
bash
ts_uinput -d -v
# 输出 /dev/input/eventX,可链接为 /dev/input/ts_uinput
常见问题排查
| 现象 | 可能原因 | 建议 |
|---|---|---|
/dev/input/eventX 无 GT911 |
I²C 地址错误、复位序列不对 | 逻辑分析校验 RESET/INT 时序;尝试改用 0x14 地址 |
| 触摸坐标错位 | touchscreen-inverted-* 配置不符、校准文件失效 |
调整设备树翻转属性,重新 ts_calibrate |
| 多点触控异常 | tslib 滤波限制(如 variance 不支持 MT) |
优先使用 median+iir 等支持多点的模块 |
| 事件数跳动 | tslib 未抓取事件 |
module_raw input grab_events=1 |
| GUI 无触摸响应 | 未使用 ts_uinput、上层绑定错误设备 |
确认 QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/ts_uinput 等环境变量 |
硬件层面:确定 GT911 I²C 地址、引脚映射与上电时序是成功驱动的前提。
内核层面:设备树节点、驱动配置、输入子系统流程需整体理解,方便调试 I²C/中断/多点触控功能。
用户空间:通过 tslib 进行滤波和校准,可大幅提升触摸体验;配合 ts_uinput 能够为各种图形栈提供统一的输入接口。
系统启动:掌握内核早期流程有助于定位硬件初始化问题(如 I²C 控制器未启用导致触摸驱动探测失败)。
协同调试:确保 DRM 显示模式与触摸校准一致,必要时统一屏幕旋转和坐标转换。
通过本文的结构化整理,开发者可以按照 "硬件 → 设备树 → 驱动 → 用户态 → 系统启动" 的顺序,可以快速构建并排查 STM32MP1 平台 GT911 触摸显示方案。
以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!