SWD其實和JTAG類似,是一種調試串口。
JTAG大致了解了一下。JTAG(Joint Test Action Group)主要4 lines:TMS(模式選擇),TCK(時鍾),TDI(數據輸入),TDO(數據輸出)。都是串行總線。JTAG model中通過狀態機的方式,對cmd進行解析后控制TMS和TDI的輸出。
SWD(Serial Wire Debug)主要2 lines: SWDIO(雙向串行數據線),SWDCLK(串行時鍾線,Master drive)。協議:ARM CPU standard bi-directional wire protocol
ADI:ARM Debug Interface。
DAP(Debug Access Port)分為 DP (debug port)and AP(Access port)。通過物理連接訪問DAP register實現debug控制。
因為DAP分為DP和AP,所以訪問方式分為兩種: 1. DPACC(debug port access訪問DP REG) 2.APACC(debug port access訪問AP REG)
DP分為 SW-DP(Seiral Wire Debug Port),JTAG-DP和SWJ-DP(SW-DP和JTAG-DP的結合)。我要用到的是SWJ-DP
DP可以訪問多個AP.其中AP分為MEM-AP和JTAG-AP。MEM-AP的作用是用來作為連接AHB/APB的橋梁,可以訪問內存,比如AHB-AP,APB-AP,JTAG-AP,Cortex-M3
DP就是調試接口的硬件,AP 就是一個訪問周邊外設和內存的硬件接口。
外部設備通過SWDIO/SCLK pins來通信。
Trn-Trn:即Line turn-round,當總線上的數據傳輸方向發送改變時(比如由Host->Target變為Target->Host),需要插入Trn,Trn為一個CLK時序,
Idle cycles:在一個總線完成后,可以立即進入下一個總線操作或者是勒令總線進入Idle 狀態,此時可以插入Idle cycle。
初始化
看協議中首先在連接Target時需要進行LineReset,這個是最基礎也是最最簡單的命令。
具體實現為:
STM32:
首先保證Host連續送出至少50個“1”,使得Target進行Line Reset,至少插入2個Idle,然后可以讀取目標板的IDR,判斷Target的類型。(注意:STM32可能需要進行linereset后切換JTAG/SWD mode后才能讀到IDR)
get IDR后,cfg DP<SELECT>。
ARM上:
linereset方法一致。切換JTAGdao SWD mode的方法為:SWDIOTMSpins:16'h79E7(MSB first) or 16'hE79E(LSB first)
反之也可以切換啦:0x3CE7(MSB),0xE73C(LSB)
linereset后寫TARGETSEL(include DPIDR+TARGETID)。然后read IDCODE register(DPIDR)看看和寫的TARGETSEL的ID對的上不.這個ID有講究的,見intf_spec P54
啰嗦一句,不同AP的IDCODE是固定的,這里可以先讀一下DPIDR,然后決定TARGETSEL怎么填。填寫TARGETSEL的目的是讓DP可以片選到正確的AP。
TARGETSEL包括APSEL/APBANKSEL/DPBANKSEL。分別用於 AP片選 ; 要訪問的AP REG的BANK地址(adddr[7:4]);DP的4個寄存器選擇(見314H文檔中P63)
ARM IDCODE如下:
協議:
Host send 8-bit request to target -> Target response 3-bit OK acknowledge to host -> 33-bit data phase (write by host / read by target)
request phase:共8bit
-Start 起始位,始終為1,這也是Target判斷總線從空閑狀態退出的條件
-APnDP 選擇要訪問的是DP寄存器還是AP寄存器。0:DP 1:AP
- Rnw 選擇是讀還是寫。0:Write 1:Read
-A[2:3] DP或者AP寄存器的地址,注意它是低位在前。
-Praity 奇偶校驗位,它是APnDP、RnW和A[2:3]共4個bit的校驗位
-Stop 停止位。始終為0。
-Park 該位確切來說應該始終為1
acknowledge phase:
-OK : means successful —— 3‘b001
-WAIT:means host must retry the operation later —— 3'b010
-FAULT: means an error has occurred and one of the sticky bits in CTRL/STAT is set. The host can check the sticky error bits to see what kind of error has occurred.It must clear the sticky bits in ABORT register before using any AP commands, because the target will always respond with FAULT as long as one of the sticky error bits are set. ——3‘b100
data phase:
32*data_bits + 1*parity_bit
讀命令為 數據頭+Trn+ACK+RDATA+Parity 構成,但實際操作發現Trn這位是忽略掉的(所以不知道對此Trn的理解是否有誤),及發送完數據頭后立即讀入ACK,判斷Target是否正確響應。
寫命令為 數據頭+Trn+ACK+Trn+WDATA+Parity,在這不同的是,在寫命令時必須要考慮2個Trn的位置。
寄存器
SW-DP (serial write debug port)registers:
占位,待續
依據官方spec的補充筆記
MEM-AP 訪問方式見下圖。從上往下看依次尋址,最后訪問到目的寄存器
PS:注意auto addr++ 4K邊界的問題
參考:
1.blog :https://blog.csdn.net/baiyibin0530/article/details/51682179 這個blog的內容是以對STM32開發板做SWD調試寫的。對於我來說比較有參考意義的為初始化部分。
2.github: https://github.com/MarkDing/swd_programing_sram 基於cortex M3的debug port,programming internal SRAM。對於我來說,只有協議部分比較有用。
3.自用。ARM 官方出品的Debug interface spec。
4.https://www.cnblogs.com/wuhh123/p/10711222.html