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

最后歡迎關(guān)注痞子衡個(gè)人微信公眾號(hào)【痞子衡嵌入式】,一個(gè)專注嵌入式技術(shù)的公眾號(hào),跟著痞子衡一起玩轉(zhuǎn)嵌入式。
衡杰(痞子衡),目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)應(yīng)用部門,擔(dān)任高級(jí)嵌入式系統(tǒng)應(yīng)用工程師。
專欄內(nèi)所有文章的轉(zhuǎn)載請(qǐng)注明出處:http://www.rzrgm.cn/henjay724/
與痞子衡進(jìn)一步交流或咨詢業(yè)務(wù)合作請(qǐng)發(fā)郵件至 hengjie1989@foxmail.com
可以關(guān)注痞子衡的Github主頁(yè) https://github.com/JayHeng,有很多好玩的嵌入式項(xiàng)目。
關(guān)于專欄文章有任何疑問請(qǐng)直接在博客下面留言,痞子衡會(huì)及時(shí)回復(fù)免費(fèi)(劃重點(diǎn))答疑。
痞子衡郵箱已被私信擠爆,技術(shù)問題不推薦私信,堅(jiān)持私信請(qǐng)先掃碼付款(5元起步)再發(fā)。
浙公網(wǎng)安備 33010602011771號(hào)