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.

[FAQ] [参考译文] [常见问题解答] TMS570LC4357:Hercules 器件上中止异常的疑难解答

Guru**** 1788580 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1029488/faq-tms570lc4357-troubleshooting-the-abort-exceptions-on-hercules-devices

器件型号:TMS570LC4357

Hercules (TMS570和 RM4x/RM5x)器件上发生的中止调试指南

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    1. 什么是例外?

      “异常”是使处理器暂时停止正常程序执行流程的事件,例如,为来自外设的中断提供服务。 在尝试处理异常之前、处理器会保留当前处理器状态的关键部分、以便在处理程序例程完成后恢复原始程序。

      在实际情况下、例外情况主要分为以下几类:

      • 中断(正常中断 IRQ 和快速中断 FIQ/NMI)
      • 中止(数据中止、预取中止)
      • 未定义指令(UNDEF)异常
    1. 什么是异常优先级顺序?

      当多个异常同时发生时、它们将按固定的优先级顺序进行处理。 在用户程序继续执行之前、依次处理每个异常。 不可能同时发生所有异常。 例如、未定义指令和 SVC 异常是互斥的、因为它们都是通过执行一条指令来触发的。

      由于数据中止异常的优先级高于 FIQ 异常、因此在处理 FIQ 之前实际上会注册数据中止。 进入数据中止处理程序、但随后立即将控制权传递给 FIQ 处理程序。 处理 FIQ 后、控制返回到数据中止处理程序。 这意味着、数据传输错误不会像在首先处理 FIQ 时那样逃避检测。

      例外情况 优先级
      复位 1 (最高)
      数据中止 2.
      频率 3.
      IRQ 4.
      预取中止 5.
      服务 6.
      未定义中止 6 (最低)

      进入所有异常时禁用 IRQ。 进入 FIQ 和复位时禁用 FIQ。

    1. 处理器对异常的响应是什么?

      当一个异常发生时、ARM CPU:

      • 将 CPSR 复制到 SPSR_中

      • 设置适当的 CPSR 位

        • 如果内核当前处于 Thumb 状态、则进入 ARM 状态
        • 模式域位
        • 中断禁用位(如果合适)
      • 将返回地址存储在 LR_中

      • 将 PC 设置为矢量地址

    1. 中止(DABT、PABT 和 UNDEF)之间的差异

      如果数据是从受保护或有故障的存储器位置读取或写入的、则处理器会接收数据中止。 数据中止可以是同步的、也可以是异步的。

      导致数据中止的指令位于 R14_ABT–8、这意味着指针指向导致中止的指令之外的两条指令。

      如果处理器尝试执行来自受保护或有故障的存储器位置的指令、则会执行预取中止。 所有预取中止都是同步的。

      导致数据中止的指令位于 R14_ABT–4。 LR_ABT 指向导致异常的指令之后的指令。 处理程序必须返回到 LR_ABT–4

      当处理器遇到相应版本的 ARM 指令集中未定义的指令时、或者当 VFP 被禁用时、该指令用于 VFP 时、处理器会接收到未定义的指令异常。 未定义指令异常可用于模拟未定义的指令、或仅用于处理故障情况。

      导致 UNDEF 中止的指令位于 R14_UND–4。

    1. 为什么预取中止和数据中止的返回地址不同?

      对于预取、返回地址为:R14_abt =已中止指令的地址+ 4;对于数据中止、返回地址为:R14_abt =已中止指令的地址+ 8。

      CPU 程序计数器(PC)在执行期间的特定点被更新。 在获取/解码/执行的不同阶段可能会发生异常。

      在预取中止的情况下、只有当处理器实际尝试执行指令时才会发生异常。 在发出预取中止时、程序计数器不会更新、lr_ABT 指向导致异常的指令之后的指令。

      在数据中止的情况下,指令正在执行,而指令的执行会导致异常。 当加载或存储指令尝试访问存储器时、程序计数器已更新。  lr_ABT 中存储的值(PC–4)指向生成异常的地址以外的第二条指令。

      请参阅 ARM TRM 中的表3-4。 此表汇总了进入异常时保存在相关 R14中的 PC 值、以及 ARM 建议退出异常处理程序的指令。

    1. 如何知道存在中止?

      当一个异常中断发生时、程序在异常向量表中被暂停。 如果在异常向量地址设置了断点、程序计数器在地址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 "异常进入和退出"

    1. 未定义指令异常(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 读取的地址处的指令
        1. 如果这是一条有效指令、请检查用于执行的模式(ARM 或 THUMB)是否正确(有效指令的模式不匹配可能导致未定义指令异常)。
        2. 如果指令无效、请检查地址是否损坏或 RAM 损坏。

      7.3示例:

      当 VFP 未使能时、处理器在执行浮点运算时接受未定义指令异常。 CPSR[4:0]=b11011。

      导致 UNDEF 异常的指令是  位于0x00007430的 vldr s0、[R13、0xc]。

    r14_UND = 0x00007434。 进入 UNDEF 中止前的模式为 SPSR_UND[4:0]=b11111 (系统模式)。

    1. 数据中止异常(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 =写入访问导致了中止

    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 错误、则会发生此情况。

    1. 数据中止异常示例

    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附近找到一个可能导致异常的“存储”指令。
    1. 由于 MPU 问题导致数据中止

    您应该为应用程序中访问的区域定义有效的 MPU 设置、以便 CPU 能够相应地访问该区域。 如果未定义所用区域的 MPU、则可能会导致 后台故障数据中止 异常、具体取决于使用的是特权访问还是非特权访问:

    11.1对于特权访问:

    如果 BR 位(SCTLR Arm 寄存器的位17)被置位、则默认存储器映射将用作任何未命中指定区域的访问的后台区域;如果 BR 位为0、则对于指定区域之外的任何访问都将发生后台故障异常。

    11.2对于非特权级访问:

    对于指定 MPU 区域之外的任何访问、都会发生后台故障异常。 为了防止此类访问发生后台故障异常、请将区域0定义为覆盖整个存储器映射的后台区域、然后将其用作定义 MPU 以外区域的后台区域。

    1. 预取中止异常

    当取指令导致错误时、会发生预取中止(PABT)异常。 当发生预取中止时、处理器会将预取指令标记为无效、但在执行指令之前不会接收到异常。 如果指令未被执行、例如、由于指令在流水线中时发生分支、则不会发生中止。 所有预取中止 都是同步的。

    未定义指令中止和预取中止异常之间的区别在于、在预取情况下、CPU 无法从地址提取指令;在未定义指令异常中、CPU 不知道指令的作用是什么。

    可以通过读取指令故障状态寄存器(IFSR)、指令故障地址寄存器(IFAR)和辅助指令故障状态寄存器(AIFSR)来分析预取中止的原因。

    IFAR 包含 CPU 试图从中提取指令的地址。 IFAR 的内容对于预取中止始终有效、因为所有预取中止都是同步的。

    AIFSR 记录有关故障性质和位置的附加信息、例如 ATCM (闪存)或 BTCM (SRAM)。

    12.1预取中止的可能原因

    • MPU 设置不正确:如果根据 IFSR 状态发生了权限故障、则可能发生了以下情况之一:

      1. 正在从设置了“从不执行”属性的位置提取指令。
      2. 从 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 (闪存)。