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 可以有四種組合

  1. 不要送出任何訊息.
    一般這是無 console 產品最終出貨的狀態. (註一)
  2. 訊息由 UART 送出.
    這是有 system console 的高階產品的出貨狀態.
  3. 訊息由 semihost 送出.
    無 console 產品的除錯狀態.
  4. 訊息由 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 指令) 的入口.

Cortex-M Exceptions
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

後面還有, 改天再補充.

arrow
arrow
    創作者介紹
    創作者 MagicJackTing 的頭像
    MagicJackTing

    傑克! 真是太神奇了!

    MagicJackTing 發表在 痞客邦 留言(0) 人氣()