已知问题
本文列出了所有TouchGFX版本中已知存在的问题以及潜在的权宜措施。 此外,如果您需要执行任何特定的升级步骤才能将TouchGFX升级至特定版本,文中将会提到。 请注意,如果当前版本与最新版本之间隔了几个版本,您需要执行所有版本的升级步骤,直至升级到最新版本。
TouchGFX 4.19.0
使用字体排印的新方法
从TouchGFX 4.18.1到TouchGFX 4.19.0,字体排印的使用发生了变化。 现在,字体排印有一个默认设置和零或多个特定语言设置。
在Designer指南中 了解更多相关信息
文本特定的方向和字体排印不再是一个选项,这些选项转移到了新的默认设置和特定语言设置中。 该项新功能会对使用该功能的项目生成的代码产生影响。 文本转换器将为默认设置生成一个字体id,并为每种特定语言设置生成一个id。 根据特定语言设置生成的字体id将被自动命名,参见下面示例。
示例:自动生成的字体id
- 默认字体排印id: 标题
- 特定语言设置: JPN
在generated/fonts/include/fonts/ApplicationFontProvider.hpp
中生成两个字体ID:
struct TypographyFontIndex
{
static const touchgfx::FontId HEADLINE = 0;
static const touchgfx::FontId HEADLINE_AUTO_GENERATED_FOR_JPN = 1;
};
升级到4.19.0时自动生成的字体排印
如前所述,文本特定的方向和字体排印不再是一个选项。 由于功能上的这一变化,在升级旧版本时,可能会生成具有默认和特定语言设置的新字体排印。 您可以通过id来识别这些自动生成的字体排印。 文本方向作为后缀或A-Z范围内的字母:
- Headline_LTR
- PosterText_RTL
- Title_A
- ButtonText_B
在用户代码中引用字体id
如果在用户代码中引用字体id,则可能需要对其进行更新。 当字体id不是通过符号而是通过值引用的情况下,会有出错的风险,因为在升级期间字体id可能会更改。 建议始终通过符号引用字体id,即:用TypographyFontIndex::HEADLINE
而非0
。
将LibJPEG与ARMCLANG结合使用
在CubeMX中选择了LibJPEG中间件的ARMCLANG项目无法运行。 ARMCLANG启用半托管,因为LibJPEG引用libc文件函数(如:fopen)。
半托管使应用程序在启动时等待与半托管感知调试器连接。
解决此问题的一种方法是取消两个文件中对JFILE的定义来删除对LibJPEG中fopen的引用:LibJPEG/source/jdatasrc.c
and LibJPEG/source/jdatadst.c
:
LibJPEG/source/jdatasrc.c
#include "jerror.h"
#undef JFILE
/* Expanded data source object for stdio input */
#ifdef JFILE
LibJPEG/source/jdatadst.c
#include "jerror.h"
#undef JFILE
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
H750B Discovery上的MJPEG视频
H750B Discovery板使用YCbCr视频数据的硬件解码。 TouchGFX为该板提供的代码中的一个错误导致某些视频播放会出现虚影。
解决方案是改为软件解码。 在某些情况下,也可以通过修改视频的宽度几个像素来解决问题。
ThreadX汇编程序文件
Keil IDE的ThreadX汇编程序文件使用新的ARMCLANG V6汇编程序语法。 某些固件包中提供的startup.s文件使用的是旧的ARMCC汇编程序语法。 这意味着您必须将项目设置为使用ARMCLANG V6汇编程序,然后针对startup_stm32xxx.s进行重写:
TouchGFX 4.18.0
CubeMX 6.1.0和CubeProgrammer 2.6的问题
由于“C/C++编译器” / “语言”选项的错误设置(从“自动”更改为“C++”导致编译错误),CubeMX生成的CubeMX 版本6.1.0 EWARM工程不能与X-CUBE-TOUCHGFX一起使用。 此问题将在CubeMX 6.1.1中进行修正。 在此期间,将选项手动改回“自动”将解决编译问题,但是会在CubeMX生成代码时还原。
CubeProgrammer 2.6中与外部加载器 (.stldr
)引用方式相关的问题会损坏所有现有应用模板(AT)的Makefile,还会妨碍TouchGFX Designer中“运行目标”功能的正常工作。 此问题还扩展到了基于最新AT版本的用户工程。 应用程序模板将更新以修补该问题,并将适用于CubeProgrammer 2.5和2.6。 如果您已有不能与CubeProgrammer 2.6一起使用的基于AT的工程,您可以进行下列修改以添加支持。 在引用外部文件夹时,用户必须从bin
文件夹执行STM32CubeProgrammer_CLI.exe
。 一般而言,指:
cd
进入STM32CubeProgrammer安装文件夹中的bin
文件夹。- 执行命令,通过对
.stldr
文件的相对引用对连接的目标硬件进行烧录。
@cd "$(st_stm32cube_programmer_bin_path)" && ./$(stm_stm32cube_programmer_exe) -c port=SWD -d $(application_path)/$(binary_output_path)/target.hex -el $(stm32cubeLoader_relative_path) -hardRst
Note
新的.touchgfx格式
从TouchGFX 4.17.0到TouchGFX 4.18.0,.touchfgx文件的内容主要在两个方面做了重大改变。 其后果会全面更新.touchfgx文件,只需使用TouchGFX Designer打开TouchGFX工程文件,然后保存即可。 主要变化在以下领域:
默认值不再写入 .touchgfx文件
具有默认值(例如框体偏移量X=0,Y=0 或黑色(red=0,green=0,blue=0))的控件参数之前被写入.touchfgx文件;但在TouchGFX版本4.18.0中,这些值不再写入。 其结果会导致稍小些的.touchgfx文件。
删除了TextEntries块
重命名了SingleUseId,其名称现包含随机数字和字母(而不是连续的数字),这会简化合并几个活跃的开发人员共同开发的同一工程的工作,因为新的一次性使用文本id不会获得重复的id。 另外,.touchgfx中的“TextEntries”部分已被删除,这带来.touchgfx文件尺寸大大减少。
LCD16bpp::fillRect与LCD16bpp::drawGlyph
LCD16bpp中的fillRect和drawGlyph函数现在用完整的24位颜色(而非缩减后的16位(RGB565)颜色)传递给DMA。 这可能会导致硬件(非模拟器)上出现错误的颜色,可以通过CubeMX重新生成DMA类来修复该问题。
Makefile和xlsx
TouchGFX 4.18.0使用新的.xml格式(而不是以前使用的旧的.xlsx格式)来存储文本和译文。 这意味着Makefiles和visual studio项目中所有对"text .xlsx"的引用都应该改为"text .xml"。 TextConvert工具可以自动识别,即使旧的texts.xlsx文件存在而texts.xml不存在,其会将texts.xlsx转换为texts.xml,以适应所有未来的使用。
要查看能正常工作的新Makefile,只需使用TouchGFX Designer新建一个(空白)项目,文件位于文件夹generated/simulator/gcc/Makefile中。
texts.xsd中的字体大小限制
Designer中用于验证texts.xml的texts.xsd的字体大小有255的限制。 如果字体大于255,您将在Designer中看到如下错误消息:
解决方法是关闭工程,将texts.xsd中的“字体大小”属性从xs:unsignedByte更改为xs:unsignedInt,然后重新打开工程。
Linux上的SDL2链接器错误
现在只为Windows用户提供仿真器使用的SDL2库。 Linux用户需要自己安装SDL2库。 仅需要执行一次的命令,对于ubuntu,命令是
sudo apt install libsdl2-dev libsdl2-image-dev
即可安装libsdl2和libsdl2-image,包含开发所用的头文件。
TouchGFX 4.17.0
绘图工具不再支持setAlpha()
出于性能方面的考虑,Canvas Widget Renderer(CWR)使用的绘图控件不再支持alpha。 通过在有绘图控件的画布控件上设置alpha,仍然可以达到效果。 一般而言,可以将下面这样的代码:
painter.setColor(Color::getColorFromRGB(0xFF, 0x00, 0x00));
painter.setAlpha(128);
circle.setPainter(painter);
修改成这样:
painter.setColor(Color::getColorFromRGB(0xFF, 0x00, 0x00));
circle.setPainter(painter);
circle.setAlpha(128);
如果之前将alpha应用于绘图控件和画布控件,可以将这两个alpha值相乘,然后除以255,如下所示:
painter.setColor(Color::getColorFromRGB(0xFF, 0x00, 0x00));
painter.setAlpha(painterAlpha);
circle.setPainter(painter);
circle.setAlpha(circleAlpha);
变成
painter.setColor(Color::getColorFromRGB(0xFF, 0x00, 0x00));
circle.setPainter(painter);
circle.setAlpha((painterAlpha * circleAlpha) / 255);
或者使用LCD::div255()替代除以255。
使用HAL类
在版本4.17.0之前,完全不使用HAL的TouchGFX框架中的多个文件包含头文件touchgfx/hal/HAL.hpp。 这可能导致用户代码由于编译器不知道HAL而不进行编译。这些不必要的引用现已清理。 为了修正这个问题,只需包含HAL头文件,如下所示:
#include <touchgfx/hal/HAL.hpp>
另外,Screen类有两个新函数getScreenWidth() 和getScreenHeight(),用于给出屏幕尺寸。 推荐该方法用来获得屏幕尺寸,可从Screen的任意子类(如Screen1View.cpp)直接调用。
TouchGFX Generator中的FMC显示接口
当使用TouchGFX Generator中新的FMC显示接口时,用CubeMX 6.2.1生成时FMC存储区的内存偏移是不正确的(零)。 这会在CubeMX 6.3.0中修正,在发布时,X-CUBE-TouchGFX需要的最低版本将跳至6.3.0而不是目前的6.2.1。 到那时,用户可以在TouchGFXGeneratedHAL.cpp
中输入正确的FMC BANK存储地址(将在重新生成时被覆盖)。 如
#define FMC_BANK1_REG ((uint16_t *) 0x60000000)
#define FMC_BANK1_MEM ((uint16_t *) 0x60000002)
用户还可以在TouchGFXHAL.cpp
中全部重新定义它们。
16-24或32bpp配置的L8图像
在加载L8图像的CLUT时,对OSWrappers::taskYield()
的调用被错误地引入了STM32DMA类。 要解决此问题,用户可以执行以下操作:
- 导航到您的
Users/<user name>/STM32Cube/Repository/Packs/STMicroelectronics/X-CUBE-TOUCHGFX/4.17.0/CubeMX/templates/Target
文件夹。 - 根据您的位深打开相应的
dma\u Xbpp\u implementation\u tmp.ftl
文件 - 删除或注释
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U)
循环中对OSWrappers::taskYield()
的调用,并从STM32CubeMX重新生成代码,以使用此修改的模板生成代码。
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U)
{
// OSWrappers::taskYield();
}
TouchGFX 4.15.0
支持的MCU
虽然TouchGFX完全支持Cortex-M33,但在CubeMX中添加支持前,当前CubeMX(v6.0.1)版本中不能启用多上下文MCU的“软件包”(包括TouchGFX Generator)。 对基于Cortex-M33的MCU禁用“Trust Zone”,从而将MCU限制在单上下文,将允许您启用TouchGFX Generator。 应在“用户代码”区手动使能TrustZone。
TouchGFX 4.14.0
ARMCLANG支持
虽然TouchGFX现在为Cortex-M0、Cortex-M4f、Cortex-M7和Cortex-M33提供ARMCLANG(ARM编译器v6.x)库,CubeMX却不能生成启用ARMCLANG编译器(ARM编译器v6.x)的工程。 想在其工程中使用该编译器的用户需要在Keil uVision中的工程选项中手动选择编译器。
如果在CubeMX内配置FreeRTOS中间件,生成的任何使用ARMCC(ARM编译器v5.x)的工程都都会包含FreeRTOS可移植文件,这些文件与ARMCLANG是不兼容的;必须手工替换这些文件。 每当从CubeMX内部运行“生成代码”时,任何手工修改都会被覆盖,最好在版本控制(git等)下维护工程,以便撤销这些特定修改。
总之, 由于CubeMX只能生成使用ARM Compiler v5.x编译器的工程,因此用户每次从CubeMX生成代码时必须修改下列内容,在版本控制下维护项目除外。
- 在工程选项中选择ARM Compiler v6.x。
- 链接ARMCLANG库而不是ARMCC库(通过CubeMX配置)。
- 如果在CubeMX内配置FreeRTOS,为了兼容ARM Compiler v6.x,应从
portable/GCC
文件夹获取FreeRTOS可移植文件,而不是portable/RVDS
文件夹(ARM Compiler v5.x的默认选择)。
工作流程
下列流程描述了如何在Keil uVision中对CubeMX生成的工程使用v6.x ARM 编译器和TouchGFX ARMCLANG库。
- 在Keil uVision中选择ARMCLANG(v. 6.x)。
如果您在CubeMX中配置了FreeRTOS,CubeMX将生成错误的可移植文件,并将您的工程配置为使用这些文件。 您必须使用来自https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/6199b72fbf57a7c5b3d7b195a3bd1446779314cd/portable/GCC的文件(`port.c`和`portmacro.h`)或下载一个FreeRTOS版本并从中找到相应文件来手工替换。
替换
port.c
:将include路径设置修改为包含
portable/GCC
文件夹中的portmacro.h
(本例中以Cortex-M7为例):“生成代码”期间中,TouchGFX Designer生成后步骤会根据您选择的编译器版本自动插入正确的库。
TouchGFX 4.13.0
错误
字体转换器
FontConverter工具会为unicodes码生成字形像素数据,这是字体规则的一部分,而无论该字形是否在应用中实际文本中用到。 这可能会导致数兆字节的额外字形像素数据。 这里可以找到不会为应用中未使用的字形生成像素数据的FontConverter新工具(Windows和Linux):
在4.13.0安装的根目录下提取该压缩文件将更新touchgfx\framework\tools内部的fontconverter库
touchgfx\framework\tools
额外编译器支持
用ARMCLANG编译器(v6.12)构建的库可以在这里找到:
在4.13.0安装的根目录提取此文件可将库touchgfx_core_clang.lib
置入
touchgfx\lib\core\cortex_m7\Keil
向后兼容
已弃用的功能
下列弃用的功能已经被移除了。 如果您在代码中引用了它们,您可能需要重新编写应用中的这部分内容:
- 已弃用的
TRANSPARENT_COL
定义 Drawable::getType()
HAL::blitSetTransparencyKey()
HAL::registerTextCache()
HAL::cacheTextString()
默认禁用TextureMapper
默认禁用TextureMapper,以消减TouchGFX使用的代码空间。 TouchGFX designer会在所有新工程中插入代码,以启用纹理映射器。
如果您将旧工程移植到TouchGFX 4.13,并更新至TouchGFX 4.13,将由TouchGFX Designer处理这些问题。
如果是手工更新,则需要插入代码来启用TextureMapper。 否则,将不会在屏幕上绘制任何TextureMapper。
阅读更多内容:配置TouchGFX特性。
不兼容HAL SDL1
有两个函数从TouchGFX库代码移到了HALSDL2.cpp
。 这对将HALSDL2.cpp
用在Windows模拟器的HAL应用而言没有分别。
如果您有一个老应用(早于TouchGFX 4.8.0),则您的模拟器可能是在使用HALSDL(非2)。 此模拟器HAL不再包含在TouchGFX中。 HALSDL缺失了之前包含在TouchGFX库中的两个函数。 您需要将它们手动添加到HALSDL.cpp
:
HALSDL.cpp
void simulator_enable_stdio();
void simulator_enable_stdio()
{
HWND consoleHwnd = GetConsoleWindow(); // Get handle of console window
if (!consoleHwnd) // No console window yet?
{
HWND activeHwnd = GetActiveWindow(); // Remember which window is active
AllocConsole(); // Allocate a new console
consoleHwnd = GetConsoleWindow(); // Get handle of console window
FILE* dummy;
freopen_s(&dummy, "CONIN$", "r", stdin); // Redirect stdin/stdout/stderr to the new console
freopen_s(&dummy, "CONOUT$", "w", stdout);
freopen_s(&dummy, "CONOUT$", "w", stderr);
SwitchToThisWindow(activeHwnd, true); // Switch back to the originally active window
}
if (consoleHwnd)
{
ShowWindow(consoleHwnd, SW_SHOW); // Show/hide it!
}
}
void simulator_printf(const char* format, va_list pArg);
void simulator_printf(const char* format, va_list pArg)
{
// Create a console window, if window is visible.
simulator_enable_stdio();
if (GetConsoleWindow()) // Only print if we have a console window
{
vprintf(format, pArg);
}
}
TouchGFX 4.12.3
向后兼容
屏幕切换
更早的版本在完成屏幕切换后重绘整个屏幕。 额外的重绘在一些较慢的平台上会导致了性能问题。 如果您出于某些原因需要此类重绘,则需要使屏幕的相关部分失效,例如,在切换到的屏幕的虚函数Screen::afterTransition()
中调用container.invalidate()
。
二进制字体
由于字距调整数据现已包含在二进制字体中,因而修改了二进制字体的格式。 需要重新生成二进制字体文件,原有的老文件会工作不正常。 根据Makefiles的设置方式,通常可以通过重新生成所有资源来完成(如“make -f simulator/gcc/Makefile clean assets”
)。
TouchGFX 4.11.0
向后兼容
在touchgfx/framework/include/touchgfx/lcd/LCD.hpp
中,我们删除了头文件touchgfx/hal/HAL.hpp
,这个是在早期版本中误插入的。 这可能会导致包含LCD.hpp
并使用HAL.hpp
内容的文件发生编译错误。 解决方案是在您的文件中也包含进touchgfx/framework/include/touchgfx/hal/HAL.hpp
。
TouchGFX 4.10.0
从4.9.x升级
从版本4.10.0开始,TouchGFX只在STM32 MCU上运行。
如需更新老项目,您需要执行下列操作。
在应用启动时添加下面突出显示的代码,以通知TouchGFX正在STM32硬件上运行。 合适的添加位置是BoardConfiguration.cpp
中hw_init()
函数的结尾处。
BoardConfiguration.cpp
void hw_init() {
...
//Enable CRC engine for STM32 Lock check
__HAL_RCC_CRC_CLK_ENABLE();
}
向后兼容
删除了未使用的文件\touchgfx\framework\include\touchgfx\canvas_widget_renderer\RGBA8.hpp
。
工程更新器的问题
从TouchGFX Designer调用的IAR和Keil工程更新器不遵循在相应IDE中设置的自定义文件级别优化。
TextArea和ChromART(DMA2D)
用ChromART渲染TextAreas(当TextArea是最顶端的元素/最后进行绘制时)导致帧缓冲区提前解锁,继而导致当前帧提前完成/传输到显示屏。 在TouchGFX调用endFrame()
后,所有绘制操作(包括DMA操作)应已完成。 由于TextArea在如何恰当地保护帧缓冲区方面违反该约定,即使从endFrame()
返回后,仍然允许DMA操作继续。
控件的约定为:
- 锁定帧缓冲(返回指向帧缓冲的指针)。
- 在帧缓冲中绘制一些内容。
- 解锁帧缓冲区。
或者,使用DMA操作,这种情况下将自动处理帧缓冲的同步。
在版本4.10.0中,如果是当前屏幕最顶端的元素(最后进行绘制),TextArea将两个流程混合可能导致短时间的故障。 该问题可通过用下列endFrame()
重写手工保护endFrame()
来修正(基于F4 HAL)。 此举确保如果ChromART操作仍在进行时endFrame()
不返回。
void STM32F4HAL::endFrame()
{
if (dma.isDMARunning())
{
OSWrappers::tryTakeFrameBufferSemaphore();
}
HAL::endFrame();
}
TouchGFX 4.9.0
从4.8.0升级
随着应用模板(从实质上将板支持包与核心框架分离开来)的引入,我们在版本4.9.0的touchgfx文件夹中删除了许多底层驱动和其他文件。 这些文件现在由应用模板提供。 但是,这也意味着您不能通过仅仅替换touchgfx文件夹来升级到4.9.0,那样做会导致一些BSP文件缺失。 反之,TouchGFX Designer能够自动执行升级。 可通过两种不同的方式升级,您需要确定哪种方式是适合。
Caution
方法1:保留原始文件结构
使用该方法,只需在新的TouchGFX Designer 4.9.0中打开工程。 TouchGFX Designer将提示您是否要升级,在点击“确定”后,TouchGFX Designer将进行必要的修改。 TouchGFX Designer将执行下列操作:
- 将新的压缩过的touchgfx文件夹解压到应用中,并修改TouchGFX路径以与之匹配。
- 下载并解压所有已从touchgfx文件夹中删除的文件,因此您的工程仍然可以通过编译。
此方法几乎会让一切保持原样,如果原有文件结构适合您的工程,则这是最轻松的选择。 此方法的主要缺点是不会有图像转换器加速(通过操作图像文件夹而不是单个文件)。 但是,您可以手动修改makefile,以便使用此方法。
方法2:导入到新的模板
您可以使用此方法将工程转换到基于新模板的文件结构中。 为此,您必须首先使用上面的方法1让Designer升级工程。 然后,使用合适的应用模板(模拟器或与您的评估板匹配的应用模板)新建工程。 在Designer中打开此新工程后,转至顶部菜单并点击“编辑->导入GUI”。 在对话框中指定工程的.touchgfx文件。 Designer会自动将所有UI文件(包括资源)导入新建的工程。 如果您在gui文件夹之外增加了额外的代码,您需要将这些文件手动复制到新工程。
方法3:手工升级(无TouchGFX Designer)
如果不使用TouchGFX Designer,您可以用以下方式进行升级:
- 用版本4.9.0的安装文件夹中的touchgfx文件夹替换您工程中使用的touchgfx文件夹。
- 下载本zip文件并将其解压到touchgfx文件夹,恢复删除的文件。