주요 내용으로 건너뛰기

Framebuffer Strategies

이 섹션에서는 다음과 같은 프레임 버퍼 전략 중 하나를 사용하는 TouchGFX HAL을 생성하기 위해 TouchGFX Generator를 구성하는 방법을 보여줍니다.

  • Single
  • Double
  • Partial

프레임 버퍼에 대한 자세한 내용은 여기를 참조하십시오.

모든 프레임 버퍼 옵션

Single Framebuffer

버퍼 전략으로 Single Buffer를 선택한 개발자들은 컴파일러가 내부 RAM에서 프레임 버퍼에 대한 메모리를 할당하게 할 수도 있고, 해당 버퍼에 대한 특정 위치를 선택할 수도 있습니다.

By Allocation

By Allocation을 선택하면 TouchGFX Generator가 애플리케이션의 크기와 비트 심도(depth)를 기반으로 배열을 할당합니다.

Single framebuffer, by allocation

이 배열을 프레임 버퍼로 사용하도록 HAL을 구성하기 위한 코드가 생성됩니다.

TouchGFXGeneratedHAL.cpp
namespace {
// Use the section "TouchGFX_Framebuffer" in the linker script
// to specify the placement of the buffer
LOCATION_PRAGMA("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 272 * 2 + 3) / 4] LOCATION_ATTRIBUTE("TouchGFX_Framebuffer");
}

void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)frameBuf, (void*)0, (void*)0);
}

By Address

프레임 버퍼의 위치를 위해 By Address을 선택하면 TouchGFX Generator가 HAL 초기화가 진행되는 동안 지정된 Start Address를 사용하게 됩니다.

Single framebuffer, by address

TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)0xC0000000, (void*)0, (void*)0);
}

이중 프레임 버퍼

Double frame buffer 구성에서는 선택한 프레임 버퍼 전략과 디스플레이 인터페이스에 따라 TouchGFX Generator가 HAL에서 프레임 버퍼 전환을 위한 코드를 생성합니다. 프레임 버퍼 위치에 대한 이러한 메모리 인터페이스는 메인 이벤트 루프 동안 TouchGFX Engine에서 사용됩니다.

By Address

By Address을 선택하면 TouchGFX Generator가 HAL 초기화 동안 2개의 지정된 시작 주소를 사용하게 됩니다.

Double framebuffer, by address

TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC003FC00, (void*)0);
}
Tip
디스플레이 인터페이스로 병렬 RGB(LTDC)를 사용할 때 시작 주소는 LTDC 계층 설정에서 상속됩니다.
Tip
병렬 RGB(LTDC)를 'By Allocation' 모드의 디스플레이 인터페이스로 사용하면 생성된 TouchGFX HAL이 런타임 시 LTDC 계층 색상 프레임 버퍼 시작 주소를 자동으로 구성하기 때문에 LTDC 구성에서 값을 설정하면 안 됩니다.

By Allocation

By Allocation을 선택하면 TouchGFX Generator가 단일 프레임 버퍼에서와 똑같이 애플리케이션의 크기와 비트 심도(depth)에 따라 배열을 할당합니다. 단, 크기만 2배가 됩니다.

Single framebuffer, by allocation

TouchGFXGeneratedHAL.cpp
namespace {
// Use the section "TouchGFX_Framebuffer" in the linker to specify the placement of the buffer
LOCATION_PRAGMA("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 272 * 2 + 3) / 4 * 2] LOCATION_ATTRIBUTE("TouchGFX_Framebuffer");
}

void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();

setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf)/(sizeof(uint32_t)*2)), (void*)0);
}

Partial Buffer

Partial Buffer 전략에서는 TouchGFX가 디스플레이와 동일한 크기의 프레임 버퍼를 사용하지 않습니다. 대신, 사용자는 프레임 버퍼로 사용할 특정 크기의 블록 개수를 선택할 수 있습니다. TouchGFX는 Frame Buffer Allocator 개체를 사용해 이러한 블록의 사용을 제어합니다.

Partial Buffer 전략을 사용하는 경우에는 외부 메모리(프레임 버퍼가 위치하게 되는 곳)에 대한 포인터를 제공하지 않으며, 내부 메모리에 프레임 버퍼 배열을 할당하지도 않습니다.

프레임 버퍼의 개념에 대한 일반 개요는 프레임 버퍼에 관한 문서를 참조하십시오.

Tip
일반적으로 STM32G0 같은 소형 마이크로컨트롤러는 프레임 버퍼에 맞는 내부 RAM을 충분히 갖추고 있지 못합니다. 이러한 MCU를 사용하는 저가 솔루션에는 "Partial Buffer"가 가장 적합합니다.

Partial framebuffer

Partial buffer 전략은 보통 TFT 컨트롤러가 장착되지 않고 작은 내부 RAM이 장착된 저가 MCU에서만 사용되므로 개발자가 프레임 버퍼의 내용을 디스플레이에 전송하는 작업을 수행하게 됩니다. 예를 들어 TFT 컨트롤러가 장착되지 않은 MCU의 시리얼 디스플레이에 픽셀을 전송하는 방법은 FMC/SPI 시나리오를 참조하십시오.

Partial Framebuffer 전략을 사용할 때 TouchGFX와 디스플레이를 링크하려면 개발자가 아래와 같이 2개의 함수를 구현해야 합니다. 아래에 나와 있는 코드는 TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp 내부에서 CubeMX에 의해 생성되며, TouchGFX Engine과 디스플레이 드라이버 간의 인터페이스를 정의합니다.

TouchGFXGeneratedHAL.cpp
/* ******************************************************
* Functions required by Partial Frame Buffer Strategy
* ******************************************************
*
* int touchgfxDisplayDriverTransmitActive() must return whether or not data is currently being transmitted, over e.g. SPI.
* void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h) will be called
* when the framework wants to send a block. 이제, 사용자는 인수가 나타내는 데이터를 전송해야 합니다.
*/

extern "C" int touchgfxDisplayDriverTransmitActive();
extern "C" int touchgfxDisplayDriverShouldTransferBlock(uint16_t bottom);
extern "C" void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
extern "C" void touchgfxSignalVSync(void);

TouchGFX Designer에서 사용할 수 있는 STM32G071 TouchGFX 보드 설정에서는 이러한 함수가 Core/Src/MB1642BDisplayDriver.c에서 구현됩니다(여기에는 하나만 표시).

Core/Src/MB1642BDisplayDriver.c
int touchgfxDisplayDriverTransmitActive(void)
{
return IsTransmittingBlock_;
}

이 전략에서는 CubeMX가 TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp의 읽기 전용 TouchGFXGeneratedHAL 클래스 내에 TouchGFXGeneratedHAL::flushFrameBuffer(Rect&)도 생성합니다.

Note
flushFrameBuffer(Rect&) 함수는 일반적으로 TFT 컨트롤러가 없는 MCU에 사용됩니다. Partial Framebuffer 전략의 경우, TouchGFX Generator는 특히 Partial Framebuffer 전략에 대해 이 메서드에 대한 정의를 생성할 수 있습니다.
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HAL::flushFrameBuffer(rect);
// Try transmitting a block
PartialFrameBufferManager::tryTransmitBlock();
}