目录
- TouchGFX 简介
- 一些基础概念 Some Basic Concepts
- 开发简介 Development Introduction
- 搭建开发板
- TouchGFX 开发
1 TouchGFX 简介
TouchGFX is delivered as one X-Cube package the X-Cube-TouchGFX
简单来说是一基于 STM32 的 GUI 应用开发组件,其包含三个部分:(官网链接)
- TouchGFX Designer :TouchGFX 中构建 GUI 界面的可视化工具
- TouchGFX Generator:STM32CubeMX 的插件,为基于 STM32 的硬件设置和生成 TouchGFX 抽象层
- **TouchGFX Engine **:用于驱动 UI 应用程序的 TouchGFX C++ 框架,以及处理屏幕更新、用户事件和定时等。并提供针对 STM32 MPU 的优化,从而以 CPU 最低负荷和内存消耗实现最佳性能
安装建议参考 官方文档
2 一些基础概念 Some Basic Concepts
2.1 嵌入式图形
对于 TouchGFX 而言,嵌入式系统指的是所有基于 STM32 MPU 的系统。图形指的是每秒 60 帧用户交互应用界面
为了在基于 STM32 MPU 的系统板实现用户交互界面,至少需要四个部分:MCU、RAM、Flash、Display
TouchGFX 使用 MCU 读取 Flash 中数据并组织传送到 RAM 中生成和更新画面,最终输出到显示器上。
- MUC:在生成图像的过程中,负责所有重活。从 Flash 中读取数据,计算后写入 RAM 中等待读取显示。
- RAM:RAM 用于存储经过计算后的图像数据。当显示的时候,MCU 将会从 RAM 中读取数据。
- Flash:用于存储静态数据(图像、字体、文本)。MCU 读取 Flash 写入或者组合计算到 RAM 中。由于 MCU 内部 Flash 的大小通常无法满足图像显示的要求,一般会配置一个外部 Flash。如果是对于一些简单的应用,内部 MCU 足以。
- Display:显示器部分
2.2 颜色格式 Color Format
我们所见到显示屏上的颜色或者图像,其数据存储在 RAM 中,称为 帧缓冲区(Framebuffer)。一般来说,所显示的颜色通常是有限的。每一个像素点上的颜色由 RGB 三种颜色混合而成,颜色的丰富与这三种颜色的表达形式有直接关系。一般采用 RGB 各八位显示。色深是指单个像素点表示所需要的位数之和,例如 24位,RGBA——(255,255,255)
颜色格式:
-
RGB8888——24位色深
1
uint32_t brightPurpleRGB8888 = 255<<16 | 0<<8 | 255<<0;
-
RGB565——16位色深
1
uint32_t brightPurpleRGB565 = 31 << 11 | 0 << 5 | 0 << 0;
-
RGBx2222, xRGB2222, BGRx2222, xBGR2222——6位色深
1
uint8_t brightYellowRGBx2222 = 3<<6 | 3<<4 | 0<<2;
2.3 图像引擎
图像引擎分为两种:即时图像演算以及保留式图像。TouchGFX 为保留模式的图形引擎。这可以让用户专注于操作而 TouchGFX 专注于将图形模型装配形成画面。
保留式图像引擎(Retained Mode Graphics Engines):
用户操作被显示的组件的抽象模型,引擎负责在正确的时间将这个组建模型转换为争取的图形绘制操作
这样做的优点:
- 使用门槛低:保留式图像引擎相对来说使用简单,用户只需要分配布局而不需要了解背后的真正绘图操作
- 性能:TouchGFX 优化了屏幕上显示模型所需要的绘制调用。
- 状态管理:TouchGFX 会检测场景模型的那一部分是活动,这反过来又使得用户更容易优化场景模型内容
- 内存消耗:TouchGFX 通过优化,减少了大量的内存,通常能做到每秒渲染 60 帧。
2.4 内存使用
官方文档中给出了 TouchGFX 的内存使用:
| Memory Type | Usage |
|---|---|
| Internal_RAM | Internal RAM is used for configuration data like coordinates and color of all the Widgets. A few object for the current screen is allocated here. |
| Internal_Flash | Internal flash is used for program code for the application, the TouchGFX library, and other libraries used. |
| External_RAM | External RAM is typically used for framebuffers and maybe a bitmap cache. |
| External_Flash | External flash is used to store images, fonts and texts. |
其中 TouchGFX 只使用 静态存储分配,这些存储空间是实现分配好的,所以不存在运行的时候内存溢出。
3 开发简介 Development Introduction
3.1主要部件
TouchGFX 由五个主要的软硬件组成,在 TouchGFX 中每个操作都会生成一个部件。TouchGFX Engine 不是任何主要操作的输出,而是 TouchGFX 项目的起点。
3.2 STM32CubeMX / STM32CubeIDE
TouchGFX 需要 STM32CubeMX 来配置 MCU 并生成基础性的驱动代码。对于外设(外部 RAM,外部 Flash,显示器……)需要自行添加初始化代码和特定的外设芯片的驱动程序。理论上可以自己写,但是除非你是专家不然不推荐~
3.3 硬件考虑
从上面的结构可以知道,TouchGFX 在实现交互界面的时候,通常会用到外部 Flash 以及外部 RAM 来作为外部帧缓存(framebuffter)。其中外部拓展的存储设备分为 并行(Serial)和 串行(Parallel)。下图列举了一些,而这些外部存储的连接方式均可以在 STM32CubeMX 中配置。其中 NOR Flash 存储支持许多种协议的传输:Signal、DUal、Quad 和 Octo。更详细的介绍参考 官方文档
[
帧缓存外部 RAM 选择
如果需要使用外部 RAM 实现帧缓存 可以参考官方给出的表格:
4 搭建开发板
官方文档 中这一部分很细致地介绍了如何搭建一个稳定的显示平台,如果有自制平台的需求,强烈推荐阅读一下!在这里不过多赘述,望谅解。
5 TouchGFX 开发
5.1 TouchGFX AL
TouchGFX 抽象层(AL,Abstract Layer)是位于板启动阶段开发的板级初始化代码于 TouchGFX Engine 之间的软件组件。其主要任务是将引擎与底层硬件和操作系统相结合。这通过抽象底层硬件和操作系统的特性来完成,以便引擎可对其统一访问以及处理。
AL又分为:硬件抽象层(HAL)以及操作系统抽象层(OSAL)
由于 TouchGFX AL 是一种没有自身线程或类似线程的被动软件模块,因此他必须通过 TouchGFX Engine 主循环调用特定的函数或者通过中断来执行其操作。
| 中断 | 执行操作 |
|---|---|
| I1:显示就绪 | 设置 LTDC VSYNC 中断,以触发操作 取消阻塞主循环,并启动在上一帧中准备好的帧缓存数据传输 |
| H1:报告触摸与物理按钮事件 | 返回有关触摸事件或物理按键单击的任何信息 |
| H2:获取下一个可用的帧缓冲区 | 使用双缓冲设置,只需返回当前未传输至显示器的帧缓冲的整个帧缓冲区 |
| H3:执行渲染操作 | 这一步取决于 MCU 的性能。执行其余的硬件辅助渲染操作和软件回退 |
| H4:区域渲染完成 | 无操作 |
| H5:渲染完成 | 阻塞主循环 |
5.2 Generator 用户指南
准备工作
在我们进入 STM32CubeMX 或者 STM32CubeMX 中创建运行 TouchGFX 项目时,我们需要先确认:
- 所使用的芯片是否支持 TouchGFX
- STM32Cube 工具是否已经安装了 TouchGFX 的插件/软件包,并确认使能 TouchGFX
查看是否安装 TouchGFX:
点击 附加软件 中找到 TouchGFX Generator 的项目,用户可以通过 附加软件 来访问 X-CUBE 的附加功能
如果采用双核 MCU,需要确认正确的环境启用。TouchGFX 只能在 一个 核中启动。
生成的代码框架
一旦在 附加软件 中启用了 TouchGFX Generator,则 STM32CubeMX 始终会生成一个名为 TouchGFX 的文件夹,无论如何配置,其内部文件结构是固定的。
1 | │ .mxproject |
下面介绍一些文件的功能:
| 文件 | 功能 |
|---|---|
| myproject.ioc | STM32CubeMX Project File |
| Core | main.c and startup code |
| Drivers | CMSIS and MCU family drivers |
| EWARM | IDE project folder. Can be EWARM, MDK-ARM or STM32CubeIDE |
| Middlewares | Contains TouchGFX library / head files and third party software like FreeRTOS |
| ApplicationTemplate.touchfx.part | The .part file is updated by STM32CubeMX with information that is relevant to TouchGFX Designer Project, e.g. screen dimensions and bit depth |
| App | X-CUBE interface to STM32CubeMX. app_touchgfx.c contains definitions for the function MX_TouchGFX_Process(void) and MX_TouchGFX_Init(void) which are used to initialize TouchGFX and start its main loop. |
| target / generated | This sub-folder contains the read-only files that get overwritten by STM32CubeMX when configurations change. TouchGFXGeneratedHAL.cpp is a sub-class of the TouchGFX class HAL and contains the code that STM32CubeMX can generate based on its current configuration. OSWrappers.cpp (The OSAL) contains the functions required to synchronize withTouchGFX Engine, and finally TouchGFXConfiguration.cpp which contains the code to construct and configure TouchGFX, including the HAL. |
| target | Contains the bulk of files that can be modified by the user to extend the behavior of the HAL or to override configurations generated by STM32CubeMX. STM32TouchController.cpp contains an empty touch controller interface. TouchGFXHAL.cpp defines a sub-class, TouchGFXHAL, of TouchGFXGeneratedHAL. |
需要注意的是,TouchGFXConfiguration.cpp包含一个用于构建 HAL 的函数以及一个用于启动 TouchGFX 主循环的函数。 可在可编辑的用户类 TouchGFXHAL中完成其他配置。 HAL 的一般架构如下所示:
特性概述 Feature Overview
使能 TouchGFX Generator 后,我们可以在 Configuration 中看到三个组的配置信息:
- 依赖关系(Dependencies):该组包含关于针对开发人员的有关配置中的 依赖关系 、警告、具体错误的通知。如果没有条目,则该组将会隐藏
- 显示(Display):该组包含与显示有关的设置,如接口,帧缓存的位深,宽度和高度。这些设置将会直接影响 TouchGFX 项目里画布的大小以及基于显示部件所生成的代码
- 驱动程序(Driver):该组允许用户选择与应用相关的滴答计时器、图形加速和 RTOS 有关的一些现成驱动程序。(自从 STM32 支持 FreeRTOS 设置后, TouchGFX Generator 为每个选项提供驱动。)
显示 Display
接口与尺寸:
STM32 MCU 支持多个显示接口:Parallel RGB(LTDC)、MIPI DSI、FMC、SPI
需要注意的是:如果使用 LTDC 与 FMC, TouchGFX 可以生成代码让帧缓冲与显示器连接;但对于 DSI 与 SPI 而言,接口的驱动程序需要又开发者自己完成。
帧缓冲区的像素格式
设置的缓冲格式将会限制 TouchGFX Generator 的设置,支持的显示格式如下:其中一些像素格式无法或只能部分进行硬件加速(DMA2D),(bpp = bit per pixel)
- Grey2 (2 bpp)
- Grey4 (4 bpp)
- ABRG2222 (8 bpp)
- ARGB2222 (8 bpp)
- BGRA2222 (8 bpp)
- RGBA2222 (8 bpp)
- RGB565 (16 bpp)
- RGB888 (24 bpp)
- ARGB8888 (32 bpp)
注意:对于 cortex F7/H7,如果帧缓冲区设置在写缓存的内存中(e.g. SRAM),那么在 DMA2D 访问它之前,DCache 将被生成的代码刷新。需要记得在 STM32CubeMX 的 Cortex M7 的系统核心设置中启用 CPU 缓存,以便让这个缓存机制发挥作用
缓冲策略
- 单帧缓冲:仅使用一个应用帧缓冲区,占用内存少但是可能会使性能受限。可与 缓冲位置 配置一起使用,将其放置在 内部 RAM 中。
- 双缓冲:使用两个帧缓冲区。以牺牲内存换取性能。
- 部分缓冲:将一个或多个用户定义的内存块作为帧缓冲区。该策略适用于低成本解决方案,他不依赖于外部 RAM 但可以实现超出可用内存的全帧缓冲能力。
对于单缓冲与双缓冲,用户可以设置 缓冲器位置 来配置其位置:
- 按分配:允许链接器根据链接器脚本来放置帧缓冲存储器。默认位于内部 RAM 中。
- 按地址:允许用户定义一个单或双帧缓冲地址
对于 部分帧缓冲,其允许用户定义:块数(始终放在内部 RAM 中),块大小(字节)
驱动 Driver
应用滴答计时器
滴答计时源定义了如何展开驱动程序的开发。开发者具有两个选项:
- LTDC:如果设置 Display-interface 为 LTDC。则 TouchGFX Generator 将在
TouchGFXGenerated HAL类中安装驱动程序(LTDC 中断处理程序),该函数通过调用OSWrappers::signalVSync()来展开驱动应用程序。 - Custom and FMC:如果设置为 Custom and FMC,开发者需要实现一个程序(Handler),通过反复调用
OSWrappers::signalVSync()来驱动应用程序运行。
图像加速器
对于图形加速,开发者拥有三个选项:
- None:应用只使用 CPU 渲染
- Chrom-ART (DMA2D):应用程序在可能的情况下使用 Chrom-ART 芯片来移动和混合像素,释放 CPU。驱动程序由 TouchGFX Generator 安装,不需要开发人员采取任何措施。
通过在 STM32CUbeMX 的 DMA2D IP 的 NIVIC 中断设置中启用或禁用 DMA2D 全局中断来实现这两者之间的切换:
- 启用全局中断:使用 STM32Cube HAL 驱动,其中有一个 DMA2D Handle 回调函数
hdma2d.XferCpltCallback - 禁用全局中断:则直接使用 DMA2D_IRQHandler() 中断处理程序
注意:
当 DMA2D 使用全局变量的时候,确保 IRQ handler 调用 DMA2D HAL handler (默认行为)
如果全局中断启用,但却禁用了 IRQ handler 和 调用 HAL 处理程序 ,这则会导致回调函数将永远不会被调用
实时操作系统
……
Scenarios
LTDC/ Parellel RGB
使用TFT控制器的MUC,TouchGFX Generator 可生成用来配置 LTDC,以及将像素从帧缓存传输到显示器的HAL 部分代码。一旦 TLDC 触发 VSYNC 中断,生成的代码将启用正确的帧缓存传输,并通过调用 OSWrappers::signalVSync() 来解除 TouchGFX Engine 主循环阻塞。
显示接口
使用 并行RGB(LTDC) 时,TouchGFX Generator 可以生成支持 LTDC 泪痣所需要的所有 TouchGFX HAL 代码。
若要使 LTDC 成为 TouchGFX Generator 的可选项,需要在 STM32CubeMX 中 Multimedia 中启用 LTDC
使能之后,LTDC 选项将在 TouchGFX Generator 的显示部分(Display)中可用。在使能之后还要 记得 后续步骤:
- 配置 LTDC(GPIO 与相关时序参数),以便与连接的显示器规格相匹配
- 配置 LTDC,以便与所需的 TouchGFX 应用程序 需求 相匹配
在启用后,你可能会看到许多设置报错或者警告,这些称之为 依赖项,我们需要配置相关的依赖项目才可以使 LTDC 正常工作。
依赖关系:
| 依赖关系 | 说明 |
|---|---|
| 不支持的像素格式 | TouchGFX 帧缓冲的驱动程序 仅支持 RGB565(16bit)和RGB888(24bit)格式。LTDC的像素格式必须与 TouchGFX HAL 的所选驱动相匹配 |
| 配置的其他层 | TouchGFX 只能利用单层。尽管 TouchGFX 应用程序可能在使能两个层的情况下运行,但用户需要注意,这个可能导致 LTDC 配置错误,更改 LTDC 块中的层数 |
| 混合因数应为 PAxCA | 默认情况下,混合因数为 Alpha 常数;这应为 Alpha常数 x 像素 Alpha(Pixel Alpha x Alpha Constant ) |
| Alpha 常数为 0 | 默认情况下,LTDC 层的 alpha 常数为0。除非始终在应用程序中具有全局的 alpha, 负责该常数应该大于 0,最好为 255 |
注意:通常需要确保帧缓存图像宽度和图像高度与窗口尺寸匹配。
TouchGFX 驱动程序 / VSYNC 信号
一旦 LTDC 被选作显示接口,开发人员就可以访问 LTED 应用滴答计时驱动(Drive -> Application Tick Source)或者 TouchGFX 驱动程序。
根据 LTDC 配置生成的 LTDC 中断处理程序:
为了使 LTDC 驱动程序能够正常工作,用户必须通过 LTDC NVIC 或通过 Global NVIC 设置来使能 LTDC 的全局中断,同时使能中断处理代码的生成(Code generation -> Generate IRQ handler ☑️, Call HAL handler ☑️ )
1 | extern "C" |





