用SWD調試接口測量代碼運行時間
關於時間測量的種種問題
在嵌入式中,我們經常需要測量某段代碼的執行時間或測量事件觸發的時間,常規的思路是:
1:在測量起始點,反轉電平
2:在測量結束點,再次反轉電平
然后通過示波器或者邏輯分析儀來測量反轉間隔,也就是代碼時間
這種方法,在測量兩個或多個時間信號同步的時候,非常有用,實際上,這也是唯一的方法。
但是如果在測量中,其它代碼也會控制這個管腳電平或者周期性動作,這時便需要在<動作1>之前
增加前導碼,從而便於在繁雜的波形中,一眼識別出需要特定的波形
同時,如果測量的時間值非常小,那么用示波器即便可以識別,但不容易捕獲
SWD解決方案
在ARM Cortex-M 芯片中,用SWD調試接口取代了傳統的JTAG調試接口,從而占用MCU更少的管腳,同時提高了調試性能。
SWD由四根線組成,SWO,SWDIO,SWCLK,GND;SWDIO和SWCLK組成了基本的串行調試接口,SWO則提供一個信息輸出通道,
可以輸出很多信息,比如指令的執行時間或者ISR觸發事件,所以我們可以通過SWD接口配合IDE來獲取代碼執行時間,從而在某種程度上取代示波器
IAR中使用SWD測量時間
注:下文假設讀者已經熟悉IAR的使用方法,如果您不熟悉,請參考網上對應的入門教程
1:配置SWD時鍾
這里,我們需要在調試器選項中
1:選擇SWD調試接口

2:將時鍾頻率設置成MCU的時鍾頻率,同時將SWO時鍾選擇成自動識別模式

配置完成后,進入debug模式,選擇J-Link—>SWD Configuration配置頁,重點關注SWO時鍾的實際值,如下所示

如果顯示不對,則說明SWO配置不對
2:設置時標變量
在示波器方案中,我們需要用某個管腳來測量實際,SWD也類似,只不過將物理管腳替換成某個變量而已。
這里,我們設置TimeLine變量作為時標變量
volatile uint32_t TimeLine = 0;
volatile是為了防止TimeLine被編譯器優化,從而造成測量值不准確。
3:設置Data Log
Data Log是IAR的一種調試斷點,類似數據斷點,IAR會實時記錄對應的變化,因此被稱為Log。
在調試模式下,在TimeLine變量上右擊,選擇”Set Data Log Breakpoint for ‘TimeLine’”選項

設置后,不會像常規的斷點那樣用紅色來標注,在IAR底下,我們需要進入Jlink的BreakPoint Usage來查看,如下圖所示

這里,我們可以清楚的看到TimeLine已經被設置成讀寫斷點
4:使能Data Log和Data Log Summary
在Jlink菜單下,進入Data Log和Data Log Summary窗口,然后右鍵選擇Enable

至此,我們設置完畢,可以將TimeLine放置在測量的起始,結束位置
5:開始時間測量
我們的測試代碼如下
while(1) { TimeLine = 0; index++; TimeLine = 1; index++; }
按上述完成配置后,點擊Run全速運行幾秒鍾,然后暫停,可以在Data Log和Data Log Summary窗口看到對應的信息


咦,為什么全是Overflow???哪里錯了
還記得我們剛開始設置SWO的時鍾速度嗎?當時間測量點的間隔過小,且發送速率過快時,會超出SWO的傳輸能力,從而造成overflow問題
為了驗證確實是這個原因,我們將在代碼中插入一些軟件延時,如下所示
void delay(volatile uint32_t tick) { while(tick--); } .... while(1) { TimeLine = 0; index++; delay(0xFFFF); TimeLine = 1; index++; delay(0xFFFF); }
重編譯,進入調試模式,全是運行,暫停,ok,這次可以看到一切正常了
/******************** Data log 窗口 ************************/ Time Approx PC Description Type Value Address 17040.43 us X 0x8000a6c TimeLine W 0 @ 0x20000390+? 25232.68 us X 0x8000a7c TimeLine W 1 @ 0x20000390+? 33424.99 us X 0x8000a6c TimeLine W 0 @ 0x20000390+? 41617.24 us X 0x8000a7c TimeLine W 1 @ 0x20000390+? 49809.54 us X 0x8000a6c TimeLine W 0 @ 0x20000390+? 58001.79 us X 0x8000a7c TimeLine W 1 @ 0x20000390+? 66194.10 us X 0x8000a6c TimeLine W 0 @ 0x20000390+? 74386.35 us X 0x8000a7c TimeLine W 1 @ 0x20000390+? 82578.65 us X 0x8000a6c TimeLine W 0 @ 0x20000390+? 90770.90 us X 0x8000a7c TimeLine W 1 @ 0x20000390+? 98963.21 us X 0x8000a6c TimeLine W 0 @ 0x20000390+? /********************* Data Log Summary 窗口 *****************/ TimeLine Total Accesses: 335 Read Accesses: 0 Write Accesses: 335 Approximative time count: 335 Overflow count: 0
另外,我們也可以打開J-link菜單下的TimeLine選項(不要和我們的TimeLine變量搞混了)

效果圖如下所示

6:注意事項
當SWO數據量過大的時候,容易出現過沖的情況,解決方案是在調試模式下,單步進行,從而避免發送大數據

全文完,希望本文對您有幫助^_^
