3. TouchGFX前世今生:发展历史、商业背景与核心设计哲学
说实话,很多工程师用TouchGFX做界面,却不太清楚它的来路。我当年第一次接触TouchGFX时,也觉得它像个“黑盒”——功能强大,但总搞不懂它为什么这么设计。后来深入研究了它的历史,才恍然大悟。
这一章,我们就聊聊TouchGFX的“前世今生”。你理解了它的出身和设计哲学,才能真正用好它。
3.1 从瑞典小公司到ST官方工具
TouchGFX的故事,得从2012年说起。
它最初是一家瑞典公司——TouchGFX AB的产品。创始团队是一群嵌入式图形发烧友,他们发现当时的MCU越来越强,但GUI框架却还停留在“画点、画线”的原始阶段。于是,他们决定自己搞一套。
早期的TouchGFX,说实话,挺小众的。主要服务一些北欧的工业客户。我2016年在一个工业HMI项目里第一次用到它,当时版本还是4.x,文档也不全,全靠啃源码。但它的渲染效率确实惊艳——同样的硬件,比当时流行的uCGUI流畅得多。
转折点在2018年。那年,意法半导体(ST)正式收购了TouchGFX AB。为什么ST要买它?原因很简单:ST的STM32系列MCU卖得越来越好,但缺一个“杀手级”的GUI工具。收购后,TouchGFX变成了ST的官方免费中间件。
关键时间线:
- 2012年:TouchGFX AB成立,发布首个商业版本
- 2015年:推出TouchGFX Designer(拖拽式UI设计工具)
- 2018年:被ST收购,成为STM32生态系统的一部分
- 2019年:TouchGFX 4.13发布,开始免费开放
- 2023年:TouchGFX 4.22,全面支持STM32MP系列MPU
被ST收购后,TouchGFX的定位变了——从“卖License”变成了“帮ST卖芯片”。这对开发者是好事,因为工具免费了,而且和STM32的HAL库、CubeMX深度绑定。
3.2 版本迭代:从“能用”到“好用”
我经历过TouchGFX好几个大版本的升级,每次都有“眼前一亮”的感觉。
| 版本 | 发布时间 | 核心变化 | 我的感受 |
|---|---|---|---|
| 4.0 - 4.6 | 2015-2017 | 基础框架、C++ API、硬件加速初版 | 功能够用,但文档太少,全靠自己试 |
| 4.10 - 4.12 | 2018-2019 | Designer大改版、支持动态字体、缓存优化 | 终于能“所见即所得”了,效率提升明显 |
| 4.13 - 4.15 | 2019-2020 | 免费开放、支持FreeRTOS、多屏管理 | 嗯,从这版开始,我敢在商业项目里放心用了 |
| 4.18 - 4.20 | 2021-2022 | Partial Buffer模式、GPU加速、视频播放 | 低内存设备也能跑复杂动画了,这个很实用 |
| 4.22+ | 2023-至今 | MPU支持、Linux后端、多核协同 | 从MCU到MPU,TouchGFX的野心变大了 |
我个人觉得,4.13版本是个分水岭。之前TouchGFX是收费的,一套License要几千美元,小公司根本用不起。免费之后,社区迅速壮大,Bug修复也快了很多。
一个小建议:如果你现在开始新项目,直接用最新的4.22+版本。老版本(4.13以下)的API风格和现在差别很大,迁移起来挺痛苦的。我曾经帮客户把一个4.10的项目升级到4.18,改了整整两周。
3.3 核心设计哲学:为什么TouchGFX“快”?
TouchGFX的设计哲学,说白了就三个词:硬件加速、帧缓存优化、C++深度绑定。我们一个一个说。
3.3.1 硬件加速:不浪费每一颗晶体管
TouchGFX从一开始就假设“硬件是来帮忙的”。它深度利用了STM32的LTDC(LCD-TFT显示控制器)、DMA2D(图形加速DMA)和Chrom-ART加速器。
举个例子,你在界面上画一张图,如果纯用CPU刷像素,可能得几毫秒。但用DMA2D,几百微秒就搞定了。TouchGFX的渲染管线,几乎每个环节都优先走硬件。
// TouchGFX内部典型的DMA2D配置片段
// 这不是你写的代码,但了解它有助于理解性能来源
void HAL_DMA2D_StartTransfer(...) {
// 配置源地址、目标地址、像素格式
// 硬件自动完成颜色格式转换、Alpha混合
// CPU可以在这段时间做其他事
DMA2D->CR = DMA2D_CR_START;
while (!(DMA2D->ISR & DMA2D_FLAG_TC));
}
我曾经在一个项目里对比过:同样的界面,用TouchGFX的硬件加速模式,帧率是软件渲染的3倍以上。而且CPU占用率从80%降到了20%。
3.3.2 帧缓存策略:用空间换时间
TouchGFX的帧缓存策略,是它“快”的另一个关键。它支持三种模式:
- Full Frame Buffer(全帧缓存):整屏缓存,适合大内存设备,渲染最流畅
- Partial Frame Buffer(部分帧缓存):只缓存屏幕的一部分,适合内存紧张的场景
- Double Buffer(双缓冲):两个缓存交替使用,避免撕裂
我建议,如果你的MCU有1MB以上的SRAM或SDRAM,优先用全帧缓存+双缓冲。如果内存只有几百KB,那就用部分帧缓存,但要注意渲染区域的划分——划分不好,反而会卡。
避坑指南:我曾经在一个项目里,为了省内存,把部分帧缓存的行数设得太小(只有8行)。结果界面滚动时,屏幕像“拉窗帘”一样,一截一截地刷新。后来改成32行,问题才解决。部分帧缓存的行数,建议至少是字体高度的2倍。
3.3.3 C++深度绑定:面向对象的GUI
TouchGFX是用C++写的,而且用了很多现代C++的特性。它的UI组件是“对象”而不是“结构体”。每个按钮、每个文本框,都是一个类实例。
这种设计的好处是:封装性好,复用性强。你写一个自定义控件,继承自touchgfx::Widget,然后重写draw()方法就行了。不像某些C语言框架,所有控件都塞在一个大结构体里,改一个地方可能影响全局。
// TouchGFX自定义控件的典型写法
class MyCustomWidget : public touchgfx::Widget {
public:
void draw(const touchgfx::Rect& invalidatedArea) const override {
// 在这里实现你的绘制逻辑
// 可以调用硬件加速API
}
touchgfx::Rect getSolidRect() const override {
return touchgfx::Rect(0, 0, getWidth(), getHeight());
}
};
不过,C++也带来一个问题:编译后的二进制体积偏大。同样的界面,用C写的框架可能只占几十KB,TouchGFX动不动就几百KB。所以,如果你的MCU Flash只有128KB,用TouchGFX会有点吃力。
3.4 TouchGFX的知识体系结构
为了让你更直观地理解TouchGFX的“骨架”,我画了一张结构图。它展示了TouchGFX的核心模块和它们之间的关系。
从这张图你可以看到,TouchGFX的架构是分层解耦的。你写UI代码时,基本只跟“应用层”和“框架层”打交道。底层怎么用DMA2D、怎么刷LTDC,都被封装好了。
这种设计的好处是:移植性好。我曾在STM32F429和STM32H743上跑过同一个TouchGFX工程,除了HAL配置不同,UI代码一行没改。
3.5 商业背景带来的“烙印”
TouchGFX被ST收购后,不可避免地打上了ST的烙印。这既是优势,也是限制。
优势:
- 与STM32生态深度集成,CubeMX一键生成工程
- 免费,没有License费用
- 官方维护,更新稳定
限制:
- 对非ST芯片支持很弱(虽然理论上可以移植,但没人帮你做)
- 闭源,核心渲染代码看不到
- 版本升级有时会“断崖式”变化(比如4.13到4.14,API改了不少)
我个人觉得,如果你用的是STM32系列,TouchGFX是首选。但如果你用其他厂家的MCU,还是看看LVGL或者Embedded Wizard吧——移植成本会低很多。
一个小经验:TouchGFX的社区论坛(community.touchgfx.com)其实挺活跃的。很多ST的工程师会直接在上面回答问题。我遇到过一个DMA2D的Bug,就是在论坛上找到的官方补丁。所以,别只闷头自己查,多去社区逛逛。
3.6 小结
TouchGFX从一个瑞典小公司的产品,变成ST的官方工具,走了十年。它的核心设计哲学——硬件加速、帧缓存优化、C++深度绑定——决定了它“快”但“挑硬件”的特性。
理解这些背景,你就能明白:为什么TouchGFX在STM32上跑得飞起,但移植到其他平台却困难重重。这不是技术问题,而是商业选择。