玩轉ART-Pi(七)——TouchGFX從文件系統中讀取圖片

目錄

玩轉ART-Pi(一)——使用STM32CUBMX生成TouchGFX工程
玩轉ART-Pi(二)——製作MDK的外部QSPI-FLASH燒錄算法
玩轉ART-Pi(三)——如何在ART-PI上創建TouchGFX工程
玩轉ART-Pi(四)——添加文件系統
玩轉ART-Pi(五)——添加網絡功能
玩轉ART-Pi(六)——添加FTP服務器
玩轉ART-Pi(七)——TouchGFX從文件系統中讀取圖片





實驗平臺:

硬件: RT-Thread官方ART-PI H750開發版
軟件: RT-Thread Studio 1.1.5

聯繫作者:

加我微信,備註“加羣”,加入技術交流羣
在這裏插入圖片描述

實驗思路

官方文檔介紹:使用非內存映射的閃存存儲圖像

出於性能原因,TouchGFX要求直接存儲在外部閃存中的所有圖形數據(通過指針),而無需通過驅動程序層。這意味着TouchGFX無法直接從非內存映射的閃存(如SD卡)進行渲染。爲了克服此限制,位圖緩存提供了一種在加電期間將部分或全部位圖數據緩存在RAM中的機制。因此,當您需要將位圖存儲在慢速外部存儲(例如USB磁盤或SD卡)上時,位圖緩存非常有用。

從文件系統中讀取圖片資源

1.修改鏈接腳本

默認情況下,TouchGFX中的所有位圖都放入ExtFlashSection中,標準的鏈接描述文件(此處爲GCC)將其他只讀數據一起放入閃存。在此示例中,我們將圖像數據放入地址爲0x9A000000的ExtFlashSection中。您可以選擇任何其他未使用的地址(不屬於代碼或數據地址空間的一部分)。
首先,除了正常的內部閃存和RAM區域外,我們還定義了一個新的存儲區域(地址爲0x9A000000的USB閃存):
在這裏插入圖片描述
然後,指示鏈接器將ExtFlashSection放入USB區域:
在這裏插入圖片描述
鏈接後,我們可以通過檢查映射文件(application.map)來檢查位圖的地址。這是相關的部分:
在這裏插入圖片描述
現在,假設我們希望位圖數據進入SD卡。我們可以使用簡單的objcopy命令從.elf文件中提取位圖的二進制數據:






arm-none-eabi-objcopy -O binary -j ExtFlashSection "${BuildArtifactFileBaseName}.elf" "images.bin"

在這裏插入圖片描述
此時編譯代碼,會生成一個僅包含圖像字節數組的文件(images.bin)。該文件可以複製到USB閃存,SD卡,甚至可以編程到閃存芯片。

接下來,當TouchGFX要求地址0x9A000000以上的數據時,我們從SD卡上的images.bin文件中獲取數據。

2.修改BlockCopy功能

當您將位圖緩存到RAM時,TouchGFX會調用HAL :: BlockCopy來獲取數據。
爲了將其鏈接到SD卡或者nor flash上的數據,我們可以在您的特定HAL類中實現一個新的BlockCopy。在這裏,我們假設該類稱爲TouchGFXHAL(由TouchGFX Generator生成)。
首先在SD卡中尋找images.bin,如果沒有掛載SD卡,則在nor flash中尋找:

bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
{
   
   
    uint32_t dataOffset = (uint32_t)src;
    if (dataOffset >= 0x9A000000 && dataOffset < 0xA0000000)
    {
   
   
            int fd;
            struct statfs buffer;
            if(rt_device_find("sd0") != RT_NULL)
            {
   
   
                if ((dfs_statfs("/sdcard",&buffer) == RT_EOK) | (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == RT_EOK))
                {
   
   
                    fd = open("/sdcard/images.bin", O_RDONLY, 0);
                    if (fd < 0)
                    {
   
   
                        rt_kprintf("open file for read failed\n");
                        return false;
                    }
                    dataOffset =  dataOffset - 0x9A000000;
                    lseek(fd, dataOffset, SEEK_SET);
                    // for copying data from there.
                    read(fd, (uint8_t *)dest, numBytes);
                    close(fd);
                }
                return true;
            }
            else if(dfs_statfs("/flash",&buffer) == RT_EOK)
            {
   
   
                fd = open("/flash/images.bin", O_RDONLY, 0);
                if (fd < 0)
                {
   
   
                    rt_kprintf("open file for read failed\n");
                    return false;
                }
                dataOffset =  dataOffset - 0x9A000000;
                lseek(fd, dataOffset, SEEK_SET);
                // for copying data from there.
                read(fd, (uint8_t *)dest, numBytes);
                close(fd);
                return true;
            }
            else
            {
   
   
                return false;
            }
    }
    else
    {
   
   
        // For all other addresses, just use the default implementation.
        // This is important, as blockCopy is also used for other things in the core framework.
        return HAL::blockCopy(dest, src, numBytes);
    }
}

3.將位圖數據從閃存複製到緩存

在TouchGFXHAL.cpp中啓用和配置位圖緩存。首先,需要刪除默認創建的位圖緩存數據庫,然後根據提供的存儲區域設置新的緩存。
在這裏插入圖片描述

4.通過fileziia將images.bin上傳到SD卡或者nor flash

有SD的可以通過讀卡器或者fileziia將images.bin複製到卡里,程序默認先從SD卡中尋找images.bin文件。
在這裏插入圖片描述
沒有SD卡的,就上傳到NOR FLASH裏,程序找不到SD後,會從NOR FLASH中尋找images.bin文件。
在這裏插入圖片描述


5.demo演示

導入touchgfx的demo。
在這裏插入圖片描述
演示代碼下載:https://download.csdn.net/download/sinat_31039061/13139312
在這裏插入圖片描述


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章