跳轉到主要內容

2. CPU的執行

動機

在本節中,我們要確保MCU核心、內部RAM和快閃記憶體以所需的時脈速度執行。

TouchGFX可在任何MCU速度下執行,但錯誤的時脈配置可能會導致低於所需的效能。 隨後,基於您的開發板,需要配置特定時間參數,如觸控控制器的I2C時脈。 若不能確保MCU以正確的速度執行的情況下,這些設定無法生效。

對於STM32微控制器,您需要設置系統時脈。 然後對該時鐘進行除頻,以生成FCLK核心時脈和各種外設時脈,如APB1外設時脈。

目標

本節的目標為修改專案,以獲得正確的時脈配置。 您還應驗證內部RAM和快閃記憶體是否以預期速度運作。

驗證

以下是本節的驗證點:

驗證點基本原理
SystemCoreClock的變數值正確微控制器被配置在所需的操作頻率之下運作。
內部RAM可讀微控制器具有預期的內部RAM容量,該區可讀,並可以測量速度
可讀的內部快閃記憶體微控制器具有預期的內部快閃記憶體容量,該區可讀,並可以測量速度
關閉Cache快取在關閉Cache快取時執行,可使系統更簡單且易於理解。

先決條件

以下是此步驟的先決條件:

  • 有關硬體上的時脈源的資訊。 通常使用晶體振盪器,但也可以使用其他解決方案。

執行

現在,我們將逐步調整專案時脈配置,以獲取所需的MCU頻率。 然後,我們將討論如何測量內部快閃記憶體的讀取速度。

系統時脈

在STM32CubeMX中,按下「時脈設定」分頁。 這會為您提供特定MCU的時脈概述:

時脈配置

在該範例中,選擇HSI作為時脈源。 許多專案使用外部晶體振盪器HSE,同時選擇合適的除頻(/M)和倍頻(/N)參數。 本指南不做有關時脈配置的介紹。 更改時脈設定後,必須在STM32CubeMX中重新生成專案(點選右上角的"產生程式碼")。

核心時脈(HCLK)可在執行時透過產生的程式碼進行計算,並保存在變數中。 程式碼可使用此變數在時脈週期和秒單位之間進行正確轉換(如開啟定時器)。 要重新計算時脈變數,您必須呼叫SystemCoreClockUpdate()函數。 在main.c(使用者程式碼區段)中插入一個呼叫:

SystemCoreClockUpdate

如果在此函數的末尾設定中斷點,則可以看到基於設定的核心時脈:

SystemCoreClock

另一個測試重點為系統定時器 (System Timer)。 該定時器按HCLK時鐘運行,該時鐘經過除頻以產生1ms的中斷。 該定時器用於STM32Cube韌體以實現毫秒為單位的延遲。

我們可通過在main中插入如5秒的延遲來對此進行測試。 用秒表或類似的方法來驗證這一點:

測量延遲

快閃記憶體與RAM大小和速度

使用系統計時器可輕鬆檢查記憶體的讀取速度。 系統定時器 (System Timer) 的中斷會每毫秒對計數變數加一。 通過在一段程式碼之前和之後讀取此變數,我們可以測量程式碼的運行時間(解析度為1 ms)。 此方案可在應用程式中許多不同位置以測量時間週期。 此方案不是很精確,但可以在沒有示波器等外部設備的情況下完成。

為此,我們首先需要兩個volatile變數來保存結果。 如果我們不在此處儲存結果,則編譯器在某些優化情況下會刪除測量程式碼:

測量結果儲存於這二個全域的volatile變數

在此範例中我們讀取了從0x08000000到0x08020000(128 Kb)的快閃記憶體,並對程式碼進行計時:

對讀取循環進行計時

您可以使用像這樣的程式碼來驗證不同記憶體的速度。 在STM32CubeMX中建立設定後,您可以測量讀取速度,並記錄結果。 隨後可以重複測量並驗證。 如果要測量記憶體頻寬(即以kb為單位的讀取速度),您可以將資料量與測量時間進行比較。

在16 MHz的STM32F429上,如果程式碼程式碼的執行時間為12 ms,則內部快閃記憶體的讀取速度(使用此方法)為128kb/0.012s = 10,666 kb/s。

可輕鬆更改上面的測試程式碼區段,以驗證所有內部快閃記憶體是否啟用並且可讀。 只需更改起始和結束位址。

該程式還可以檢查內部RAM。 在F429,RAM從位址0x20000000開始。 核心偶合記憶體從0x10000000開始。 檢查MCU的資料手冊以獲取相關記憶體位址。

您應該對不同的記憶體進行一些測量並記下結果。 對於RAM,請測試讀取和寫入速度。

連結器設定檔(Linker script)

另一個關注點為連結器設定檔(Linker script)。 該設定檔將系統中RAM和快閃記憶體的位址告知連結器。 連結器設定檔雖然由CubeMX與專案一起生成,但對其進行研究以獲取更多的了解會帶來許多好處。 因為在稍後大多會因應專案的需要而對此設計檔作修改。

F7和H7上的快取

基於ARM Cortex-M7的STM32F7和STM32H7微控制器包括資料和指令快取。 在平台穩定之前,建議至少禁用資料快取【D-Cache】。 在許多情況下,資料快取雖然可顯著提高性能,但同時也會使測試變得複雜。

在擁有穩定的平台後即可啟用資料快取。 此時由於平台已穩定正常因此可以更容易地鎖定問題是否源自資料快取管理。

由於MCU核心對快取作讀取和寫入的同時又有DMA2和LTDC等週邊會直接讀取非快取區的記憶體,這使得資料快取的讀取變得相當複雜。 因此您可能會遇到雖然已將資料寫入影像緩衝區但在顯示器上看不到某些資料的情況。 這是因為這些資料只在寫入快取的階段因此LTDC在RAM中找不到這些新的資料。 解決方案就是在某一時刻刷新專案中的快取,但我們建議稍後再做處理。

在STM32CubeMX當中可以在「系統核心 (System Core)」的設定選項當中關閉/啟用快取的使用。

TouchGFX內部DCache狀態機

TouchGFX引擎記錄當前和最後一次渲染操作,有兩種狀態:HARDWARESOFTWARE。 初始狀態設為HARDWARE,因為大部分繪圖操作由硬體完成。 當發生狀態切換時,狀態機將呼叫適合的虛擬函式以處理快取驗證失效(cache invalidation)。 當狀態從HARDWARE轉換成SOFTWARE時,狀態機將呼叫虛擬物件操作方法(virtual method)void touchgfx::HAL::InvalidateCache(),當狀態從SOFTWARE 轉換成HARDWARE時,狀態機將呼叫虛擬物件操作方法void touchgfx::HAL::FlushCache()。 這兩個函式需由使用者在衍生的(derived)HAL物件類別當中實作。

TouchGFX引擎內部DCache狀態機

TouchGFX Generator會在TouchGFXGeneratedHAL物件類別當中產生這些衍生物件方法的實作以及呼叫DCache 驗證失效的處理。

進一步閱讀

此處的連結文件包含更多有關STM32CubeMX和STM32快取的資訊: