电子发烧友 电子发烧友
  • 首页
  • 技术
    可编程逻辑
    MEMS/传感技术
    嵌入式技术
    模拟技术
    控制/MCU
    处理器/DSP
    存储技术
    EMC/EMI设计
    电源/新能源
    测量仪表
    制造/封装
    RF/无线
    接口/总线/驱动
    EDA/IC设计
    光电显示
    连接器
    PCB设计
    LEDs
    汽车电子
    医疗电子
    人工智能
    可穿戴设备
    军用/航空电子
    工业控制
    触控感测
    智能电网
    音视频及家电
    通信网络
    机器人
    vr|ar|虚拟现实
    安全设备/系统
    移动通信
    便携设备
    物联网
    区块链
    HarmonyOS
    RISC-V MCU
    光伏
    ChatGPT
    IGBT
    充电桩
    氮化镓
    BLDC
    逆变器
    5G
    电机控制
  • 资源
    技术文库
    新品速递
    电路图
    元器件知识
    电子百科
    最新技术文章
  • 下载
    在线工具
    常用软件
    电子书
    datasheet
  • 专栏
    电子说
    专栏
  • 社区
    论坛
    问答
    小组
    技术专栏
    社区之星
    试用中心
    HarmonyOS技术社区
    2023电子工程师大会
  • 研究院
  • 活动
    设计大赛
    硬创大赛
    社区活动
    线下会议
    在线研讨会
    小测验
  • 学院
    直播
    课程
  • 视频
  • 企业号
  • 华秋智造
  • 工具
    PCB在线检查
    datasheet查询
    选型替代查询
    免费样品申请
    免费评测试用
    工程师专区
    技术子站
0
  • 聊天消息
  • 系统消息
  • 评论与回复
查看更多
查看更多
查看更多
  • 0

    关注
  • 0

    粉丝
  • 0

    动态
  • 个人中心
  • 内容管理
  • 积分兑换
    当前积分:
  • 修改资料
  • 退出登录
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心
发布
  • 发文章

  • 发资料

  • 发帖

  • 提问

  • 发视频

创作活动
下载中心
  • 推荐
  • 分类
  • 资料
  • 软件
  • 工具
  • 排行榜
  • DataSheet

完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>

3天内不再提示

你真正了解SWD如何下载调试的么?

要长高 来源:CSDN博主 作者:背包旅行码农 2023-12-06 11:20 次阅读

作为 ARM 嵌入式 工程师下载调试器都应该知道,但你真正了解SWD如何下载调试的么?ARM 芯片通过什么物理 接口和什么方式连接完全取决于芯片Debug子系统的架构如何?

你可以从芯片手册的Debug章节获得DAP(Debug Access Port)的 信息。我调试的是 NXP 公司 最新车载芯片S32K3系列的芯片,从S32K3xx Reference Manual中Debug 子系统章节中得知该芯片的debug和Trace接口基于Arm CoreSight SoC-400的标准。 从Arm CoreSight SoC-400 Techn ical Reference Manual章节Debug Access Port中你可以获取到详细的信息。这里只做关键内容介绍,只介绍涉及的部分。

参考文档:Arm CoreSight SoC-400 Technical Reference Manual , CoreSight Components Technical Reference Manual , Arm CoreSight Architecture Specification。

从Arm CoreSight SoC-400 Technical Reference Manual中Figure 4-1 Structure of the CoreSight SoC-400 DAP components看出SWD只是接入芯片调试子系统的一种方式而已。

1663903486186432.png

那么外部调试工具是怎么通过SWD的方式接入到ARM核内部的呢?下面我们详细介绍一下CoreSight SoC-400 DAP组件架构。

DAP是片外调试工具接入SOC组件的集合。访问方式是按照ARM®调试接口架构规范 ADIv5.0~ ADIv5.2实现。

DAP由以下组件组成:

•DP用于管理与外部调试器的连接。

•AP访问片上系统资源。 每种类型的AP可以有多个。

•DAPBUS互连,用于将DP连接到一个或多个AP。

AP提供了非侵入式访问权限:

•CoreSight组件下载或者烧录模型。 通常是通过系统级CoreSight APB总线和APB-AP来完成的。

•内存映射的系统组件,通常使用AXI-AP或AHB-AP。

•使用JTAG-AP的旧版JTAG配置的调试组件。

而且,某些支持CoreSight的 处理器直接连接到DAPBUS互连,并实现自己的ADIv5兼容AP。

CoreSight SoC具有单个多功能DP,如下所示:

SWJ-DP 这是一个组合调试 端口,可以通过ADIv5.1定义的JTAG或串行线协议进行 通信。它包含两个调试端口SW-DP和JTAG-DP,您可以通过接口时序命令选择它们,以在调试端口接口之间切换。

JTAG-DP 兼容DP架构版本0。SW-DP兼容DP架构版本2和Serial Wire协议版本2,使SW-DP可以与其他SW-DP或其他实现组件共享连接。

CoreSight SoC中包含的AP端口是:

AXI-AP AXI-AP实现了ADIv5存储器访问端口(MEM-AP)架构,以直接连接到AXI存储器系统。 您可以使用适当的桥接组件将其连接到其他内存系统。

AHB-AP AHB-AP提供了一个AHB-Lite主站,用于访问系统AHB总线。 这兼容ADIv5.1中的MEM-AP并且可以执行8到32位访问。

APB-AP APB-AP在AMBA v3.0中提供了一个APB主设备,用于访问调试APB总线。 这兼容具有32位固定传输大小的MEM-AP体系结构。

JTAG-AP JTAG-AP提供对片上组件的JTAG访问,用作JTAG主端口以驱动 ASIC中的JTAG链。 这是ADIv5.1中JTAG-AP的实现。

DAPBUS 互连将DP连接到AP。 系统可能不包含某些类型的AP,或者可能包含多个相同类型的AP。

单纯看CoreSight SoC-400 DAP组件架构,感觉会比较空洞,我们结合一下S32K3XX DAP架构图来看一下。

1663903499758403.png

从芯片的DAP architecture,不难看出S32K3采用的是Arm®CoreSight™架构。

你基本可以找到 CoreSight SoC-400和S32K3XX的DAP architecture对应关系:

S32K3XX CoreSight SoC-400

SWJ-DAP <--> Serial Wire JTAG Debug Port (SWJ-DP)

DAPMUX <--> DAPBUS interconnect

AHB_AP <--> AHB Access Port (AHB-AP)

APB-AP <--> APB Access Port (APB-AP)

MDM_AP <--> DAPBUS exported interface

SDA_AP <--> DAPBUS exported interface

SWJ-DP由JTAG-DP和SW-DP的组成。 它选择JTAG或SWD作为连接机制,并启用JTAG-DP或SW-DP作为DAP的接口。

JTAG和SWD接口

JTAG接口具有四个强制引脚tck,tms,tdi和tdo,以及一个可选的复位引脚ntrst。 JTAG-DP和SW-DP还需要独立的上电复位npotrst。

SWD接口需要两个引脚:

•双向swdio 信号

时钟swclk,可以从设备输入或输出。

为了使JTAG或SWD共享 连接器,必须在SWJ-DP模块外部进行连接。 特别是,tms必须是双向引脚,以支持SWD模式下的双向swdio引脚。

20- Pin ARM Standard JTAG Connector

1663903522710894.png

(From https://www2. keil.com/coresight/coresight-connectors)

它支持用于访问基于ARM7和ARM9的设备的JTAG接口。 对于Cortex-Mx设备,它支持串行线和JTAG接口,以访问Cortex-Mx设备上可用的所有SWD,SWV和JTAG信号。

那么是调试工具是通过什么方式访问Cortex-Mx内部的呢?

参考文档:ARM® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2

DAP访问方式是按照ARM®调试接口架构规范ADIv5.0~ADIv5.2实现。

DAP****结构框图如下:

来自ARM® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2的Figure A1-2 Structure of the DAP, showing DPv0 JTAG-DP accesses to a generic AP

1663903524417397.png

ADI包括:

Debug Access Port (DAP),DAP外部物理连接 和 DAP与内部调试资源组件的连接。

DAP包含两个逻辑模块,Debug Port(DP) 和 Access Port(AP)。DP来连接外部的host,AP来访问内部的调试组件 寄存器:

• Access to the Debug Port (DP) registe rs. This is provided by Debug Port accesses (DPACC).

• Access to the Access Port (AP) registers. This is provided by Access Port accesses (APACC)

ADIv5标准外部接口支持一下几种DP:

• The JTAG Debug Port (JTAG-DP)

• The Serial Wire Debug Port (SW-DP)

• The Serial Wire/JTAG Debug Port (SWJ-DP)

内部资源接口包含:

AP (MEM-AP or JTAG-AP)

由于我选择使用的是SW-DP的方式访问,我这里只对SWD协议处理流程介绍。

我们下面剖析一下SW-DP报文格式(担心翻译有误,就用英文原文):

Start A single start bit, with value 0b1.

APnDP A single bit, indica ting whether the Debug Port or the Access Port Access register is to be accessed. This bit is 0b0 for a DPACC access, or 0b1 for an APACC access.

RnW A single bit, indicating whether the access is a read or a write. This bit is 0b0 for a write access, or 0b1 for a read access.

A[2:3] Two bits, giving the A[3:2] address field for the DP or AP register Address:

• For a DPACC access, the register being addressed depends on the A[3:2] value and, if A[3:2]==0b01, the value that is held in SELECT. DPBANKSEL. For det ails, see:

— DP architecture version 1 (DPv1) address map on page B2-50

1663903536691891.png

— DP architecture version 2 (DPv2) address map on page B2-51.

1663903545571092.png

• For an APACC access, the register being addressed depends on the A[3:2] value and the value

that is held in SELECT.{APSEL,APBANKSEL}. For details about addressing, see:

— MEM-AP Prog rammers’ Model on page C2-169 for accesses to a MEM-AP register

1663903552519817.png

— JTAG-AP register summary on page C3-206 for accesses to a JTAG-AP register.

1663903560152462.png

Note

The A[3:2] value is transmitted Least Significant Bit (LSB) first on the wire, which is why it appears as A[2:3] on the diagrams.

Parity A single parity bit for the preceding packet. See Parity on page B4-108.

Stop A single stop bit. In the synchronous SWD protocol, this bit is always 0b0.

Park A single bit. The host must drive the Park bit HIGH to park the line before tristating it for the turnaround period, to ensure that the line is read as HIGH by the target, which is required because the pull-up on the SWD interface is weak. The target reads this bit as 0b1.

Trn Turnaround. See Line turnaround on page B4-107.

Note

All the examples that are given in this chapter show the default turnaround period of one cycle.

ACK[0:2] A three-bit target-to-host response.

1663903569279765.png

WDATA[0:31]

32 bits of write data, from host to target.

RDATA[0:31]

32 bits of read data, from target to host

我们已经了解了报文格式,那我们结合SWD的报文读写时序图来理解。

Successful write operation (OK response)

1663903577467676.png

Successful read operation (OK response)

1663903599297173.png

下面我结合Successful write operation (OK response)和Structure of the Debug Access Port举个例子演示一下SWD如何控制DAP。

Every AP or DP access transaction from the debugger includes two address bits, A[3:2]:

• For a DP register access, the address bits A[3:2] and SELECT.DPBANKSEL determine which register is accessed. SELECT is a DP register.

• For an AP register access, SELECT.APSEL selects an AP to access, and the address bits A[3:2] are combined with SELECT.APBANKSEL to determine which AP register is accessed, as summarized in Structure of the Debug Access Port. That is, the two address bits A[3:2] are decoded to select one of the four 32-bit words from the register bank indicated by SELECT.APBANKSEL in the AP indicated by SELECT.APSEL. Bits [1:0] of all AP and DP register addresses are 0b00.

假如我要向AP0寄存器0x14里写入0xF0000001,调试工具操作流程如下:

1663903615337573.png

使用DP寄存器向DP的SELECT寄存器写入:

— SELECT.APSEL to 0x00. APSEL, bits[31:24]

— SELECT.APBANKSEL to 0x1. APBANKSEL, bits[7:4]

APnDP 写0 表示DP操作,A[3:2]写0x02表示操作0x08 SELECT 寄存器。写入0x00000001.

使用AP寄存器向AP0的0x14寄存器写入:

APnDP 写1 表示AP操作,由于已经向DP的SELECT选择了APBANKSEL为0x01,A[3:2]写0x01表示操作0x14 寄存器。写入0xF0000001. 在这个情况下能访问0x10~0x1C等4个寄存器。

其他AP操作其实流程一样。

下面我稍微了解一下MEM-AP.

来自 ARM® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2的Figure C2-1 MEM-AP connecting the DP to debug components

1663903652399406.png

说白了MEM-AP为DAP提供了一种直接访问系统地址空间的访问。操作其实和通用AP的访问一样。MEM-AP访问系统地址空间,其实有多了一层间接访问。我们直接从OpenOCD源码中看整个过程。

https://sourceforge.net/p/openocd/code/ci/v0.11.0/tree/src/target/cortex_m. c#l2521

struct target_type cortexm_target = {

.name = "cortex_m",

.deprecated_name = "cortex_m3",

.poll = cortex_m_poll,

.arch_state = armv7m_arch_state,

.target_request_data = cortex_m_target_request_data,

.halt = cortex_m_halt,

.resume = cortex_m_resume,

.step = cortex_m_step,

.assert_reset = cortex_m_assert_reset,

.deassert_reset = cortex_m_deassert_reset,

.soft_reset_halt = cortex_m_soft_reset_halt,

.get_gdb_arch = arm_get_gdb_arch,

.get_gdb_reg_list = armv7m_get_gdb_reg_list,

.read_memory = cortex_m_read_memory,

.write_memory = cortex_m_write_memory,

.checksum_memory = armv7m_checksum_memory,

.blank_check_memory = armv7m_blank_check_memory,

.run_algorithm = armv7m_run_algorithm,

.start_algorithm = armv7m_start_algorithm,

.wait_algorithm = armv7m_wait_algorithm,

.add_breakpoint = cortex_m_add_breakpoint,

.remove_breakpoint = cortex_m_remove_breakpoint,

.add_watchpoint = cortex_m_add_watchpoint,

.remove_watchpoint = cortex_m_remove_watchpoint,

.commands = cortex_m_command_handlers,

.target_create = cortex_m_target_create,

.target_jim_configure = adiv5_jim_configure,

.init_target = cortex_m_init_target,

.examine = cortex_m_examine,

.deinit_target = cortex_m_deinit_target,

.profiling = cortex_m_profiling,

};

OpenOCD通过DAP MEM AP的访问实现Cortex M系统地址空间的访问。

cortex_m_read_memory和cortex_m_write_memory实现了读写操作。看一下这两个函数是怎么实现的。

cortex_m_read_memory实现

static int cortex_m_read_memory(struct target *target, target_addr_t address,

uint32_t size, uint32_t count, uint8_t *buffer)

{

struct armv7m_common *armv7m = target_to_armv7m(target);

if (armv7m->arm.is_armv6m) {

/* armv6m does not handle unaligned memory access */

if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))

return ERROR_TARGET_UNALIGNED_ACCESS;

}

return mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address);

}

int mem_ap_read_buf(struct adiv5_ap *ap,

uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)

{

return mem_ap_read(ap, buffer, size, count, address, true);

}

/**

* Synchronous read of a block of memory, using a specific access size.

*

* @param ap The MEM-AP to access.

* @param buffer The data buffer to receive the data. No particular alignment is assumed.

* @param size Which access size to use, in bytes. 1, 2 or 4.

* @param count The number of reads to do (in size units, not bytes).

* @param adr Address to be read; it must be readable by the currently selected MEM-AP.

* @param addrinc Whether the target address should be increased after each read or not. This

* should normally be true, except when reading from e.g. a FIFO.

* @return ERROR_OK on success, otherwise an error code.

*/

static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count,

uint32_t adr, bool addrinc)

{

struct adiv5_dap *dap = ap->dap;

size_t nbytes = size * count;

const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;

uint32_t csw_size;

uint32_t address = adr;

int retval = ERROR_OK;

/* TI BE-32 Quirks mode:

* Reads on big-endian TMS570 behave strangely differently than writes.

* They read from the physical address requested, but with DRW byte-reversed.

* For example, a byte read from address 0 will place the result in the high bytes of DRW.

* Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,

* so avoid them. */

if (size == 4)

csw_size = CSW_32BIT;

else if (size == 2)

csw_size = CSW_16BIT;

else if (size == 1)

csw_size = CSW_8BIT;

else

return ERROR_TARGET_UNALIGNED_ACCESS;

if (ap->unaligned_access_bad && (adr % size != 0))

return ERROR_TARGET_UNALIGNED_ACCESS;

/* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant

* over-allocation if packed transfers are going to be used, but determining the real need at

* this point would be messy. */

uint32_t *read_buf = calloc(count, sizeof(uint32_t));

/* Multiplication count * sizeof(uint32_t) may overflow, calloc() is safe */

uint32_t *read_ptr = read_buf;

if (read_buf == NULL) {

LOG_ERROR("Fai led to allocate read buffer");

return ERROR_FAIL;

}

/* Queue up all reads. Each read will store the entire DRW word in the read buffer. How many

* useful bytes it contains, and their location in the word, depends on the type of transfer

* and alignment. */

while (nbytes > 0) {

uint32_t this_size = size;

/* Select packed transfer if possible */

if (addrinc && ap->packed_transfers && nbytes >= 4

&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {

this_size = 4;

retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);

} else {

retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);

}

if (retval != ERROR_OK)

break;

retval = mem_ap_setup_tar(ap, address);

if (retval != ERROR_OK)

break;

retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW, read_ptr++);

if (retval != ERROR_OK)

break;

nbytes -= this_size;

if (addrinc)

address += this_size;

mem_ap_update_tar_cache(ap);

}

if (retval == ERROR_OK)

retval = dap_run(dap);

/* Restore state */

address = adr;

nbytes = size * count;

read_ptr = read_buf;

/* If something failed, read TAR to find out how much data was successfully read, so we can

* at least give the caller what we have. */

if (retval != ERROR_OK) {

uint32_t tar;

if (mem_ap_read_tar(ap, &tar) == ERROR_OK) {

/* TAR is incremented after failed transfer on some devices (eg Cortex-M4) */

LOG_ERROR("Failed to read memory at 0x%08"PRIx32, tar);

if (nbytes > tar - address)

nbytes = tar - address;

} else {

LOG_ERROR("Failed to read memory and, additionally, failed to find out where");

nbytes = 0;

}

}

/* Replay loop to populate caller's buffer from the correct word and byte lane */

while (nbytes > 0) {

uint32_t this_size = size;

if (addrinc && ap->packed_transfers && nbytes >= 4

&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {

this_size = 4;

}

if (dap->ti_be_32_quirks) {

switch (this_size) {

case 4:

*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));

*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));

/* fallthrough */

case 2:

*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));

/* fallthrough */

case 1:

*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));

}

} else {

switch (this_size) {

case 4:

*buffer++ = *read_ptr >> 8 * (address++ & 3);

*buffer++ = *read_ptr >> 8 * (address++ & 3);

/* fallthrough */

case 2:

*buffer++ = *read_ptr >> 8 * (address++ & 3);

/* fallthrough */

case 1:

*buffer++ = *read_ptr >> 8 * (address++ & 3);

}

}

read_ptr++;

nbytes -= this_size;

}

free(read_buf);

return retval;

}

static int cortex_m_write_memory(struct target *target, target_addr_t address,

uint32_t size, uint32_t count, const uint8_t *buffer)

{

struct armv7m_common *armv7m = target_to_armv7m(target);

if (armv7m->arm.is_armv6m) {

/* armv6m does not handle unaligned memory access */

if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))

return ERROR_TARGET_UNALIGNED_ACCESS;

}

return mem_ap_write_buf(armv7m->debug_ap, buffer, size, count, address);

}

int mem_ap_write_buf(struct adiv5_ap *ap,

const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)

{

return mem_ap_write(ap, buffer, size, count, address, true);

}

/**

* Synchronous write of a block of memory, using a specific access size.

*

* @param ap The MEM-AP to access.

* @param buffer The data buffer to write. No particular alignment is assumed.

* @param size Which access size to use, in bytes. 1, 2 or 4.

* @param count The number of writes to do (in size units, not bytes).

* @param address Address to be written; it must be writable by the currently selected MEM-AP.

* @param addrinc Whether the target address should be increased for each write or not. This

* should normally be true, except when writing to e.g. a FIFO.

* @return ERROR_OK on success, otherwise an error code.

*/

static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count,

uint32_t address, bool addrinc)

{

struct adiv5_dap *dap = ap->dap;

size_t nbytes = size * count;

const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;

uint32_t csw_size;

uint32_t addr_xor;

int retval = ERROR_OK;

/* TI BE-32 Quirks mode:

* Writes on big-endian TMS570 behave very strangely. Observed behavior:

* size write address bytes written in order

* 4 TAR ^ 0 (val >> 24), (val >> 16), (val >> 8), (val)

* 2 TAR ^ 2 (val >> 8), (val)

* 1 TAR ^ 3 (val)

* For example, if you attempt to write a single byte to address 0, the processor

* will actually write a byte to address 3.

*

* To make writes of size < 4 work as expected, we xor a value with the address before

* setting the TAP, and we set the TAP after every transfer rather then relying on

* address increment. */

if (size == 4) {

csw_size = CSW_32BIT;

addr_xor = 0;

} else if (size == 2) {

csw_size = CSW_16BIT;

addr_xor = dap->ti_be_32_quirks ? 2 : 0;

} else if (size == 1) {

csw_size = CSW_8BIT;

addr_xor = dap->ti_be_32_quirks ? 3 : 0;

} else {

return ERROR_TARGET_UNALIGNED_ACCESS;

}

if (ap->unaligned_access_bad && (address % size != 0))

return ERROR_TARGET_UNALIGNED_ACCESS;

while (nbytes > 0) {

uint32_t this_size = size;

/* Select packed transfer if possible */

if (addrinc && ap->packed_transfers && nbytes >= 4

&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {

this_size = 4;

retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);

} else {

retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);

}

if (retval != ERROR_OK)

break;

retval = mem_ap_setup_tar(ap, address ^ addr_xor);

if (retval != ERROR_OK)

return retval;

/* How many source bytes each transfer will consume, and their location in the DRW,

* depends on the type of transfer and alignment. See ARM document IHI0031C. */

uint32_t outvalue = 0;

uint32_t drw_byte_idx = address;

if (dap->ti_be_32_quirks) {

switch (this_size) {

case 4:

outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor);

outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor);

outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor);

outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx & 3) ^ addr_xor);

break;

case 2:

outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (drw_byte_idx++ & 3) ^ addr_xor);

outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (drw_byte_idx & 3) ^ addr_xor);

break;

case 1:

outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (drw_byte_idx & 3) ^ addr_xor);

break;

}

} else {

switch (this_size) {

case 4:

outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);

outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);

/* fallthrough */

case 2:

outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);

/* fallthrough */

case 1:

outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);

}

}

nbytes -= this_size;

retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW, outvalue);

if (retval != ERROR_OK)

break;

mem_ap_update_tar_cache(ap);

if (addrinc)

address += this_size;

}

/* REVISIT: Might want to have a queued version of this function that does not run. */

if (retval == ERROR_OK)

retval = dap_run(dap);

if (retval != ERROR_OK) {

uint32_t tar;

if (mem_ap_read_tar(ap, &tar) == ERROR_OK)

LOG_ERROR("Failed to write memory at 0x%08"PRIx32, tar);

else

LOG_ERROR("Failed to write memory and, additionally, failed to find out where");

}

return retval;

}

MEM-AP这里我就不画图介绍了,对于我来说只要知道MEM-AP是如何帮助DAP访问到系统地址空间的原理就可以了,大家直接看源码实现去理解。大家想要知道更多细节可以参考ADIv5.0~ADIv5.2章节 7. The Memory Access Port (MEM-AP)

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8651

    浏览量

    361816
  • 调试器
    调试器
    +关注

    关注

    1

    文章

    288

    浏览量

    23409
  • 车载芯片
    车载芯片
    +关注

    关注

    0

    文章

    63

    浏览量

    14538
  • SWD
    SWD
    +关注

    关注

    1

    文章

    54

    浏览量

    11670
  • 调试接口
    调试接口
    +关注

    关注

    0

    文章

    10

    浏览量

    5051
收藏 人收藏

    评论

    相关推荐

    stm32w的下载调试方式包含了jtage,swd是否支持串口isp下载

    大侠 请支支招吧stm32w的下载调试方式包含了jtage,swd是否支持串口isp下载
    发表于 03-28 10:17

    调试器能用SWD下载,为什么有些调试器还要带一个虚拟串口?

    新手请教一下,淘宝买了个stlink能 运行SWD和JTAG,SWD下载。为什么有些其它的调试器在支持SWD的情况下还要带一个虚拟串口来
    发表于 08-07 11:46

    为什么STM32会禁止JTAG调试功能却保留SWD下载调试功能呢

    为什么STM32会禁止JTAG调试功能却保留SWD下载调试功能呢?
    发表于 11-25 08:56

    SWD和JTAG接口的含义和区别

    作为嵌入式软件工程师,下载调试器都应该知道,但真正了解SWD 和 JTAG接口的含义和区别吗
    发表于 12-10 07:24

    STLINK和JLINK使用SWD四线调试下载STM32的方法

    STLINK和JLINK使用SWD四线调试下载STM32的方法
    发表于 01-19 06:48

    SWD和传统的调试方式区别在哪

    SWD 和传统的调试方式区别 1. SWD 模式比 JTAG 在高速模式下面更加可靠。 在大数据量的情况下面 JTAG 下载程序会失败, 但是 SW
    发表于 01-26 06:10

    如何解决STM32禁用SWD调试接口后不能下载程序的问题?

    如何解决STM32禁用SWD调试接口后不能下载程序的问题?
    发表于 01-27 07:53

    JTAG接口如何转SWD接口_JTAG接口转SWD接口方法

    本文为大家介绍JTAG接口转SWD接口方法,利用此转换方式,可以简化板载调试接口(相应单片机应支持SWD调试)。
    发表于 01-11 10:23 3.1w次阅读
    JTAG接口如何转<b class='flag-5'>SWD</b>接口_JTAG接口转<b class='flag-5'>SWD</b>接口方法

    调试接口SWD和JTAG的区别

    作者 | strongerHuang 微信公众号 | strongerHuang 作为嵌入式工程师,下载调试器都应该知道,但你真正了解SWD
    的头像 发表于 10-27 09:29 1.6w次阅读
    <b class='flag-5'>调试</b>接口<b class='flag-5'>SWD</b>和JTAG的区别

    下载调试接口SWD和JTAG的区别

    作为嵌入式工程师,下载调试器都应该知道,但你真正了解SWD 和 JTAG 接口的含义和区别吗? 1、什么是
    的头像 发表于 11-28 11:44 3939次阅读

    stm32 SWD调试接口的使用

    SWD 和传统的调试方式区别    1. SWD 模式比 JTAG 在高速模式下面更加可靠。 在大数据量的情况下面 JTAG 下载程序会失败, 但是
    发表于 12-02 17:06 27次下载
    stm32 <b class='flag-5'>SWD</b><b class='flag-5'>调试</b>接口的使用

    解决STM32禁用SWD调试接口后不能下载程序的问题

    STM32的PA13(SWDIO)、PA14(SWCLK)这两个引脚为SWD调试接口,因为STM32默认把这两个接口当作了下载接口,所以如果程序中有用到这两个接口的任意一个(比如用来作为普通
    发表于 12-02 18:51 29次下载
    解决STM32禁用<b class='flag-5'>SWD</b><b class='flag-5'>调试</b>接口后不能<b class='flag-5'>下载</b>程序的问题

    SWD 仿真模式

    转自https://zhidao.baidu.com/question/15403504727290183871)SWD 仿真模式概念简述先所说 SWD 和传统的调试方式有什么不一样:首先给大家介绍
    发表于 12-29 19:52 5次下载
    <b class='flag-5'>SWD</b> 仿真模式

    华大芯片入坑系列-SWD调试

    华大芯片入坑系列-SWD调试这两天调自制的板子,发现可以使用离线编程器的SWD模式烧录,但是Jlink的SWD模式怎么也调不通,那就无法仿真,很糟心。后来询问厂家后,说这块芯片可能不支
    发表于 01-12 18:47 10次下载
    华大芯片入坑系列-<b class='flag-5'>SWD</b><b class='flag-5'>调试</b>

    简述SWD下载器通信协议底层原理

    基于Cortex-M内核的单片机,目前主流的下载接口就是JTAG和SWDSWD 和 JTAG引脚区别: **JTAG:** * **TDI:**
    发表于 02-20 16:05 2258次阅读
    简述<b class='flag-5'>SWD</b><b class='flag-5'>下载</b>器通信协议底层原理

    精选推荐

    更多
    • 文章
    • 资料
    • 帖子
    • 一期一会,中图仪器参加德国斯图加特Control展,共探质控创新技术

      中图仪器
      1天前
      255 阅读
    • OpenHarmony语言基础类库【@ohos.util.LightWeightMap (非线性容器LightWeightMap)】

      jf_46214456
      1天前
      499 阅读
    • 鸿蒙OpenHarmony【轻量系统 环境搭建】 (基于Hi3861开发板)

      jf_46214456
      1天前
      495 阅读
    • 频谱扩展(FSS)功能:FSS在现代 SMPS 设计中的优势及局限性

      eeDesign
      1天前
      362 阅读
    • HarmonyOS开发案例:【image、image-animator组件】

      jf_46214456
      1天前
      485 阅读
    • 一种开源的基于STM32的四轴飞行器代码+原理图

      z568581045
      2688KB
      1积分
      186下载
    • wisdom-advisor程序智能调整框架

      李晨灵
      2.42 MB
      免费
      0下载
    • Gryffin Web安全扫描平台

      1652711011.026500
      0.06 MB
      免费
      1下载
    • Gloo Kubernetes原生API网关

      王秀珍
      40.01 MB
      免费
      5下载
    • 用于将红外跟踪相机转换为白光闪光灯的白光LED PCB

      任凭风吹
      0.09 MB
      免费
      0下载
    • 基于 FPGA 的光纤混沌加密系统

      FPGA技术江湖
      2天前
      378 阅读
    • 使用DSP28377D外扩RAM写入一个地址数据相邻地址数据也会改变

      郑佳龙
      2天前
      727 阅读
    • rk3568跑屏幕共享app时出现系统重启

      jf_75620565
      2天前
      744 阅读
    • 信号线上串个小电阻干啥用的?

      回头太晚
      2天前
      721 阅读
    • 给我一个FPGA,可以撬起所有显示的接口和面板

      FPGA技术江湖
      3天前
      633 阅读

    推荐专栏

    更多

      资讯网国际商标起名孩子五行起名大全起公司名字大全免费简单柘城住一晚多少钱鼠年宝宝起名大全女孩杜姓起名李姓带木带火字起名肖姓男孩起名字给小孩起名字大全郭全网营销推广网站印刷网站制作公司注册三字起名商丘市和顺沁园春开封网站设计seo关键词购买双胞胎 起名鲤鱼王授权发起页域名农资小店起名医药行业网站建设口腔商标起名大全木命怎样起名今年猪宝宝起名白鹿原电影哪里可以免费观看wap网站建设seo优化软件工作原理于姓姑娘起名字免费结合八字公司起名九月九日忆山东兄弟古诗的意思乌鲁木齐seo少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

      资讯网 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化