一、文檔背景
所有的軟件都是為了完成某些功能,當(dāng)我們在設(shè)計(jì)一個(gè)項(xiàng)目產(chǎn)品功能的時(shí)候,勢必要考慮系統(tǒng)的反應(yīng)速度。在硬件固定的情況下,軟件的時(shí)效性就決定著系統(tǒng)的反應(yīng)速度了。我們大部分任務(wù)都采用一種輪詢或者是監(jiān)控的狀態(tài),如果一個(gè)任務(wù)占據(jù)了太長的 CPU 時(shí)間,就會(huì)帶來整個(gè)系統(tǒng)的延時(shí),特別是在多任務(wù)的 RTOS 系統(tǒng)中,如果有時(shí)候任務(wù)時(shí)間太長,就導(dǎo)致總系統(tǒng)達(dá)不到我們的預(yù)期,那么我們就需要非常清楚地知道我們的任務(wù)到底運(yùn)行了多少時(shí)間。
二、 實(shí)現(xiàn) 記錄函數(shù)執(zhí)行時(shí)間的思路
事件記錄器為應(yīng)用程序代碼中的事件注釋提供了API接口(函數(shù)調(diào)用)。這些功能不僅記錄事件本身,還記錄了時(shí)間戳和附加信息。數(shù)據(jù)存儲(chǔ)在目標(biāo)硬件的RAM中的事件緩沖區(qū)中。
1. 添加Event Recorder組件
本次使用的是CMSIS-View組件,不是采用的compiler。在Keil MDK中,可以通過管理運(yùn)行時(shí)環(huán)境來啟用EventRecorder功能。
2. 配置Event Recorder組件
在EventRecorderConf.h文件中進(jìn)行以下配置:
○ EVENT_RECORD_COUNT設(shè)置記錄數(shù)量。
○ EVENT_TIMESTAMP_SOURCE選擇時(shí)間戳來源。
○ EVENT_TIMESTAMP_FREQ設(shè)定時(shí)鐘頻率。
○ 內(nèi)存設(shè)置
為Event Recorder組件分配所需的內(nèi)存。所需RAM大小計(jì)算公式為:164 + 16 * <記錄數(shù)>。此外,還需將EventRecorder信息數(shù)據(jù)段之外的內(nèi)存初始化為0。
○ 在代碼中集成Event Recorder
在代碼中添加以下相關(guān)函數(shù)調(diào)用:
○ EventRecorderInitialize(uint32_t recording, uint32_t start):初始化事件記錄器。
○ EventStartA(slot)開始記錄事件。
○ EventStopA(slot)停止記錄事件。
通過在函數(shù)的開始位置調(diào)用EventStartA(slot),并在結(jié)束位置調(diào)用EventStopA(slot),可以記錄函數(shù)的執(zhí)行時(shí)間。
○ 編譯與調(diào)試工程
編譯完成后,進(jìn)入調(diào)試界面,找到“Event Statistics”視圖,查看函數(shù)執(zhí)行時(shí)間的平均值、最小值、最大值、開始時(shí)間和結(jié)束時(shí)間。
三、 如何在STM32F746實(shí)現(xiàn)記錄函數(shù)執(zhí)行時(shí)間
1. 選用STM32F746 中自帶的 Blink 示例進(jìn)行測試。
編譯例程,并下載到目標(biāo)板中,測試 LED 燈可以正常閃爍,保證程序編譯和下載都可以正確執(zhí)行。
2. 添加Event Recorder 組件。
如圖 1 所示,打開 Manage Run-time Enviroment ,展開 CMSIS-View勾選 Event Recorder 并點(diǎn)擊 OK

圖 1
如圖 2 所示,可以看到工程中添加了EventRecorder.c 和 EventRecorderConf.h 兩個(gè)文件。

圖 2
3. 配置Event Recorder
如圖 3 所示,打開EventRecorderConf.h 文件,點(diǎn)擊底部的 Configuration Wizard。
在圖形界面中點(diǎn)擊 Expand All,展開Event Recorder 的配置參數(shù)。
這里我們只更改一下 Time Stamp Clock Frequency,如圖 4 更改為 216000000

圖 3

圖 4
4. 內(nèi)存設(shè)置
如圖 5,點(diǎn)擊 Option for Taget ... ,選擇 Target 標(biāo)簽,在 RAM 設(shè)置區(qū)域,更改為圖中所示內(nèi)容。

圖 5
5. 添加Event Recorder 相關(guān)代碼
在 main.c 中包含 EventRecorder.h 頭文件

圖 6
在 main 函數(shù)中對EventRecorder 進(jìn)行初始化

圖 7
在 Blinky.c中包含 EventRecorder.h 頭文件

圖 8
在thrLED 函數(shù)中增加EventStartA(0);EventStopA(0);

圖 9
6. 編譯下載
按 F7 進(jìn)行編譯,可以看到?jīng)]有任何錯(cuò)誤。下載到目標(biāo)板上。

圖 10
五、討論分析
1. 修改函數(shù)內(nèi)的時(shí)間,查看分析結(jié)果。
EventStopA(0);

圖 13
2. 多個(gè)函數(shù)進(jìn)行測量時(shí)間。
EventStartB(0);
osThreadFlagsSet (tid_thrLED, 1U); // Set flag to thrLED
EventStopB(0);

圖 14
六、結(jié)論
1. 通過EventRecorder,我們能夠精準(zhǔn)地測量函數(shù)的執(zhí)行時(shí)間,從而為性能分析提供堅(jiān)實(shí)的數(shù)據(jù)支持。
2. EventRecorder不僅限于單一函數(shù)的時(shí)間測量,它同樣擅長同時(shí)監(jiān)控多個(gè)函數(shù)的執(zhí)行時(shí)長,使得復(fù)雜的應(yīng)用場景下的性能評估變得游刃有余。
3. 更令人稱道的是,這項(xiàng)技術(shù)并不依賴于繁瑣的跟蹤機(jī)制;僅需借助STLINK仿真器即可輕松實(shí)現(xiàn),極大地簡化了開發(fā)流程中的調(diào)試步驟。
4. 以極其精簡的內(nèi)存開銷作為代價(jià),EventRecorder卻能為我們帶來詳盡而深入的應(yīng)用程序執(zhí)行時(shí)間分析報(bào)告,堪稱是軟件優(yōu)化過程中不可或缺的利器。
如有任何問題或建議,請聯(lián)系相關(guān)負(fù)責(zé)人或技術(shù)支持團(tuán)隊(duì)。