大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是IAR內部C-SPY調試組件配套宏文件(.mac)用法。
痞子衡之前寫過一篇 《JLink Script文件基礎及其在IAR下調用方法》,那篇文章介紹了 J-Link 硬件調試器配套的 .JLinkScript 文件功能及用法,今天我們要講的主角 .mac 文件之於 IAR 內部 C-SPY 調試組件的作用就像 .JLinkScript 之於 J-Link 調試器的作用一樣,.mac 文件也是為了完成在 IAR 下的特殊調試需求而存在的。
一、C-SPY宏(macros)作用
我們知道在 IAR 開發環境下負責綜合調度外部硬件調試器與芯片內部調試模塊來完成用戶實際調試需求的組件是 C-SPY,有了 C-SPY,你才可以愉快地在 IAR 里進行單步調試、打斷點等操作。
宏文件(.mac)是 C-SPY 組件定義和解釋執行的一種專用類腳本文件,它的語法比較像 C 語言,但本質上是一種腳本語言,由 CSpyBat.exe 在用戶調試的過程中解釋執行。
\IAR Systems\Embedded Workbench 9.10.2\common\bin\CSpyBat.exe
宏文件的功能主要有以下 5 點,其中第 2 點配置板級硬件是最常用的功能。比如你想在板載外部 SDRAM 里直接調試工程代碼執行,但是調試組件在下載程序進 SDRAM 之前需要一個已經初始化好的 SDRAM,這個 SDRAM 初始化工作就可以由宏文件來完成(當然修改 IDE flashloader 去完成也是一種可選方法)。
1. 調試流程自動化,例如跟蹤打印輸出,打印變量值,設置斷點。
2. 配置板級硬件,例如初始化硬件寄存器、初始化外存。
3. 在運行時為應用程序提供模擬數據。
4. 模擬外圍設備(只適用於使用模擬器驅動程序的情況)
5. 開發小的調試工具函數,例如計算堆棧深度,參見示例 \arm\src\sim\stack.mac
二、C-SPY宏文件基礎
C-SPY 宏文件這一套東西整體上由三大部分組成:基本語法、預定義系統宏函數、保留 setup 宏函數。
2.1 宏文件基礎語法
C-SPY 宏語言並不是一個通用的腳本語言,因此其並不像你熟知的那些 Python 之類的腳本語言那樣語法完善,它僅是為了配合 C-SPY 完成一些必要操作。C-SPY 宏語法跟 C 語言類似,支持 C 語言中允許的大多數語句(if else,while,變量聲明,…),但不是所有的語句。
- 全部語法: \IAR Systems\Embedded Workbench 9.10.2\arm\doc\EWARM_DebuggingGuide.ENU 手冊里的 BRIEFLY ABOUT THE MACRO LANGUAGE 章節
下面是一個典型的用戶自定義 C-SPY 宏函數示例(設置地址 0x400D403C 處寄存器的值),涉及的語法包括函數定義(支持參數和返回值),變量定義(統一為 __var 類型), 邏輯表達式, do while 語句,系統宏函數調用(加 __ 前綴)。掌握示例函數里的語法基本就足夠使用宏文件功能了。
// 定義函數,無參,默認返回值 0(缺省)
Peripheral_WaitSetDone()
{
// 定義 reg 變量
__var reg;
do
{
// 讀取 0x400D403C 地址處的值 (32bit)
reg = __readMemory32(0x400D403C, "Memory");
// 延時 10 ms
__delay(10);
// 判斷 reg[1:0] 是否為 0
}while((reg & 0x3) == 0);
// 將 0x3 寫入 0x400D403C 地址處
__writeMemory32(0x00000003, 0x400D403C, "Memory");
// 輸出信息到 IAR 調試窗口
__message "Message: Peripheral Reg Set Done\n";
}
2.2 預定義系統宏功能
C-SPY 宏體系里實現了很多基礎操作功能,這些功能通過 API 函數接口形式開放給用戶宏函數來調用,這些 API 全部以 __ 為前綴,大約有 100 多個 API。下面列舉出最常用的一些宏 API:
系統宏原型 | 功能解釋 |
---|---|
__delay(value) | ms級精度延時 |
__readAPReg(register) __readDPReg(register) __writeAPReg(data, register) __writeDPReg(data, register) |
讀寫內核 AP/DP 寄存器 |
__driverType(driver_id) __gdbserver_exec_command("string") __jlinkExecCommand(cmdstr) __jtagCommand(ir) |
與硬件調試器命令交互 |
__fillMemory8(value, address, zone, length, format) __fillMemory16(value, address, zone, length, format) __fillMemory32(value, address, zone, length, format) __fillMemory64(value, address, zone, length, format) |
按模板值設置指定內存范圍 |
__writeMemory8(value, address, zone) __writeMemoryByte(value, address, zone) __writeMemory16(value, address, zone) __writeMemory32(value, address, zone) __writeMemory64(value, address, zone) __readMemory8(address, zone) __readMemoryByte(address, zone) __readMemory16(address, zone) __readMemory32(address, zone) __readMemory64(address, zone) |
讀寫指定內存地址處的數據 |
- 全部系統宏 API: \IAR Systems\Embedded Workbench 9.10.2\arm\doc\EWARM_DebuggingGuide.ENU 手冊里的 Summary of system macros 表
2.3 保留setup宏函數
終於要講到 C-SPY 宏最關鍵的部分了,前面都是基礎,而 C-SPY 宏最核心的功能其實在保留 setup 宏函數里,這些 setup 宏函數由 C-SPY 預先定義,但是內部具體操作可由用戶來編寫。在 IAR 在線下載調試過程中按規定觸發條件來調用執行這些函數,setup 宏函數里最常用的是 execUserPreload():
保留setup宏函數 | 應用場合 | 執行時機 |
---|---|---|
execConfigureTraceETM | 配置ETM/PTM模塊相關寄存器 | 調試執行開始前 |
execConfigureTraceSWO | 配置SWO調試口相關寄存器 | 調試執行開始前 |
execUserPreload | 初始化板級硬件環境 | 調試器與CPU已建立連接但未下載應用程序前 |
execUserExecutionStarted | 用戶自定義 | 調試器開始執行應用程序指令前 |
execUserExecutionStopped | 用戶自定義 | 調試器結束執行應用程序指令后 |
execUserFlashInit | 輔助flashloader功能,設置Flash相關內存映射環境 | 在調試器將flashloader下載進RAM之前 |
execUserSetup | 初始化板級調試環境(硬件、斷點、中斷,宏文件) | 調試器將應用程序下載完成后 |
execUserFlashReset | 輔助flashloader功能 | 在調試器將flashloader下載進RAM之后,但還未開始執行flashloader前 |
execUserPreReset | 設置需要的設備狀態 | 在每次系統復位命令執行前 |
execUserReset | 恢復數據 | 在每次系統復位命令執行后 |
execUserExit | 保存狀態數據 | 調試執行結束后 |
execUserFlashExit | 輔助flashloader功能,保存狀態數據 | Flash下載完成后 |
execUserCoreConnect | 做一些CPU連接前的准備動作 | 調試器剛建立連接,但尚未連接CPU |
三、宏文件在IAR下使用方法
宏文件在 IAR 下主要有兩種調用執行方式,一種是由 C-SPY 在調試過程中自動執行(要借助保留 setup 宏函數),另一種是用戶手動指定執行(此時可以不用保留 setup 宏函數):
3.1 在線調試時C-SPY自動執行
不管是哪種調用方式,用戶都需要首先准備一個宏文件(.mac),然后在 IAR 工程選項 Debugger / Setup / Setup macros 里勾選 Use macro file(s),並且指定宏文件路徑。
我們以恩智浦軟件包 \SDK_2.11.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7\iar 工程為例,在這個路徑下創建一個測試用的 evkmimxrt1170_connect_cm7_test.mac 文件,並且將其指定為工程宏文件。
在這個測試用的 .mac 文件里定義全部 13 個保留 setup 函數,函數體內不需要真實內容,只有下面這樣的一句打印信息即可,便於我們在 IAR 調試信息窗口觀察其有沒有被 C-SPY 調用執行。
execUserPreload()
{
__message "--------execUserPreload() is called";;
}
然后在 MIMXRT1170-EVK 板上借助板載 DAP-Link 調試器直接下載 RAM build 版本工程(即不涉及 flashloader),調試器復位類型為 Software,下面是 IAR 調試信息窗口的輸出。從結果里看除了 ETM/SWO 相關 setup 宏函數和 flashloader 相關 setup 宏函數未被執行外,其余 setup 宏函數均如預期執行了:
1. 用戶點擊 IAR 在線調試按鈕,啟動 C-SPY
2. C-SPY 嘗試調用 flashloader,但無數據需下載進Flash
3. C-SPY 預加載用戶宏文件 evkmimxrt1170_connect_cm7_test.mac
4. C-SPY 與硬件調試器(DAP-Link)建立了連接
5. execUserCoreConnect() 被執行
6. C-SPY 連接上了芯片內核
7. execUserPreReset() 被執行
8. C-SPY 嘗試執行軟件復位(可能此處未執行成功)
9. execUserPreload() 被執行
10. C-SPY 將工程應用程序 hello_world_demo_cm7.out 下載進芯片內部 RAM
11. execUserPreReset() 被執行
12. C-SPY 執行了軟件復位,芯片復位成功
13. execUserReset() 被執行
14. C-SPY 與芯片調試模塊ETM交互
15. execUserSetup() 被執行
16. execUserExecutionStarted() 被執行
17. C-SPY 接管調試,斷點停在 main 函數
18. execUserExecutionStopped() 被執行
19. 用戶點擊結束 IAR 在線調試
20. execUserExit() 被執行
同樣的實驗在 Flash build 版本工程(即涉及 flashloader)上再做一次,調試器復位類型也為 Software,結果如下。此時結果與 RAM build 差異較大,因為默認 flashloader 配套 FlashIMXRT1170_FlexSPI.mac 文件也加入了戰斗,我們測試用的 evkmimxrt1170_connect_cm7_test.mac 文件是在應用程序下載進 Flash 之后才出場的(記住這里的順序,非常重要,痞子衡后面會另寫文章着重介紹),因此這個測試用的 .mac 文件里的 flashloader 相關宏函數根本派不上用場:
1. 用戶點擊 IAR 在線調試按鈕,啟動 C-SPY
2. C-SPY 預加載 flashloader 配套宏文件 FlashIMXRT1170_FlexSPI.mac(里面僅定義了execUserFlashInit )
3. C-SPY 與硬件調試器(DAP-Link)建立了連接
4. C-SPY 連接上了芯片內核
5. C-SPY 嘗試執行軟件復位(可能此處未執行成功)
6. execUserFlashInit() 被執行 - 來自 FlashIMXRT1170_FlexSPI.mac
7. C-SPY 將 flashloader 加載進芯片內部 RAM
8. C-SPY 借助 flashloader 將工程應用程序 hello_world_demo_cm7.out 下載進板載外部 Flash
9. C-SPY 預加載用戶宏文件 evkmimxrt1170_connect_cm7_test.mac
10. execUserPreload() 被執行
11. C-SPY 完成 Flash 下載的數據校驗
12. execUserPreReset() 被執行
13. C-SPY 執行了軟件復位,芯片復位成功
14. execUserReset() 被執行
15. C-SPY 與芯片調試模塊ETM交互
16. execUserSetup() 被執行
17. execUserExecutionStarted() 被執行
18. C-SPY 接管調試,斷點停在 main 函數
19. execUserExecutionStopped() 被執行
20. 用戶點擊結束 IAR 在線調試
21. execUserExit() 被執行
3.2 自定義條件觸發或Watch窗口里手動指定執行
宏文件的自定義觸發或者手動調用方式主要跟深入調試有關,用於調試過程中的特殊需求,麥克泰寫的一篇文章 《C-SPY setup macro file 的作用》 里給的兩個示例就挺有參考意義的。比如我們可以在 IAR 的 Quick Watch 窗口手動填入 .mac 文件里宏函數,並單擊執行,這時可在 IAR 調試信息窗口實時看到執行結果。
至此,IAR內部C-SPY調試組件配套宏文件(.mac)用法痞子衡便介紹完畢了,掌聲在哪里~~~
歡迎訂閱
文章會同時發布到我的 博客園主頁、CSDN主頁、知乎主頁、微信公眾號 平台上。
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。