CMSIS-DAP协议关键命令完整数据包示例详解

一、DAP_Info (0x00) - 获取调试器信息

场景1:获取产品名称

请求包(查询产品名称,信息类型=0x02):

复制代码
00000000: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

字节级解析:

复制代码
字节[0] (命令ID): 0x00 = DAP_Info
字节[1] (信息类型): 0x02 = 查询产品名称
字节[2-63] (填充): 全0x00

响应包示例(产品名称="DAPLink CMSIS-DAP"):

复制代码
00000000: 00 11 44 41 50 4c 69 6e 6b 20 43 4d 53 49 53 2d  ..DAPLink CMSIS-
00000010: 44 41 50 00 00 00 00 00 00 00 00 00 00 00 00 00  DAP.............
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0] (命令ID回显): 0x00
字节[1] (字符串长度): 0x11 = 17字节
字节[2-18] (字符串数据): 
    0x44 0x41 0x50 = "DAP"
    0x4C 0x69 0x6E 0x6B = "Link"
    0x20 = 空格
    0x43 0x4D 0x53 0x49 0x53 = "CMSIS"
    0x2D = "-"
    0x44 0x41 0x50 = "DAP"
字节[19] (空终止符): 0x00
字节[20-63] (填充): 全0x00

场景2:获取固件版本(信息类型=0x04)

请求包:

复制代码
00000000: 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

响应包示例(固件版本="0254"):

复制代码
00000000: 00 04 30 32 35 34 00 00 00 00 00 00 00 00 00 00  ..0254..........
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

所有信息类型完整列表:

类型值 含义 典型响应
0x01 供应商名称 "ARM"
0x02 产品名称 "DAPLink CMSIS-DAP"
0x03 序列号 "1234567890"
0x04 固件版本 "0254"
0x05 目标设备供应商 "STMicroelectronics"
0x06 目标设备名称 "STM32F103C8"
0xF0 功能位图 0x07 (Bit0:SWD, Bit1:JTAG, Bit2:SWO)
0xFE 包计数大小 0x01 (1字节)
0xFF 包大小 0x40 (64字节)

功能位图详细说明:

复制代码
位图: 0x07 = 0b00000111
位0 (LSB): 1 = 支持SWD接口
位1: 1 = 支持JTAG接口  
位2: 1 = 支持SWO跟踪
位3: 0 = 不支持原子命令
位4: 0 = 不支持时序测试
位5: 0 = 不支持批量传输
位6: 0 = 不支持大端传输
位7 (MSB): 0 = 保留

二、DAP_Connect (0x02) - 连接目标调试接口

场景:连接SWD接口(端口=1)

请求包:

复制代码
00000000: 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

字节级解析:

复制代码
字节[0] (命令ID): 0x02 = DAP_Connect
字节[1] (端口号): 0x01 = 选择SWD接口
    0x00: 默认端口(自动选择)
    0x01: SWD端口
    0x02: JTAG端口
字节[2-63] (保留/填充): 全0x00

成功连接SWD的响应包:

复制代码
00000000: 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0] (命令ID回显): 0x02
字节[1] (连接状态): 0x01 = SWD连接成功
    0x00: 连接失败
    0x01: SWD连接成功
    0x02: JTAG连接成功
字节[2-63] (保留/填充): 全0x00

连接失败的可能原因和响应:

复制代码
// 端口不可用(如请求JTAG但只支持SWD)
响应: 02 00 00 00 00 00 00 00 ...

// 硬件连接故障
响应: 02 00 00 00 00 00 00 00 ...

三、DAP_SWJ_Sequence (0x12) - 发送位序列

场景1:SWD线复位(发送51个时钟高电平)

请求包:

复制代码
00000000: 12 33 FF FF FF FF FF 07 00 00 00 00 00 00 00 00  .3..............
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细位序列分解:

复制代码
字节[0]: 0x12 = 命令ID
字节[1]: 0x33 = 51位序列长度 (0x33 = 51十进制)

数据字节[2-7]共6个字节,携带51位数据:
字节[2]: 0xFF = 0b11111111 → 发送: 1,1,1,1,1,1,1,1 (8位)
字节[3]: 0xFF = 0b11111111 → 发送: 1,1,1,1,1,1,1,1 (16位)
字节[4]: 0xFF = 0b11111111 → 发送: 1,1,1,1,1,1,1,1 (24位)
字节[5]: 0xFF = 0b11111111 → 发送: 1,1,1,1,1,1,1,1 (32位)
字节[6]: 0xFF = 0b11111111 → 发送: 1,1,1,1,1,1,1,1 (40位)
字节[7]: 0x07 = 0b00000111 → 发送: 1,1,1,0,0,0,0,0 (最后3位有效)

总计: 8×5 + 3 = 51位
时序: 在SWCLK时钟的每个上升沿,SWDIO保持高电平

成功响应包:

复制代码
00000000: 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

字节[0]: 0x12 = 命令ID回显
字节[1]: 0x00 = 执行成功
字节[2-63]: 全0x00填充

场景2:JTAG到SWD切换序列(0xE79E,16位)

请求包:

复制代码
00000000: 12 10 9E E7 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

位序列详细解析(LSB优先发送):

复制代码
字节[0]: 0x12 = 命令ID
字节[1]: 0x10 = 16位序列长度

要发送的原始序列: 0xE79E = 0b1110011110011110
存储格式: 0x9E (低字节), 0xE7 (高字节)

LSB优先发送顺序分析:
0x9E = 0b10011110 → LSB=0, 发送顺序: 0,1,1,1,1,0,0,1
0xE7 = 0b11100111 → LSB=1, 发送顺序: 1,1,1,0,0,1,1,1

完整16位发送顺序:
位0: 0 (0x9E的bit0)
位1: 1 (0x9E的bit1)  
位2: 1 (0x9E的bit2)
位3: 1 (0x9E的bit3)
位4: 1 (0x9E的bit4)
位5: 0 (0x9E的bit5)
位6: 0 (0x9E的bit6)
位7: 1 (0x9E的bit7)
位8: 1 (0xE7的bit0)
位9: 1 (0xE7的bit1)
位10: 1 (0xE7的bit2)
位11: 0 (0xE7的bit3)
位12: 0 (0xE7的bit4)
位13: 1 (0xE7的bit5)
位14: 1 (0xE7的bit6)
位15: 1 (0xE7的bit7)

对应波形: SWDIO在SWCLK时钟的每个上升沿输出上述位值

成功响应包:

复制代码
00000000: 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

四、DAP_Transfer (0x05) - 数据传输(核心命令)

场景1:读取DP IDCODE寄存器(地址0x0)

请求包:

复制代码
00000000: 05 00 01 8F 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

传输请求字节(0x8F)详细解析:

复制代码
字节[0]: 0x05 = 命令ID
字节[1]: 0x00 = DAP索引(通常为0)
字节[2]: 0x01 = 传输数量(1个请求)
字节[3]: 0x8F = 传输请求字节

0x8F = 0b10001111
位分解:
Bit0 (More): 1 = 这不是最后一个请求,后面还有请求
Bit1 (RnW):  1 = 读操作
Bit2 (APnDP): 1 = 访问AP(不是DP)← 注意:这里有问题!
Bit3 (A2):   1 = 地址位2
Bit4 (A3):   0 = 地址位3
Bits5-7:    000 = 保留

根据CMSIS-DAP规范,读取DP IDCODE的正确参数是:
- More: 0(单次请求)
- RnW: 1(读)
- APnDP: 0(DP访问)
- A2: 0(地址位2)
- A3: 0(地址位3)
→ 0b00000101 = 0x05

但实际实现中,DAPLink可能使用不同的约定。

修正后的正确请求包:

复制代码
00000000: 05 00 01 05 00 00 00 00 00 00 00 00 00 00 00 00  ................

响应包示例(STM32F103 IDCODE=0x1BA01477):

复制代码
00000000: 05 01 01 77 14 A0 1B 00 00 00 00 00 00 00 00 00  ...w............
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0]: 0x05 = 命令ID回显
字节[1]: 0x01 = 传输响应数量(1个响应)
字节[2]: 0x01 = 第1个传输响应状态
    0x01 = DAP_TRANSFER_OK(成功)
    0x02 = DAP_TRANSFER_WAIT(等待)
    0x04 = DAP_TRANSFER_FAULT(错误)
    0x08 = DAP_TRANSFER_ERROR(奇偶校验错误)
    0x10 = DAP_TRANSFER_MISMATCH(值不匹配)
字节[3-6]: 0x77, 0x14, 0xA0, 0x1B = 读取的数据(小端字节序)
    实际值 = 0x1BA01477(STM32F103的IDCODE)
字节[7-63]: 填充0x00

场景2:写AP CSW寄存器(设置访问属性)

请求包(写AP CSW=0x23000012):

复制代码
00000000: 05 00 02 02 00 12 00 00 23 00 00 00 00 00 00 00  ........#.......
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0]: 0x05 = 命令ID
字节[1]: 0x00 = DAP索引
字节[2]: 0x02 = 传输数量(2个请求)

请求1(字节[3]): 0x02 = 写AP CSW
    0x02 = 0b00000010
    Bit0 (More): 0 = 还有更多请求(请求2)
    Bit1 (RnW):  0 = 写操作
    Bit2 (APnDP): 1 = 访问AP
    Bit3 (A2):   0 = 地址位2(CSW地址为0x0,A2=0)
    Bit4 (A3):   0 = 地址位3(A3=0)
    写数据: 0x12, 0x00, 0x00, 0x23 (小端 = 0x23000012)

请求2(字节[4]): 0x00 = 虚读(用于获取前一个操作的状态)
    0x00 = 0b00000000
    Bit0 (More): 0 = 最后一个请求
    Bit1 (RnW):  0 = 写操作?应该是读操作?实际上这是虚读
    Bit2 (APnDP): 0 = DP访问
    Bit3 (A2):   0
    Bit4 (A3):   0
    地址0x0(DP IDCODE),但因为是虚读,不关心数据

字节[5-8]: 写入数据 = 0x12, 0x00, 0x00, 0x23 (小端 = 0x23000012)
字节[9-63]: 填充0x00

响应包:

复制代码
00000000: 05 02 01 00 00 00 00 01 77 14 A0 1B 00 00 00 00  ........w.......
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x05 = 命令ID回显
字节[1]: 0x02 = 传输响应数量(2个响应)

响应1(字节[2]): 0x01 = 状态OK
响应1数据(字节[3-6]): 0x00, 0x00, 0x00, 0x00 (写操作无返回数据)

响应2(字节[7]): 0x01 = 状态OK  
响应2数据(字节[8-11]): 0x77, 0x14, 0xA0, 0x1B = 0x1BA01477 (虚读返回的IDCODE)

场景3:批量传输 - 读取3个连续内存地址

请求包(读取0x20000000, 0x20000004, 0x20000008):

复制代码
00000000: 05 00 05 02 12 12 12 11 00 00 00 20 00 00 00 20  ........... ... 
00000010: 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00  ... ............
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

分步解析:

复制代码
字节[0]: 0x05 = 命令ID
字节[1]: 0x00 = DAP索引
字节[2]: 0x05 = 传输数量(5个请求)

请求1(字节[3]): 0x02 = 写DP SELECT,选择AP0
    0x02 = 0b00000010 (More=0, RnW=0写, APnDP=0DP, A2=0, A3=0)
    数据: 0x00, 0x00, 0x00, 0x00 (写入DP SELECT=0x00)

请求2(字节[4]): 0x12 = 写AP CSW
    0x12 = 0b00010010 (More=0, RnW=0写, APnDP=1AP, A2=0, A3=1)
    地址: A3=1,A2=0 = 地址0x4 (CSW寄存器)
    数据: 0x12, 0x00, 0x00, 0x23 (0x23000012)

请求3(字节[5]): 0x12 = 写AP TAR,设置地址0x20000000
    0x12 = 0b00010010 (More=0, RnW=0写, APnDP=1AP, A2=0, A3=1)
    地址: A3=1,A2=0 = 地址0x4 (TAR寄存器)
    数据: 0x00, 0x00, 0x00, 0x20 (0x20000000)

请求4(字节[6]): 0x12 = 写AP TAR,设置地址0x20000004
    0x12 = 0b00010010 (More=0, RnW=0写, APnDP=1AP, A2=0, A3=1)
    数据: 0x04, 0x00, 0x00, 0x20 (0x20000004)

请求5(字节[7]): 0x11 = 读AP DRW
    0x11 = 0b00010001 (More=0, RnW=1读, APnDP=1AP, A2=0, A3=0)
    地址: A3=0,A2=0 = 地址0xC (DRW寄存器)

写入数据(字节[8-23]):
    0x00,0x00,0x00,0x00  # 请求1数据: DP SELECT=0
    0x12,0x00,0x00,0x23  # 请求2数据: AP CSW=0x23000012
    0x00,0x00,0x00,0x20  # 请求3数据: AP TAR=0x20000000
    0x04,0x00,0x00,0x20  # 请求4数据: AP TAR=0x20000004

响应包:

复制代码
00000000: 05 05 01 00 00 00 00 01 00 00 00 00 01 00 00 00  ................
00000010: 00 01 78 56 34 12 01 EF CD AB 89 01 11 11 11 11  ....xV4.........
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x05 = 命令ID回显
字节[1]: 0x05 = 传输响应数量(5个响应)

响应1(字节[2]): 0x01 = 状态OK
响应1数据(字节[3-6]): 0x00,0x00,0x00,0x00

响应2(字节[7]): 0x01 = 状态OK
响应2数据(字节[8-11]): 0x00,0x00,0x00,0x00

响应3(字节[12]): 0x01 = 状态OK
响应3数据(字节[13-16]): 0x00,0x00,0x00,0x00

响应4(字节[17]): 0x01 = 状态OK
响应4数据(字节[18-21]): 0x78,0x56,0x34,0x12 = 0x12345678

响应5(字节[22]): 0x01 = 状态OK
响应5数据(字节[23-26]): 0xEF,0xCD,0xAB,0x89 = 0x89ABCDEF

五、DAP_TransferBlock (0x06) - 块传输

场景:连续写入4个字到内存地址0x20000000

数据定义:

复制代码
地址        数据
0x20000000: 0x01234567
0x20000004: 0x89ABCDEF  
0x20000008: 0x11111111
0x2000000C: 0x22222222

请求包:

复制代码
00000000: 06 00 02 00 00 00 20 04 00 67 45 23 01 EF CD AB  ...... .gE#....
00000010: 89 11 11 11 11 22 22 22 22 00 00 00 00 00 00 00  .....""".......
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0]: 0x06 = 命令ID
字节[1]: 0x00 = DAP索引
字节[2]: 0x02 = 传输请求字节
    0x02 = 0b00000010
    Bit0 (More): 0
    Bit1 (RnW):  0 = 写操作
    Bit2 (APnDP): 1 = 访问AP
    Bit3 (A2):   0
    Bit4 (A3):   0
字节[3-5]: 0x00,0x00,0x20 = 寄存器地址(小端 = 0x20000000)
字节[6-7]: 0x04,0x00 = 传输数量(小端 = 4个字)
字节[8-23]: 要写入的4个32位数据(每个小端格式)
    0x67,0x45,0x23,0x01 = 0x01234567
    0xEF,0xCD,0xAB,0x89 = 0x89ABCDEF
    0x11,0x11,0x11,0x11 = 0x11111111
    0x22,0x22,0x22,0x22 = 0x22222222
字节[24-63]: 填充0x00

成功响应包:

复制代码
00000000: 06 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x06 = 命令ID回显
字节[1]: 0x00 = 响应状态(成功)
字节[2-3]: 0x04,0x00 = 实际传输数量(小端 = 4)
字节[4-63]: 填充0x00(写操作无读取数据返回)

场景:批量读取4个字从内存地址0x20000000

请求包:

复制代码
00000000: 06 00 03 00 00 00 20 04 00 00 00 00 00 00 00 00  ...... .........
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x06 = 命令ID
字节[1]: 0x00 = DAP索引
字节[2]: 0x03 = 传输请求字节
    0x03 = 0b00000011
    Bit0 (More): 1
    Bit1 (RnW):  1 = 读操作
    Bit2 (APnDP): 1 = 访问AP
字节[3-5]: 0x00,0x00,0x20 = 地址0x20000000
字节[6-7]: 0x04,0x00 = 读取4个字
字节[8-63]: 无写入数据

响应包(假设内存内容为0x11223344等):

复制代码
00000000: 06 00 04 00 44 33 22 11 88 77 66 55 CC BB AA 99  ....D3"..wfU....
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x06 = 命令ID回显
字节[1]: 0x00 = 响应状态(成功)
字节[2-3]: 0x04,0x00 = 实际读取数量(4)
字节[4-19]: 读取的4个32位数据(小端格式)
    0x44,0x33,0x22,0x11 = 0x11223344
    0x88,0x77,0x66,0x55 = 0x55667788
    0xCC,0xBB,0xAA,0x99 = 0x99AABBCC
    0x00,0x00,0x00,0x00 = 0x00000000

六、DAP_WriteABORT (0x08) - 写ABORT寄存器

场景:清除DP ABORT寄存器(写0x0000001E)

请求包:

复制代码
00000000: 08 00 1E 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0]: 0x08 = 命令ID
字节[1]: 0x00 = DAP索引
字节[2-5]: 0x1E,0x00,0x00,0x00 = 写入的值(小端 = 0x0000001E)

0x0000001E的含义(DP ABORT寄存器):
Bit0 (ORUNERRCLR): 1 = 清除溢出错误
Bit1 (WDBERRCLR): 1 = 清除写数据错误
Bit2 (STKERRCLR): 1 = 清除堆栈错误
Bit3 (STKCMPCLR): 1 = 清除堆栈比较错误
Bit4: 保留
Bit5 (DAPABORT): 1 = 中止DAP传输
实际值0x1E = 0b00011110,清除所有错误并中止DAP

成功响应包:

复制代码
00000000: 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x08 = 命令ID回显
字节[1]: 0x00 = 执行成功
字节[2-63]: 填充0x00

七、DAP_SWJ_Pins (0x10) - 控制SWJ引脚

场景:控制目标芯片复位引脚

请求包(拉低nRESET引脚100ms):

复制代码
00000000: 10 00 20 64 00 00 00 00 00 00 00 00 00 00 00 00  . d............
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0]: 0x10 = 命令ID
字节[1]: 0x00 = 引脚输出值
    Bit0 (SWCLK/TCK): 0 = 低电平
    Bit1 (SWDIO/TMS): 0 = 低电平
    Bit2: 保留
    Bit3: 保留
    Bit4: 保留
    Bit5 (nRESET): 0 = 低电平(拉低复位)
    Bit6: 保留
    Bit7 (nTRST): 0 = 低电平
字节[2]: 0x20 = 引脚选择掩码
    0x20 = 0b00100000
    只控制Bit5 (nRESET引脚),其他引脚保持原状
字节[3-4]: 0x64,0x00 = 等待时间(小端 = 0x0064 = 100ms)
字节[5-63]: 填充0x00

响应包(返回当前引脚状态):

复制代码
00000000: 10 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00  . ..............
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

解析:

复制代码
字节[0]: 0x10 = 命令ID回显
字节[1]: 0x20 = 当前引脚输入状态
    0x20 = 0b00100000
    Bit5 (nRESET): 1 = 高电平(由于内部上拉)
    (注意:虽然我们输出低电平,但读取的是输入状态)
字节[2-63]: 填充0x00

完整的复位序列:

复制代码
// 1. 拉低nRESET 100ms
发送: 10 00 20 64 00  // 输出nRESET=0,保持100ms
接收: 10 20           // 引脚状态

// 2. 释放nRESET 100ms  
发送: 10 20 20 64 00  // 输出nRESET=1,保持100ms
接收: 10 20           // 引脚状态

八、DAP_SWJ_Clock (0x11) - 设置时钟频率

场景:设置SWD时钟为1MHz

请求包:

复制代码
00000000: 11 40 42 0F 00 00 00 00 00 00 00 00 00 00 00 00  .@B.............
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

详细解析:

复制代码
字节[0]: 0x11 = 命令ID
字节[1-4]: 0x40,0x42,0x0F,0x00 = 时钟频率(小端 = 0x000F4240 = 1,000,000 Hz)
字节[5-63]: 填充0x00

成功响应包:

复制代码
00000000: 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

常见时钟频率:

复制代码
0x000F4240 = 1,000,000 Hz (1MHz)
0x001E8480 = 2,000,000 Hz (2MHz)
0x002DC6C0 = 3,000,000 Hz (3MHz)
0x003D0900 = 4,000,000 Hz (4MHz)
0x004C4B40 = 5,000,000 Hz (5MHz)
0x00989680 = 10,000,000 Hz (10MHz)

九、完整调试会话数据流示例

以下是Keil连接STM32F103并读取IDCODE的完整数据包交换:

阶段1:初始化连接

复制代码
1. DAP_Info获取产品名称
   发送: 00 02 00 00 00 00 ...
   接收: 00 11 44 41 50 4C 69 6E 6B 20 43 4D 53 49 53 2D 44 41 50 00 ...

2. 设置SWD时钟1MHz
   发送: 11 40 42 0F 00 00 00 00 ...
   接收: 11 00 00 00 00 00 00 00 ...

3. SWD线复位(51个时钟高电平)
   发送: 12 33 FF FF FF FF FF 07 00 ...
   接收: 12 00 00 00 00 00 00 00 ...

4. JTAG-to-SWD切换序列
   发送: 12 10 9E E7 00 00 00 00 ...
   接收: 12 00 00 00 00 00 00 00 ...

5. 连接SWD接口
   发送: 02 01 00 00 00 00 00 00 ...
   接收: 02 01 00 00 00 00 00 00 ...

阶段2:读取芯片IDCODE

复制代码
6. 配置传输参数
   发送: 04 00 32 00 00 00 00 00 ...
   接收: 04 00 00 00 00 00 00 00 ...

7. 读取DP IDCODE
   发送: 05 00 01 05 00 00 00 00 ...
   接收: 05 01 01 77 14 A0 1B 00 ...

8. 写DP ABORT清除错误标志
   发送: 08 00 1E 00 00 00 00 00 ...
   接收: 08 00 00 00 00 00 00 00 ...

9. 写DP SELECT选择AP0
   发送: 05 00 02 01 00 00 00 00 00 00 00 00 ...
   接收: 05 02 01 00 00 00 00 01 77 14 A0 1B ...

10. 写AP CSW配置访问属性
   发送: 05 00 02 12 00 00 00 00 12 00 00 23 ...
   接收: 05 02 01 00 00 00 00 01 00 00 00 00 ...

阶段3:读写内存

复制代码
11. 写AP TAR设置地址0x20000000
   发送: 05 00 02 12 00 00 00 00 00 00 00 20 ...
   接收: 05 02 01 00 00 00 00 01 00 00 00 00 ...

12. 读AP DRW获取内存值
   发送: 05 00 01 11 00 00 00 00 ...
   接收: 05 01 01 78 56 34 12 00 ...
    读取到内存值0x12345678

十、错误处理和数据包状态码

传输状态码详解:

复制代码
#define DAP_TRANSFER_OK        0x01  // 成功
#define DAP_TRANSFER_WAIT      0x02  // 等待响应(需要重试)
#define DAP_TRANSFER_FAULT     0x04  // 传输错误(协议错误)
#define DAP_TRANSFER_ERROR     0x08  // 奇偶校验错误
#define DAP_TRANSFER_MISMATCH  0x10  // 值不匹配(读写验证失败)

错误响应示例:

复制代码
// 传输错误(DAP_TRANSFER_FAULT)
响应: 05 01 04 00 00 00 00 00 00 00 00 00 ...

// 奇偶校验错误(DAP_TRANSFER_ERROR)  
响应: 05 01 08 00 00 00 00 00 00 00 00 00 ...

// 等待响应(需要重试)
响应: 05 01 02 00 00 00 00 00 00 00 00 00 ...

错误恢复流程:

复制代码
1. 发送DAP_WriteABORT清除错误标志
   请求: 08 00 1E 00 00 00

2. 重新发送失败的传输命令

3. 如果仍然失败,降低时钟频率重试
   请求: 11 40 42 0F 00 00 00 00  // 1MHz

总结

这个详细的数据包示例展示了CMSIS-DAP协议的关键命令的完整64字节数据格式。每个数据包都严格按照协议规范构造,包含了:

  1. 命令ID​ - 标识操作类型

  2. 参数​ - 具体操作参数

  3. 数据​ - 传输的数据内容

  4. 填充​ - 补全64字节

理解这些数据包格式对于:

  • 调试DAPLink固件问题

  • 开发自定义调试工具

  • 分析调试通信问题

  • 优化调试性能

都具有重要意义。每个字节都有其特定含义,整个协议栈设计精巧而高效。

相关推荐
暮雪倾风2 小时前
【软件安装】VSPD(Virtual Serial Port Driver)虚拟串口软件安装及使用
单片机·串口
SY师弟3 小时前
蓝桥杯单片机——安装芯片包
单片机·嵌入式硬件·职场和发展·蓝桥杯
小宋同学在不断学习3 小时前
蓝桥杯电子赛 __ 定时器1中断实现LED定时翻转
单片机·蓝桥杯·定时器
DLGXY3 小时前
STM32(二十三)——读写备份寄存器&实时时钟
stm32·单片机·fpga开发
国科安芯3 小时前
抗辐照ASP4644四通道降压稳压器在商业卫星通信处理模块的应用研究
单片机·嵌入式硬件·安全·fpga开发·架构·安全性测试
爱倒腾的老唐4 小时前
06、STM32 的 I/O 应用
stm32·单片机·嵌入式硬件
承前智4 小时前
基于任意单片机的PWM调速电机
单片机·嵌入式硬件
干啥都是小小白4 小时前
如何移植FreerRTOS到STM32F103(2026.3.13)
stm32·单片机·嵌入式硬件
爱上珍珠的贝壳4 小时前
ESP32-S3-CAM:认识引脚
单片机·嵌入式硬件·智能硬件·esp32-s3