주요 내용으로 건너뛰기

글꼴 데이터에 메모리 매핑 모드가 아닌 플래시 사용

이 섹션에서는 매핑되지 않은 글꼴 스토리지 형식을 사용하여 거의 모든 글꼴 데이터를 매핑되지 않은 외부 플래시에 넣는 방법을 살펴보겠습니다. 이러한 스토리지 형식을 사용하면 수많은 문자를 애플리케이션에 저장하기 때문에 글꼴 데이터에 대한 내부 플래시 사용량이 10KB를 넘지 않습니다.

글꼴 레이아웃

TouchGFX는 애플리케이션에 컴파일된 글꼴에 대해 두 가지 글꼴 레이아웃을 지원합니다. Configurations 탭의 TouchGFX Designer에서 사용할 레이아웃을 선택합니다.

글꼴 레이아웃 구성

매핑 스토리지 형식은 기본 글꼴 레이아웃으로, 글꼴이 메모리 매핑 플래시(내부 또는 외부 QSPI 플래시)에 저장되는 시스템에서 사용해야 합니다.

매핑되지 않은 스토리지 형식은 새로운 글꼴 레이아웃입니다. 이 형식에서는 대부분의 글꼴 데이터를 매핑되지 않은 플래시에 저장할 수 있습니다. 보통은 SPI 플래시이지만, 어떤 유형의 스토리지든 사용이 가능합니다.

매핑 스토리지 형식

매핑 스토리지 형식은 두 개의 테이블에 글꼴 데이터를 보관합니다.

첫 번째 테이블은 touchgfx::GlyphNode의 배열입니다. 여기에는 높이, 너비, 유니코드 같은 개별 문자의 속성이 포함되어 있습니다.

generated/fonts/src/Table_verdana_20_4bpp.cpp
FONT_TABLE_LOCATION_FLASH_PRAGMA
KEEP extern const touchgfx::GlyphNode glyphs_verdana_20_4bpp[] FONT_TABLE_LOCATION_FLASH_ATTRIBUTE =
{
{ 0, 0x0020, 0, 0, 0, 0, 7, 0, 0, 0x00 },
{ 0, 0x002C, 5, 7, 3, 1, 7, 0, 2, 0x00 },
{ 21, 0x0030, 11, 14, 14, 1, 13, 0, 0, 0x00 },
{ 105, 0x0032, 11, 14, 14, 1, 13, 0, 0, 0x00 },
{ 189, 0x0033, 11, 14, 14, 1, 13, 0, 0, 0x00 },
{ 273, 0x0034, 12, 14, 14, 0, 13, 0, 0, 0x00 },
...
}

두 번째 테이블(큰 글꼴의 경우 여러 파일로 분할)에는 문자의 픽셀 패턴이 포함되어 있습니다.

generated/fonts/src/Font_verdana_20_4bpp_0.cpp
FONT_GLYPH_LOCATION_FLASH_PRAGMA
KEEP extern const uint8_t unicodes_verdana_20_4bpp_0[] FONT_GLYPH_LOCATION_FLASH_ATTRIBUTE =
{
// Unicode: [0x0020]
// (Has no glyph data)
// Unicode: [0x002C]
0x00, 0x87, 0x04, 0x20, 0xFF, 0x03, 0x60, 0xBF, 0x00, 0xA0, 0x5F, 0x00, 0xE0, 0x0D, 0x00, 0xF3,
0x07, 0x00, 0xF6, 0x01, 0x00,
// Unicode: [0x0030]
0x00, 0xA3, 0xFE, 0x9D, 0x01, 0x00, 0x40, 0xFF, 0x9B, 0xFC, 0x1D, 0x00, 0xD0, 0x4F, 0x00, 0x80,
0x9F, 0x00, 0xF3, 0x0B, 0x00, 0x10, 0xEE, 0x00, 0xF7, 0x07, 0x00, 0x00, 0xFB, 0x03, 0xF9, 0x06,
...
}

GlyphNode는 텍스트 레이아웃 시 TouchGFX 엔진에서 사용됩니다. 그리기를 하는 동안 DMA2D 또는 소프트웨어 루틴에서 픽셀을 읽습니다.

일반 LCD 클래스(LCD16bpp 또는 LCD24bpp)를 사용하는 플랫폼에서는 이러한 테이블들을 반드시 내부 플래시나 메모리 매핑된 외부 플래시에 저장해야 합니다.

LCD16bppSerialFlash를 사용하는 플랫폼에서는 렌더링 소프트웨어가 매핑되지 않은 직렬 플래시에서 픽셀 패턴을 읽을 수 있지만, GlyphNode는 내부 플래시(직접 검색됨)에 있어야 합니다.

이 레이아웃은 각 문자마다 내부 플래시 14바이트를 사용합니다.

매핑되지 않은 스토리지 형식

매핑되지 않은 스토리지 형식은 글꼴 데이터를 세 개의 테이블로 분할합니다. 매핑 스토리지 레이아웃에서 나온 두 개의 테이블이 재사용되지만, 세 번째 테이블은 추가됩니다.

generated/fonts/src/Table_verdana_20_4bpp.cpp
FONT_SEARCHTABLE_LOCATION_FLASH_PRAGMA
KEEP extern const uint16_t unicodelist_verdana_20_4bpp[] FONT_SEARCHTABLE_LOCATION_FLASH_ATTRIBUTE =
{
0x0020,
0x002E,
0x003F,
0x004E,
0x0054,
....
}

이 세 번째 테이블에는 글꼴에 있는 유니코드만 포함되어 있습니다.

이 글꼴 레이아웃을 사용할 때 세 번째 테이블은 반드시 내부 플래시에 있어야 하지만, 나머지 두 테이블은 외부 플래시로 이동이 가능합니다. 세 번째 테이블은 각 문자에 2바이트를 사용하는 반면, GlyphNode 테이블은 14바이트를 사용한다는 점에서 상당한 절감 효과가 있습니다. 따라서 내부 플래시의 저장 요구 사항이 줄어듭니다.

글꼴 데이터 리더

글꼴 데이터가 매핑되지 않은 플래시에 저장되면 MCU가 이를 직접 액세스할 수 없습니다. 따라서 글꼴 하위 시스템에 flash reader 오브젝트를 제공해야 합니다. 이에 대한 코드는 TouchGFX Generator에서 자동으로 생성됩니다

TouchGFXConfiguration.cpp
static TouchGFXDataReader dataReader;
static LCD16bppSerialFlash display(dataReader);
static ApplicationFontProvider fontProvider;
static Texts texts;
static TouchGFXHAL hal(dma, display, tc, 240, 320);
void touchgfx_init()
{
Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
TypedText::registerTexts(&texts);
Texts::setLanguage(0);
hal.setDataReader(&dataReader);
fontProvider.setFlashReader(&dataReader);
...

TouchGFX Generator를 사용하지 않는 경우에는 수동으로 생성해야 합니다.

TouchGFXDataReader에서 함수를 구현해야만 플래시에서 데이터를 실제로 읽을 수 있습니다.

요약

글꼴 데이터는 2~3개의 테이블에 저장됩니다. 아래 표는 플래시 저장을 나타낸 것입니다.

테이블(이름 예)매핑 스토리지 형식매핑되지 않은 스토리지 형식
GlyphNodes in glyphs_verdana_20_4bpp내부외부
Pixel data in unicodes_verdana_20_4bpp_0외부외부
Unicodes in unicodelist_verdana_20_4bpp미사용내부

예제

다음은 새 글꼴 레이아웃을 사용하는 애플리케이션의 스크린샷입니다.

한자 4000자가 포함된 애플리케이션 예제

이 애플리케이션은 MB1642A 디스플레이 모듈이 장착된 STM32G071 Nucleo 보드에서 실행됩니다.

STM32G071 Nucleo에서 실행 중인 애플리케이션 예제

이 애플리케이션에는 20비트(픽셀당 4비트) 크기의 한자 4000자가 있습니다. 애플리케이션과 데이터는 STM32G071에서 사용 가능한 128Kb중 61Kb 차지합니다. 글꼴 데이터는 다음과 같이 배포됩니다(마이너 객체 제외).

테이블위치크기
GlyphNodes외부 SPI 플래시57,372 바이트
픽셀 패턴외부 SPI 플래시3.116.296 바이트
유니코드 목록내부 플래시8,000 바이트

링커 스크립트 수정

매핑되지 않은 글꼴 레이아웃을 올바르게 사용하려면 테이블을 올바르게 배치하도록 링커 스크립트를 업데이트해야 합니다.

STM32F746.ld
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20008FFF;
define symbol __ICFEDIT_region_SERIAL_FLASH_start__ = 0x90000000;
define symbol __ICFEDIT_region_SERIAL_FLASH_end__ = 0x91000000;

place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };

place in SERIAL_FLASH_region {section ExtFlashSection, section FontFlashSection };

이 링커 스크립트에서는 ExtFlashSection(이미지 및 글꼴 픽셀)과 FontFlashSection(GlyphNodes)이 모두 외부 플래시에 있습니다. 다른 모든 읽기 전용 데이터는 내부 플래시(ROM_region)에 있습니다.