影像緩衝區策略
本節介紹如何設定TouchGFX Generator,以產生使用以下其中一種影像緩衝區策略的TouchGFX HAL:
- 單一影像緩衝區
- 雙影像緩衝區
- 部份影像緩衝區
點擊這裡閱讀更多關於影像緩衝區的內容。
單一影像緩衝區
選取單一影像緩衝區(Single Frame Buffer)作為緩衝策略,開發人員可以讓編譯器於內部RAM中配置影像緩衝區所需的記憶體,或者也可以自行在內部RAM中指定影像緩衝區的存取位置。
依配置 (By Allocation)
選擇依配置(By Allocation)時,TouchGFX Generator將根據圖形的大小和像素位元深度來配置影像緩衝陣列。
產生用於設定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);
}
依位址
當為影像緩衝區的位置選擇依位址時,TouchGFX Generator將在HAL初始化階段使用所指定的起始位址。
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0, (void*)0);
}
雙影像緩衝
在雙影像緩衝區 (Double Frame Buffer) 配置中,TouchGFX Generator將根據所選取的影像緩衝區策略和顯示介面在HAL中產生用於影像緩衝區切換的程式碼。 在主事件循環中TouchGFX引擎將會用到與影像緩衝區相連的記憶體介面。
依位址
選擇依位址時,TouchGFX Generator將在HAL初始化階段使用兩個指定的起始位址。
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC003FC00, (void*)0);
}
Tip
Tip
依配置 (By Allocation)
選擇依配置(By Allocation) 時,TouchGFX Generator將根據圖形的大小和位元深度來配置陣列大小,這與使用單一影像緩衝區完全一樣,差別只在於配置了兩個相同大小的陣列。
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);
}
局部影像緩衝區
採用部分影像緩衝區策略時,TouchGFX不使用與顯示尺寸相同的影像緩衝區。 相反,用戶可以選擇具有給定尺寸的若干塊作為影像緩衝區。 TouchGFX利用影像緩衝區分配器(Frame Buffer Allocator)來控制這些塊的使用。
使用此策略時,無需提供指向外部記憶體(影像緩衝區所在位置)的指標,也不需要在內部記憶體中分配影像緩衝區陣列。
有關影像緩衝區的概念,請參見有關影像緩衝區的文章。
Tip
由於局部緩衝區通常僅用於無TFT控制器且內部RAM很小的低成本MCU,因此局部緩衝區策略就期望開發人員能完成將緩衝內容傳輸到顯示器的實作。 參見FMC/SPI方案,以瞭解如何將像傳送到不具TFT控制器的MCU所連接的序列傳輸顯示器。
為了在TouchGFX裡使用局部影像緩衝策略連結顯示幕,開發人員需要實作以下兩個功能。 下面顯示的程式碼由TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp
中的CubeMX生成,它定義了TouchGFX 引擎和顯示驅動程式之間的介面。
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) 然後使用者必須傳輸參數表示的資料。
*/
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
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HAL::flushFrameBuffer(rect);
// Try transmitting a block
PartialFrameBufferManager::tryTransmitBlock();
}