痞子衡嵌入式:IAR內部C-SPY除錯元件配套巨集檔案(.mac)用法介紹

痞子衡發表於2022-03-24

  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是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主頁知乎主頁微信公眾號 平臺上。

微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。

相關文章