Hercules (TMS570和 RM4x/RM5x)器件上发生的中止调试指南
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hercules (TMS570和 RM4x/RM5x)器件上发生的中止调试指南
什么是例外?
“异常”是使处理器暂时停止正常程序执行流程的事件,例如,为来自外设的中断提供服务。 在尝试处理异常之前、处理器会保留当前处理器状态的关键部分、以便在处理程序例程完成后恢复原始程序。
在实际情况下、例外情况主要分为以下几类:
什么是异常优先级顺序?
当多个异常同时发生时、它们将按固定的优先级顺序进行处理。 在用户程序继续执行之前、依次处理每个异常。 不可能同时发生所有异常。 例如、未定义指令和 SVC 异常是互斥的、因为它们都是通过执行一条指令来触发的。
由于数据中止异常的优先级高于 FIQ 异常、因此在处理 FIQ 之前实际上会注册数据中止。 进入数据中止处理程序、但随后立即将控制权传递给 FIQ 处理程序。 处理 FIQ 后、控制返回到数据中止处理程序。 这意味着、数据传输错误不会像在首先处理 FIQ 时那样逃避检测。
例外情况 | 优先级 |
---|---|
复位 | 1 (最高) |
数据中止 | 2. |
频率 | 3. |
IRQ | 4. |
预取中止 | 5. |
服务 | 6. |
未定义中止 | 6 (最低) |
进入所有异常时禁用 IRQ。 进入 FIQ 和复位时禁用 FIQ。
处理器对异常的响应是什么?
当一个异常发生时、ARM CPU:
将 CPSR 复制到 SPSR_中
设置适当的 CPSR 位
- 如果内核当前处于 Thumb 状态、则进入 ARM 状态
- 模式域位
- 中断禁用位(如果合适)
将返回地址存储在 LR_中
将 PC 设置为矢量地址
中止(DABT、PABT 和 UNDEF)之间的差异
如果数据是从受保护或有故障的存储器位置读取或写入的、则处理器会接收数据中止。 数据中止可以是同步的、也可以是异步的。
导致数据中止的指令位于 R14_ABT–8、这意味着指针指向导致中止的指令之外的两条指令。
如果处理器尝试执行来自受保护或有故障的存储器位置的指令、则会执行预取中止。 所有预取中止都是同步的。
导致数据中止的指令位于 R14_ABT–4。 LR_ABT 指向导致异常的指令之后的指令。 处理程序必须返回到 LR_ABT–4
当处理器遇到相应版本的 ARM 指令集中未定义的指令时、或者当 VFP 被禁用时、该指令用于 VFP 时、处理器会接收到未定义的指令异常。 未定义指令异常可用于模拟未定义的指令、或仅用于处理故障情况。
导致 UNDEF 中止的指令位于 R14_UND–4。
为什么预取中止和数据中止的返回地址不同?
对于预取、返回地址为:R14_abt =已中止指令的地址+ 4;对于数据中止、返回地址为:R14_abt =已中止指令的地址+ 8。
CPU 程序计数器(PC)在执行期间的特定点被更新。 在获取/解码/执行的不同阶段可能会发生异常。
在预取中止的情况下、只有当处理器实际尝试执行指令时才会发生异常。 在发出预取中止时、程序计数器不会更新、lr_ABT 指向导致异常的指令之后的指令。
在数据中止的情况下,指令正在执行,而指令的执行会导致异常。 当加载或存储指令尝试访问存储器时、程序计数器已更新。 lr_ABT 中存储的值(PC–4)指向生成异常的地址以外的第二条指令。
请参阅 ARM TRM 中的表3-4。 此表汇总了进入异常时保存在相关 R14中的 PC 值、以及 ARM 建议退出异常处理程序的指令。
如何知道存在中止?
当一个异常中断发生时、程序在异常向量表中被暂停。 如果在异常向量地址设置了断点、程序计数器在地址0x0C (PABT)、0x10 (DABT)或0x04 (UNDEF)处停止。
有三 个重要的 ARM Cortex-R4/R5寄存器可用于确认处理器的当前状态:
CPSR: CPSR 可用于验证处理器的当前模式。 CPSR 寄存器的 MODE 位可用于检查当前模式是否为中止。
M[4:0] 模式 10000 用户 10001 频率 10010. IRQ 10011. 监控器 10111. 中止 11011. 未定义 11111 系统 SPSR: SPSR 可被用来在进入异常前检查之前的模式。 例如,如果处理器从系统模式移至中止模式,则 SPSR 将模式显示为“系统”,而 CPSR 将模式显示为“中止”。 SPSR 寄存器的位定义与 CPSR 寄存器的位定义相同。
R14寄存器:R14寄存器用于查找导致同步中止的实际指令或函数调用。 触发异常的指令的实际地址将是 R14-x,其中的“x”取决于异常的类型。
有关详细信息、请参阅 Cortex-R4/R5 TRM: https://developer.arm.com/documentation/ddi0363/e/中的表3.4 "异常进入和退出"
未定义指令异常(UNDEF)
如果 CPU 不理解提取的指令、则可能会发生未定义的指令异常。
没有与此异常相关联的故障状态和故障地址寄存器;只有链路寄存器(R14_UND)提供相关信息。 导致 UNDEF 中止的指令位于 R14_UND–4。
7.1执行错误指令的可能原因
- 分支到已损坏或尚未使用所需函数初始化的 RAM 代码
- 堆栈上的返回地址已损坏(例如、堆栈溢出或弹出/推入计数不匹配)。
- 函数指针未初始化或损坏。
7.2处理未定义指令异常
- 通过检查停止地址来确认 CPU 控制是否滞留在未定义指令异常中。 如果地址为0x04、则控制在未定义指令异常中结束。
- 检查 R14_UND 寄存器的值。 R14_UND–X 提供导致未定义指令异常的指令的地址。 “X”取决于模式(对于 ARM 模式,X=4;对于 Thumb 模式,X=2)。
- 检查从 R14_UND - X 读取的地址处的指令
- 如果这是一条有效指令、请检查用于执行的模式(ARM 或 THUMB)是否正确(有效指令的模式不匹配可能导致未定义指令异常)。
- 如果指令无效、请检查地址是否损坏或 RAM 损坏。
7.3示例:
当 VFP 未使能时、处理器在执行浮点运算时接受未定义指令异常。 CPSR[4:0]=b11011。
导致 UNDEF 异常的指令是 位于0x00007430的 vldr s0、[R13、0xc]。
r14_UND = 0x00007434。 进入 UNDEF 中止前的模式为 SPSR_UND[4:0]=b11111 (系统模式)。
数据中止异常(DABT)
数据中止异常是对无效数据访问的响应。 如果异常被确认为数据中止、第一步是检查 Cortex-R CPU 的数据故障状态寄存器(DFSR)的值。
DFSR 寄存器 下图显示了 DFSR 寄存器位分配:
使用“S”位[10]和“状态位”[0:3]来了解数据中止的性质。 有关状态说明、请参阅下表:
SD 位
SD 位用于区分发生外部中止时的 AXI 解码或从器件错误。 该位仅对外部中止有效。 对于所有其他类型的中止、该位设置为零:
0 = AXI 解码错误(DECERR)或 AHB 错误导致了中止
1 = AXI 从器件错误(SLVERR)或不支持的独占访问导致了中止。 示例:使用 AHB 外设端口进行独占访问
RW 位
RW 位指示是读取访问还是写入访问导致了中止。
0 =读取访问导致了中止
1 =写入访问导致了中止
常见的数据中止类型
9.1后台: 对于 CPU 要访问的任何区域、存储器保护单元(MPU)设置必须正确。 如果 CPU 发出的地址不在定义的任何区域内并且 MPU 被启用、MPU 被硬接线以中止访问。 也就是说、对未映射到 MPU 中某个区域的地址的所有访问都会产生一个后台故障。
如果启用了后台区域且访问权限为特权、则不会发生后台故障。 一个 MPU
后台故障可能指示堆栈溢出、并通过分配更多堆栈来纠正。
9.2权限:当 MPU 设置阻止访问某个区域时、可能会发生这种情况。 例如、如果用户模式应用程序尝试访问 仅特权模式访问 区域、则会发生权限错误。
示例:
下面显示的写入操作触发了中止。 0x08028008处存储器位置的 MPU 设置为只读。
如下图所示、DFAR 寄存器显示触发数据中止的地址、因为它是 BTCM (使用 ADFSR 进行验证)处的权限错误(使用 DFSR 进行验证)。 R14_abt–8 (0x000070E0) 指向导致该访问的指令。 它显示了一个 STR 操作。
无法从具有器件或严格排序存储器类型属性的区域执行指令。
9.3同步/异步外部:当访问从 CPU 传输到 AXI/AHB 总线并遇到错误时、会发生这种情况。 这是数据中止时发生的最常见故障类型。 如果中止是同步的、则可以使用数据故障地址寄存器(DFAR)检查访问时导致数据中止的实际存储器地址、DFAR 保存发生同步中止时的故障地址。
9.4同步/异步 ECC:如果在 TCM 接口或高速缓存中检测到 ECC 错误、则会发生此情况。
10.1同步中止异常
通常,导致错误的“加载”区域指令或“存储”指令都是同步的。 DFAR 显示访问的目标地址。 此外、如上一节所述、 R14_abt–8 指向导致该访问的指令。
示例1:从存储器位置加载数据时出现2位 ECC 错误
下面显示的读取操作触发了中止。 0x08000010处的数据有2位 ECC 错误。
如上图所示、DFAR 寄存器显示触发数据中止的地址、因为它是 BTCM (使用 ADFSR 进行验证)处的同步 ECC 错误(使用 DFSR 进行验证)。 R14_abt–8 (0x00001F7C) 指向导致该访问的指令。 它显示了 LDM 操作。
示例2:将数据写入未实现的存储器位置
下面显示的写入操作触发了中止。 地址0x08100018超出有效存储器范围。
如上图所示、DFAR 寄存器显示触发数据中止的地址、因为它是同步中止(使用 DFSR 进行验证)。 R14_abt–8 (0x000070CC)指向导致该访问的指令。 它显示了一个 STR 操作。
图:发生数据中止之前
图:数据中止发生后
10.2异步故障
异步故障很难分析、因为我们无法跟踪导致中止的确切位置。 我们无法使用同步故障中使用的 DFAR 寄存器。 通常,导致错误的“存储”指令与具有“正常”或“设备”存储器属性的区域是异步的。
通过 DFSR 寄存器、我们可以检查状态位、SD 位和 RW 位。 SD:内部 AXI 解码错误、或外部 AXI 从器件错误 RW:指示读取或写入访问是否导致中止。有关详细信息、请阅读上面的第8节。
10.3如何跟踪导致异步数据中止的指令
- R14_abt–8是导致异常的指令附近的位置。
- 在 R14_abt–8附近找到一个可能导致异常的“存储”指令。
您应该为应用程序中访问的区域定义有效的 MPU 设置、以便 CPU 能够相应地访问该区域。 如果未定义所用区域的 MPU、则可能会导致 后台故障数据中止 异常、具体取决于使用的是特权访问还是非特权访问:
11.1对于特权访问:
如果 BR 位(SCTLR Arm 寄存器的位17)被置位、则默认存储器映射将用作任何未命中指定区域的访问的后台区域;如果 BR 位为0、则对于指定区域之外的任何访问都将发生后台故障异常。
11.2对于非特权级访问:
对于指定 MPU 区域之外的任何访问、都会发生后台故障异常。 为了防止此类访问发生后台故障异常、请将区域0定义为覆盖整个存储器映射的后台区域、然后将其用作定义 MPU 以外区域的后台区域。
当取指令导致错误时、会发生预取中止(PABT)异常。 当发生预取中止时、处理器会将预取指令标记为无效、但在执行指令之前不会接收到异常。 如果指令未被执行、例如、由于指令在流水线中时发生分支、则不会发生中止。 所有预取中止 都是同步的。
未定义指令中止和预取中止异常之间的区别在于、在预取情况下、CPU 无法从地址提取指令;在未定义指令异常中、CPU 不知道指令的作用是什么。
可以通过读取指令故障状态寄存器(IFSR)、指令故障地址寄存器(IFAR)和辅助指令故障状态寄存器(AIFSR)来分析预取中止的原因。
IFAR 包含 CPU 试图从中提取指令的地址。 IFAR 的内容对于预取中止始终有效、因为所有预取中止都是同步的。
AIFSR 记录有关故障性质和位置的附加信息、例如 ATCM (闪存)或 BTCM (SRAM)。
12.1预取中止的可能原因
MPU 设置不正确:如果根据 IFSR 状态发生了权限故障、则可能发生了以下情况之一:
- 正在从设置了“从不执行”属性的位置提取指令。
- 从 IFAR 读取的目标地址具有“Device”(设备)或“严格排序”存储器属性。 这意味着这些区域没有可执行代码。
读取指令时出现 ECC 错误:
读取指令时检测到 ECC 错误。 IFAR 寄存器提供导致检测到错误的地址。 辅助 IFSR 指示 ECC 错误的来源。
错误的返回地址或分支地址-返回地址已损坏-分支地址已损坏
12.2处理预取中止异常
通过检查 HALT 地址来确认 CPU 控件是否滞留在预取中止异常中。 如果偏移量为0x0C、则表示预取中止中的控制已结束。
检查 IFSR 和 IFAR 的状态以确定故障类型和导致中止的地址。
如果出现“权限”故障,请查找从 IFAR 寄存器读取的地址所在的区域。 可以检查该区域的代码区域是否存在 MPU 违规。 (从不执行设置、器件、严格排序存储器)。
12.3 预取中止异常示例
示例1:
以下示例演示了调试预取中止的步骤。 在这里、CPU 执行滞留在预取中止处理程序中。 相关的寄存器值如下:
SPSR_abt:0x8000011F: MODE–(11111)系统模式。 这意味着当中止被触发时、CPU 处于系统模式。
IFSR:0x0000000D:状态表示一个权限中止。 在 IFAR 中捕获的地址有效、并且是导致中止的实际地址。
IFAR:0x0013F800:该地址位于具有严格排序属性的 MPU 区域下。
示例2:
示例2的相关寄存器值如下:
SPSR_abt:0x600001D1: MODE–(10001) FIQ 模式。 这意味着当中止被触发时、CPU 处于 FIQ 模式。
IFSR:0x00000409:状态表示同步外部中止或 ECC 中止。 在 IFAR 中捕获的地址有效、并且是导致中止的实际地址。
IFAR: 0x00009000:此地址不包含有效指令,且 ECC 值错误。
AIFSR:0x00400000: 此状态表示错误源来自 ATCM (闪存)。