# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x140000, font_hs20,data, , 0x150000,0x2250ac, spiffs, data, spiffs, 0x3C0000,0x30000, coredump, data, coredump,0x3F0000,0x10000,
2025年2月11日 星期二
定義Arduino Flash Partition
在Arduino 的工程目錄中,增加一個 partitions.csv 文字檔案,內容範例如下
2025年2月7日 星期五
獨立編譯 LVGL 中文字庫並放置於Flash中並使用Arduino讀取
透過LVGL官方網站字體轉換網頁,轉換出需要的UNICODE字庫
Font converter
這邊取用 HarmonyOS_Sans_SC_Regular.ttf 作為TTF字體測試範例,可於此處下載字體
因為要轉換字體大小為20,在Name欄位填寫 font_harmony_sans_20
TTF字體範圍: 0x20-0xBF,0x3000-0x301F,0x4E00-0x9FAF,0xFF00-0xFF64
按下Submit後開始進行轉換,完成後,會下載一個 font_harmony_sans_20.c 的檔案,裡面即為字型檔案,接著要將此檔案複製一份,將此檔案分別為兩個檔案,font_harmony_sans_20.c與font_harmony_sans_20_font.c
font_harmony_sans_20.c 是將 glyph_bitmap[] 與 glyph_dsc[] 兩個陣列移除後的檔案,font_harmony_sans_20_font.c 則相反,是將 glyph_bitmap[] 與 glyph_dsc[] 兩個陣列的所有資料及檔頭資訊保留下來的檔案,如下圖 (已將兩陣列資料摺疊收起)
將font_harmony_sans_20.c與font_harmony_sans_20_font.c 複製到 Arduino\libraries\lvgl\src\font 目錄下
修改 font_harmony_sans_20.c 檔案
1.修改引入檔案路徑
修改前
#include "lvgl/lvgl.h"修改後
#include "../../lvgl.h"
2.增加ESP相關函數
#include <esp_partition.h> #include <esp_err.h> #include <esp_log.h> #include <nvs_flash.h> static const char *TAG = "lv_font_harmony_sans_20";
3.在font_harmony_sans_20.c 增加讀取MMU記憶體位址的函數,最後的 font_dsc.glyph_dsc 偏移量會在後面透過命令得到
lv_port_font_harmony_sans_20_load(const char *partition_label) { const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, partition_label); if(partition == NULL) { ESP_LOGE(TAG, "Can't find %s partition!", partition_label); abort(); } ESP_LOGE(TAG, "Find %s partition!", partition_label); const void *flash_offset; esp_partition_mmap_handle_t map_handle; // Map the partition to data memory ESP_ERROR_CHECK(esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &flash_offset, &map_handle)); ESP_LOGE(TAG, "Mapped partition to data memory address %p\n", flash_offset); ESP_LOGE(TAG, "mapped %s@%1p", partition->label, flash_offset); font_dsc.glyph_bitmap = flash_offset; font_dsc.glyph_dsc = flash_offset+0x1d26dc; //2bpp }
並在 lv_font.h中增加
extern const lv_font_t font_harmony_sans_20; void lv_port_font_harmony_sans_20_load(const char *partition_label);增加一個 rodata_gen_bin.ld 腳本檔案,確保 .rodata是從0x00的位置開始
SECTIONS { . = 0x0; .text : { *(.rodata) } = 0 }
開始編譯 font_harmony_sans_20_font.c 檔案,路徑會因安裝Arduino在不同位置而有所差異
1. 編譯 font_harmony_sans_20_font.c 產生.o 檔案
C:\Users\yyli\AppData\Local\Arduino15\packages\esp32\tools\esp-x32\2405\bin\xtensa-esp32-elf-gcc -c -D LV_CONF_SKIP -D LV_FONT_FMT_TXT_LARGE -I d:\Users\yyli\Documents\Arduino\\libraries\lvgl font_harmony_sans_20_font.c
2. 編譯 .o code
C:\Users\yyli\AppData\Local\Arduino15\packages\esp32\tools\esp-x32\2405\bin\xtensa-esp32-elf-ld -T rodata_gen_bin.ld .\font_harmony_sans_20_font.o -o font_harmony_sans_20_font.out
3. 生成 .bin code
C:\Users\yyli\AppData\Local\Arduino15\packages\esp32\tools\esp-x32\2405\bin\xtensa-esp32-elf-objcopy --output-target elf-xtensa-le -O binary -S font_harmony_sans_20_font.out font_harmony_sans_20_font.bin
4. 查看字型陣列資料的偏移值
C:\Users\yyli\AppData\Local\Arduino15\packages\esp32\tools\esp-x32\2405\bin\xtensa-esp32-elf-objdump -t font_harmony_sans_20_font.out
Dump偏移量的結果,把結果回填到 font_harmony_sans_20.c 的 font_dsc.glyph_dsc 偏移值,在此例為 0x1d26dc
font_harmony_sans_20_font.out: file format elf32-xtensa-le SYMBOL TABLE: 00000000 l d .text 00000000 .text 00000000 l d .comment 00000000 .comment 00000000 l d .xtensa.info 00000000 .xtensa.info 00000000 l d .xt.prop 00000000 .xt.prop 00000000 l df *ABS* 00000000 font_harmony_sans_20_font.c 00000000 l O .text 001d26db glyph_bitmap 001d26dc l O .text 000529d0 glyph_dsc使用樂鑫官方的Flash downliad tool將font_harmony_sans_20_font.bin燒錄到 Font Flash 定義的為止即可,(定義Arduino flash partition) 上面產生的 font_harmony_sans_20_font.bin 在flash要預留glyph_bitmap + glyph_dsc 的大小,所以在partition.csv中定義 bin起始位址 0x150000,size為 0x2250ac 到此完成把字體bin燒錄到flash,在程式中要用到中文字時先呼叫 lv_port_font_harmony_sans_20_load("font_hs20"); 函數就能夠使用中文字了
lv_init(); lv_display_t * disp; /*TFT_eSPI can be enabled lv_conf.h to initialize the display in a simple way*/ disp = lv_tft_espi_create(TFT_HOR_RES, TFT_VER_RES, draw_buf, sizeof(draw_buf)); lv_display_set_rotation(disp, TFT_ROTATION); /* Create simple label */ lv_obj_t *label = lv_label_create(lv_screen_active()); lv_port_font_harmony_sans_20_load("font_hs20"); lv_obj_set_style_text_font(label, &font_harmony_sans_20, 0); lv_label_set_text(label, "Hello Arduino! (V9.0) 中文版"); lv_obj_align(label, LV_ALIGN_CENTER, 0, -50);
訂閱:
文章 (Atom)
定義Arduino Flash Partition
在Arduino 的工程目錄中,增加一個 partitions.csv 文字檔案,內容範例如下 # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, o...
-
markdown 因要讀取電表的資料,所以接觸了SCPI這個語言,這次又要讀取示波器的波形資料,所以乾脆整理了一下使用的命令,方便於日後查詢 SCPI (Standard Command for Programmable Instrumentation)可程式化儀器標準語言,是透...
-
之前使用ESP8266製作Homekit裝置時,都須藉由RPi3當中繼,才能透過手機與Homekit裝置做控制 現在在ESP32上,裝置已經可以獨立運作,不再需要RPi3了 感謝網路上的許多神人們 younghyunjo , maximkulkin 開發ESP32的程...
-
markdown Home Assistant 我是用 官方的映象檔 安裝在樹莓派上使用,下載的檔案就直接燒錄在SD卡即可,這邊我使用的燒錄軟體是 Rufus 。 但別急著插進樹莓派開機,還要設定WiFi連線,才能讓樹莓派連上網路 在SD卡根目錄下,新增一個CONFIG的目錄,...