Skip to main content

Generator用户指南

TouchGFX Generator是X-CUBE-TOUCHGFX的一部分,也是CubeMX附加软件组件,可帮助开发人员配置TouchGFX并运行于他的硬件平台上。 根据已有的CubeMX设置和用户输入,TouchGFX Generator将生成TouchGFX应用所需的有效配置文件。 这包括TouchGFX HAL、TouchGFX OSAL和TouchGFX配置文件。

通过CubeMX生成代码后,可通过开发UI的TouchGFX Designer打开TouchGFX项目。 TouchGFX Designer会自动将任何额外生成的代码文件添加到通过CubeMX所配置的目标IDE。

使能TouchGFX Generator

下图显示了在附加软件类别中已使能TouchGFX Generator的项目。 用户可通过按“附加软件”按钮来访问X-CUBE的附加功能。

选择CubeMx中的附加软件

下图显示了项目中如何使能TouchGFX Generator:

使能TouchGFX Generator

生成的代码架构

在描述TouchGFX Generator的功能之前,了解所生成代码的架构以及开发人员如何使用该架构来定制配置和行为至关重要。

通过巧妙使用分布在CubeMX生成的C代码中的用户代码段,为CubeMX生成的文件中的手动用户代码提供保护。在TouchGFX Generator生成的C++代码中,通过继承来实现这种灵活性。

通过附加软件添加TouchGFX Generator并使能后,CubeMX总是会为项目创建一个TouchGFX文件夹。 无论配置如何,该文件夹总是包含相同的文件,而文件内容则因CubeMX和用户配置而异。

以下列表概述了使能TouchGFX Generator的CubeMX项目内容,并重点介绍与TouchGFX有关的文件。 下面按列表概述了最重要条目的功能。

TouchGFX Folder
│   .mxproject
│ myproject.ioc
├───Core
├───Drivers
├───EWARM
├───Middlewares
└───TouchGFX
│ ApplicationTemplate.touchgfx.part
├───App
│ app_touchgfx.c
│ app_touchgfx.h
└───target
│ STM32TouchController.cpp
│ STM32TouchController.hpp
│ TouchGFXGPIO.cpp
│ TouchGFXHAL.cpp
│ TouchGFXHAL.hpp

└───generated
OSWrappers.cpp
TouchGFXConfiguration.cpp
TouchGFXGeneratedHAL.cpp
TouchGFXGeneratedHAL.hpp
文件夹职责
myproject.iocCubeMX项目文件
内核main.c和启动代码
驱动CMSIS和MCU系列驱动程序
EWARMIDE项目文件夹。 可以为EWARM、MDK-ARM或STM32CubeIDE
中间件包含TouchGFX库/头文件以及FreeRTOS等第三方软件。
ApplicationTemplate.touchgfx.partCubeMX使用与TouchGFX Designer项目相关的信息(如屏幕尺寸和位深)来更新.part文件
应用X-CUBE interface to CubeMX. app_touchgfx.c contains definitions for the functions MX_TouchGFX_Process(void) and MX_TouchGFX_Init(void) which are used to initialize TouchGFX and start its main loop.
目标/生成该子文件夹包含只读文件,当配置更改时,这些文件会被CubeMX覆盖。 TouchGFXGeneratedHAL.cpp是TouchGFX类HAL的子类,并包含CubeMX基于其当前配置生成的代码。 OSWrappers.cpp(OSAL) 包含与TouchGFX Engine同步所需的功能,最后是TouchGFXConfiguration.cpp,其包含用于构建和配置TouchGFX的代码,包括HAL。
目标包含大量文件,用户可修改这些文件,以扩展HAL行为,或覆盖CubeMX生成的配置。 STM32TouchController.cpp包含触摸控制器操作的空接口。 TouchGFXHAL.cpp定义TouchGFXGeneratedHAL的子类TouchGFXHAL

需要注意的是,TouchGFXConfiguration.cpp包含一个用于构建HAL的函数以及一个用于启动TouchGFX主循环的函数。 可在可编辑的用户类TouchGFXHAL中完成其他配置。 HAL的一般架构如下所示:

生成的代码的层次结构

特性概述

使能TouchGFX Generator后,用户界面中存在三个组:

  • 依赖关系- 该组包含针对开关人员的有关配置中的依赖关系、警告或具体错误的通知。 如果没有条目,则该组将隐藏。
  • 显示- 该组包含与显示有关的设置,如接口、帧缓存的位深、宽度和高度。 这些设置直接影响TouchGFX项目里画布的大小以及基于显示部件所生成的代码。
  • 驱动程序- 该组允许用户选择与应用相关的滴答计时源、图形加速和RTOS有关的一些现成驱动程序。 由于CubeMX支持FreeRTOS(CMSIS RTOS v1和v2)配置,TouchGFX Generator为每个选项提供了驱动程序。

TouchGFX Generator有三个组:依赖关系、显示、驱动程序

显示

显示组包含与显示有关的配置,如接口、尺寸和缓冲策略。

接口与尺寸

如今,STM32微控制器可使用多个显示接口,如:

  • 并行RGB
  • MIPI DSI
  • FMC
  • SPI

对于带有LTDC的MCU,TouchGFX Generator可生成驱动程序,以将帧缓冲内容传输到相连接的显示器。 对于DSI、FMC和SPI接口,驱动程序必须由开发人员自己实现。

Further reading
有关不同显示界面的驱动程序具体事例,请参见方案章节。

缓冲策略

可通过TouchGFX Generator配置以下帧缓冲策略:

  • 单帧缓冲 - 仅使用一个应用帧缓冲区。 可能会使性能受限,但占用内存更少。 可与“缓冲位置”配置一起使用,将其放置在内部RAM中。 为进一步优化,用户可以定义一个函数,该函数返回显示控制器正在处理的当前行。 该方法用于框架,以允许更新该帧期间已传输到显示屏的内存。
  • 双缓冲 - 使用两个帧缓冲区。 通常以牺牲内存为代价来获得更好的性能。
  • 部分缓冲- 将一个或多个用户定义的内存块作为帧缓冲区。 该策略适用于低成本解决方案,它不依赖外部RAM但可以实现超出可用内存的全帧缓冲能力。

对于单缓冲区和双缓冲区,用户可通过“缓冲器位置”来配置其位置,该配置提供以下选项:

  • 按分配- 允许链接器根据链接器脚本来放置帧缓冲存储器。 默认位于内部RAM中。
  • 按地址- 允许用户定义一个(单) 或两个(双) 帧缓冲地址。

部分帧缓冲策略允许用户定义以下参数:

  • 块数(始终放置在内部RAM中)
  • 块大小(字节)

要了解有关部分缓冲战略的一些核心概念,请阅读使用部分帧缓冲区降低内存要求的专用文章。 本文从概念上说明了如何实现部分帧缓冲,并且本文中显示的代码与TouchGFX Generator生成的代码略有不同。 有关为这些策略生成的具体示例代码,请参见帧缓冲策略

驱动器

驱动器部分允许开发人员为TouchGFX AL的各种功能选择驱动程序。

应用滴答计时源

滴答计时源定义了如何展开驱动应用程序的开发。 开发人员具有以下选项:

  • LTDC- 如果在“显示”组中将LTDC选作接口,则应用计时源可以为“LTDC”。 这意味着TouchGFX Generator将在TouchGFXGenerated HAL类中安装驱动程序函数(LTDC中断处理程序) ,该函数通过调用OSWrappers::signalVSync()来展开驱动应用程序。
  • 定制- 在这种情况下,开发人员通过重复调用OSWrappers::signalVSync()来实现驱动应用程序。

图形加速器

对于图形加速,开发人员有三个选项:

  • - 应用程序仅使用CPU来绘制frames.
  • Chrom-ART (DMA2D)- 应用程序在可能的情况下使用Chrom-ART芯片来移动和混合像素,释放CPU。 驱动程序由TouchGFX Generator安装,不需要开发人员采取任何措施。
  1. Uses the STM32Cube HAL driver where it registers a callback funtion to the dma2d handle hdma2d.XferCpltCallback.
  2. Uses the DMA2D_IRQHandler() interrupt handler directly.

Switching between these two is done by enabling or disabling the DMA2D global interrupt in the NVIC Settings in CubeMX for DMA2D IP. Enabling the global interrupt generated code for option 1), disabling the global interrupt generates code for option 2).

Note
  • When using global interrupt for DMA2D, ensure that the "IRQ handler" calls the "DMA2D HAL handler", this is default behaviour.
  • If disabling "IRQ handler" and "Call HAL handler" for DMA2D while global interrupt is enabled will cause the registered callback to never be called.
  • 实时操作系统

    开发人员可使用任何支持TouchGFX的RTOS(甚至无操作系统)。 如抽象层架构中所述,TouchGFX Engine使用OSWrappers接口将其主事件循环以及帧缓冲访问与用户选择的RTOS同步。

    可直接在CubeMX中配置FreeRTOS,TouchGFX Generator允许用户为任务的定义和TouchGFX RTOS驱动程序生成代码。 TouchGFX Generator可生成兼容CMSIS V1和CMSIS V2的RTOS驱动程序,该驱动程序可用于兼容CMSIS的任何RTOS。 在这种情况下,开发人员无法依赖CubeMX生成任务定义代码,必须在用户代码中完成。

    下图显示了通过TouchGFX Generator可用的选项。

    RTOS驱动程序选项

    调用以下函数时,将进入TouchGFX主循环。

    void MX_TouchGFX_Process(void);

    开发人员需要在任务处理程序中为要在其中运行TouchGFX应用程序的任务调用此函数。 如果用户从CubeMX配置了名为DefaultTask的FeeRTOS任务,则以下示例显示了如何调用MX_TouchGFX_Process(),以启动其任务处理程序的用户代码部分中的TouchGFX。

    void StartDefaultTask(void *argument)
    {
      /* USER CODE BEGIN 5 */
    MX_TouchGFX_Process();
      /* USER CODE END 5 */ 
    }

    使能FreeRTOS时,CubeMX还将调用osKernelStart()启动调度器。

    其他兼容CMSIS的OS

    当开发人员采用与CubeMX提供的操作系统(FreeRTOS)不同的其他兼容CMSIS的操作系统时,他必须手动完成RTOS配置和任务定义。 通常,需要执行以下手动步骤:

    1. 配置RTOS
    2. 定义任务以运行TouchGFX (MX_TouchGFX_Process)
    3. 启动调度器

    以下是如何对Azure RTOS执行步骤2和3的示例。 由于CubeMX无法为此进行任何配置,因此必须在提供的用户代码部分中执行所有操作,以免代码被覆盖。 以下代码显示了GUI任务定义的伪代码。 通常,任何不是由CubeMX生成的代码均应放在分散于整个main.c文件中的用户代码部分

    /* BEGIN USER CODE SECTION */
    #include "tx_api.h"

    #define GUI_THREAD_STACK_SIZE 1024
    TX_THREAD gui_thread;
    void gui_thread_entry(ULONG thread_input); //Thread prototype
    /* END USER CODE SECTION */

    int main()
    {
    /* BEGIN USER CODE SECTION - Choose an appropriate one from main.c */
    /* Allocate the stack for gui thread */
    tx_byte_allocate(...);

    /* Create the gui thread. */
    tx_thread_create(&gui_thread, "GUI Thread", gui_thread_entry, 0,
    pointer, GUI_TASK_STACK_SIZE,
    1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* END USER CODE SECTION*/

    调用MX_TouchGFX_Process,以启动任务处理程序中的TouchGFX Engine主循环。

    /* BEGIN USER CODE SECTION */
    void gui_thread_entry(ULONG thread_input)
    {
    MX_TouchGFX_Process();
    }
    /* END USER CODE SECTION*/

    启动调度器,以启动GUI任务和您的TouchGFX应用。

    /* BEGIN USER CODE SECTION */
    tx_kernel_enter();
    /* END USER CODE SECTION*/

    其它功能

    外部数据读取器

    对于RGB565帧缓冲像素格式,touchgfx支持所谓的数据读取器接口,该接口使开发人员能够直接从非存储器映射串行闪存读取数据,而无需进行缓存,当然这需要增加额外的缓冲存储区。 有关如何实现DataReader,从非存储映射闪存芯片中获取应用程序资源的示例,请参见SerialFlash文章。

    数据读取器选项通常用于没有足够的内存用于额外缓冲区的低成本解决方案(如STM32G0) 。 如果DMA2D使能了,则无法使能该选项。

    一旦RGB565选作帧缓冲像素格式后,附加功能组将变得可用。

    其它功能:数据读取器

    开发人员可进行以下配置:

    • 外部数据读取器:使能或禁用功能。 如果使能,TouchGFX将直接通过生成的接口检索应用资源。 如果禁用,则开发人员需要将图片资源缓存到内存缓冲区中。
    • 外部数据读取器:行缓冲区大小:创建两个缓冲区,以便将图像或文本混合到帧缓冲中。 默认值为一个屏幕宽度*4字节,以支持ARGB8888像素格式的全尺寸图像。
    • 外部数据读取器:最小DMA传输大小:设置启动DMA传输所需的最小字节。 如果请求传输的字节更少,将不使用DMA。

    在使能外部数据读取器的情况下生成代码后,将创建以下附加文件,以支持直接从非存储器映射闪存中检索图片资源。

    • TouchGFX/target/generated/TouchGFXGeneratedDataReader.cpp
    • TouchGFX/target/generated/TouchGFXGeneratedDataReader.hpp
    • TouchGFX/target/TouchGFXDataReader.cpp
    • TouchGFX/target/TouchGFXDataReader.hpp

    像往常一样,对于TouchGFX Generator生成的代码,TouchGFXGeneratedDataReader为只读,用户修改应在TouchGFXDataReader类中进行。 TouchGFXGeneratedDataReader的类型为touchgfx::FlashDataReader

    将TouchGFX HAL配置为使用DataReader,并对以下文件进行修改。

    • TouchGFX/target/generated/TouchGFXConfiguration.cpp
    • TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp
    • TouchGFX/target/generated/TouchGFXGeneratedHAL.hpp
    Note
    仅当禁用DMA2D和LTDC时,DataReader附加功能才可用。

    8bit LTDC Color Look-up Table

    When the LTDC is configured to read the framebuffer in L8 format and TouchGFX renders in either ABRG2222, ARGB222, BGRA2222, or RGBA2222, TouchGFX Generator will provide a CLUT which is loaded into the LTDC during TouchGFXHAL::initialize(). Please refer to the STM32 MCU reference manual for more details on usage of LTDC and CLUT.

    生成的项目

    使用CubeMX中的生成代码按钮生成代码时,TouchGFX(至少) 适用于以下IDE:

    1. EWARM
    2. MDK-ARM
    3. STM32CubeIDE

    要获得最优项目结构,请选择以下项目生成选项:

    • 应用结构:高级
    • 禁用在根下生成(仅限STM32CubeIDE)

    要获得最优项目结构,请选择以下项目生成选项:

    • 应用结构:高级
    • 禁用在根下生成(仅限STM32CubeIDE)

    选择“高级应用结构”,然后取消选择“在根下生成”

    CubeMX还将生成具有以下结构的*TouchGFX*文件夹:

    TouchGFX文件夹结构

    • 应用文件夹,包含用于初始化和启动TouchGFX的代码。
    • 目标文件夹,包含生成的只读代码(在内部生成) 和可更改的用户类(STM32TouchController.cppTouchGFXGPIO.cppTouchGFXHAL.cpp)
    • .part文件,使用TouchGFX Designer来打开,以便创建完整的TouchGFX项目,其中包括TouchGFX头文件和库。part文件包含设计人员在生成TouchGFX应用程序代码时使用的相关程序信息,如像素格式和屏幕尺寸。

    TouchGFX Designer项目

    以下代码是在生成的代码架构章节中提到的.part文件内容示例。 当TouchGFX Designer创建新文件(如新屏幕和图片资源)时,后生成命令(如下所示)将更新CubeMX中选择的项目(如EWARM)。

    {
    "Application": {
    "Name": "my_project",
    "TouchGfxPath": "../Middlewares/ST/touchgfx",
    "AvailableColorDepths": [ 16 ],
    "AvailableLCDs":
    {
    "16": "LCD16bpp"
    },
    "AvailableResolutions" :
    [
    {
    "Width": 320,
    "Height": 240
    }
    ],
    "PostGenerateTargetCommand" : "touchgfx update_project --project-file=../my_project.ioc --platform=m7"
    },
    "Version": "4.13.0"
    }

    使用TouchGFX Designer打开.part文件时,开发人员可以选择加载现存UI或从空白模板开始。

    选择UI

    按下TouchGFX Designer中的生成代码后,TouchGFX文件夹的结构如下所示。 下图显示了TouchGFX文件夹结构的具体示例,并着重显示了生成后的新文件及文件夹。

    生成代码

    TouchGFX文件夹结构

    TouchGFX将从.ioc CubeMX文件(适用于STM32CubeIDE、EWARM、MDK-ARM)中检测所选的IDE,并使用新生成的文件(如用于屏幕定义、图像和字体的文件)来更新项目。

    此时,开发人员可以切换使用CubeMX、TouchGFX Designer和工具链/IDE,其中:

    • CubeMX可以更新IDE项目中的驱动程序
    • CubeMX使用UI相关更改来更新TouchGFX.part文件,设计工具可以立即获取这些更改
    • CubeMX基于TouchGFX在特定平台所需的TouchGFX Generator配置来生成HAL代码(TouchGFX/target/generated/)。
    • TouchGFX Designer使用生成的代码来更新项目。

    修改生成文件

    需要注意的是,由于HAL的类层次结构,用户可以无视CubeMX生成的HAL配置或操作。 在以下示例中,开发人员可以修改初始化函数,以额外配置TouchGFX,或修改TouchGFXGeneratedHAL中现有的配置集。

    TouchGFXHAL.cpp
    void TouchGFXHAL::initialize()
    {
    // Calling parent implementation of initialize().
    //
    // To overwrite the generated implementation, omit call to parent function
    // and implemented needed functionality here.
    // Please note, HAL::initialize() must be called to initialize the framework.

    TouchGFXGeneratedHAL::initialize();

    //Overriding configurations
    hal.lockDMAToFrontPorch(true);
    hal.setFingerSize(4);
    hal....
    }

    升级项目

    TouchGFX Generator参数存储在.ioc文件中(CubeMX项目)。 当发布新版TouchGFX Generator时,旧版的参数可能与新版的参数不兼容,并可能需要移植。

    由于cubeMX不支持X-CUBE版本之间的升级,因此,基于.touchgfx文件的PostGenerateTargetCommand部分中的以下命令,当按下生成代码时,将通过TouchGFX Designer自动执行升级。

    .touchgfx
    "PostGenerateTargetCommand" : "touchgfx update_project --project-file=../upgrade.ioc --platform=m7"

    该命令将读取.ioc文件并更新参数,以适应X-CUBE-TOUCHGFX的当前版本。 以下是通过X-CUBE-TOUCHGFX 4.13.0创建的.ioc文件上手动运行脚本(X-CUBE-TOUCHGFX 4.14.0)的示例。

    使用STM32F746 DISCO应用模板从4.13.0升级到4.14.0的示例
    $ touchgfx update_project --project-file=../STM32F746G_DISCO.ioc
    TouchGFX Generator 4.13.0 found
    Creating backup of ../STM32F746G_DISCO.ioc as
    ../backup_STM32F746G_DISCO.ioc
    Performing upgrade 4.13.0 -> 4.14.0 ... OK

    使用CubeMX打开更新过的项目时,系统会提示用户安装.ioc文件代表的X-CUBE-TOUCHGFX版本(如果尚未安装)。 点击立即下载后将下载并安装X-Cube-TouchGFX-4.14.0。

    缺失的其他软件组件:TouchGFX Generator 4.14.0

    升级期间将保留TouchGFX Generator中的所有配置,.ioc文件的备份文件将被放在原始文件旁,并带有前缀backup_

    Note
    要使用TouchGFX Generator提供的新功能,必须在CubeMX中执行生成代码
    Caution
    如果通过CubeMX为现有的TouchGFX项目升级X-CUBE-TOUCHGFX,升级过程并非通过TouchGFX Designer来运行,TouchGFX Generator参数将被重置为默认值,因为它们要适用于不同版本。