我正在尝试在没有任何外部设备的情况下从 JTAG 切换到 SWD。为什么?因为我想使用 SWO 引脚将日志信息流发送到另一台设备。
为了在不使用外部调试器的情况下完成此操作,我将 nTRST 引脚 (PB4) 连接到 SWDIO (PA13) 并将 TDI 引脚 (PA15) 连接到 SWCLK (PA14)。然后的想法是在 nTRST 和 TDI 引脚上输出模式和时钟,以将它们发送到 SWDIO 和 SWCLK。
在第 31.3.1 章的参考手册 (RM0008) 中,它显示了从 SWJ-DP 切换到 SW-DP 的顺序如下:
- 通过发送至少 50 个时钟周期且 TMS (SWDIO) = 1 进入线路复位
- 发送位模式 0111100111100111(首先发送 MSB),所以在我的情况下,当首先移出 LSB 时为 0b1110011110011110。
- 发送至少 50 个时钟周期且 TMS (SWDIO) = 1
现在到了有趣的部分,我已经设法让它在 STM32F303 微控制器上工作,但是,当我在 STM32F103 微控制器上做同样的事情时,它就不起作用了。但是...如果我将 STM32F103 连接到 JTAG-lock-pick-Tiny-v2 并使用 OPENOCD,它就可以工作。稍后再详细介绍。
我发现了一些有趣的事实/事情,但我不确定它们是否相关。
- 在第 31.4 章的 RM0008 中,它说:“STM32F10xxx MCU 采用各种封装,可用引脚数不同。因此,与引脚可用性相关的某些功能 (ETM) 可能因封装而异。
- 在 CoreSight DAP-Lite 技术参考手册第 2.2.5 章中,从 JTAG 切换到 SWD 时有第四步。第四步是执行 READID 以验证 SWJ-DP 已切换到 SWD。
- 为了能够在 GPIO 引脚上输出数据,我必须使用以下功能:
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* JTAG-DP Disabled and SerialWire-DebugPort (SW-DP) Enabled */
在使用 OPENOCD 时,我尝试将 GPIO“bitbanging”的输出与输出进行比较。第一个区别是时钟速度,使用 OPENOCD 和 JTAG-lock-pick-Tiny-v2 时为 1MHz,使用 bitbanging 时为 22kHz 左右。我已经尝试过 125kHz 以上的速度,如第 11.1.2 章的“nRF51 系列参考手册”中所述,SWDCLK 上的最小时钟速度为 125kHz。没有不同。OPENOCD 和我的 bitbanging 的位序列是相同的,但是在第二次“线路复位”之后,OPENOCD 确实执行了第四步中提到的 READID 和其他一些读写操作,请参见下图:
要执行 READID,您应该发送模式 0b10100101,这是我在第二行重置后添加的,没有任何区别。我使用了 SALEAE 逻辑分析仪来比较流量,见下图:
更新/编辑: 我编辑了 OpenOCD 的配置文件以使用 22kHz 频率,这也有效,即使用较低频率没有问题。我下载了 OpenOCD 的源代码,并在发送“魔法”序列后将其编辑为停止。这是行不通的。然后我在读取 IDCODE 后将 OpenOCD 设置为停止。仍然不起作用,所以在写入和读取中必须有一些重要的东西。
更新/编辑 2:
在对 OpenOCD 的源代码进行了更多挖掘之后,我相信我已经找到了问题所在。在 arm_adi_v5.c 文件中,我while(1){}
在这段代码之前和之后添加了一个:
LOG_DEBUG("DAP: wait CDBGPWRUPACK");
retval = dap_dp_poll_register(dap, DP_CTRL_STAT,
CDBGPWRUPACK, CDBGPWRUPACK,
DAP_POWER_DOMAIN_TIMEOUT);
if (retval != ERROR_OK)
return retval;
如果while(1){}
在它不起作用之前使用它,并且如果我们在它起作用之后设置它。并从 Saleae 中提取信号并在 meld 中对它们进行比较,我得到:
不同的部分是:
SWD,Request DebugPort Write CTRL/STAT,,,,,,,,,,,,,,
,SWD,Turnaround,,,,,,,,,,,,,,
,SWD,ACK OK,,,,,,,,,,,,,,
,SWD,Turnaround,,,,,,,,,,,,,,
,SWD,WData '1342177312' reg CTRL/STAT bits CSYSPWRUPACK=0, CSYSPWRUPREQ=1, CDBGPWRUPACK=0, CDBGPWRUPREQ=1, CDBGRSTACK=0, CDBGRSTREQ=0, TRNCNT='0', MASKLANE='0', WDATAERR=0, READOK=0, STICKYERR=1, STICKYCMP=0, TRNMODE=Normal, STICKYORUN=0, ORUNDETECT=0
,SWD,Data parityok,,,,,,,,,,,,,,
,SWD,Request DebugPort Read CTRL/STAT,,,,,,,,,,,,,,
,SWD,Turnaround,,,,,,,,,,,,,,
,SWD,ACK OK,,,,,,,,,,,,,,
,SWD,WData '4026531840' reg CTRL/STAT bits CSYSPWRUPACK=1, CSYSPWRUPREQ=1, CDBGPWRUPACK=1, CDBGPWRUPREQ=1, CDBGRSTACK=0, CDBGRSTREQ=0, TRNCNT='0', MASKLANE='0', WDATAERR=0, READOK=0, STICKYERR=0, STICKYCMP=0, TRNMODE=Normal, STICKYORUN=0, ORUNDETECT=0
,SWD,Data parityok,,,,,,,,,,,,,,
,SWD,Request DebugPort Write CTRL/STAT,,,,,,,,,,,,,,
,SWD,Turnaround,,,,,,,,,,,,,,
,SWD,ACK OK,,,,,,,,,,,,,,
,SWD,Turnaround,,,,,,,,,,,,,,
,SWD,WData '1342177280' reg CTRL/STAT bits CSYSPWRUPACK=0, CSYSPWRUPREQ=1, CDBGPWRUPACK=0, CDBGPWRUPREQ=1, CDBGRSTACK=0, CDBGRSTREQ=0, TRNCNT='0', MASKLANE='0', WDATAERR=0, READOK=0, STICKYERR=0, STICKYCMP=0, TRNMODE=Normal, STICKYORUN=0, ORUNDETECT=0
,SWD,Data parityok,,,,,,,,,,,,,,
,SWD,Request DebugPort Read CTRL/STAT,,,,,,,,,,,,,,
,SWD,Turnaround,,,,,,,,,,,,,,
,SWD,ACK OK,,,,,,,,,,,,,,
,SWD,WData '4026531840' reg CTRL/STAT bits CSYSPWRUPACK=1, CSYSPWRUPREQ=1, CDBGPWRUPACK=1, CDBGPWRUPREQ=1, CDBGRSTACK=0, CDBGRSTREQ=0, TRNCNT='0', MASKLANE='0', WDATAERR=0, READOK=0, STICKYERR=0, STICKYCMP=0, TRNMODE=Normal, STICKYORUN=0, ORUNDETECT=0
,SWD,Data parityok,,,,,,,,,,,,,,
一旦我取得更多进展,我将再次更新。