주요 내용으로 건너뛰기

Generator User Guide

X-CUBE-TOUCHGFX에 포함된 TouchGFX Generator는 개발자가 하드웨어 플랫폼에서 실행되도록 TouchGFX를 구성하는 것을 도와주는 STM32CubeMX 추가 소프트웨어 구성 요소입니다. TouchGFX Generator는 기존 STM32CubeMX 설정 및 사용자 입력을 토대로 작동 중인 TouchGFX Application을 구성하는 데 필요한 파일을 생성합니다. TouchGFX HAL, TouchGFX OSAL 및 TouchGFX Configuration을 위한 파일이 여기에 해당합니다.

STM32CubeMX를 통해 코드가 생성되면 UI 개발이 이루어지는 TouchGFX Designer를 통해 TouchGFX 프로젝트를 열 수 있습니다. TouchGFX Designer는 STM32CubeMX의 해당 프로젝트에 대해 구성된 대상 IDE 프로젝트에 생성된 추가 코드 파일을 자동으로 추가합니다.

TouchGFX Generator 활성화

사용자는 "Select Components" 버튼을 눌러 액세스 권한을 얻은 후 X-CUBE에서 기능을 추가합니다.

STM32CubeMX에서 추가 소프트웨어 선택

다음 그림은 프로젝트에서 TouchGFX Generator를 활성화할 수 있는 방법을 보여줍니다:

TouchGFX Generator 활성화

TouchGFX를 듀얼 코어 MCU로 활성화하는 경우에는 올바른 컨텍스트에 맞춰서 활성화해야 합니다. TouchGFX는 단일 컨텍스트에 대해서만 활성화가 가능합니다.

듀얼 코어에서 TouchGFX Generator 활성화

생성 코드 아키텍처

TouchGFX Generator의 기능을 설명하기에 앞서, 생성된 코드의 아키텍처와 개발자가 이를 사용해 구성 및 동작을 사용자 지정하는 방법을 이해하는 것이 중요합니다.

STM32CubeMX에서 생성된 파일에서 직접 작성된 사용자 코드는 STM32CubeMX(C 코드)에서 생성된 코드 전반에 전략적으로 배치된 사용자 코드 섹션을 사용해 보호가 됩니다.  TouchGFX Generator에서 생성된 코드(C++ 코드) 에서는 상속을 통해 이러한 유연성이 달성됩니다.

TouchGFX Generator가 추가 소프트웨어를 통해 추가되고 활성화가 되면 STM32CubeMX는 항상 해당 프로젝트에 대해 TouchGFX 폴더를 생성합니다. 구성에 관계 없이 이 폴더에는 항상 동일한 파일들이 포함되지만, 파일의 내용은 STM32CubeMX 및 사용자 구성에 따라 바뀝니다.

아래 목록은 TouchGFX 관련 파일에 중점을 두고 TouchGFX Generator가 활성화된 STM32CubeMX 프로젝트의 내용이 개략적으로 나와있습니다. 목록 뒤에 나오는 표에는 가장 중요한 엔트리의 책임이 나와 있습니다:

TouchGFX 폴더
│   .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 프로젝트 파일
Coremain.c 및 스타트업 코드
DriversCMSIS 및 MCU 제품군 드라이버
EWARMIDE 프로젝트폴더 (EWARM, MDK-ARM 또는 STM32CubeIDE)
MiddlewaresTouchGFX 라이브러리/헤더파일과 FreeRTOS 같은 타사 소프트웨어가 포함되어 있습니다.
ApplicationTemplate.touchgfx.partSTM32CubeMX가 TouchGFX Designer 프로젝트와 관련된 정보로 .part 파일을 업데이트합니다. 예를 들면 화면 크기 및 비트 해상도,
AppSTM32CubeMX에 대한 X-CUBE 인터페이스 등이 이러한 정보에 해당됩니다. app_touchgfx.c에는 TouchGFX를 개시하고 메인 루프를 시작하는 데 사용되는 함수 MX_TouchGFX_Process(void) 및 MX_TouchGFX_Init(void)에 대한 정의가 포함되어 있습니다.
target/generated이 하위 폴더에는 구성이 변경될 때 STM32CubeMX에서 덮어쓰기를 하는 읽기 전용 파일이 포함되어 있습니다. TouchGFXGeneratedHAL.cpp는 TouchGFX 클래스 HAL의 하위 클래스로, 현재 구성을 토대로 STM32CubeMX에서 생성된 코드가 포함되어 있습니다. OSWrappers.cpp  (OSAL)에는 TouchGFX Engine과의 동기화에 필요한 함수가 포함되어 있고, 마지막으로 TouchGFXConfiguration.cpp에는 HAL을 포함하여 TouchGFX를 구성하기 위한 코드가 포함되어 있습니다.
targetHAL의 동작을 확장하거나 STM32CubeMX에서 생성된 구성을 재정의하기 위해 사용자가 수정할 수 있는 대량의 파일이 포함되어 있습니다. STM32TouchController.cpp에는 빈 터치 컨트롤러 인터페이스가 포함되어 있습니다. TouchGFXHAL.cppTouchGFXGeneratedHAL의 하위 클래스인 TouchGFXHAL을 정의합니다.

TouchGFXConfiguration.cpp에는 HAL을 구성하는 함수와 TouchGFX의 메인 루프를 시작하는 함수가 포함되어 있다는 점이 중요합니다. 편집이 가능한 사용자 클래스 TouchGFXHAL에서 추가 구성이 가능합니다. HAL의 일반적인 아키텍처는 아래와 같습니다:

생성된 코드의 계층 구조

기능 개요

TouchGFX Generator를 실행하면 사용자 인터페이스에 세 개의 메인 그룹이 생성됩니다. 현재 구성에서 문제가 감지되면 4번째 "종속성"이 표시됩니다.

  • Dependencies - 이 그룹에는 구성에서의 종속성, 경고 또는 구체적 오류에 대해 개발자에게 제공되는 알림이 포함되어 있습니다. 엔트리가 없는 경우에는 이 그룹이 숨겨집니다.
  • Display - 이 그룹에는 인터페이스, 프레임 버퍼 비트 심도, 너비 및 높이 같이 디스플레이와 관련된 설정이 포함되어 있습니다. 이러한 설정은 TouchGFX 프로젝트의 캔버스 크기는 물론이고 자산에 대해 생성된 코드에 직접적인 영향을 미칩니다.
  • Driver - 이 그룹에서는 사용자가 애플리케이션 틱 소스, 그래픽 가속(DMA2D 및 GPU2D) 및 RTOS와 관련된 다수의 기성 드라이버를 선택할 수 있습니다. STM32CubeMX에서는 FreeRTOS(CMSIS RTOS v1 및 v2) 구성이 지원되기 때문에 TouchGFX Generator는 이러한 옵션 각각에 대한 드라이버를 제공합니다.
  • Additional Features - RGB565를 선택하면 이 그룹이 나타나는데, 여기서 사용자는 비메모리 맵핑 플래시의 이미지/폰트 데이터를 사용하여 애플리케이션을 생성할 수 있습니다.
  • Video Decoding - 이 그룹에서는 사용자가 하드웨어 또는 소프트웨어 비디오 디코딩을 활성화할 수 있습니다. 비디오 위젯을 사용할 때는 이 옵션이 필요합니다. 다만 일부 MCU는 비디오 디코딩을 지원하지 않습니다.

TouchGFX Generator에는 Display, Driver, Video Decoding의 세 가지 그룹이 있습니다.

Display

Display 그룹에는 디스플레이와 관련된 구성(예: 인터페이스, 크기 및 버퍼링 전략) 이 포함되어 있습니다.

Interface and dimensions

현재 STM32 마이크로컨트롤러서는 다음과 같이 여러 디스플레이 인터페이스를 사용할 수 있습니다.

  • 병렬 RGB(LTDC)
  • MIPI DSI
  • FMC
  • SPI

LTDC 또는 FMC에 디스플레이가 연결된 MCU의 경우, TouchGFX Generator는 연결된 디스플레이로 프레임 버퍼를 전송하는 코드를 생성할 수 있습니다. DSI 및 SPI 인터페이스의 경우, 개발자가 드라이버를 직접 구현해야 합니다.

Further reading
서로 다른 디스플레이 인터페이스의 구체적인 코드 예시는 시나리오 섹션을 참조하십시오.

프레임 버퍼 픽셀 형식

아래의 프레임 버퍼 픽셀 형식들이 현재 TouchGFX Generator에서 지원되고 있습니다. "Custom" 디스플레이 인터페이스를 사용할 때는 모든 옵션을 이용할 수 있지만, 그렇지 않은 경우에는 디스플레이 컨트롤러 설정으로 옵션이 제한됩니다(예: LTDC 프레임 버퍼 형식을 "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
For STM32F7/H7: 프레임버퍼가 Write Through 캐시 메모리(예: SRAM)에 배치되면 DMA2D(Generator에서 구성되었을 경우)가 액세스하기 전에 생성된 코드가 DCache를 플러싱합니다. 이러한 캐싱 메커니즘이 작동하려면 STM32CubeMX에서 Cortex M7시스템 코어 설정에서 CPU 캐시를 활성화해야 합니다.
Further reading
CPU 캐싱에 대한 자세한 내용은 F7 및 H7의 캐시 하위 섹션을 참조하십시오.

Buffering Strategy

TouchGFX Generator를 통해 다음과 같은 프레임 버퍼 전략을 구성할 수 있습니다:

  • Single Buffer (단일 버퍼) - 오직 하나의 애플리케이션 프레임 버퍼만 사용합니다. 성능이 제한될 수 있지만, 메모리를 비교적 덜 사용합니다. 'Buffer Location' 구성을 사용해 내부 RAM에 배치할 수 있습니다. 추가적인 최적화를 위해 사용자는 디스플레이 컨트롤러에서 현재 처리 중인 라인을 반환하는 함수를 정의할 수 있습니다. 프레임워크에서 이 방법을 사용하면 현재 프레임 동안 디스플레이에 이미 전송된 메모리를 업데이트할 수 있습니다.
  • Double Buffer (이중 버퍼) - 2개의 프레임 버퍼를 사용합니다. 보통은 메모리의 비용 대비 성능을 높일 수 있습니다.
  • Partial Buffer (부분 버퍼) - 프레임 버퍼에서 사용자가 정의한 1개 이상의 메모리 집합체(chunk) 를 사용합니다. 이 전략은 외부 RAM에 의존하지 않고 전체 프레임 버퍼가 가용 메모리를 초과할 수 있도록 디스플레이를 사용하는 저비용 솔루션을 대상으로 합니다.

Single Buffer 및 Double Buffer의 경우, 사용자가 다음과 같은 옵션을 제공하는 "Buffer Location" 구성을 통해 위치를 구성할 수 있습니다.

  • By Allocation - 링커가 링커 스크립트에 따라 프레임 버퍼 메모리를 배치할 수 있게 지원합니다. 내부 RAM에 배치되도록 기본 설정되어 있습니다.
  • By Address - 사용자가 1개(Single) 또는 2개(Double) 의 프레임 버퍼 주소를 정의할 수 있게 해줍니다.

Partial Buffer 전략에서는 사용자가 다음과 같은 파라미터를 정의할 수 있습니다.

  • 블록 수(내부 RAM에 항상 배치)
  • 블록 크기(바이트)

부분 버퍼 전략과 관련된 몇 가지 핵심 개념들을 이해하려면 부분 프레임 버퍼를 이용한 메모리 요구 사항 감소에 대한 전용 문서를 읽어보시기 바랍니다. 이 문서에서는 부분 프레임 버퍼를 달성하는 방법을 개념적으로 보여주며, 여기 나온 코드는 TouchGFX Generator에서 생성된 것과 다소 차이가 있습니다. 이러한 전략에 대해 생성된 코드의 구체적인 예는 프레임 버퍼 전략을 참조하시기 바랍니다.

Driver

드라이버 섹션에서 개발자는 TouchGFX AL의 다양한 책임에 맞는 드라이버를 선택할 수 있습니다.

Application Tick Source

애플리케이션을 위한 application tick source는 애플리케이션을 구동하는 방법을 정의합니다. 개발자에게는 다음과 같은 옵션이 제공됩니다:

  • LTDC - "Display" 그룹에 대한 인터페이스로 LTDC를 선택하면 "LTDC"가 Application Tick Source가 됩니다. 즉, TouchGFX GeneratorOSWrappers::signalVSync()를 호출하여 애플리케이션을 진행시키는 TouchGFXGeneratedHAL 클래스에 드라이버 함수(LTDC 인터럽트 핸들러)를 설치합니다.
  • Custom 및 FMC - 이 경우, 개발자는 OSWrappers::signalVSync()를 반복적으로 호출하여 애플리케이션을 진행시키는 핸들러를 구현해야 합니다.

Graphics Accelerator

개발자는 그래픽 가속과 관련해 세 가지 옵션을 갖게 됩니다:

  • None - 애플리케이션은 오직 CPU를 사용해 렌더링합니다.
  • DMA2D Accelerator (ChromART) - 애플리케이션은 픽셀의 이동 및 혼합이 가능할 때 ChromART를 사용함으로써 CPU 주기를 확보합니다. TouchGFX Generator에서 드라이버가 생성되므로 개발자가 별도의 조치를 취할 필요가 없습니다.

DMA2D를 지원하는 MCUS에 대해 CubeMX *Multimedia* 카테고리에서 DMA2D가 활성화됩니다.

TouchGFX Generator에서 공급되는 Chrom-ART(DMA2D) 드라이버에서는 두 가지 방식으로 TransferCompleteInterrupt를 수신할 수 있습니다.

  1. STM32Cube HAL 드라이버를 사용해 dma2d 핸들러 hdma2d.XferCpltCallback에 콜백 함수를 등록합니다.
  2. DMA2D_IRQHandler() 인터럽트 핸들러를 직접 사용합니다.

DMA2D IP의 경우, STM32CubeMX의 NVIC 설정에서 DMA2D 전역 인터럽트를 활성화하거나 비활성화하는 방법으로 이 둘 간을 전환할 수 있습니다. 전역 인터럽트를 활성화하면 옵션 1) 에 대한 코드가 생성되고, 전역 인터럽트를 비활성화하면 옵션 2) 에 대한 코드가 생성됩니다.

Note
  • DMA2D에 전역 인터럽트를 사용할 때는 "IRQ handler"가 "DMA2D HAL handler"를 호출하는지 확인해야 합니다. 이것이 기본 동작입니다.
  • 전역 인터럽트가 활성화된 상태에서 DMA2D에서 'IRQ handler' 및 'Call HAL handler'를 비활성화하면 등록된 콜백(callback) 이 절대로 호출되지 않습니다.
    • GPU2D (NeoChrom)는 텍스처 맵핑을 포함해 TouchGFX의 여러 그리기 작업을 가속할 수 있는 그래픽 가속기로, RGB565, RGB888 및 ARGB8888 형식의 프레임버퍼를 지원합니다.

    GPU2D를 지원하는 MCUS에 대해 CubeMX의 *Multimedia* 카테고리에서 GPU2D가 활성화됩니다.

    Caution
    CubeMX 프로젝트의 Multimedia 섹션에서 GPU2D가 활성화되었을 때만 GPU2D 옵션이 표시됩니다. 이 옵션은 STM32U599 디바이스에서만 사용할 수 있으며, Middlewares 섹션의 ThreadX RTOS도 활성화 되었을 때만 TouchGFX에서 사용하도록 활성화할 수 있습니다.

    Real-Time Operating System

    개발자는 TouchGFX에서 어떤 RTOS든 사용할 수 있습니다(OS가 없는 경우에도). AL(Abstraction Layer) 아키텍처에 설명되어 있듯이, TouchGFX Engine은 OSWrappers 인터페이스를 사용해 메인 이벤트 루프를 비롯해 프레임 버퍼 액세스를 사용자가 선택한 RTOS와 동기화합니다. 개발자가 TouchGFX Generator의 운영 시스템을 선택할 경우, 코드가 생성되어 선택한 운영체제의 프리미티브를 통해 내부에서 동기화합니다. 무엇보다도 스택 크기를 결정하려면 여전히 STM32CubeMX를 통해 운영 체제를 구성해야 합니다.

    FreeRTOS(CMSIS OS V1 및 V2)와 ThreadX (Native Middleware 또는 Azure RTOS Software Packs)는 STM32CubeMX와 TouchGFX Generator 내에서 바로 구성할 수 있으며, 이를 통해 사용자에게 작업 정의 및 TouchGFX RTOS 드라이버를 위한 생성 코드를 제공합니다. TouchGFX Generator는 RTOS와 호환하는 CMSIS, ThreadX용 드라이버 그리고 운영체제 없이 베어 메탈로 동작하는 드라이버를 수행하는 RTOS 드라이버와 호환하는 CMSIS V1 및 CMSIS V2를 생성할 수 있습니다.

    ThreadX

    ThreadX를 활성화하는 방법에는 두 가지가 있는데, 하나는 AZRTOS Software Pack을 선택하는 것이고, 다른 하나는 선택한 MCU 디바이스에 STM32CubeMX의 ThreadX Middleware 옵션이 있을 때 이를 활성화하는 것입니다.

    Note
  • 새로 나온 STM32 MCU 디바이스는 모두 기본적으로 별도의 팩을 다운로드할 필요 없이 STM32CubeMX에서 바로 사용할 수 있는 ThreadX Middleware를 지원합니다. TouchGFX Board Support 팩은 ThreadX 미들웨어가 있을 경우 이를 사용하거나 X-CUBE-AZRTOS 소프트웨어 팩을 사용하도록 서서히 전환됩니다.
  • ThreadX 지원을 제공하는 X-CUBE-AZRTOS-XX Expansion Packs은 STM32G0xx, STM32G4xx, STM32L4xx, STM32F4xx, STM32F7xx, STM32H7xx MCU 시리즈에서 이미 사용할 수 있습니다.
  • 아래 그림에는 TouchGFX Generator를 통해 사용할 수 있는 옵션들이 나와 있습니다.

    RTOS 드라이버 옵션

    Note
  • ThreadX Middleware가 활성화되면 NoOS 옵션이 비활성화됩니다.
  • ThreadX Middleware가 활성화되면 CMSIS_RTOS_V1CMSIS_RTOS_V2 옵션이 비활성화됩니다. ST에서는 CMSIS OS wrapper를 제공하지 않으므로 고객이 Custom 옵션을 선택해서 CMSIS wrapper를 실행해야 합니다.
  • STM32CubeMX에 포함된 Middleware 목록에서 ThreadX 활성화 및 구성하기

    ThreadX의 메모리를 올바르게 구성하려면 Memory Pool Allocation이 관건입니다. 권장값은 Static Allocation입니다. ThreadX Middleware 구성에서 다음과 같은 절차를 수행합니다.

    • 아래 그램에서와 같이 모드 목록에서 Core를 선택하여 THREADX Middleware를 활성화합니다.
    • TX_TIMER_TICKS_PER_SECOND1000으로 설정하여 1 밀리초마다 Tick을 발생시킵니다.
    • Memory Pool AllocationUse Static Allocation으로 설정합니다.

    Native ThreadX Middleware 활성화 및 구성하기

    Caution
  • Native ThreadX Middleware가 활성화된 상태에서는 Memory Pool AllocationUse Dynamic Allocation으로 설정해야 합니다.
    • Memory Pool AllocationUse Dynamic Allocation으로 설정될 때
      • 사용자는 생성된 app_azure_rtos.c 파일의 USER CODE BEGIN DYNAMIC_MEM_ALLOC 섹션에서 사라진 코드를 추가해야 합니다.
      • 또한 생성된 app_azure_rtos.c 파일에 기술된 권고사항에 따라 링커 파일을 업데이트해야 합니다.
    AZRTOS Software Pack에서 ThreadX 활성화 및 구성하기
    • Software Packs ->와 Components를 선택하거나, Alt-O를 누릅니다.
    • STMicroelectonics.X-CUBE-AZRTOS-XX를 선택합니다. 필요할 경우 팩을 다운로드합니다.
    • RTOS ThreadX를 선택하고 Core 확인란을 선택하여 ThreadX를 활성화합니다. 이제 Software Packs Component Selector를 안전하게 종료할 수 있습니다.

    X-CUBE-AZRTOS Software Pack에서 ThreadX 활성화하기

    • 좌측에 있는 Categories 목록에서 Software Packs 그룹을 선택하고 STMicroelectonics.X-CUBE-AZRTOS-XX를 선택합니다.
    • RTOS ThreadX 모드를 선택하여 ThreadX 활성화하기
    • Memory Pool AllocationUse Static Allocation으로 설정합니다.

    ThreadX 구성 - X-CUBE-AZRTOS Software Pack

    • TX_TIMER_TICKS_PER_SECOND1000으로 설정하여 1 밀리초마다 Tick을 발생시킵니다.

    ThreadX 구성 - X-CUBE-AZRTOS Software Pack

    FreeRTOS

    다음 함수를 호출하면 TouchGFX 메인 루프에 들어갑니다.

    void MX_TouchGFX_Process(void);

    개발자는 TouchGFX 애플리케이션을 실행하려는 작업에 대한 작업 핸들러에서 이 함수를 호출해야 합니다. 사용자가 DefaultTask라는 STM32CubeMX에서 FeeRTOS 작업을 구성한 경우, 아래 예시는 작업 핸들러의 사용자 코드 섹션에서 TouchGFX를 시작하기 위해 MX_TouchGFX_Process()가 어떻게 호출되는지를 보여줍니다.

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

    STM32CubeMX는 또한 osKernelStart()로 호출을 생성하며, 이때 스케쥴러가 작동합니다.

    ThreadX Middleware

    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 */
    }

    ...
    }

    초기화 시 ThreadX 커널에서 tx_application_define() 함수가 호출됩니다.
    tx_application_define().
    에서는 MX_TouchGFX_Init() 함수가 호출됩니다. ThreadX 커널이 실행된 후 TouchGFX 스레드가 실행됩니다.

    Note
  • STM32CubeMX는 ThreadX MiddlewaresStatic Memory Pool Allocation 전용 전체 코드를 생성합니다.
  • Dynamic Memory Allocation을 통해 ThreadX를 구성하려는 경우에는 X-CUBE-TOUCHGFX 확장팩 안에 들어있는 STM32H7B3I-DK/Applications/AnimatedImages 예제를 참조하시기 바랍니다.
  • 기타 CMSIS 호환 OS

    STM32CubeMX에서 제공되는 것과 다른 CMSIS 호환 OS(FreeRTOS 및 ThreadX)가 필요한 개발자는 RTOS 구성 및 작업 정의를 수동으로 수행해야 합니다. 일반적으로 다음과 같은 수동 단계를 거쳐야 합니다:

    1. RTOS 구성
    2. TouchGFX(MX_TouchGFX_Process) 를 실행하기 위한 작업 정의
    3. 스케줄러 시작

    MX_TouchGFX_Process를 호출해 작업 핸들러 내부의 TouchGFX Engine 메인 루프를 시작합니다.

    void MX_TouchGFX_Process(void);

    추가 기능

    External Data Reader

    RGB565 프레임 버퍼 픽셀 형식에서 TouchGFX는 소위 Data Reader라는 인터페이스를 지원합니다. 덕분에 개발자는 메모리에서 추가 버퍼로 인한 비용이 발생하는 캐싱 대신, 메모리 매핑이 되지 않은 시리얼 플래시에서 직접 데이터를 읽어올 수 있습니다. 플래시 칩에서 애플리케이션 자산을 검색하기 위해 DataReader를 구현하는 방법에 대한 예는 시리얼 플래시 문서를 참조하시기 바랍니다.

    Data Reader 옵션은 보통 추가 버퍼에 대한 메모리가 충분하지 않은 저가 솔루션(예: STM32G0)에서 사용됩니다. DMA2D가 활성화되어 있는 경우에는 이 플래시를 사용할 수 없습니다.

    프레임 버퍼 픽셀 형식으로 RGB565가 선택되면 Additional Features 그룹을 사용할 수 있게 됩니다.

    추가 기능: DataReader

    개발자는 다음과 같이 구성을 수행할 수 있습니다:

    • External Data Reader: 이 기능을 활성화 또는 비활성화합니다. 활성화를 하면 TouchGFX가 생성된 인터페이스를 통해 직접 자산에 대한 데이터를 검색하게 됩니다. 비활성화를 하면 개발자가 대신 메모리의 버퍼에 이미지를 캐싱해야 합니다.
    • External Data Reader: Line Buffer Size: 프레임 버퍼에 이미지 또는 텍스트를 혼합할 수 있도록 2개의 버퍼를 생성합니다. ARGB8888 픽셀 형식에서 풀 사이즈 이미지를 지원하도록 화면 너비* 4바이트가 기본 값입니다.
    • External Data Reader: Minimum DMA transfer size: DMA 전송을 시작하기 위해 필요한 최소한의 바이트를 설정합니다. 더 많은 바이트가 요청된 경우에는 DMA가 사용되지 않습니다.

    External Data Reader가 활성화된 상태에서 코드를 생성한 후에는 메모리 매핑이 되지 않은 플래시에서 직접 자산을 검색할 수 있도록 다음과 같은 파일이 추가로 생성됩니다.

    • 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입니다.

    DataReader를 사용하도록 TouchGFX HAL를 구성하기 위해 다음과 같은 파일이 수정됩니다.

    • TouchGFX/target/generated/TouchGFXConfiguration.cpp
    • TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp
    • TouchGFX/target/generated/TouchGFXGeneratedHAL.hpp
    Note
    DataReader 추가 가능은 DMA2D 및 LTDC가 비활성화된 경우에만 사용할 수 있습니다.

    8bit LTDC Color Look-up Table

    L8 형식으로 프레임 버퍼를 읽도록 LTDC가 구성되어 있고 TouchGFX가 ABRG2222ARGB222BGRA2222 또는  RGBA2222에서 렌더링되면 TouchGFX Generator는 TouchGFXHAL::initialize(). 동안 LTDC에 로드되는 CLUT를 제공합니다. LTDC 및 CLUT 사용에 대한 자세한 내용은 STM32 MCU 참조 매뉴얼을 참조하시기 바랍니다.

    Video Decoding

    Video Decoding 섹션에서는 개발자가 하드웨어 또는 소프트웨어 비디오 디코딩 기능을 사용해 TouchGFX HAL을 개선할 수 있습니다.

    Video Decoding은 오직 RGB565(16bpp) 및 RGB888(24bpp) 프레임 버퍼 픽셀 형식만 지원합니다. 두 형식을 선택하지 않으면 Video Decoding 섹션을 사용할 수 없습니다.

    Note
    일부 MCU는 하드웨어 비디오 디코딩을 지원하지 않습니다.

    Type

    Video Decoding에서 "Type"은 기본적으로 비활성화되어 있습니다. STM32CubeMX에서 필요한 주변 장치가 활성화되어 있지 않으면 "Software"와 "Hardware" 모두 회색으로 표시됩니다. 이때 마우스를 회색으로 표시된 옵션 위로 가져가면 주변 장치가 필요하다는 메시지가 나타납니다.

    "Hardware"에 대한 Video Type 종속성을 나타내는 정보 상자

    • Software - STM32CubeMX의 Middleware 섹션에서 LIBJPEG를 활성화하면 "Software" 옵션을 선택할 수 있으며, 이에 따라 소프트웨어 디코더가 생성됩니다. 이 말은 TouchGFX Generator가 소프트웨어 MJPEG 디코더를 생성한다는 것을 의미합니다.
    • Hardware - Multimedia 섹션에서 JPEG를 활성화하고, TouchGFX Generator에서 CMSIS 호환 RTOS를 선택하면 "Hardware" 옵션을 선택할 수 있습니다.

    Video Decoding Type 옵션

    LIBJPEG 설정에 있는 "RGB scanline format" 섹션에서 RGB 순서는 효율을 높이기 위해 "RGB"가 아닌 "BGR"로 설정해야 합니다. 픽셀당 바이트 수는 3으로 설정해야 합니다.

    필요한 LIBJPEG RGB scanline format 설정

    하드웨어 디코딩 작업에서는 JPEG 설정의 RGB 형식이 디스플레이와 동일해야 합니다.

    Further reading
    그 밖에 각종 비디오 디코딩 시나리오에 따른 실제 코드 예제를 보려면 시나리오 섹션을 참조하십시오.

    Concurrent videos

    "Concurrent Videos" 옵션은 언제든지 동일한 GUI 스크린에서 동시에 디코딩할 수 있는 최대 용량의 비디오를 말합니다. 스크린 1개에서 비디오 1개만 디코딩하고 싶다면 "Number of Videos"를 1로 설정하면 됩니다.

    동시에 디코딩할 수 있는 비디오 수는 최대 4개입니다.

    Strategy

    개발자에게는 비디오 디코딩 전략과 관련하여 다음과 같이 세 가지 옵션이 있습니다.

    • Direct to Framebuffer - 비디오가 UI 스레드에 디코딩됩니다. 이 옵션은 나머지 전략에 비해 속도가 느립니다. 하드웨어 비디오 디코딩 작업에서는 "Direct to Framebuffer" 옵션을 사용할 수 없습니다.
    • Single Buffer - 비디오가 별도의 태스크에서 전용 버퍼로 디코딩됩니다. 이 버퍼는 내부 메모리에 할당됩니다.
    • Double Buffer - 비디오가 별도의 태스크에서 전용 버퍼 2개로 디코딩되기 때문에 메모리 대비 성능이 우수합니다.

    단일 또는 이중 프레임 버퍼 전략 작업에서는 CMSIS 호환 OS를 활성화해야 합니다.

    CMSIS RTOS 요구 사항에 대한 정보 상자

    Note
    이중 버퍼 전략을 선택할 때는 메모리 사용량에 주의해야 합니다.
    Further reading
    비디오 디코딩을 위해 FreeRTOS를 구성하는 실제 예제를 보려면 시나리오 섹션을 참조하십시오.

    Decode Format

    소프트웨어 디코딩에서는 개발자가 프레임 버퍼의 픽셀 형식에 상관없이 RGB 버퍼의 픽셀 형식을 선택할 수 있습니다. TouchGFX Generator는 형식이 다를 경우 ChromART에서 픽셀 형식을 변환할 수 있는 코드를 생성하기 때문입니다. 비디오 디코딩 버퍼를 RGB565 형식으로 지정하면 개발자가 메모리 공간을 줄일 수 있습니다.

    디코드 형식

    버퍼 크기

    Buffer Width 및 Buffer Height 설정은 애플리케이션에서 가장 큰 비디오 치수와 일치해야 합니다. 또한 Width는 32의 약수이어야 합니다.

    애플리케이션에서 RGB888 디스플레이를 사용할 경우 TouchGFXGeneratedHAL.cpp에서 480*272 비디오와 "Single Buffer" 비디오 디코딩 전략을 설정하여 다음과 같은 코드가 생성됩니다.

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

    생성된 프로젝트

    TouchGFX는 STM32CubeMX에서 Generate Code 버튼을 사용해 코드를 생성할 때 최소한 다음 IDE에서 작동합니다.

    1. EWARM
    2. MDK-ARM
    3. STM32CubeIDE

    최적의 프로젝트 구조를 위해 다음과 같은 프로젝트 생성 옵션을 선택합니다:

    • 애플리케이션 구조: Advanced
    • Generate under root 비활성화(STM32CubeIDE 전용)

    Advanced 애플리케이션 구조를 선택하고 루트 아래 Generate의 선택을 해제

    STM32CubeMX는 다음과 같은 구조를 가진 TouchGFX 폴더도 생성합니다.

    TouchGFX 폴더 구조

    • App 폴더에는 TouchGFX를 개시 및 시작하기 위한 코드가 포함되어 있습니다.
    • target 폴더에는 읽기 전용으로 생성된 코드(generated/ 내부의)와 수정 가능한 사용자 클래스(STM32TouchController.cppTouchGFXGPIO.cpp  TouchGFXHAL.cpp)가 포함되어 있습니다.
    • TouchGFX 헤더 파일 및 라이브러리를 완전히 갖춘 전체 TouchGFX 프로젝트를 생성할 수 있도록 TouchGFX Designer를 사용해.part 파일을 열 수 있습니다. 이 파일에는 픽셀 형식과 TouchGFX 애플리케이션 코드를 생성할 때 설계자가 사용하는 캔버스 크기 같이 관련된 애플리케이션 정보가 포함되어 있습니다.

    TouchGFX Designer 프로젝트

    다음 JSON 구조는 STM32U599 기반 프로젝트를 위한 Generated Code Architecture 섹션에 언급된 .part 파일의 콘텐츠에 대한 예시입니다. 아래 예제에 나와 있는 PostGenerate 명령을 실행하면 TouchGFX 및 옵션 구성요소를 위한 필수 라이브러리와 TouchGFX 설계자가 생성한 새 파일(예: 새로운 스크린 및 애셋)을 통해 STM32CubeMX Project Manager 탭(예: 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에서 Generate Code를 누르고 난 이후의 TouchGFX 폴더의 구조는 아래와 같습니다. 아래 그림에는 TouchGFX 폴더 구조의 구체적인 예가 나와 있는데, 생성 이후 새로 생긴 파일과 폴더가 강조 표시되어 있습니다.

    코드 생성

    TouchGFX 폴더 구조

    TouchGFX는 .ioc STM32CubeMX 파일(STM32CubeIDE, EWARM, MDK-ARM의 경우)에서 선택한 IDE를 탐지하고, 화면 정의, 이미지 및 글꼴 자산에 대한 파일과 같이 새로 생성된 파일로 프로젝트 파일을 업데이트합니다.

    이 때 개발자는 STM32CubeMX, TouchGFX Designer 및 툴체인/IDE를 오가며 작업을 수행할 수 있습니다.

    • STM32CubeMX는 드라이버로 IDE 프로젝트를 업데이트
    • STM32CubeMX는 설계자가 즉시 선택한 UI 관련 변경 사항으로 TouchGFX .part 파일을 업데이트
    • STM32CubeMX는 TouchGFX가 특정 플랫폼에서 작동하는 데 필요한 TouchGFX Generator 구성을 토대로 HAL 코드(TouchGFX/target/generated/)를 생성합니다.
    • TouchGFX Designer는 생성된 코드로 프로젝트를 업데이트합니다.
    Note
    듀얼 코어 프로젝트에서 특정 컨텍스트에 대해 TouchGFX를 활성화한 경우, TouchGFX 프로젝트는 일반적으로 해당 컨텍스트에 대한 전용 폴더("CM4/TouchGFX" 또는 "CM7/TouchGFX")에 위치하게 됩니다.

    생성된 동작 수정

    HAL의 클래스 계층 구조 덕분에 사용자는 STM32CubeMX에서 생성된 HAL 구성 또는 동작을 재정의할 수 있다는 것을 기억하시기 바랍니다. 아래 예제에서 개발자는 추가로 TouchGFX를 구성하거나TouchGFXGeneratedHAL에 설정된 기존 구성을 수정하도록 initialize 함수를 수정할 수 있습니다.

    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 파일(STM32CubeMX 프로젝트)에 저장됩니다. 새로운 버전의 TouchGFX Generator가 출시되면 이전 버전의 파라미터가 새 버전과 호환이 되지 않아서 마이그레이션이 필요할 수 있습니다.

    STM32CubeMX는 X-CUBE 버전 사이에서 업그레이드를 지원하지 않기 때문에 Generate Code를 누르면 .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

    STM32CubeMX를 통해 업데이트된 프로젝트를 열면 사용자에게 .ioc 파일에 표시되어 있는 X-CUBE-TOUCHGFX 버전을 설치하라는 메시지가 뜹니다(아직 설치되지 않은 경우). Download now를 클릭하면 X-Cube-TouchGFX-4.14.0이 다운로드 및 설치됩니다.

    추가 소프트웨어 구성 요소 누락: TouchGFX Generator 4.14.0

    업그레이드 절차가 진행되는 동안 TouchGFX Generator의 모든 구성이 유지되고, .ioc 파일의 백업이 앞에 backup_이 붙어 있는 원본과 나란히 배치됩니다.

    Note
    TouchGFX Generator에서 제공하는 새로운 기능을 사용하려면 STM32CubeMX에서 코드 생성을 수행해야 합니다.
    Caution
    기존 TouchGFX 프로젝트에서 STM32CubeMX를 통해 X-CUBE-TOUCHGFX를 업그레이드했지만 해당 업그레이드 프로세스가 TouchGFX Designer에서 실행되지 않는 경우, 다른 버전에 적용이 가능하도록 TouchGFX Generator 파라미터가 기본값으로 재설정됩니다.