轉自: http://www.armbbs.cn/forum.php?mod=viewthread&tid=95867&highlight=Ozone
承接上一個帖子:
Ozone使用介紹-基礎功能
http://armbbs.cn/forum.php?mod=viewthread&tid=95855&extra=page%3D1
因為廢話和貼圖太多,一個帖子不方便看,所以分為了三個帖子,本帖介紹Trace功能。
其實幾個月前還是沒有太關注Trace這個功能,最近趁購買J-Trace的時候,也順道看了看Trace的一些相關介紹。
Trace其實分為很多種(自己瞎划分的哈,大家隨便看看):
1、自己寫printf,根據自己的printf來進行跟蹤
2、利用基於MCU支持的Jlink_RTT、 USB CDC、TCP/IP、串口等種方式的流模式
,和一些內嵌入工程的接口調試代碼,來提供Trace記錄,如SystemView(基於Segger的RTT,號稱可以跟蹤裸機不知道怎么做到的)、Tracealyzer(基於多種流模式)
System介紹:https://www.segger.com/products/development-tools/systemview/
Tracealyzer介紹:https://percepio.com/tracealyzer/
3、利用基於MCU硬件的Trace接口(比如Trace Pins、TraceBuffer、SWO)而實現的追蹤功能。其中SWO(Serial Wire Viewer(SWV))速度很低,但是占用接口很少;TraceBuffer(ETB算是)的上限會基於MCU本身的buffer大小;Trace Pins(ETM)只是負責實時上報出去,由跟蹤調試器(J-Trace等)進行對應的協議轉發或處理。
以下是Ozone手冊的介紹:
ARM官網也會對自家硬件的ETM功能做對應介紹:(ST的手冊這方面沒有啥介紹)http://www2.keil.com/coresight/
感覺其中2主要針對帶有OS的目標程序進行追蹤,主要說說3:
下圖摘自http://www.myir-tech.com/resource/510.asp(米爾科技)
ETB,嵌入式跟蹤緩存
CoreSightETB 是一個跟蹤接收器,它可使用可配置大小的 RAM 為跟蹤數據提供芯片上存儲。
ETM,嵌入式跟蹤宏單元
ETM宏單元為 ARM 微處理器提供實時指令跟蹤和數據跟蹤。跟蹤軟件工具使用 ETM 生成的信息重建全部或部分程序的執行情況。
CTI:Cross Trigger Interface ATB:Advanced Trace Bus
這么看的話,如果想要在STM32上實現硬件的Trace功能,需要的調試器本身就必須對接Trace接口。“大家都有便宜的”的Jlink是無法滿足的,我之前購買的Stlink V3、DAPlink應該是都不行的。這個時候必須購買具備Trace功能(接口)的調試器了。在我決定購買Jlink Trace的時候,並沒有比對過其他家具備Trace功能的調試器(好吧,就是不知道有……,當時還以為IAR只做IDE工具,沒有調試器的)。
我購買的:
德國的Segger:J-TracePro https://www.segger.com/products/debug-trace-probes/
后面搜了下,發現以下幾家其實是都支持的。
瑞典的IAR:I-Jet Trace https://www.iar.com/iar-embedded-workbench/add-ons-and-integrations/in-circuit-debugging-probes/
(算英國?)ARM(自家的寶寶):ULINKpro https://store.developer.arm.com/store/debug-probes/ulinkpro-debug-adapter#purchase>
德國LAUTERBACH(調試界的勞斯萊斯):Cortex-M (ARMv6/7/832-bit) Debugger
https://www.lauterbach.com/frames.html?home.html
其他的歡迎大家補充,支持Cortex M系列的我目前知道的就是這幾個了。具體性能不敢對比,都是調試界的泰山北斗,算是神仙打架吧……;每家支持跟蹤的調試器,都有配套自己的跟蹤工具(I-Jet和ULINKpro好像是集成進入IAR和Keil中了)
畢竟買的是J-Trace,上一張和Jlink的對比圖,發現還是會大一圈的,如下圖
其中Jlink&Trace的手冊也給出了連接方法,和PCB的接口是對應的
后面的Trace都是基於Ozone進行演示的,如果有其他“小伙伴”有其它Trace工具的,歡迎借給我測試功能_。
跟跟蹤相關的三個窗口分別是Code Profile、InstructionTrace還有Timeline,這時候可以選擇把這些窗口打開。
Trace需要進行配置才可以,因為上一偏帖子是關閉了Trace的,所以這時候在具備Trace的界面會提示Trace已經被禁止了,需要手動打開
配置有三種:
1、Trace Pins配置
其中時間標簽(TimeStamps)可以選擇勾選,官方手冊上面寫道,如果不勾選時間標簽的話,還可以進一步提升跟蹤性能。這個也好理解,畢竟都需要通過Trace的硬件接口(ARM的ETM協議)上報出來,減少了TimeStamps的參數(不再占傳輸帶寬了),理應提高跟蹤性能。
CPU時鍾頻率設置,我的理解是為了根據指令條目綜合得到Timeline的時間軸信息的,畢竟Trace回來的指令只能編號,目標板也不可能提供時間信息,即使提供也太占傳輸帶寬了。
TracePort 帶寬的話,我覺得如果是目標板設計時,要么就會留出所有的端口(4個),要么一個也不會留,沒道理項目上設計預留Trace接口,還只給出了1或2個吧……Segger提供的測試板是4個,所以選擇4bit。
最大指令計數上限,這個地方目前Ozone的上限是64M,設置大於64M沒有意義。這個后面再Timeline窗口會提到。
Trace-Time是個時間修正設置。根據Ozone的跟蹤精度介紹,我的理解是在這里可以對跟蹤的數據進行延遲的修正。對我意義不大,沒有那么高的精度要求。
2、Trace Buffer:STM32F4不支持,不知道怎么測試
3、SWO:本次沒有測試,畢竟已經有Trace Pin了
當正確設置完畢后,就可以進行追蹤了,因為還沒有開始RUN起來,所以追蹤的窗口還是顯示No Data
點開RUN的時候,程序和用其他IDE一樣,已經
有個細節需要注意,Segger是有一套自己的(STM32F4xx_Startup.s)啟動文件的,雖然套路和我們常用的ST的一樣,都是從Reset_Handler啟動,進行初始化的,兩者的寫法略有不同,不過后面都是調用system_stm32f4xx.c(這個都是ST提供的了)文件。移植不同IDE工程的時候,這個地方也是需要進行一些改動的(比如從Keil移植到ES)。
因為啟動文件的不同,所以會導致在Run之后,Ozone在使用自家啟動文件(例程里面就是使用自家的啟動文件)的時候,就可以追蹤從Reset_Handler啟動后的執行情況。
但是如果直接使用Keil工程包導入的使用ST自帶的啟動文件的話,Ozone並不能正確識別啟動文件的操作。
Ozone的起始點是可以設置的
先上個全局的動態圖看一下吧(這個圖我指令跟蹤上限是10M)
1、Timeline時間線窗口:
當打開Trace功能,同時開始運行程序,Ozone會根據J-Trace不斷通過接口協議(USB3.0 或者 千兆網線)上報的ETM數據進行記錄。根據上報的ETM記錄,可以重建整個時間線的指令執行情況。橫軸指令數目或時間(根據指令計數和設置的MCU主頻得導的時間),縱軸是函數之間的調用關系,不需要使用RTOS,裸跑也能實現。
以下是裸跑的情況
猜測STM32的指令都是一個指令周期相同,所以不存在不等分的情況
在時間線中選中任何一個函數的圖框,都會跳轉到該函數在文件窗口中的語句位置、反匯編窗口的指令位置、指令追蹤窗口的計數位置,動圖如下:
可以看到指令追蹤窗口下點擊和時間線點擊是一樣的(本來就是一個東西,時間線是為了更直觀的看到指令的執行的一種表現形式)
遺憾的是,指令執行的上限,雖然在上圖的最大指令計數上限,可以更改到比64M更多的數據,比如2.2G。但是就我實驗發現,不論怎么設置,都無法突破64M左右的上限。因為購買這個J-Trace,看廣告(產品介紹寫的是無限跟蹤),所以覺得不應該有這個問題。
當時一度以為64M這個坎是J-Trace的硬件性能決定的,因為當時拆解J-Trace時候發現J-Trace內部的SDRAM是1Gb(型號IS43LD32320),這樣如果J-Trace實現的跟蹤機制是先將ETM的情況記錄在SDRAM中,當手動Ozone點擊停止(或斷點)后再將執行情況上報給Ozone的話,刨除掉ETM編碼指令所浪費的字節,硬件上必然是有瓶頸的。這肯定是談不上無限追蹤的。
當時內心深處有一種被深深欺騙的感覺,但是又覺得Segger不至於這樣吧。所以又做了個實驗,USB不太會抓包。但是J-Trace是有網口的,可以通過Wireshark來抓包試試。
於是我根據這個想法做了個實驗:
1.1、J-Trace和PC連接上之后的抓包結果,此時通訊數據速率不大
1.2、點擊綠色運行按鈕,程序開始運行,此時通訊數據速率變大
1.3、等帶一段時間后,點擊暫停,Timeline窗口出現Trace的內容,拖動Timeline的窗口,追蹤到的指令總數是67M左右,此時通訊數據速率也不大
所以最后我猜測,J-Trace在程序運行時就已經將跟蹤數據不斷的發送出來到PC了;
而不是將這些數據滾存在J-Trace的SDRAM中等調試結束后,再通過網線(或USB線)將滾存的追蹤數據從SDRAM讀取出來再發送。
為了解答我的疑惑,我給Segger發了個郵件,同時也問他們網站上寫的關於無限跟蹤是指什么。很快,當天就回復了,內容如下:(基本印證了我的猜測)
后來又仔細看了看Segger的官網對Ozone的描述中,又看到點東西。老版的J-Trace應該是內置了存儲空間(應該是RAM吧),具備跟蹤64M指令的能力。
不知道是不是Ozone當前還沒有兼容新款的硬件。我手里面這款J-Trace硬件相對來說是最新版本(固件也已經升級到了最新的DLL了)。
跟蹤上限這點I-Jet里面也有介紹:
2、指令跟蹤窗口:
當程序停下來的時候(手動暫停或進入斷點),當前PC指針在最底部,之前執行過的所有指令都會在該窗口下顯現出來(隸屬的函數語句在反匯編指令的右側)。
上限由之前設置過的指令跟蹤上限決定。和時間線窗口相同,點擊后也是有着相同的交互關系。該窗口也支持指令根據函數折疊,動圖如下:
3&4&6、文件窗口&反匯編窗口&跟蹤(斷點)窗口
因為有了跟蹤,所以比起Debug來說,Trace可以展現出來語句(指令)執行的次數。之前使用Jlink的話,只能看到通過打斷點,或者在已有程序里面加一個(更改程序,多多少少會改變實際程序的運行)計數器、打印等,才能得到執行次數。舉一個(網上抄的)不恰當的例子,Debug本身更像是個照相機,但是Trace相對來說是個錄像機了,可以幫忙我們更高的定位、排查問題。
在這兩個窗口下,還可以設置Trace Start 和 Trace End。這個功能被Ozone 稱作 Selective Tracing。可以只跟蹤被選中的代碼(可以選多組),這樣Excute Count、Timeline和Instruction Trace都會只記錄選中的代碼。選擇設置后,這些起止位置會在跟蹤(斷點)窗口中顯示出來,同時支持勾選是否部分跟蹤。
這個操作完成后,Ozone會只顯示和記錄選中的跟蹤內容,畢竟不是無限記錄(可以省着點用)。
5、代碼執行狀態窗口:
可以看到函數語句的執行覆蓋率、反匯編后指令的執行覆蓋率、以及Run Count和Fetch Count,還有就是負載率了。動圖如下:
其中,如果不想看某些空閑函數的CPU負載率的話,可以去掉這個函數的負載率計算。這個在使用OS的時候可以去掉Idle任務。點開函數的折疊,也可以看到具體的指令執行情況。根據Segger回復我的郵件,這個過程應該是可以無限追蹤的
感覺Fetch Count是函數中的C語句每條匯編后的指令執行次數之和,所以次數會遠遠大於函數本身的Run Count。不知道這個理解對不對。
通過鼠標選中Exclude All NOP可以實現排除掉空指令(NOP)的執行、統計狀況
也可以選擇性的Export需要的跟蹤記錄
生成的記錄如下所示:
這篇帖子又寫的很長……看來只能下篇帖子寫特殊功能了
本主題由 eric2013 於 2019-12-7 10:08 添加圖章 版主推薦