2. TouchGFX基础回顾

在进入量产部署与调试之前,有必要把 TouchGFX 的运行时骨架重新梳理一遍。很多现场问题——画面撕裂、触摸无响应、内存不足、动画卡顿——追根溯源并不是驱动或硬件故障,而是对框架的分层职责、MVP 数据流向和事件分发路径理解不到位。本节从架构、模式、控件、事件四个维度建立一张"全局地图",为后续的部署与排障提供判断依据。

一、架构组成:三层协作的运行时结构

TouchGFX 在 MCU 上运行时可以划分为三个协作层:硬件抽象层、框架核心层和应用层。硬件抽象层负责把 LCD 控制器、DMA2D/GPU2D、触摸控制器、外部 SDRAM/Flash 等外设封装成统一接口,典型实现是 TouchGFXHAL 与 TouchGFXGeneratedHAL;框架核心层包含渲染引擎、Drawable 树、Screen/Presenter/View 基类、Model 基类以及 TouchGFXEngine 主循环;应用层则是开发者用 Designer 生成的界面代码与手写的业务逻辑。

渲染路径上,框架采用"脏矩形 + 双缓冲"策略:只有发生变化的区域才被重绘,绘制结果写入帧缓冲,再由 LTDC 或 SPI/RGB 接口扫描输出。理解这条路径,就能解释为什么"局部刷新比全屏刷新省 CPU",也能解释为什么帧缓冲数量与 SDRAM 带宽直接决定能否跑满 60 FPS。

TouchGFX 运行时架构与 MVP 数据流 应用层 Application View 控件树 / 绘制 / 动画 Presenter 激活/退出/交互协调 Model 业务数据 / 状态 回调 读写 通知 更新 框架核心层 TouchGFX Core 渲染引擎 脏矩形 / 双缓冲 事件分发 Click / Drag / Gesture Drawable 树 层级 / 可见性 TouchGFXEngine 主循环 tick / 采样 / 帧同步 硬件抽象层 HAL LTDC / SPI 显示 帧缓冲扫描输出 DMA2D / GPU2D 填充 / 混合 / 拷贝 触摸控制器 I2C 采样 / 中断 SDRAM / Flash 帧缓冲 / 资源

二、MVP 模式:把界面与业务解耦

TouchGFX 采用 MVP(Model-View-Presenter)而非 MVC,核心目的是让 View 只关心"怎么画",Model 只关心"数据是什么",Presenter 负责"什么时候做什么"。三者通过生成代码中的 setModel()、bind() 和回调函数连接。

典型的数据流是:用户在 View 上点击按钮 → View 调用 Presenter 的槽函数 → Presenter 调用 Model 的接口 → Model 更新数据并触发回调 → Presenter 收到回调后调用 view.updateXxx() → View 刷新控件。这条链路是单向的,任何"View 直接改 Model"或"Model 直接操作控件"的写法都会破坏可测试性,也是量产阶段最难排查的一类耦合缺陷。

// Presenter 中典型的交互转发
void Screen1Presenter::onButtonClicked()
{
    model->incrementCounter();      // 交给 Model 处理业务
}

// Model 数据变化后回调 Presenter
void Screen1Presenter::counterUpdated(int value)
{
    view.setCounterText(value);     // 由 View 负责显示
}

三、控件体系:从基础到复合

TouchGFX 的控件以 Drawable 为根,按能力可分为四类:基础绘制类(Box、TextArea、Image)、交互类(Button、ToggleButton、Slider、FlexButton)、容器类(Container、ScrollableContainer、ModalWindow)和动态效果类(AnimatedImage、TextureMapper、MoveAnimator)。Designer 中拖拽出的每个控件最终都会生成对应的 C++ 成员变量,命名规则为 控件类型 + 序号,例如 button1、textArea2。

控件类别代表控件典型用途量产关注点
基础绘制Box / TextArea / Image背景、文字、图标位图格式与 Flash 占用
交互Button / Slider / FlexButton点击、拖动、状态切换触摸采样率与去抖
容器Container / ScrollableContainer页面分区、列表滚动嵌套层级与重绘范围
动态效果AnimatedImage / TextureMapper动画、3D 变换帧率与 SDRAM 带宽

四、事件机制:从触摸采样到回调

事件机制的入口是 HAL 的触摸采样。框架在每个 tick 中读取触摸坐标,生成 ClickEvent、DragEvent、GestureEvent 等对象,然后沿 Drawable 树自顶向下做命中测试。命中后事件被投递给对应控件的 handleClickEvent(),控件再通过回调触发 Presenter 逻辑。

事件分发遵循"最上层可见且可交互的 Drawable 优先"原则。如果某个控件被透明遮罩覆盖,或 setTouchable(false) 被误设,就会出现"看得见却点不动"的现象,这是量产调试中最高频的触摸类问题。

五、适用场景与常见误区

TouchGFX 适合中高分辨率、需要流畅动画与复杂交互的 HMI 场景,例如工业面板、家电触控屏、医疗设备界面。对于仅需显示少量文字与图标的极简界面,裸机 + 简单绘图库往往更省资源。

常见误区有三:一是把业务逻辑写进 View,导致换屏时大量复制代码;二是在 Presenter 中直接操作硬件外设,破坏分层;三是忽略 invalidate() 的调用时机,造成画面不刷新或过度刷新。量产前应通过代码审查逐项排除。