【Linux 驱动开发】STM32MP1 + GT911 触摸显示系统开发笔记

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.OrgQtWayland/libinput 等)获取稳定的触摸事件。

gt911 驱动框架:

GT911 驱动框架解析:

  1. 平台层:platform_bus 匹配 i2c2 控制器 → i2c_adapter 驱动(drivers/i2c/busses/i2c-stm32f7.c)注册。
  2. I²C 子系统:设备树节点 touchscreen@5di2c_client → 匹配 drivers/input/touchscreen/goodix.c
  3. 输入子系统:
    • goodix_probe() 解析 GPIO、复位 GT911、读取固件信息。
    • 注册 input_dev,设置多点触控 BTN_TOUCHABS_MT_POSITION_X/Y 等。
    • 请求中断,在 goodix_irq_handler() 中通过 I²C 读取坐标缓冲区,调用 input_mt_report_slot_state()input_sync() 上报。
  4. 应用层:evdevlibinputtslib 等通过 /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),以下步骤以通用流程为参考。

  1. 源码准备与编译
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 的重定义。新版本通常无需此工作。

  1. 拷贝文件到目标根文件系统
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/
  1. 配置 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等)。

  1. 环境变量设置

/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.sh98-touchscreen.rules)。

  1. 校准与测试
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 触摸显示方案。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

相关推荐
zmjjdank1ng1 小时前
如何保证ansible的幂等性
linux·服务器·ansible
Flamingˢ1 小时前
基于ARM的裸机程序设计和开发(一):Zynq SoC FPGA的诞生
arm开发·fpga开发
深圳市九鼎创展科技2 小时前
国产高性能 AIoT 核心板!九鼎创展 Z3576 核心板全面解析(基于瑞芯微 RK3576)
大数据·linux·人工智能·嵌入式硬件·ubuntu
SC_CSDN_L2 小时前
【精选记录】解决VMware中Linux虚拟机桥接模式下ping 出现DUP(重复包)问题
linux·服务器·网络·dup
Mumunu-2 小时前
Apple Silicon核心arm64 架构MAC部署openclaw
linux·运维·macos
泽平5902 小时前
Linux Pinctrl子系统
linux·运维·服务器·驱动开发·单片机·linux驱动
Wizard7972 小时前
LINUX BootLoader启动程序解析
android·linux
柏木乃一2 小时前
Linux线程(2)线程的优点和缺点/线程异常/posix线程库原理
linux·运维·服务器·c++·线程·posix
MIXLLRED2 小时前
Ubuntu 22.04 + ROS2 Humble 环境下设计图形化交互界面
linux·ubuntu·交互·图形界面