JTAG vs. SWD/SWO
這幾年 Cortex-M 系列的 ARM 微控制器大行其道, 在開發工具上也有一些使用上的調整:
- 以前的晶片除錯器 (debugger) 用的是 JTAG 介面標準, 可以多個 CPU/DSP 一起除錯.
- Cortex-M 則主推 SWD 介面, 一個 debugger 一次只能除錯一個 MCU 晶片.
- 以前 ITM 是標準配備, 現在則為選配.
- SWD 介面還有另一個選配: SWO.
有 ITM 的晶片一般都可以繼續使用 JTAG 介面的除錯器. 有 SWO 功能則可以使用 trace tool 協助分析無法以單純設斷點可以找到的問題. 例如: STMicroelectronics 比較阿沙力, 所有 Cortex-M 系列的晶片都有內含 ITM, 也有 SWO 功能. 但是像 Nuvoton 的 Cortex-M MCU 則都只有 SWD (是的, 連 SWO 都沒有). 差別是:
- STMicroelectronics 可以使用 JTAG 介面的除錯器, Nuvoton 則只能用 SWD 介面的除錯器.
- 使用 Keil µVision 除錯時, semihost 的系統訊息一個是從原本的 'Debug (printf) Viewer' 視窗檢視 (由 View --> Serial Windows --> Debug (printf) Viewer 開啟). 沒有 ITM 的晶片則只能從虛擬的 'UART #1' 視窗檢視 (由 View --> Serial Windows --> UART #1 開啟)
- 有 SWO 可以輸出 Debug Trace Output 給 trace tool 分析問題. 沒有 SWO 則遇到難解的 bug, 只能用你的 '智力' 想辦法解決了.
關於 semihost
semihost 是開發 ARM MCU 應用時很好用的軟體工具. 硬體線路板上不必真的把 UART 的接腳接出來就可以由 debugger 接收 MCU 利用 printf() 吐出來的訊息 (除錯訊息或者系統訊息).
一般使用 semihost 可以有四種組合
- 不要送出任何訊息.
一般這是無 console 產品最終出貨的狀態. (註一) - 訊息由 UART 送出.
這是有 system console 的高階產品的出貨狀態. - 訊息由 semihost 送出.
無 console 產品的除錯狀態. - 訊息由 semihost 或 UART 送出.
有 console 產品的除錯狀態. 訊息會先試著由 semihost 送出 (BKPT 指令(註二)), 如果失敗再試者由 UART 送出.
注意: 如果啟用了 semihost (第三及第四種組合), 但 debugger 不在線上, 程式依然會試著由 Cortex-M 的 BKPT 指令送出每一個字元.
註一: 這個作法和利用巨集將 printf() 取消不一樣, 呼叫 printf() 的指令以及訊息都還在, 只是底層的 fputc() 不輸出字元, 因此編譯後的 code size 並不沒有太大變化.
註二: BKPT指令是 thumb2 的軟體中斷指令, 相當於以前 ARM state 或者是 thumb state 的 SVC 指令.
像是 Nuvoton 晶片的 BSP 裡有一支 retarget.c 即可以完成這 4 種組合.
- 在專案上附加一個 define 設定 DEBUG_ENABLE_SEMIHOST, 或者在 retarget.c 中附加下列這一行
#define DEBUG_ENABLE_SEMIHOST
- 要使用實體 UART, 則需要把DEBUG_PORT定義為你想要用來輸出訊息的那一個 UART port, 並在 main() 裡把你要用的 UART port 作一下初始設定. 下例是使用 UART1 的例子.
#define DEBUG_PORT UART1
- 不想要有實體 UART, 則需要在 retarget.c 中取消這一行前面的註解符號
//#define DISABLE_UART
semihost 的入口
semihost 主要是配合除錯器 (debugger) 以及 ARM 的系統服務 (Supervisor Call) 這個中斷向量一起運作. 下表是 Cortex-M 的 NVIC 向量表, 其中 '例外#11' (Exception 11) 就是 '系統服務' (SVC 指令) 的入口.
Exception No. | CMSIS IRQ# | Exception Type | Priority | M0 M1 | M3 M4 | Function |
---|---|---|---|---|---|---|
1 | - | Reset | -3 (Highest) | Y | Y | 系統重置 Reset |
2 | -14 | NMI | -2 | Y | Y | 強制 (不可遮罩) 中斷 Non-Maskable Interrupt |
3 | -13 | Hard-Hault | -1 | Y | Y | 無法處理之錯誤; 當各種錯誤對應的 "錯誤處理程式" 因目前被關閉或者被例外遮罩所濾除而無法啟用時. All classes of fault, when the corresponding fault handler cannot be activated because it is currently disabled or masked by exeception masking. |
4 | -12 | Mem-Manage | 可設定 | N | Y | 記憶體管理錯誤; 錯誤來源為 MPU 違規或無效存取 (例如: 由非 "可執行區域" 提取指令). Memory Manage Fault; caused by MPU violation or invalid access (such as an instruction fetch from a non-executable region) |
5 | -11 | Bus-Fault | 可設定 | N | Y | 由匯流排系統接收到錯誤; 錯誤來源為指令預先提取失敗 (abort), 或資料存取錯誤. Error response received from the bus system; caused by an instruction prefetch abort or data access error. |
6 | -10 | Usage-Fault | 可設定 | N | Y | 一般原因為無效指令或意圖執行不支援的指令 (如: 在 Cortex-M3 嘗試切換到 ARM 狀態) Typical caused are invalid instructions or invalid instruction attempts (such as trying to switch to ARM state in Cortex-M3) |
7-10 | - | - | - | - | - | 保留 Reserved |
11 | -5 | SVC | 可設定 | Y | Y | 系統服務, 經由 SVC 指令呼叫 Supervisor Call via SVC instruction |
12 | -4 | Debug-Monitor | 可設定 | N | Y | 這是 Cortex-M3/M4 加入的新系統例外. 一般除錯程式時執行到除錯中斷點時, MCU 是整個停來的, 因此所有的 IRQ 中斷都不會執行. 這麼一來像是計時器, 或者傳輸週邊所產生的 IRQ 就都完全停擺了. 而這一個新的 Ddebug monitor 模式則可以讓優先權較高的 (比 Debug Monitor 高的) IRQ 中斷繼續被 MCU 執行, MCU 不會因為停在除錯中斷點而完全停擺. |
13 | - | - | - | - | - | 保留 Reserved |
14 | -2 | PendSV | 可設定 | Y | Y | 可延遲系統服務 (Pendable request for System Service) |
15 | -1 | SysTick | 可設定 | Y | Y | 系統心跳 (System Tick Timer) |
16-255 | 0-239 | IRQ | 可設定 | Y | Y | M0:IRQ #0~#31, M3:IRQ #0~#239 |
後面還有, 改天再補充.
留言列表