用SWD調試接口測量代碼運行時間 ( SWO )


用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 LogData Log Summary窗口,然后右鍵選擇Enable

至此,我們設置完畢,可以將TimeLine放置在測量的起始,結束位置

5:開始時間測量

我們的測試代碼如下

while(1)
{
    TimeLine = 0;
    index++;
    TimeLine = 1;
    index++;
}

按上述完成配置后,點擊Run全速運行幾秒鍾,然后暫停,可以在Data LogData 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數據量過大的時候,容易出現過沖的情況,解決方案是在調試模式下,單步進行,從而避免發送大數據

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM