주요 내용으로 건너뛰기

알려진 문제

이 섹션에서는 모든 TouchGFX 버전에 존재하는 것으로 알려진 문제와 가능한 해결책을 알아보겠습니다. 또한 TouchGFX를 특정 버전으로 업그레이드하는 데 필요한 단계가 있다면 함께 알려드리겠습니다. 다만 현재 사용 중인 버전이 이전 릴리스라면 최신 릴리스 버전으로 업그레이드하는 단계를 수행해야 합니다.

CubeMX 6.1.0 및 CubeProgrammer 2.6에서 알려진 문제

버전 CubeMX 6.1.0부터 CubeMX에서 생성된 EWARM 프로젝트는 X-CUBE-TOUCHGFX와 호환되지 않는데, 이는 "C/C++ Compiler" / "Language" 옵션이 "Auto"에서 "C++"로 변경되어 잘못 설정되는 바람에 컴파일 오류가 발생하기 때문입니다. 이 문제는 CubeMX 6.1.1에서 해결될 예정입니다. 한편, 옵션을 수동으로 다시 "Auto"로 변경하면 컴파일 문제가 해결되지만 CubeMX에서 코드를 생성하면 원래 설정으로 돌아갑니다.

CubeProgrammer 2.6에서는 외부 로더(.stldr)의 참조 방식과 관련된 버그가 기존 애플리케이션 템플릿(AT)에 사용되는 Makefile을 손상시킬 뿐만 아니라 TouchGFX Designer에서 "Run Target” 기능의 정상적인 작동을 방해합니다. 이 문제는 현재 AT 버전을 기준으로 사용자 프로젝트에도 영향을 미칩니다. 이 버그에 대한 보상을 목적으로 애플리케이션 템플릿에 대한 업데이트가 예정되어 있으며, CubeProgrammer 2.5와 2.6에 모두 적용됩니다. 만약 CubeProgrammer 2.6과 호환되지 않는 AT를 기반으로 프로젝트를 생성했다면 다음과 같이 수정하여 지원을 추가할 수 있습니다. 사용자가 외부 로더를 참조할 때 bin 폴더에서 STM32CubeProgrammer_CLI.exe를 실행해야 합니다. 일반적으로,

  • STM32CubeProgrammer 설치 폴더의 bin 폴더로 cd 명령을 실행합니다.
  • 아래와 같이 명령을 실행하여 .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

TouchGFX 4.17.0

페인터가 더 이상 setAlpha()를 지원하지 않습니다.

캔버스 위젯 렌더러(CWR)에서 사용되는 페인터는 성능 문제로 알파를 더는 지원하지 않습니다. 하지만 페인터가 포함된 캔버스 위젯에서 알파를 설정하면 알파 효과가 지속됩니다. 일반적으로 코드를 다음과 같은 모습에서

   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);

이전에 페인터와 캔버스 위젯에 알파를 적용했다면 다음과 같이 두 알파 값을 곱셈한 후 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);

그 밖에 255로 나누지 않고 LCD::div255()를 사용하는 방법도 있습니다.

HAL 클래스 사용

버전 4.17.0 이전에는 헤더 파일 touchgfx/hal/HAL.hpp가 HAL을 전혀 사용하지 않는 TouchGFX 프레임워크의 일부 파일에 포함되었습니다. 이렇게 불필요한 참조는 삭제되었지만 결과적으로 컴파일러가 HAL을 인식하지 못하기 때문에 사용자 코드를 컴파일하지 못할 수도 있습니다. 이러한 문제는 다음과 같이 HAL 헤더 파일을 추가하여 간단하게 해결할 수 있습니다.

#include <touchgfx/hal/HAL.hpp>

또한 Screen 클래스에 스크린 크기를 지정할 수 있는 getScreenWidth() 함수와 getScreenHeight() 함수가 새로 추가되었습니다. 두 함수는 스크린 크기를 지정하는 데 유용한 방법으로 Screen1View.cpp 같은 스크린 서브 클래스에서 직접 호출할 수 있습니다.

TouchGFX Generator의 FMC 디스플레이 인터페이스

TouchGFX Generator에서 새로운 FMC 디스플레이 인터페이스를 사용할 경우 CubeMX 6.2.1에서 생성하면 FMC 뱅크의 메모리 오프셋이 정확하지 않습니다(0). 이 문제는 CubeMX 6.3.0에서 해결될 예정이며, 릴리스되면 X-CUBE-TouchGFX의 최소 필요 버전도 6.2.1이 아닌 6.3.0으로 상향됩니다. 사용자는 문제가 해결될 때까지 TouchGFXGeneratedHAL.cpp에서 FMC 뱅크 메모리 주소를 정확하게 입력할 수 있습니다(재생성 시 덮어쓰게 됩니다). 예를 들면 다음과 같습니다.

#define FMC_BANK1_REG ((uint16_t *) 0x60000000)
#define FMC_BANK1_MEM ((uint16_t *) 0x60000002)

그 밖에도 사용자는 TouchGFXHAL.cpp에서 완전히 재정의할 수 있습니다.

16- 24- 또는 32bpp 구성에서의 L8 이미지

Cortex-M33은 현재 TouchGFX에서 완벽하게 지원되지만 현재 CubeMX 버전(v6.0.1)에서는 CubeMX에 지원이 추가될 때까지 "소프트웨어 팩"(특히 TouchGFX Generator)을 멀티 컨텍스트 MCU에 사용할 수 없습니다. 하지만 Cortex-M33 기반 MCU에서 "Trust Zone”을 비활성화하면 MCU가 단일 컨텍스트로 제한되어 TouchGFX Generator를 사용할 수 있습니다.

  1. 프로젝트 옵션에서 ARM Compiler v6.x를 선택합니다.
  2. ARMCC 라이브러리(CubeMX에서 구성)가 아닌 ARMCLANG 라이브러리와 연결합니다.
  3. CubeMX에서 FreeRTOS를 구성한 경우 FreeRTOS 이식 가능 파일을 portable/RVDS 폴더(ARM Compiler v5.x의 기본 폴더)가 아닌 portable/GCC 폴더에서 가져와야 ARM Compiler v6.x와 호환됩니다.
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U)
{
// OSWrappers::taskYield();
}

TouchGFX 4.15.0

MCU 지원

이제 TouchGFX가 ARMCLANG(ARM 컴파일러 v6.x) 라이브러리를 Cortex-M0, Cortex-M4f, Cortex-M7Cortex-M33에게 제공하기 때문에 CubeMX가 ARMCLANG 컴파일러(ARM 컴파일러 v6.x)를 실행하는 프로젝트를 생성할 수 없습니다. 이에 따라 프로젝트에서 컴파일러를 사용하고자 하는 사용자는 Keil uVision의 프로젝트 옵션에서 컴파일러를 수동으로 선택해야 합니다. 단, TrustZone는 사용자 코드 섹션에서 수동으로 활성화해야 합니다.

TouchGFX 4.14.0

ARMCLANG Support

CubeMX에서 FreeRTOS 미들웨어를 구성한 경우 ARMCC(ARM Compiler v5.x)를 사용해 생성된 프로젝트에 FreeRTOS 이식 가능 파일이 만들어지지만 ARMCLANG과 호환되지 않습니다. 따라서 수동으로 교체해야 합니다. 수동으로 변경한 내용은 CubeMX에서 "Generate code"를 실행할 때마다 덮어쓰게 되기 때문에 프로젝트의 버전을 지속적으로 관리(git 등)하여 특정 변경 내용을 실행 취소하는 것이 좋습니다.

요약하자면, CubeMX는 오직 ARM Compiler v5.x 컴파일러 프로젝트만 생성하기 때문에 사용자는 프로젝트의 버전을 지속적으로 관리하지 않는 한 CubeMX에서 코드가 생성될 때마다 다음과 같이 수정해야 합니다.

요약하자면, CubeMX는 오직 ARM Compiler v5.x 컴파일러 프로젝트만 생성하기 때문에 사용자는 프로젝트의 버전을 지속적으로 관리하지 않는 한 CubeMX에서 코드가 생성될 때마다 다음과 같이 수정해야 합니다.

  1. Keil uVision에서 ARMCLANG(v. 6.x)을 선택합니다.
  2. ARMCC 라이브러리(CubeMX에서 구성)가 아닌 ARMCLANG 라이브러리와 연결합니다.
  3. CubeMX에서 FreeRTOS를 구성한 경우 FreeRTOS 이식 가능 파일을 portable/RVDS 폴더(ARM Compiler v5.x의 기본 폴더)가 아닌 portable/GCC 폴더에서 가져와야 ARM Compiler v6.x와 호환됩니다.

워크플로

다음 워크플로는 Keil uVision에서 ARM Compiler v6.x를 구성하여 CubeMX 생성 프로젝트 및 TouchGFX ARMCLANG 라이브러리와 함께 사용할 수 있는 방법을 설명한 것입니다.

  1. Keil uVision에서 ARMCLANG(v. 6.x)을 선택합니다.

ARMCLANG Support

  1. CubeMX에서 FreeRTOS를 구성하면 CubeMX가 잘못된 이식 가능 파일을 생성하고 프로젝트에서 잘못된 파일을 사용하도록 구성하게 됩니다. 이 파일들은 port.cportmacro.h 파일(https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/6199b72fbf57a7c5b3d7b195a3bd1446779314cd/portable/GCC)로 수동으로 교체하거나, 혹은 FreeRTOS 릴리스를 다운로드하여 해당 파일을 직접 찾아야 합니다.

    아래와 같이 port.c를 교체합니다.

    port.c

    include 경로 설정을 변경하여 portable/GCC 폴더의 portmacro.h 파일이 포함되도록 설정합니다(여기에서는 Cortex-M7).

    Portable include 경로

  2. TouchGFX Designer는 "Generate Code”의 Post-Generate 단계에서 사용자가 선택한 컴파일러 버전에 따라 정확한 라이브러리를 자동으로 삽입합니다.

TouchGFX 4.13.0

버그

글꼴 변환 도구

이전에는 글꼴 변환 도구가 실제 애플리케이션 텍스트에서 사용되는 글리프와 상관없이 글꼴 규칙에 포함된 유니코드에 맞춰 글리프 픽셀 데이터를 생성했습니다. 이로 인해 글리프 픽셀 데이터가 추가로 몇 메가바이트 늘어날 가능성이 높았습니다. 이제는 새로운 글꼴 변환 도구(Windows 및 Linux)가 애플리케이션에서 사용하지 않는 글리프 픽셀 데이터를 더 이상 생성하지 않습니다. 새로운 글꼴 변환 도구는 여기에서 찾아볼 수 있습니다.

4.13.0이 설치된 루트 경로에서 이 파일의 압축을 풀면 내부에서 글꼴 변환 도구 바이너리가 업데이트됩니다.

touchgfx\framework\tools

추가 컴파일러 지원

4.13.0이 설치된 루트 경로에서 이 파일의 압축을 풀면 내부에 touchgfx_core_clang.lib 라이브러리가 저장됩니다.

4.13.0이 설치된 루트 경로에서 이 파일의 압축을 풀면 내부에 touchgfx_core_clang.lib 라이브러리가 저장됩니다.

touchgfx\lib\core\cortex_m7\Keil

하위 호환성

지원 종료 기능

TextureMapper는 TouchGFX에서 사용하는 코드 공간을 줄이기 위해 기본적으로 비활성화됩니다. TouchGFX Designer가 새로운 프로젝트에서 코드를 삽입하여 TextureMapper를 활성화합니다.

  • 지원 종료된 TRANSPARENT_COL의 정의
  • Drawable::getType()
  • HAL::blitSetTransparencyKey()
  • HAL::registerTextCache()
  • HAL::cacheTextString()

TextureMapper는 기본적으로 비활성화되어 있습니다.

TextureMapper는 TouchGFX에서 사용하는 코드 공간을 줄이기 위해 기본적으로 비활성화됩니다. TouchGFX Designer가 새로운 프로젝트에서 코드를 삽입하여 TextureMapper를 활성화합니다.

이전 프로젝트를 TouchGFX 4.13으로 마이그레이션하고, TouchGFX 4.13으로 업데이트하면 이러한 과정을 TouchGFX Designer에서 처리합니다.

그렇지 않고 수동으로 업데이트하는 경우에는 코드를 삽입하여 TextureMapper를 활성화해야 합니다. 그렇지 않으면 TextureMapper가 스크린에 드로잉하지 않습니다.

자세한 내용은 TouchGFX 기능 구성을 참조하십시오.

호환되지 않는 HAL SDL1

하지만 TouchGFX 4.8.0 이전 애플리케이션이라면 시뮬레이터에서 HALSDL(2 아님)을 사용할 수도 있습니다. 이 시뮬레이터 HAL은 TouchGFX에 더는 포함되지 않습니다.

하지만 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()를 호출해야 합니다.

이진 글꼴

이제 이진 글꼴에 커닝 데이터도 포함되기 때문에 이진 글꼴의 형식이 바뀌었습니다. 이에 따라 이진 글꼴 파일을 다시 생성해야 하며, 이전 파일은 올바르게 실행되지 않습니다. Makefile 설정 방식에 따라 다르지만 일반적으로 모든 애셋을 다시 생성하여 실행됩니다(예: make -f simulator/gcc/Makefile clean assets).

TouchGFX 4.11.0

하위 호환성

touchgfx/framework/include/touchgfx/lcd/LCD.hpp에서 초기 버전에 실수로 삽입되었던 touchgfx/hal/HAL.hpp 파일의 include가 제거되었습니다. 이에 따라 LCD.hpp가 포함된 파일에서 컴파일 오류가 발생할 뿐만 아니라 HAL.hpp 내용을 이용하게 될 수도 있습니다. 이 문제 역시 파일에 touchgfx/framework/include/touchgfx/hal/HAL.hpp를 추가하면 해결됩니다.

TouchGFX 4.10.0

4.9.x에서 업그레이드

TouchGFX는 버전 4.10.0부터 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를 사용해 TextArea를 렌더링하면(TextArea가 항상 위에 있는 요소이기 때문에 마지막에 드로잉되는 경우) 프레임버퍼 잠금을 조기에 해제하기 때문에 결과적으로 너무 이른 시기에 완료되어 현재 프레임을 디스플레이로 전송하게 됩니다. 일단 TouchGFX에서 endFrame()이 호출되면 DMA 연산을 포함해 모든 드로잉 연산이 완료되어야 합니다. 하지만 TextArea에서 프레임버퍼를 보호하는 방법에 대한 절차를 위반하여 DMA 연산은 endFrame()에서 값이 반환된 후에도 계속 실행됩니다.

위젯의 절차는 다음 중 한 가지를 따라야 합니다.

  1. 프레임버퍼를 잠급니다(포인터를 프레임버퍼로 반환).
  2. 프레임버퍼 내에서 요소를 드로잉합니다. 
  3. 프레임버퍼의 잠금을 해제합니다.

혹은 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: 이전 파일 구조 유지

이 방법은 새 Designer 4.9.0에서 프로젝트를 열기만 하면 실행됩니다. 그러면 TouchGFX Designer가 업그레이드 여부를 묻고, 여기서 OK를 클릭하면 TouchGFX Designer가 필요한 변경 사항을 적용합니다. 이때 TouchGFX Designer는 다음과 같은 작업을 수행합니다.

  1. 줄어든 새 touchgfx 폴더의 압축을 애플리케이션에 풀고 TouchGFX 경로를 여기에 맞게 수정합니다.
  2. 프로젝트가 계속 컴파일할 수 있도록 touchgfx 폴더에서 삭제된 파일을 모두 다운로드하여 압축을 해제합니다.

이 방법은 거의 모든 것을 그대로 유지하기 때문에 이전 파일 구조가 프로젝트에 적합한 경우에는 가장 무난하게 선택할 수 있는 방법입니다. 다만 이미지 변환 프로그램의 빠른 속도가 주는 이점(각 파일이 아닌 이미지 폴더에서 작업)을 이용하지 못하는 것이 가장 큰 단점입니다. 그렇지만 Makefile을 수정하면 이 방법도 사용할 수 있습니다.

방법 2: 새 템플릿으로 가져오기

이 방법을 사용하면 프로젝트를 새로운 템플릿 기반 파일 구조로 전환할 수 있습니다. 이렇게 하려면 먼저 Designer에서 위의 방법 1을 사용해 프로젝트를 업그레이드해야 합니다. 그런 다음 해당하는 애플리케이션 템플릿(시뮬레이터 또는 평가 보드에 적합한 템플릿)을 사용해 새로운 프로젝트를 생성합니다. 새로 생성한 프로젝트를 Designer에서 열고 상단 메뉴에서 "Edit -> Import GUI"를 클릭합니다. 대화상자에서 프로젝트의 .touchgfx 파일을 지정합니다. 그러면 Designer가 애셋을 포함한 모든 UI 파일을 새로 생성된 프로젝트에 자동으로 가져옵니다. 만약에 gui 폴더 외부에서 다른 코드를 추가했다면 해당하는 파일들을 새 프로젝트에 직접 복사해야 합니다.

방법 3: Designer가 없는 수동 업그레이드

Designer를 사용하지 않는 경우에도 다음과 같은 방법으로 업그레이드가 가능합니다.

  1. 프로젝트에서 사용하는 touchgfx 폴더를 4.9.0이 설치된 폴더로 교체합니다.
  2. 이 zip 파일을 다운로드하여 touchgfx 폴더로 압축을 푼 다음 삭제된 파일들을 복구합니다.