SWD读取AP寄存器完整流程

1. 协议层架构

SWD协议通过两层结构访问目标系统:

  • DP (Debug Port): 调试端口,管理调试接口

  • AP (Access Port): 访问端口,执行实际的内存/寄存器访问

每次内存访问流程:DP SELECT选择AP → AP CSW配置 → AP TAR地址 → AP DRW数据

2. AP数量和地址

2.1 AP数量

  • 一个CoreSight系统通常有多个AP

  • 常见的AP类型:

    • MEM-AP​ (Memory Access Port): 内存访问端口 (最常用)

    • JTAG-AP​ (JTAG Access Port): JTAG调试端口

    • AHB-AP​ (AHB Access Port): AHB总线访问

    • APB-AP​ (APB Access Port): APB总线访问

  • 典型ARM Cortex-M芯片有1-4个AP

  • 每个AP有唯一的AP编号​ (0-255)

2.2 AP地址空间

每个AP有256字节的寄存器空间,包含:

地址偏移 寄存器 功能 访问
0x00 CSW 控制/状态字 读写
0x04 TAR 传输地址寄存器 读写
0x08 DRW/BD0 数据寄存器0 读写
0x0C DRW/BD1 数据寄存器1 读写
0x10 BD2 Banked Data 2 读写
0x14 BD3 Banked Data 3 读写
... ... ... ...
0xF4 CFG 配置寄存器 只读
0xF8 BASE ROM表基地址 只读
0xFC IDR ID寄存器 只读

3. 读取流程详述

3.1 阶段1: DP初始化

复制代码
操作: 读取DP IDCODE确认连接
SWD请求包: 0x81 (二进制: 1000 0001)
响应: ACK=0x01 (OKAY)
数据: 0x0BA01477 (Cortex-M3/M4 IDCODE)

3.2 阶段2: 选择AP

复制代码
操作: 写DP SELECT寄存器选择AP编号
SWD请求包: 0xA1 (1010 0001)
响应: ACK=0x01
数据: 0x000000F0
  - APSEL[7:0] = 0x0 (选择AP#0)
  - APBANKSEL[3:0] = 0x0 (选择bank 0)

3.3 阶段3: 配置AP CSW

复制代码
操作: 写AP CSW寄存器配置访问模式
SWD请求包: 0x83 (1000 0011)
响应: ACK=0x01
数据: 0x23000052
配置含义:
  - 0x23: 协议控制 (自动递增打包+单次)
  - 0x5: 数据大小=32位
  - 0x2: 地址增量=自动递增

3.4 阶段4: 设置目标地址

复制代码
操作: 写AP TAR寄存器设置内存地址
SWD请求包: 0x8B (1000 1011)
响应: ACK=0x01
数据: 0x20001000 (目标地址)

3.5 阶段5: 读取数据

复制代码
操作: 读AP DRW寄存器获取数据
SWD请求包: 0x8F (1000 1111)
响应: ACK=0x01
数据: 0x12345678 (读取值)

4. AP选择机制

4.1 DP SELECT寄存器

复制代码
位31-24: APSEL[7:0] - 选择AP编号 (0-255)
位23-8: 保留
位7-4: APBANKSEL[3:0] - 选择AP内的bank
位3-0: 保留

4.2 AP编号示例

  • AP#0: 通常为MEM-AP (内存访问)

  • AP#1: JTAG-AP或其他外设AP

  • AP#2: 系统控制AP

  • AP#3: 跟踪AP (ETM/ITM)

4.3 多AP切换示例

复制代码
// 切换到AP#0 (内存访问)
SELECT = 0x000000F0  // APSEL=0, APBANKSEL=0

// 切换到AP#1 (JTAG访问)
SELECT = 0x000001F0  // APSEL=1, APBANKSEL=0

// 切换到AP#2 (系统控制)
SELECT = 0x000002F0  // APSEL=2, APBANKSEL=0

5. AP寄存器详解

5.1 CSW寄存器 (偏移0x00)

复制代码
位31-24: 协议控制
  bit31: 保留
  bit30: 自动递增打包
  bit29: 自动递增单次
  bit28-24: 模式控制

位23-8: 保留

位7-4: 数据大小
  bit7: 保留
  bit6-4: Size[2:0]
    000: 8位
    010: 16位
    100: 32位
    110: 64位
    111: 256位

位3-0: 地址增量
  bit3: 保留
  bit2-0: AddrInc[2:0]
    000: 无递增
    001: 自增1
    010: 自增2
    100: 自增4
    110: 自增8
    111: 自增16

5.2 TAR寄存器 (偏移0x04)

  • 存储下一次内存访问的地址

  • 必须与数据大小对齐

  • 启用自动递增时,每次DRW访问后自动增加

5.3 DRW寄存器 (偏移0x08/0x0C)

  • 实际的数据读写寄存器

  • BD0(0x08)和BD1(0x0C)功能相同

  • 通常使用BD1(0x0C)

6. 批量读取优化

复制代码
1. 写CSW: 启用自动递增 (0x23000052)
2. 写TAR: 设置起始地址0x20001000
3. 读DRW#1: 获取0x20001000数据
4. 读DRW#2: 自动递增到0x20001004
5. 读DRW#3: 自动递增到0x20001008
6. 读DRW#4: 自动递增到0x2000100C

7. 错误处理

ACK响应 含义 处理
0x01 (OKAY) 成功 继续
0x02 (WAIT) 目标忙 重试操作
0x04 (FAULT) 访问错误 清除ABORT寄存器
无响应 连接问题 检查物理连接

8. 性能参数

复制代码
单次32位读取: 44位传输
理论时间: 11μs @4MHz
实际时间: ~33μs (含空闲周期)
带宽: 121KB/s @4MHz

9. 完整序列示例

复制代码
1. 0x81 → 0x01 0x0BA01477     (读DP IDCODE)
2. 0xA1 → 0x01 0x000000F0     (写DP SELECT, 选择AP#0)
3. 0x83 → 0x01 0x23000052     (写AP CSW)
4. 0x8B → 0x01 0x20001000     (写AP TAR)
5. 0x8F → 0x01 0x12345678     (读AP DRW)

10. 关键点

  1. AP通过DP SELECT寄存器选择,每个AP有唯一编号

  2. 每个AP有独立的256字节寄存器空间

  3. CSW控制访问模式(数据大小、地址递增)

  4. TAR存储目标地址,支持自动递增

  5. DRW进行实际数据读写

  6. 批量访问可利用自动递增优化性能

  7. 奇偶校验确保数据传输正确性

相关推荐
羽获飞2 小时前
从零开始学嵌入式之STM32——27.基于STM32F103C8T6MCU的寄存器方式实现按键调整PWM占空比,调整输出功率
stm32·单片机·嵌入式硬件
学嵌入式的小杨同学2 小时前
STM32 进阶封神之路(十五):DHT11 单总线实战 —— 温湿度检测从时序解析到代码落地(库函数 + 寄存器)
vscode·stm32·单片机·嵌入式硬件·mcu·智能硬件·pcb工艺
2501_937721753 小时前
stm32
stm32·单片机·嵌入式硬件
DLGXY3 小时前
STM32(二十五)——修改主频、睡眠模式、停机模式、待机模式
stm32·单片机·嵌入式硬件
BackCatK Chen3 小时前
2026年STM32新品密集发布:C5系列量产上市,低功耗无线MCU同步迭代
stm32·单片机·嵌入式硬件·stm32c5·mcu新品·stm32wl3r
最概然3 小时前
单片机也能玩依赖注入?
单片机·嵌入式硬件
学嵌入式的小杨同学5 小时前
STM32 进阶封神之路(十六):PWM 波深度实战 —— 定时器输出 + LED 调光 + 电机调速(库函数 + 寄存器)
stm32·单片机·嵌入式硬件·mcu·硬件架构·硬件工程·智能硬件
世微 如初5 小时前
探秘 AP8660:电流模式升压 DC - DC,高转换与精密基准的完美融合
单片机·芯片·led电源驱动
优信电子5 小时前
ESP32开发板单向点对点ESP-NOW无线通信
单片机·嵌入式·arduino