在 STM32H7R7 與 S7 上執行圖形處理
本文介紹 STM32H7R/S 系列 MCU 的具體架構,並討論用於圖形應用時需要考慮的事項。 然而,大部分考量都適用於所有執行含外部 RAM 和快閃記憶體圖形處理的 STM32 MCU。
本文不是教導如何建立 TouchGFX 開發板設定 (TBS) 的初學者指南,STM32H7R/S 是一款高效能且進階的 MCU。 因此,本文將只特別針對 STM32H7R/S 深入探討重要的領域。 有關如何建立 TouchGFX TBS 的一般簡介,請參閱「開發板初次啟動指南」。
有關 STM32H7R7/S7 詳細資訊請參閱產品頁面或包含完整 STM32H7RS 示範工作坊的 YouTube 播放清單。
TouchGFX Designer 包含一個適用於 STM32H7S78 DK 的 TBS,這是在 STM32H7R/S 上執行 TouchGFX 的完整範例專案。 在為 STM32H7R/S 開發 TouchGFX 應用程式時,可以使用 TBS 作為參考。 該專案以 STM32CubeMX 為基礎,亦即可以透過開啟 STM32H7S78-DK.ioc 檔案存取快取、MPU、外部記憶體等的建議設定。
記憶體設定
STM32H7R/S 是一款開機快閃記憶體 MCU。 開機快閃記憶體 MCU 是一種具有小型嵌入式快閃記憶體的 MCU,其中包含啟動程式,而主應用程式與資產一起放在外部記憶體中。 STM32H7R/S 還具有 620 kB 的嵌入式 SRAM。 因此,STM32H7R/S 在用於圖形應用時依賴外部 RAM 和快閃記憶體。 當使用外部記憶體進行圖形處理時,外部記憶體的記憶體頻寬通常會成為瓶頸,因為外部記憶體以 CPU 頻率的二或三分之一運作。 對於 STM32H7R7/S7,兩個 XSPI (16 位元和 8 位元) 介面能夠以高達 200 MHz 的雙倍傳輸速率運作,而 FMC (16 位元或 32 位元) 能夠以高達 100 MHz 的速度運作。
外部記憶體管理器
STM32CubeMX 的「類別」→「中介軟體和軟體套件」下,提供了兩個名為「外部記憶體管理器」和「外部記憶體載入器」的工具。 建立這些工具是為了幫助使用者在開機快閃記憶體或無快閃應用程式中設定外部記憶體。 這些工具使得建立外部載入器變得更加容易,例如選擇應用程式類型。 有關工具的介紹請見這裡。 一篇名為《STM32 外部序列記憶體簡介》的新文章即將發布。
Further reading
外部 RAM 中的影像緩衝區
外部 RAM 具有影像緩衝區時,首先要考慮並且最重要的事,就是記憶體頻寬要求和限制。 對於不含 GRAM 的顯示器,需要以顯示器指定的速率連續傳送影像緩衝區。 對於探索套件上使用的顯示器,頻率為 60 Hz。 亦即僅更新 LTDC 就會佔用外部 RAM 介面上的大量頻寬。 LTDC 所需頻寬可按以下公式計算:
像素時脈 = LCD_CLK = 總螢幕尺寸 * 更新率
所需頻寬 (對於一個 LTDC 層) = LCD_CLK * Bpp
此外,DMA2D 和 GPU2D 在影像緩衝區上執行操作時,也需要外部 RAM 上的頻寬。 如果記憶體也用於其他用途 (例如應用程式程式碼),這將進一步降低頻寬。
綜合起來,這些因素會造成外部 RAM 匯流排混亂。
點選此處閱讀文章,瞭解在外部 RAM 中使用影像緩衝區執行圖形處理時的注意事項。
如欲深入瞭解在外部 RAM 中使用 LTDC 顯示器介面和影像緩衝區的限制和注意事項,請參閱「LTDC 應用說明」。 請特別注意第 5 章:「使用 LTDC 建立圖形應用程式」和第 7 章:「LTDC 應用程式範例」。
如果外部 RAM 的頻寬已達到極限,請考慮第 5.5.2 章:「最佳化從外部記憶體擷取的 LTDC 影像緩衝區」和第 5.5.3 章:「最佳化從 SDRAM 擷取的 LTDC 影像緩衝區」。
Further reading
- [從外部 RAM 執行圖形處理] (running-graphics-from-external-ram)
- [AN4861:STM32 MCU 上的 LCD-TFT 顯示器控制器 (LTDC) 簡介] (https://www.st.com/resource/en/application_note/an4861-introduction-to-lcdtft-display-controller-ltdc-on-stm32-mcus-stmicroelectronics.pdf)
緊密耦合記憶體
STM32H7R/S Cortex-M7 具有 64 位元寬的緊密耦合記憶體 (TCM) 直接存取功能,且無需等待狀態。 其具有最高 192 kB 的資料 TCM (DTCM) 和指令 TCM (ITCM)。 因此,DTCM 和 ITCM 分別是讀取/寫入資料和擷取指令的最佳位置。 因此,ITCM 應該用於具有確定性執行的關鍵程式碼,例如無法等待快取未中的中斷處理程序,以及關鍵控制迴路。 在使用 RTOS 的即時應用程式中,一般大量使用堆積。 因此建議將 RTOS 堆疊和堆積放在 DTCM 中。 如果還有剩餘空間,全域變數也可以放在這裡。
值得注意的是,ITCM 和 DTCM 使用 SRAM1 和 SRAM3 記憶體的某些部分。 也就是說,使用 ITCM 和 DTCM 時,內部 SRAM 的大小會縮小。
與其他 H7 MCU 一樣,STM32H7R/S 具有 1 級 (L1) 快取。 有關 L1 快取,詳細資訊請參閱「H7 快取應用說明」。 請特別注意第 4 章:「應避免的錯誤和秘訣」。
有關如何設定外部 SPI 記憶體的詳細說明,請參閱「OSPI、HSPI 和 XSPI 應用說明」。
Further reading
- [AN6062:STM32H7Rx/7Sx 系統架構與效能簡介] (https://www.st.com/resource/en/application_note/an6062-introduction-to-stm32h7rx7sx-system-architecture-and-performance-stmicroelectronics.pdf)
- [AN4839:STM32F7 系列和 STM32H7 系列上的 1 級快取] (https://www.st.com/resource/en/application_note/an4839-level-1-cache-on-stm32f7-series-and-stm32h7-series-stmicroelectronics.pdf)
- [AN5050:STM32 MCU 上 Octo-SPI、Hexadeca-SPI 和 XSPI 介面入門] (https://www.st.com/resource/en/application_note/an5050-getting-started-with-octospi-hexadecaspi-and-xspi-interface-on-stm32-mcus-stmicroelectronics.pdf)。
應用程式類型
在啟動期間,啟動程式可以根據所選的應用程式類型執行不同的任務。 可以指向外部快閃記憶體中已存在的應用程式,也可以將應用程式載入到另一個記憶體 (通常是外部 RAM)。
執行已存在於外部快閃記憶體中的應用程式稱為「就地執行」(XiP)。 在啟動期間將應用程式從快閃記憶體複製到 RAM,然後從 RAM 執行的程序稱為「載入並執行」(LRUN)。
如果應用程式經過加密,則只能使用 LRUN。 有關 STM32 加密,詳細資訊請參閱「加密應用說明」。
Further reading
[AN6088:如何在 STM32 MCU 上使用 MCE 進行加密/解密] (https://www.st.com/resource/en/application_note/an6088-how-to-use-mce-for-encryptiondecryption-on-stm32-mcus-stmicroelectronics.pdf)
就地執行 (XiP)
以下為 XiP 記憶體配置在圖形應用程式中的範例。 XiP 是預設的應用程式類型。
如 XiP 示意圖所示,連接外部快閃記憶體的 OctoSPI 介面用於存取應用程式程式碼和圖形資產。 CPU 不斷存取應用程式程式碼,這會導致 NeoChrom GPU 或 Chrom-ART 存取資產時的存取時間變慢。 這將對圖形效能產生負面影響。 為了克服這項挑戰,強烈建議在執行 XiP 時啟用外部快閃記憶體的指令快取。 如此一來,重複指令將從快取中讀取,而不是從外部快閃記憶體中讀取,進而減少頻寬的負載,並提高外部快閃記憶體介面的效率。
載入並執行 (LRUN)
以下為 LRUN 的對應範例。
如 LRUN 示意圖所示,應用程式程式碼現在與圖形資產分離,進而改善了資產的存取。 然而,這也表示其現在充當外部 RAM 的介面,需要在 RAM 中載入資料,用來存取影像緩衝區和應用程式程式碼。 在這種情況下,強烈建議在外部 RAM 介面上啟用指令快取。
在 STM32H7R/S 上使用 LRUN 執行圖形應用程式時,還需要考慮幾件事以實現最佳效能。
首先,考慮是否可以將資產 (點陣圖、字型等) 保存在外部快閃記憶體中。 由於資產存取頻率較高,將其儲存在外部 RAM 會顯著增加對外部 RAM 頻寬的負載。 此外,通常不需要加密資產。
其次,值得研究應用程式程式碼是否適合內部 SRAM,如下所示。 與外部快閃記憶體或外部 RAM 相比,由於內部匯流排速度更快,因此可以從內部 SRAM 更快存取和執行應用程式程式碼。 STM32H7R/S 上的 AXI 匯流排 (與內部 SRAM 連接) 能夠以高達 300 MHz 的速度運作。 此外,此設定使資產、影像緩衝區和應用程式程式碼得以放置在三個不同的位置,進而將頻寬負載分散到三個獨立的匯流排上。
效能比較
以下是分別使用 XiP 和 LRUN 的複雜 GUI 範例。 LRUN 應用程式的應用程式程式碼位於在內部 SRAM。 比較顯示了 MCU 負載如何受到不同設定的影響。 透過將 TouchGFX 架構和應用程式放在內部 SRAM 中,可減少外部 RAM 和快閃記憶體中的擷取週期數,進而有效降低 MCU 的負載。
示範參考是在 STM32H7S78-DK 上運作的開箱即用示範。
比較顯示,當應用程式程式碼放在內部 SRAM 中,MCU 負載會減輕。 與 XiP 相比,使用 LRUN 時 MCU 負載減少約 50%。
比較顯示,當應用程式程式碼放在內部 SRAM 中,MCU 負載顯著降低。 這是因為與外部 RAM 和快閃記憶體相比,內部 SRAM 的存取時間更快。 與 XiP 相比,當使用 LRUN 並將應用程式程式碼放在內部 SRAM 時,MCU 負載減少了 50%。 使用 LRUN 並將應用程式程式碼儲存在內部 SRAM,可發揮最佳效能。 然而,只有當應用程式程式碼適合可用的內部 SRAM 時,這種設定才是可行的。
MPU 設定
記憶體保護單元 (MPU) 用於保護記憶體區域免受意外的記憶體存取和執行。
在 Arm® Cortex®-M7 處理器上,防止投機性存取非常重要,因為這會導致在外部記憶體上執行時的高延遲或系統錯誤。 對於 STM32H7R/S,這將影響存取記憶體的 AXI 主機,並會顯著降低圖形效能。
透過控制可存取的位址範圍,MPU 可用於防止投機性讀取存取。 最簡單的方法是使用具有整個記憶體區域的後台區域,透過將其設定為「嚴格有序,永不執行」來限制存取。
背景區域應在 ID 為 -1 的預設區域中定義,如此一來其他所有區域都將優先於此區域。 接著,應該為需要存取的記憶體區域定義具有相應設定的其他 MPU 區域。 在 STM32H7R/S 上最多可以定義 16 個區域。
以下為 STM32H7S78 DK TBS 的 MPU 設定。 此設定可以作為參考。
區域 0 | 全部 | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域基底位址 | 0x0 | |
MPU 區域大小 | 4 GB | 覆蓋 MCU 的整個記憶體區域 |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 0 級 | |
MPU 存取權限 | 禁止一切存取 | 限制所有存取 |
MPU 指令存取 | 停用 | |
MPU 共用權限 | 啟用 | |
MPU 快取權限 | 停用 | |
MPU 緩衝權限 | 停用 |
區域 1 | 外部快閃記憶體 | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域基底位址 | 0x70000000 | XSPI2 (外部快閃記憶體) 的基底位址 |
MPU 區域大小 | 128 MB | 開發板上有 128 MBytes 的外部快閃記憶體 |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 1 級 | |
MPU 存取權限 | 允許所有存取 | |
MPU 指令存取 | 停用 | |
MPU 共用權限 | 停用 | |
MPU 快取權限 | 啟用 | |
MPU 緩衝權限 | 啟用 |
區域 2 | 外部快閃記憶體 | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域 | 啟用 | |
MPU 區域基底位址 | 0x70000000 | XSPI2 (外部快閃記憶體) 的基底位址 |
MPU 區域大小 | 2 MB | 應用程式程式碼所在的外部快閃記憶體的前 2 MB 的屬性被覆寫 |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 1 級 | |
MPU 存取權限 | 允許所有存取 | |
MPU 指令存取 | 啟用 | |
MPU 共用權限 | 停用 | |
MPU 快取權限 | 啟用 | |
MPU 緩衝權限 | 啟用 |
區域 3 | 外部 PSRAM | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域基底位址 | 0x90000000 | XSPI1 (外部 PSRAM) 的基底位址 |
MPU 區域大小 | 32 MB | 開發板上有 32 MBytes 的外部 PSRAM |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 1 級 | |
MPU 存取權限 | 允許所有存取 | |
MPU 指令存取 | 停用 | |
MPU 共用權限 | 停用 | |
MPU 快取權限 | 停用 | |
MPU 緩衝權限 | 停用 |
區域 4 | DTCM | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域基底位址 | 0x20000000 | DTCM 的基底位址 |
MPU 區域大小 | 64 kB | 預設 64 kB 的 DTCM |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 1 級 | |
MPU 存取權限 | 允許所有存取 | |
MPU 指令存取 | 停用 | |
MPU 共用權限 | 停用 | |
MPU 快取權限 | 停用 | 停用 DTCM 上的快取,因為其不會提高效能 |
MPU 緩衝權限 | 停用 |
區域 5 | SRAM | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域基底位址 | 0x24000000 | SRAM1 的基底位址 |
MPU 區域大小 | 512 kB | 涵蓋 SRAM1、SRAM2、SRAM3 和 SRAM4 |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 1 級 | |
MPU 存取權限 | 允許所有存取 | |
MPU 指令存取 | 停用 | |
MPU 共用權限 | 啟用 | |
MPU 快取權限 | 啟用 | |
MPU 緩衝權限 | 啟用 |
區域 6 | GPU2D 指令清單 | 附註 |
---|---|---|
屬性 | 值 | |
MPU 區域基底位址 | 0x2406e000 | NeoChrom GPU 指令清單放在此處 |
MPU 區域大小 | 16 kB | 使用 TouchGFX 時 NeoChrom GPU 指令清單的預設大小 (在 nema_hal.c 中定義) |
MPU 子區域停用 | 0x0 | |
MPU TEX 欄位層級 | 0 級 | |
MPU 存取權限 | 允許所有存取 | |
MPU 指令存取 | 停用 | |
MPU 共用權限 | 啟用 | |
MPU 快取權限 | 停用 | 停用指令清單快取 |
MPU 緩衝權限 | 啟用 |
有關圖形特定的 MPU 設定秘訣,請參閱「LTDC 應用說明」第 5.6.2 節「設定記憶體保護單元 (MPU)」。
如需進一步參考,請參閱「MPU 應用說明」。 請特別注意第 3 章:「Cortex-M0+/M3/M4/M7 記憶體類型、暫存器和屬性」及第 6 章:「在 Armv6 和 Armv7 架構上使用 STM32Cube HAL 的 MPU 設定範例」。
Further reading
- [AN4861:STM32 MCU 上的 LCD-TFT 顯示器控制器 (LTDC) 簡介] (https://www.st.com/resource/en/application_note/an4861-introduction-to-lcdtft-display-controller-ltdc-on-stm32-mcus-stmicroelectronics.pdf)
- [AN4838:STM32 MCU 上的記憶體保護單元管理簡介] (https://www.st.com/resource/en/application_note/an4838-introduction-to-memory-protection-unit-management-on-stm32-mcus-stmicroelectronics.pdf)
偵錯
TouchGFX Designer 中 TBS 的 readme 檔案提供有關以下在 STM32CubeIDE 中進行 STM32H7R/S 偵錯的指南。
由於 STM32H7S78-DK 的 TBS 的啟動程式和應用程式結構,在 IDE 中進行程式碼偵錯可能很複雜。 若要在 STM32CubeIDE 中逐步執行 TouchGFX 應用程式的程式碼,請依照下列步驟操作:
- 在 TouchGFX Designer 中產生程式碼
- 在 STM32CubeIDE 中開啟專案
- 啟動 Boot 專案的偵錯工作階段
- 等待編譯和燒錄完成
- 終止偵錯工作階段 (Ctrl + F2)
- 啟動 Appli 專案的偵錯工作階段
- 等待編譯和燒錄完成
- 按一下「繼續」(F8)
- 按下 STM32H7S78-DK 開發板上的黑色 NRST 按鈕
- 應用程式現在位於 Appli 專案中 main() 第一行的中斷點。 如果沒有,請再按一次「繼續」(F8)
- 按一下「繼續」(F8) 或「跳過」(F6) 以繼續
有關偵錯,詳細資訊請參閱「如何開始在 STM32H7RS 上進行 DA 存取」維基頁面。
Further reading
[如何開始在 STM32H7RS 上進行 DA 存取] (https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Security:How_to_start_with_DA_access_on_STM32H7RS)
圖形應用程式的結論和一般建議
如上所述,在開發 STM32H7R/S 圖形應用程式時需要考慮幾點。 然而,只要牢記這些考量,就有可能藉助快速的 CPU 和強大的 GPU2D 實現出色的圖形效能。
首先,瞭解外部記憶體匯流排的頻寬非常重要。 這適用於所有使用外部 RAM 和快閃記憶體的 MCU,但由於 STM32H7R/S 的開機快閃記憶體結構,這一點尤其重要。
透過將關鍵指令和資料放置在 ITCM 和 DTCM 記憶體中,可以顯著提高效能。
啟用整合在 Arm® Cortex®-M7 處理器中的 L1 指令和資料快取,因為這也會提高效能。
根據應用程式要求選擇執行 XiP 還是 LRUN,但請務必注意記憶體頻寬。 如果應用程式程式碼適合內部 SRAM,LRUN 將具有最佳效能。
避免投機性讀取存取非常重要,因為這可能會顯著降低效能。 實現的方式是對所有記憶體區域應用適當的 MPU 設定。