61、Cortex-M处理器调试组件与寄存器详解

Cortex-M处理器调试组件与寄存器详解

1. Cortex-M微控制器的ROM表

现代基于Cortex - M的微控制器大多有两级ROM表:系统级(主)和处理器级(次)。主ROM表中的一个条目指向Cortex - M处理器内的次ROM表,次ROM表为处理器的调试组件(如断点单元、数据观察点和跟踪单元等)提供条目。所有调试组件和次ROM表都有一系列ID值,这使调试器能确定哪些组件可用。在某些情况下,会存在两级以上的ROM表,此时Cortex - M处理器内的ROM表可能位于更深层次(如第三级)的ROM表查找中。

2. 调试组件概述

Cortex - M处理器内有多个调试组件,Cortex - M23和Cortex - M33处理器的调试组件如下:
- 处理器内核内的调试控制块
- 断点单元(BPU,历史原因也称为闪存补丁和断点单元“FPB”)
- 数据观察点和跟踪(DWT)单元(Cortex - M23的DWT无跟踪功能)
- 仅Armv8 - M主线处理器可用的用于软件生成跟踪激励的仪器跟踪宏单元(ITM)
- 用于实时指令跟踪的嵌入式跟踪宏单元(ETM)
- 带缓冲区的指令跟踪微跟踪缓冲区(MTB)
- 多核系统中用于调试同步的交叉触发接口(CTI)
- 用于输出跟踪数据的跟踪端口接口单元(TPIU)

一般来说,应用开发者无需详细了解调试组件,但从高层次理解其工作原理是有用的,例如在某些调试功能未按预期工作时进行故障排除。对于芯片设计师,了解调试系统的工作原理很重要,有助于为芯片实现调试支持。

多数情况下,调试组件(如BPU、DWT和ETM)由调试工具管理,软件不直接访问。在Cortex - M23处理器中,调试寄存器仅调试器可访问,处理器上运行的软件无法访问调试组件;而在Cortex - M33处理器中,处理器上运行的软件可访问调试寄存器,以支持使用调试监视器功能的调试代理。

不过,软件开发者可能希望在软件中直接访问某些调试功能的情况有:
- 调试时在代码中添加软件断点
- 安全特权软件使用调试控制块中的DAUTHCTRL寄存器时,可覆盖安全调试认证设置
- 使用ITM在软件中生成跟踪激励(仅Armv8 - M主线处理器可用,Armv8 - M基线不可用)
- 集成用于监视器模式调试的调试代理(仅Armv8 - M主线处理器可用,Armv8 - M基线不可用)

除非特别说明,Armv8.0 - M中调试组件的寄存器仅在特权状态下访问,且仅使用32位传输。Armv8.1 - M架构中可允许非特权访问调试组件,但不在此讨论。

3. 处理器核心中的调试支持寄存器

处理器核心中有几个用于调试控制功能的寄存器:
- 用于停止模式调试的控制寄存器(DHCSR),处理停止和单步执行
- 用于监视器模式调试的控制寄存器(DEMCR),处理调试监视器异常管理和使用调试监视器的单步执行
- 用于访问处理器内各种寄存器(如寄存器组中的寄存器、特殊寄存器)的一对寄存器(DCRSR和DCRDR)
- 用于向量捕获调试事件处理的控制寄存器(DEMCR)
- 用于调试认证管理的控制寄存器(DAUTHCTRL),这是Armv8 - M中的新寄存器

调试寄存器在安全状态之间不进行存储体切换,但这些调试寄存器中的一些位字段仅在安全状态下可访问。处理器的调试控制块中有六个寄存器,如下表所示:
| 地址 (NS别名) | 名称 | 类型 | 复位值 |
| — | — | — | — |
| 0xE000EDF0 (0xE002EDF0) | 调试停止控制状态寄存器 (DHCSR) | R/W | 0x00000000 |
| 0xE000EDF4 (0xE002EDF4) | 调试核心寄存器选择器寄存器 (DCRSR) | W | – |
| 0xE000EDF8 (0xE002EDF8) | 调试核心寄存器数据寄存器 (DCRDR) | R/W | – |
| 0xE000EDFC (0xE002EDFC) | 调试异常和监视器控制寄存器 (DEMCR) | R/W | 0x00000000 |
| 0xE000EE04 (0xE002EE04) | 调试认证控制寄存器 (DAUTHCTRL)(仅安全特权软件可访问,调试器不可访问) | R/W | 0x0 |
| 0xE000EE08 (0xE002EE08) | 调试安全控制和状态寄存器 (DSCSR) | R/W | 0x00020000 |

此外,调试标识块和系统控制空间中还有其他用于调试功能的寄存器,详情如下表:
| 地址 (NS别名) | 名称 | 类型 | 复位值 |
| — | — | — | — |
| 0xE000EFB8 (0xE002EFB8) | 调试认证状态寄存器 (DAUTHSTATUS)(允许调试器/软件确定调试认证状态,Armv8 - M新增) | RO | 实现定义 |
| 0xE000ED30 (0xE002ED30) | 调试故障状态寄存器 (DFSR)(允许调试器/软件确定触发停止或调试监视器异常的事件) | RW | 0x00 |

多数情况下,应用软件无需访问这些寄存器(除非创建用于监视器模式调试的调试代理)。若软件修改这些寄存器,可能会给调试工具带来问题。例如,连接到设备的调试器使用DHCSR,若软件读取该寄存器,读取操作可能会改变其某些状态位。因此,应用代码应避免访问DHCSR,以免给调试器工具造成问题。

DHCSR的相关信息如下表:
| 位 | 名称 | 类型 | 复位值 | 描述 |
| — | — | — | — | — |
| 31:16 | KEY | W | – | 调试密钥,需写入值0xA05F才能写入该寄存器,否则写入将被忽略 |
| 26 | S_RESTART_ST | R | – | 指示处理器执行已重新启动(非停止),读取时清除该位 |
| 25 | S_RESET_ST | R | – | 核心已复位或正在复位,读取时清除该位 |
| 24 | S_RETIRE_ST | R | – | 自上次读取后指令已完成,读取时清除该位 |
| 20 | S_SDE | R | – | 安全调试启用(若为1,允许安全侵入式调试),未实现TrustZone时该位始终为0 |
| 19 | S_LOCKUP | R | – | 该位为1时,核心处于锁定状态 |
| 18 | S_SLEEP | R | – | 该位为1时,核心处于睡眠模式 |
| 17 | S_HALT | R | – | 该位为1时,核心停止 |
| 16 | S_REGRDY | R | – | 寄存器读写操作已完成 |
| 15:6 | Reserved | – | – | 保留 |
| 5 | C_SNAPSTALL | R/W | 0a | 用于打破停滞的内存访问(仅Armv8 - M主线可用,Cortex - M23不可用),若处理器因停滞传输卡住,即使收到停止请求也可能无法进入停止模式,C_SNAPSTALL可放弃传输,强制处理器进入调试状态 |
| 4 | Reserved | – | – | 保留 |
| 3 | C_MASKINTS | R/W | – | 单步执行时屏蔽中断,仅在处理器停止时可修改 |
| 2 | C_STEP | R/W | 0a | 单步执行处理器,仅在C_DEBUGEN设置时有效 |
| 1 | C_HALT | R/W | 0 | 停止处理器核心,仅在C_DEBUGEN设置时有效 |
| 0 | C_DEBUGEN | R/W | 0a | 启用停止模式调试 |

注:DHCSR的位5、2和0仅通过上电复位复位,位1可由上电复位(冷复位)和系统复位复位。Armv8.1 - M架构中为该寄存器添加了额外位字段,此处未涵盖。

要进入停止模式,必须设置调试停止控制和状态寄存器(DHCSR)中的C_DEBUGEN位。由于该位只能通过调试器连接,经调试访问端口(DAP)编程,因此无调试器无法停止Cortex - M处理器。设置C_DEBUGEN后,可通过设置DHCSR中的C_HALT位停止核心。C_HALT位可由调试器或(若为Armv8 - M主线处理器)处理器上运行的软件设置,而C_DEBUGEN位仅调试器可访问。

DHCSR的位字段定义在读写操作中不同。写操作时,位31到16需使用调试键值;读操作时,无调试键,上半字的返回值包含状态位。

当处理器停止(由S_HALT指示)时,调试器可使用DCRSR和DCRDR访问处理器的寄存器组和特殊寄存器。使用这些寄存器读取寄存器内容的步骤如下:
1. 确保处理器停止
2. 向DCRSR写入,将位16设置为0,表示读操作
3. 轮询直到DHCSR(0xE000EDF0)中的S_REGRDY位为1
4. 读取DCRDR以获取寄存器内容

写入寄存器的操作步骤类似:
1. 确保处理器停止
2. 向DCRDR写入数据值
3. 向DCRSR写入,将位16设置为1,表示写操作
4. 轮询直到DHCSR(0xE000EDF0)中的S_REGRDY位为1

DCRSR和DCRDR寄存器仅在停止模式调试期间传输寄存器值。使用调试监视器处理程序进行调试时,部分寄存器内容可从堆栈内存访问,其他可在监视器异常处理程序内直接访问。

DCRDR若有合适的函数库和调试器支持,也可用于半主机。例如,应用执行printf语句时,文本输出可通过多个putc(放置字符)函数调用生成。putc函数调用可实现为首先将输出字符和状态存储到DCRDR,然后触发调试模式。处理器停止时,调试器检测到处理器停止并收集输出字符进行显示。不过,此操作需要处理器停止,而使用ITM的printf解决方案无此要求。

调试以监视器模式进行时,调试代理软件需使用DEMCR(调试异常和监视器控制寄存器)提供的功能。DEMCR的相关信息如下表:
| 位 | 名称 | 类型 | 复位值 | 描述 |
| — | — | — | — | — |
| 24 | TRCENA | R/W | 0a | 跟踪系统启用,使用DWT、ETM、ITM和TPIU前必须将该位设置为1 |
| 23:20 | Reserved | – | – | 保留 |
| 20 | SDME | RO | – | 安全调试监视器启用,该位状态取决于调试认证设置,确定调试监视器异常应针对安全(1)还是非安全状态(0) |
| 19 | MON_REQ | R/W | 0 | 指示调试监视器由手动挂起请求而非硬件调试事件引起 |
| 18 | MON_STEP | R/W | 0 | 单步执行处理器,仅在MON_EN设置时有效 |
| 17 | MON_PEND | R/W | 0 | 挂起监视器异常请求,优先级允许时核心将进入监视器异常 |
| 16 | MON_EN | R/W | 0 | 启用调试监视器异常 |
| 15:12 | Reserved | – | – | 保留 |
| 11 | VC_SFERR | R/W | 0a | 安全故障调试陷阱 |
| 10 | VC_HARDERR | R/W | 0a | 硬故障调试陷阱 |
| 9 | VC_INTERR | R/W | 0a | 中断/异常服务错误调试陷阱 |
| 8 | VC_BUSERR | R/W | 0a | 总线故障调试陷阱 |
| 7 | VC_STATERR | R/W | 0a | 使用故障状态错误调试陷阱 |
| 6 | VC_CHKERR | R/W | 0a | 使用故障检查错误调试陷阱,启用由未对齐检查或除零检查引起的使用故障调试陷阱 |
| 5 | VC_NOCPERR | R/W | 0a | 因访问无效协处理器(即NOCP错误)引起的使用故障调试陷阱 |
| 4 | VC_MMERR | R/W | 0a | 内存管理故障调试陷阱 |
| 3:1 | Reserved | – | – | 保留 |
| 0 | VC_CORERESET | R/W | 0a | 核心复位调试陷阱 |

注:DEMCR的位16 - 19由系统复位和上电复位复位,其他位仅由上电复位复位;位4 - 9和位11在Armv8 - M基线中不可用;Armv8.1 - M架构中添加了额外位字段,此处未涵盖。

DEMCR寄存器用于控制向量捕获功能和调试监视器异常,并启用跟踪子系统。在使用任何跟踪功能(如指令跟踪、数据跟踪)或访问任何跟踪组件(如DWT、ITM、ETM和TPIU)之前,必须将TRCENA位设置为1。

在Armv8 - M中,TrustZone支持的添加为安全增加了额外的调试管理。调试认证控制寄存器(CoreDebug->DAUTHCTRL)使安全特权软件能够覆盖SPIDEN和SPNIDEN输入信号的设置,相关信息如下表:
| 位 | 名称 | 类型 | 复位值 | 描述 |
| — | — | — | — | — |
| 31:4 | Reserved | – | – | 保留 |
| 3 | INTSPNIDEN | R/W | 0 | 当SPNIDENSEL设置为1时,INTSPNIDEN覆盖SPNIDEN设置 |
| 2 | SPNIDENSEL | R/W | 0 | |
| 1 | INTSPIDEN | R/W | 0 | 当SPIDENSEL设置为1时,INTSPNIDEN覆盖SPIDEN设置 |
| 0 | SPIDENSEL | R/W | 0 | |

调试器和软件可使用调试认证状态寄存器(DAUTHSTATUS)确定调试认证状态,相关信息如下表:
| 位 | 名称 | 类型 | 描述 |
| — | — | — | — |
| 31:8 | Reserved | – | 保留 |
| 7:6 | SNID | RO | 安全非侵入式调试:00 - TrustZone安全扩展未实现;01 - 保留;10 - 安全非侵入式调试禁用(TrustZone已实现);11 - 安全非侵入式调试允许(TrustZone已实现) |
| 5:4 | SID | RO | 安全侵入式调试:00 - TrustZone安全扩展未实现;01 - 保留;10 - 安全侵入式调试禁用(TrustZone已实现);11 - 安全侵入式调试允许(TrustZone已实现) |
| 3:2 | NSNID | RO | 非安全非侵入式调试:0 - 保留;10 - 非侵入式调试禁用;11 - 非侵入式调试允许 |
| 1:0 | NSID | RO | 非安全侵入式调试:0
- 保留;10 - 侵入式调试禁用;11 - 侵入式调试允许 |

实现TrustZone时,许多资源在安全状态之间进行存储体切换。处理针对系统控制空间(SCS)地址范围的访问时,调试器生成的访问和软件生成的访问处理方式不同。软件生成的访问中,同一地址可能根据处理器当时的安全状态指向安全或非安全资源;而调试访问不能使用此方法,因为调试时处理器可能处于安全或非安全状态。为解决此问题,实现了调试安全控制和状态寄存器(DSCSR),使调试器无论处理器的安全状态如何,都能控制调试访问视图,相关信息如下表:
| 位 | 名称 | 类型 | 描述 |
| — | — | — | — |
| 31:18 | Reserved | – | 保留 |
| 17 | CDSKEY | W/read as 1 | 当前域安全(CDS)写启用密钥:更新CDS位(即位16)时该位应为0。写入DSCSR时,若CDSKEY为1,对CDS的写入将被忽略,防止处理器运行且写入DSCSR时意外更改CDS位 |
| 16 | CDS | R/W | 当前域安全,允许调试器检查/更改处理器的当前安全状态:0 - 非安全,1 - 安全。写入CDS时,若CDSKEY为1,对CDS的写入将被忽略 |
| 15:2 | Reserved | – | 保留 |
| 1 | SBRSEL | R/W | 安全存储体寄存器选择(仅在DSCSR.SBRSELEN设置为1时使用):0 - 非安全视图;1 - 安全视图 |
| 0 | SBRSELEN | R/W | 安全存储体寄存器选择启用。若DSCSR.SBRSELEN位为1,SBRSEL确定调试访问应针对安全还是非安全寄存器;若不为1,处理器的当前安全状态确定调试访问应查看安全还是非安全视图 |

4. 调试操作流程总结

为了更清晰地理解调试过程,下面将调试过程中的关键操作流程进行总结,包括进入停止模式、读取寄存器内容、写入寄存器内容等操作,以mermaid流程图的形式呈现:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B{是否有调试器连接}:::decision
    B -- 是 --> C(设置DHCSR的C_DEBUGEN位):::process
    B -- 否 --> D(无法进入调试模式):::process
    C --> E{是否为Armv8 - M主线处理器}:::decision
    E -- 是 --> F(可由软件或调试器设置C_HALT位):::process
    E -- 否 --> G(仅调试器可设置C_HALT位):::process
    F --> H(处理器停止):::process
    G --> H
    H --> I{读取寄存器内容?}:::decision
    I -- 是 --> J(确保处理器停止):::process
    J --> K(向DCRSR写入,位16设为0):::process
    K --> L(轮询S_REGRDY位为1):::process
    L --> M(读取DCRDR获取内容):::process
    I -- 否 --> N{写入寄存器内容?}:::decision
    N -- 是 --> O(确保处理器停止):::process
    O --> P(向DCRDR写入数据):::process
    P --> Q(向DCRSR写入,位16设为1):::process
    Q --> R(轮询S_REGRDY位为1):::process
    R --> S(写入完成):::process
    N -- 否 --> T([结束]):::startend
    M --> T
    S --> T
5. 调试组件使用场景分析

以下是不同调试组件在实际使用中的常见场景分析:

调试组件 使用场景 操作步骤
BPU(FPB) 调试时设置软件断点 1. 确保调试器连接并进入调试模式
2. 通过调试器在代码指定位置设置断点
DWT 数据观察和跟踪 1. 确保DEMCR的TRCENA位设置为1以启用跟踪系统
2. 配置DWT相关寄存器以设置观察点和跟踪功能
ITM 软件生成跟踪激励 1. 仅适用于Armv8 - M主线处理器
2. 编写代码使用ITM相关寄存器生成跟踪数据
ETM 实时指令跟踪 1. 确保DEMCR的TRCENA位设置为1以启用跟踪系统
2. 配置ETM相关寄存器以开始实时指令跟踪
MTB 带缓冲区的指令跟踪 1. 确保DEMCR的TRCENA位设置为1以启用跟踪系统
2. 配置MTB相关寄存器以设置缓冲区和跟踪功能
CTI 多核系统调试同步 1. 在多核系统中,确保各核的CTI相关寄存器配置一致
2. 通过CTI进行调试同步操作
TPIU 输出跟踪数据 1. 确保DEMCR的TRCENA位设置为1以启用跟踪系统
2. 配置TPIU相关寄存器以输出跟踪数据到指定接口
6. 调试注意事项

在进行Cortex - M处理器调试时,需要注意以下几点:

  • 寄存器访问权限 :不同寄存器在不同安全状态和架构版本下有不同的访问权限,如Armv8.0 - M中调试组件的寄存器仅在特权状态下访问,且仅使用32位传输;部分寄存器如DAUTHCTRL仅安全特权软件可访问。
  • 复位影响 :不同寄存器的复位方式不同,如DHCSR的位5、2和0仅通过上电复位复位,位1可由上电复位(冷复位)和系统复位复位;DEMCR的位16 - 19由系统复位和上电复位复位,其他位仅由上电复位复位。
  • 调试键使用 :在写入某些寄存器(如DHCSR)时,需要使用调试键,如写入DHCSR的KEY字段需写入值0xA05F,否则写入将被忽略。
  • 避免软件修改 :应用软件应避免随意修改调试相关寄存器,以免给调试工具带来问题,如避免访问DHCSR,防止改变其状态位影响调试器工作。
7. 总结

Cortex - M处理器的调试组件和寄存器是实现高效调试的关键。通过了解ROM表的结构、调试组件的功能、调试支持寄存器的作用以及相关的操作流程和注意事项,可以更好地进行处理器的调试工作。无论是芯片设计师在实现调试支持,还是开发者在进行软件调试,都需要深入掌握这些知识,以确保调试工作的顺利进行。同时,合理利用调试组件和寄存器,可以提高调试效率,快速定位和解决问题,提升开发质量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值