주요 내용으로 건너뛰기

Framebuffer Strategies

이 섹션에서는 아래와 같은 프레임 버퍼 전략 중 하나를 사용하는 TouchGFX HAL을 생성하도록 TouchGFX Generator를 구성하는 방법을 제시합니다.

  • Single
  • Double
  • Partial

Single Frame Buffer

버퍼 전략으로 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

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 계층 설정에서 상속됩니다.

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 Frame Buffer

Partial Buffer 전략을 선택한 개발자는 프레임 버퍼로 사용할 각각의 버퍼에 대해 블록 개수와 크기를 선택할 수 있습니다. 이 전략은 TouchGFX의 Frame Buffer Allocator라는 기능을 사용하며, 프레임 버퍼가 위치한 외부 메모리에 포인터를 제공하거나 내부 메모리에서 고정 크기의 배열을 할당하는 방법과는 다릅니다.

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

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
* ******************************************************
*
* * uint8_t isTransmittingData() must return whether or not data is currently being transmitted, over e.g. SPI.
* * void transmitFrameBufferBlock(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. The user must then transfer
* the data represented by the arguments.
*
* A user must call touchgfx::startNewTransfer(); once transmitFrameBufferBlock() has succesfully sent a block.
* E.g. if using DMA to transfer the block, this could be called in the "Transfer Completed" interrupt handler.
*
*/
extern "C" void transmitFrameBufferBlock(uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
extern "C" uint8_t isTransmittingData();

또한 TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp 내에 있는 읽기 전용 TouchGFXGeneratedHAL 클래스 내의 CubeMX에서 아래 함수가 생성됩니다. 

Note
이 flushFrameBuffer() 함수는 TFT 컨트롤러가 장착되지 않은 MCU에서 보통 사용됩니다. Partial Frame Buffer의 경우, TouchGFX Generator는 특히 이 프레임 버퍼 전략에 대해 이러한 메소드의 정의를 생성할 수 있습니다.
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HAL::flushFrameBuffer(rect);

// Once flushFrameBuffer() is called by the framework a block is ready for transfer
// Mark it ready for transfer and transmit it if user defined method
// isTransmittingData() does not return false

// If data is not being transmitted, transfer the data with user defined method
// transmitFrameBufferBlock().
frameBufferAllocator->markBlockReadyForTransfer();
if (!isTransmittingData())
{
touchgfx::Rect r;
const uint8_t* pixels = frameBufferAllocator->getBlockForTransfer(r);
transmitFrameBufferBlock((uint8_t*)pixels, r.x, r.y, r.width, r.height);
}
}