ARM Serial Wire Debug(SWD)是现代 Cortex-M 系列等 ARM 处理器的主流片上调试接口。它以极简的物理连接、优良的速度和丰富的调试功能成为嵌入式领域调试和烧录的标准。本文将系统梳理 SWD 的原理、协议分层、数据包格式、典型时序、错误处理及工程应用建议,帮助你从原理到实践全面掌握 ARM SWD 协议。
1. SWD 协议概述
SWD 是 ARM 为替代传统 4 线 JTAG 所开发的两线制同步串行调试协议。其优势主要体现在:
- 引脚极少:仅需 SWDIO(数据线,双向)和 SWCLK(时钟线,单向)。
- 速度高效:支持高达 50 MHz 的时钟频率。
- 布线简单:极大方便小型封装和高密度 PCB 设计。
- 主机主导:所有通信均由调试主机发起,实现无歧义主从关系。
物理连接推荐:
- SWDIO/SWCLK 各串 10kΩ 上拉电阻并对地 33pF 滤波电容。
- 信号线尽量短(<15cm),与地线分组走双绞线,提升抗干扰性。
2. SWD 协议分层与体系结构
SWD 协议严格分层,便于软硬件实现和调试:
层级 | 职责举例 | 典型操作 |
---|---|---|
应用层 | Flash 编程、IAP 调用 | 烧录、断点、单步 |
核心调试层 | 处理器控制、寄存器访问 | 核暂停、寄存器读写 |
传输层 (SWD) | 命令帧传输、校验、应答 | 读写 AP/DP 寄存器 |
物理层 | 电气特性、时序 | 位传输、拉高/拉低 |
3. 典型通信时序与数据包格式
SWD 通信以主机发起的请求-应答-数据模型为核心,一次完整事务由如下阶段构成:
3.1 请求包格式
字段 | 位数 | 含义 |
---|---|---|
Start | 1 | 起始位(1) |
APnDP | 1 | 0=DP 寄存器,1=AP 寄存器 |
RnW | 1 | 0=写操作,1=读操作 |
A[2:3] | 2 | 寄存器低两位地址 |
Parity | 1 | 奇偶校验(前5位) |
Stop | 1 | 停止位(0) |
Park | 1 | 保持位(1) |
请求包发送后,目标芯片以 3 位 ACK 响应,之后根据读写类型进入数据传输阶段。
3.2 应答与数据阶段
- ACK(3位):OK(0b001)、WAIT(0b010)、FAULT(0b100)
- 数据包(32位数据+1位奇偶校验)
3.3 完整事务时序举例(主机→目标)
- 发送 8 位请求
- 目标延迟响应,返回 3 位 ACK
- 主机根据 ACK 处理
- OK:继续数据阶段
- WAIT:重试
- FAULT:清除错误后重试
- 数据阶段(读/写数据 + 校验)
4. 典型应用流程
以 Flash 编程为例,一次 SWD 调试典型流程如下:
- 初始化 DAP (Debug Access Port)
- 使能/复位处理器核心
- 设置目标内存地址(通过 AP 寄存器)
- 下载数据到 RAM 或直接写入 Flash
- 调用 IAP/Flash 编程功能
- 校验写入结果
伪代码示意:
void SWD_WriteFlash(uint32_t addr, uint32_t* buf, size_t len) {
SWD_WriteAP(AP_TAR, addr); // 设置目标地址
for (size_t i = 0; i < len; ++i) {
SWD_WriteAP(AP_DRW, buf[i]); // 连续写入数据
SWD_WaitForACK();
}
// 触发 Flash 编程
}
5. 错误处理机制
SWD 协议通过 ACK 响应和奇偶校验实现健壮的错误检测:
- OK:正常,继续操作
- WAIT:目标繁忙,主机需重试当前命令
- FAULT:非法访问或出错,主机需清除错误(如写 ABORT 寄存器)
实际应用时,建议实现超时和重试机制,确保调试链路健壮。
6. 多设备与扩展拓扑
SWD v2 支持多芯片调试,通过 Daisy-chain 或星型总线拓扑:
- 设备选择序列:主机可动态“唤醒”特定设备
- 电源管理:未激活设备可休眠,降低功耗
- 兼容性:向下兼容 SWD v1,利于系统升级
7. 工程实践建议
7.1 硬件设计
- 信号线短且等长,避免串扰
- SWDIO/SWCLK 10kΩ 上拉,33pF 对地
- 加 ESD 防护,关键点加缓冲驱动
7.2 软件实现
- 初始化时发送 50 个时钟周期的线复位
- 发送 JTAG-to-SWD 切换序列 (0xE79E)
- 读取 DP_IDCODE 验证链路
- 实现 ACK 超时/重试及错误日志
示例初始化代码片段:
void SWD_Init(void) {
SWD_LineReset(50);
SWD_SendBits(0xE79E, 16); // 切换序列
SWD_LineReset(8);
uint32_t id = SWD_ReadDP(DP_IDCODE);
if ((id & 0x1FFF) != 0x1BA0) {
// 连接失败处理
}
}
7.3 调试技巧
- 使用逻辑分析仪捕获 SWDIO/SWCLK 信号,分析读写波形
- 软件层面详细记录 ACK 和奇偶校验错误,便于排查
- 对于异常 WAIT/FAULT,多检查目标芯片电源和时钟
8. 参考资料
- ARM IHI0031G - Debug Interface Architecture Specification
- NXP AN11553 - SWD Programming Specification
- Cortex-M3 Technical Reference Manual
公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top