跳转到主要内容

Generator用户指南

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

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

使能TouchGFX Generator

用户可通过按“选择组件”按钮来访问X-CUBE的附加功能。

选择STM32CubeMX中的附加软件

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

使能TouchGFX Generator

如果为双核MCU启用TouchGFX,请确保为正确的上下文启用。 TouchGFX只能为单一上下文启用:

在双核心芯片上使用TouchGFX Generator

生成的代码架构

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

在STM32CubeMX生成的代码(C代码)中,User Code段内的用户手写代码,会受到STM32CubeMX保护。 在TouchGFX Generator生成的C++代码中,通过继承来实现这种灵活性。

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

以下列表概述了使能TouchGFX Generator的STM32CubeMX项目内容,并重点介绍与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.iocSTM32CubeMX项目文件
内核main.c和启动代码
驱动CMSIS和MCU系列驱动程序
EWARMIDE项目文件夹。 可以为EWARM、MDK-ARM或STM32CubeIDE
中间件包含TouchGFX库/头文件以及FreeRTOS等第三方软件。
ApplicationTemplate.touchgfx.partSTM32CubeMX使用与TouchGFX Designer项目相关的信息(如屏幕尺寸和位深)来更新.part文件
应用STM32CubeMX的X-CUBE接口。  app_touchgfx.c文件包含MX_TouchGFX_Process(void)MX_TouchGFX_Init(void)函数的定义,这些函数用于初始化TouchGFX和启动其主循环。
目标/生成该子文件夹包含只读文件,当配置更改时,这些文件会被STM32CubeMX覆盖。 TouchGFXGeneratedHAL.cpp是TouchGFX类HAL的子类,并包含STM32CubeMX可基于其当前配置生成的代码。 OSWrappers.cpp(OSAL) 包含与TouchGFX Engine同步所需的功能,最后是TouchGFXConfiguration.cpp,其包含用于构建和配置TouchGFX的代码,包括HAL。
目标包含大量文件,用户可修改这些文件,以扩展HAL行为,或覆盖STM32CubeMX生成的配置。 STM32TouchController.cpp包含触摸控制器操作的空接口。 TouchGFXHAL.cpp定义TouchGFXGeneratedHAL的子类TouchGFXHAL

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

生成的代码的层次结构

特性概述

使能TouchGFX Generator后,用户界面中主要存在三个组。 如果检测到当前配置有问题,将显示第四个“依赖项”。

  • 依赖关系- 该组包含针对开关人员的有关配置中的依赖关系、警告或具体错误的通知。 如果没有条目,则该组将隐藏。
  • 显示- 该组包含与显示有关的设置,如接口、帧缓存的位深、宽度和高度。 这些设置直接影响TouchGFX项目里画布的大小以及基于显示部件所生成的代码。
  • 驱动程序- 该组允许用户选择与应用相关的滴答计时源、图形加速(DMA2D and GPU2D)和RTOS有关的一些现成驱动程序。 由于STM32CubeMX支持FreeRTOS(CMSIS RTOS v1和v2)配置,TouchGFX Generator为每个选项提供了驱动程序。
  • 其他功能-如果选择了RGB565,则会显示此组,允许用户使用非存储映射Flash中的图像和字体数据创建应用程序。
  • 视频解码 - 该组允许用户启用硬件或软件视频解码。 该选项对于视频控件是必要的。 注意!不是所有的MCU都支持视频解码。

TouchGFX Generator有三个组:显示屏、驱动器、以及视频解码

显示

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

接口与尺寸

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

  • 并行RGB(LTDC)
  • MIPI DSI
  • FMC
  • SPI

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

Further reading
有关不同显示接口的代码具体例程,请参见方案章节。

帧缓冲像素格式

TouchGFX Generator目前支持以下帧缓冲像素格式。 当使用“Custom”显示接口时,所有选项均可用,否则选项被限制为显示控制器设置(例如,配置LTDC Framebuffer格式为“RGB565”时,会将TouchGFX Generator中的配置选项限制为“RGB565”)。

  1. BW (1bpp)
  2. Grey2 (2bpp)
  3. Grey4 (4bpp)
  4. ABRG2222 (8bpp)
  5. ARGB2222 (8bpp)
  6. BGRA2222 (8bpp)
  7. RGBA2222 (8bpp)
  8. RGB565 (16bpp)
  9. RGB888 (24bpp)
  10. ARGB8888 (32bpp)
  11. XRGB8888 (32bpp)
Note
一些像素格式没有或仅有部分ChromART(DMA2D)支持。
Caution
对于STM32F7/H7:如果帧缓冲区放置在Write Through缓存存储器(例如SRAM)中,那么在DMA2D(如果已在Generator中进行配置)访问它之前,DCache会被生成的代码先清空。 记住要在STM32CubeMX中的Cortex M7System Core设置中启用CPU Cache,这样缓存机制才能正常工作。
Further reading
如需更多关于CPU缓存的详细信息,请参阅F7和H7中的“Cache(缓存)”章节。

缓冲策略

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

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

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

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

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

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

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

驱动器

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

应用滴答计时源

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

  • LTDC-如果在“Display”组中选用LTDC接口,则应用Tick源可以选“LTDC”。 这意味着TouchGFX Generator将在TouchGFXGenerated HAL类中安装驱动程序函数(LTDC中断处理程序) ,该函数通过调用OSWrappers::signalVSync()来展开驱动应用程序。
  • Custom和FMC - 在这种情况下,开发人员需要通过周期性调用OSWrappers::signalVSync()来驱动应用程序的执行。

图形加速器

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

  • -应用程序只使用CPU进行渲染。
  • DMA2D 加速器(Chrom-ART)- 应用程序在可能的情况下使用Chrom-ART芯片来移动和混合像素,释放CPU周期。 驱动程序由TouchGFX Generator生成,不需要开发人员采取任何措施。

对于支持DMA2D的MCU,可在CubeMX中的*多媒体*类别中启用DMA2D。

1. 使用STM32Cube HAL驱动程序,其将回调函数注册到dma2d句柄`hdma2d.XferCpltCallback`。 2. 直接使用`DMA2D_IRQHandler()`中断处理程序。

通过在STM32CubeMX中DMA2D IP的NVIC设置中启用或禁用DMA2D全局中断,可以在这两者之间进行切换。 选项1)启用全局中断生成的代码,选项2)禁用全局中断生成的代码。

Note
  • 对DMA2D使用全局中断时,请确保“ IRQ中断服务程序”调用“ DMA2D HAL中断处理程序”。 这是默认行为。
  • 如果在启用全局中断的同时禁用DMA2D的“ IRQ中断服务程序”和“调用HAL中断处理程序”,将导致永不调用已注册的回调。
    • GPU2D(NeoChrom)是一种图形加速器,能够加速TouchGFX中的许多绘图操作,包括纹理映射。 它支持RGB565、RGB888和ARGB8888格式的帧缓存。

    对于支持GPU2D的MCU,可在CubeMX中的*多媒体*类别中启用GPU2D。

    Caution
    只有当CubeMX中项目的多媒体部分启用了GPU2D, GPU2D选项才可见。 它只适用于STM32U599设备,并且只有在中间件部分的ThreadX RTOS也被启用的情况下,才能与TouchGFX一起使用。

    实时操作系统

    开发人员可使用任何支持TouchGFX的RTOS(甚至无操作系统)。 如抽象层架构中所述,TouchGFX Engine使用OSWrappers接口将其主事件循环以及帧缓冲访问与用户选择的RTOS同步。 当开发者通过TouchGFX Generator选择操作系统时,生成的代码将通过所选操作系统的原语实现内部同步功能。 操作系统仍然必须通过STM32CubeMX进行配置,以确定堆栈大小等。

    FreeRTOS (CMSIS OS V1和V2) 和ThreadX(本地中间件或Azure RTOS软件包) 可直接在STM32CubeMX和TouchGFX 生成器中配置,为用户提供任务定义和TouchGFX RTOS驱动程序的生成代码。 TouchGFX 生成器可生成符合CMSIS V1和CMSIS V2标准的RTOS驱动程序,与任何符合CMSIS标准的RTOS一起运行,一个用于ThreadX的驱动程序,一个用于在没有操作系统的情况下运行裸机的驱动程序。

    ThreadX

    可通过选择AZRTOS软件包或启用STM32CubeMX中的Native ThreadX 中间件(如果适用于选定的MCU设备)来启用ThreadX。

    Note
  • 默认情况下,所有新型STM32 MCU设备支持直接从STM32CubeMX获得的ThreadX 中间件,无需另外下载。 TouchGFX 板支持包将缓慢过渡到使用可用的ThreadX中间件或X-CUBE-AZRTOS软件包。
  • 提供ThreadX支持的X-CUBE-AZRTOS-XX扩展包已可用于STM32G0xx、STM32G1xx、STM32 L4xx、ST M32F4xx,STM32F7xxSTM32H7xx MCU系列。
  • 下图显示了TouchGFX Generator中可用的选项。

    RTOS驱动程序选项

    Note
  • 启用ThreadX中间件时,禁用NoOS选项。
  • 启用ThreadX中间件时,CMSIS_RTOS_V1CMSIS_RTOS_V2选项被禁用。 意法半导体不提供CMSIS OS封装,客户必须选择定制选项并执行CMSIS封装。
  • 从STM32CubeMX提供的中间件列表启用和配置ThreadX

    ThreadX成功的内存配置取决于内存池分配。 推荐数值为静态分配。 在ThreadX中间件配置中执行以下步骤:

    • 从模式列表中选择Core来启用THREADX中间件,如下图所示。
    • TX_TIMER_TICKS_PER_SECOND设置为1000,以获取每毫秒的计时
    • 内存池分配设置为使用静态分配

    启用并配置本机ThreadX中间件

    Caution
  • 启用本机ThreadX中间件时,内存池分配应设置为使用动态分配
    • 内存池分配设置为使用动态分配时
      • 用户必须在生成的app_azure_rtos.c文件的USER CODE BEGIN DYNAMIC_MEM_ALLOC部分中添加缺失的代码。
      • 用户还需要根据生成的app_azure_rtos.c文件中描述的建议更新链接器文件。
    从AZRTOS软件包启用并配置ThreadX
    • 选择软件包->选择组件或按Alt-O键
    • 选择STMicroelectonics.X-CUBE-AZRTOS-XX。 如果需要,请下载此软件包。
    • 选择RTOS ThreadX并勾选Core复选框以启用ThreadX。 现在您可以安全地关闭软件包组件选择器

    从X-CUBE-AZRTOS软件包启用ThreadX

    • 从左侧的类别列表中选择软件包组,并选择STMicroelectronics.X-CUBE-AZRTOS-XX
    • 通过选择RTOS ThreadX模式来启用ThreadX
    • 内存池分配设置为使用静态分配

    ThreadX配置 - X-CUBE-AZRTOS软件包

    • TX_TIMER_TICKS_PER_SECOND设置为1000,以获取每毫秒的计时。

    ThreadX配置 - X-CUBE-AZRTOS软件包

    FreeRTOS

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

    void MX_TouchGFX_Process(void);

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

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

    STM32CubeMX还将生成对osKernelStart()的调用;这将启动调度程序。

    ThreadX中间件

    STM32CubeMX不再负责为中间件和用户生成创建线程的代码。
    STM32CubeMX将生成对MX_TouchGFX_PreOSInit()函数的调用,该函数将初始化TouchGFX框架
    STM32CubeMX将生成对MX_ThreadX_Init()函数的调用,该函数将初始化并启动ThreadX内核

    int main(void)
    {
    /* Call PreOsInit function */
    MX_TouchGFX_PreOSInit();
    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    MX_ThreadX_Init();
    }

    TouchGFX Generator将生成MX_TouchGFX_PreOSInit()函数,该函数将简单调用touchgfx_init()

    /**
    * PreOS Initialization function
    */
    void MX_TouchGFX_PreOSInit(void)
    {
    // Calling forward to touchgfx_init in C++ domain
    touchgfx_init();
    }

    TouchGFX Generator将生成MX_TouchGFX_Init()函数,该函数将创建TouchGFX线程

    /**
    * Create TouchGFX Thread
    */
    UINT MX_TouchGFX_Init(VOID *memory_ptr)
    {
    UINT ret = TX_SUCCESS;
    CHAR *pointer = 0;

    /* Allocate the stack for TouchGFX Thread. */
    if (tx_byte_allocate((TX_BYTE_POOL*)memory_ptr, (VOID **) &pointer,
    TOUCHGFX_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
    {
    ret = TX_POOL_ERROR;
    }

    /* Create TouchGFX Thread */
    else if (tx_thread_create(&TouchGFXThread, (CHAR *)"TouchGFX", TouchGFX_Task, 0,
    pointer, TOUCHGFX_STACK_SIZE,
    5, 5,
    TX_NO_TIME_SLICE, TX_AUTO_START) != TX_SUCCESS)
    {
    ret = TX_THREAD_ERROR;
    }

    return ret;
    }

    TouchGFX Generator将生成所需的代码,这些代码将被STM32CubeMX插入到app_azure_rtos.c文件中

      /**
    * @brief Define the initial system.
    * @param first_unused_memory : Pointer to the first unused memory
    * @retval None
    */
    VOID tx_application_define(VOID *first_unused_memory)
    {
    ...

    if (tx_byte_pool_create(&touchgfx_app_byte_pool, "TouchGFX App memory pool", touchgfx_byte_pool_buffer, TOUCHGFX_APP_MEM_POOL_SIZE) != TX_SUCCESS)
    {
    /* USER CODE BEGIN TouchGFX_Byte_Pool_Error */

    /* USER CODE END TouchGFX_Byte_Pool_Error */
    }
    else
    {
    /* USER CODE BEGIN TouchGFX_Byte_Pool_Success */

    /* USER CODE END TouchGFX_Byte_Pool_Success */

    memory_ptr = (VOID *)&touchgfx_app_byte_pool;
    if (MX_TouchGFX_Init(memory_ptr) != TX_SUCCESS)
    {
    /* USER CODE BEGIN MX_X-CUBE-TOUCHGFX_Init_Error */
    while(1);
    /* USER CODE END MX_X-CUBE-TOUCHGFX_Init_Error */
    }
    /* USER CODE BEGIN MX_X-CUBE-TOUCHGFX_Init_Success */

    /* USER CODE END MX_X-CUBE-TOUCHGFX_Init_Success */
    }

    ...
    }

    tx_application_define()函数在初始化时由ThreadX内核调用。
    MX_TouchGFX_Init()函数由tx_application_define()调用。
    TouchGFX线程将在稍后启动ThreadX内核时启动。

    Note
  • STM32CubeMX仅为ThreadX中间件生成静态内存池分配配置的完整代码。
  • 如果您想用动态内存分配来配置ThreadX,请参考X-CUBE-TOUCHGFX扩展包中的STM32H7B3I-DK/Applications/AnimatedImages示例
  • 其他兼容CMSIS的OS

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

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

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

    void MX_TouchGFX_Process(void);

    其它功能

    外部数据读取器

    对于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附加功能才可用。

    8位LTDC颜色查询表

    当LTDC被配置为读取L8格式的帧缓冲器和TouchGFX渲染 ABRG2222ARGB222BGRA2222RGBA2222格式时, TouchGFX Generator将提供一个CLUT(在TouchGFXHAL::initialize()执行期间加载到LTDC)。 有关LTDC和CLUT的用法,详见STM32 MCU参考手册。

    视频解码

    ‘视频解码’部分可让开发者通过硬件或软件视频解码能力增强TouchGFX HAL。

    视频解码仅支持RGB565(16bpp)和RGB888(24bpp)格式的帧缓冲区。 如果没有选择这两种格式,则视频解码部分将不可用。

    Note
    不是所有MCU都支持硬件视频解码。

    类型

    默认情况下,视频解码的”类型”是禁用的。 如果STM32CubeMX中没有启用所需的外设,“软件解码”和“硬件解码”都将显示为灰色。 将鼠标悬停在灰色的选项上,看看需要哪些外设。

    信息框显示“硬件解码”的视频类型依赖项

    • 软件 - 如果在STM32CubeMX的中间件部分启用了LIBJPEG,则可以选择“软件”选项,并生成软件解码器。 这意味着TouchGFX Generator将生成一个软件MJPEG解码器。
    • 硬件 - 如果在多媒体部分启用了JPEG,并且在TouchGFX Generator中选择了符合CMSIS要求的RTOS,则可以选择“硬件”选项。

    视频解码类型选项

    在LIBJPEG设置中,为了提高效率,“RGB扫描线格式”中的RGB排序必须设置为“BGR”而不是“RGB”。 每个像素的字节数必须设置为3。

    需要的LIBJPEG RGB扫描线格式设置

    使用硬件解码时,JPEG设置中的RGB格式必须与显示屏相同。

    Further reading
    有关不同视频解码场景的具体示例代码,请参见“场景”部分。

    并发视频

    “并发视频”选项可设置GUI中任意给定时间在同一屏幕上同时被解码的最大数量视频。 如果希望一块屏幕上只解码一个视频,则可以将“视频数量”设置为1。

    最多可以同时解码4个视频。

    策略

    关于视频解码策略,开发人员有三种选择。

    • “直接到帧缓存区(Direct to Framebuffer)” - 视频在UI线程中被解码。 解码速度慢于其他策略。 使用硬件视频解码时,“直接到帧缓存区(Direct to Framebuffer)”选项不可用。
    • 单缓冲区 - 在专用的缓冲区中,以单独的任务进行视频解码。 该缓冲区位于内部存储器中。
    • 双缓冲区 - 在两个专用缓冲区中,以单独的任务进行视频解码,以牺牲内存为代价获得更好的性能。

    采用单或双帧缓存区策略时,必须启用符合CMSIS要求的操作系统。

    关于CMSIS RTOS要求的信息框

    Note
    使用双缓冲区策略时,要注意内存消耗。
    Further reading
    关于配置用于视频解码的FreeRTOS的具体示例,请参见“场景”部分。

    解码格式

    对于软件解码,开发人员可以选择RGB缓冲区的像素格式,不管帧缓存区的像素格式是什么。 TouchGFX Generator生成的代码允许ChromART在不同的格式之间进行像素格式转换。 视频解码缓冲区使用RGB565格式时,会使开发者占用的内存更少。

    解码格式

    缓存大小:

    缓冲区的宽度和高度设置必须对应应用程序中的最大视频尺寸。 宽度值必须能被32整除。

    以下代码是在TouchGFXGeneratedHAL.cpp中生成的代码,此应用中,使用了RGB888格式的显示屏,并使用480*272视频和“单缓冲区”视频解码策略。

    TouchGFXGeneratedHAL.cpp

    #include <DedicatedBufferVideoController.hpp>
    #include <SoftwareMJPEGDecoder.hpp>

    uint32_t lineBuffer[480];

    SoftwareMJPEGDecoder mjpegdecoder1((uint8_t*)lineBuffer);

    uint32_t videoRGBBuffer[97920];
    DedicatedBufferController<1, 480, 272, 480*3U, Bitmap::RGB888> videoController;

    //Singleton Factory
    VideoController& VideoController::getInstance()
    {
    return videoController;
    }

    void TouchGFXGeneratedHAL::initialize()
    {
    HAL::initialize();
    registerEventListener(*(Application::getInstance()));
    setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf) / (sizeof(uint32_t) * 2)), (void*)0);

    /*
    * Add software decoder to video controller
    */
    videoController.addDecoder(mjpegdecoder1, 0);

    videoController.setRGBBuffer((uint8_t*)videoRGBBuffer, sizeof(videoRGBBuffer));
    }

    生成的项目

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

    1. EWARM
    2. MDK-ARM
    3. STM32CubeIDE

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

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

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

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

    TouchGFX文件夹结构

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

    TouchGFX Designer项目

    以下json结构是基于STM32U599的项目“生成代码体系结构”部分中提到的.part文件内容示例。 以下示例中的后期生成命令将使用TouchGFX和可选组件所需的库以及TouchGFX设计器创建的新文件(如:新屏幕和资产)更新用户在STM32CubeMX项目管理器选项卡(如:EWARM)中选择的项目。

    {
    "Application": {
    "Name": "STM32U599J-DK",
    "TouchGfxPath": "../Middlewares/ST/touchgfx",
    "AvailableColorDepths": [ 24 ],
    "AvailableLCDs":
    {
    "24": "LCDGPU2D"
    },
    "AvailableResolutions": [
    {
    "Width": 480,
    "Height": 480
    }
    ],
    "PostGenerateTargetCommand": "touchgfx update_project",
    "Family": "STM32U5",
    "SubFamily": "STM32U599/5A9",
    "Platform": "m33",
    "ProjectFile": "../STM32U599J-DK.ioc",
    "OptionalComponentsRoot": "../Middlewares/ST/touchgfx_components",
    "OptionalComponents": [
    "GPU2D"
    ]
    },
    "Version": "4.19.0"
    }

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

    选择UI

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

    生成代码

    TouchGFX文件夹结构

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

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

    • STM32CubeMX可以更新IDE项目中的驱动程序
    • 与UI相关的配置修改会由STM32CubeMX更新到TouchGFX .part文件,TouchGFX designer可以立即获取这些更改
    • STM32CubeMX基于TouchGFX在特定平台所需的TouchGFX Generator配置来生成HAL代码(TouchGFX/target/generated/)。
    • TouchGFX Designer使用生成的代码来更新项目。
    Note
    对于双核项目,为特定上下文启用TouchGFX,则TouchGFX项目通常会位于该上下文的专用文件夹中,例如:“CM4 / TouchGFX”或“CM7 / TouchGFX”。

    修改生成文件

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

    TouchGFXHAL.cpp
    void TouchGFXHAL::initialize()
    {
    // Calling parent implementation of initialize().
    //
    // 若要覆写生成的实现,请忽略对父函数的调用
    // 并在此处实现所需的功能。
    // 请注意:必须调用HAL::initialize()以初始化框架。

    TouchGFXGeneratedHAL::initialize();

    //覆盖配置
    hal.lockDMAToFrontPorch(true);
    hal.setFingerSize(4);
    hal....
    }

    升级项目

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

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

    .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

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

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

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

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