Part Number:TMS570LC4357
Hercules(TMS570 和 RM4x/RM5x)器件上发生的中止调试指南
Annie Liu:
1 什么是异常?
“异常”是一个事件,它使处理器暂时停止正常的程序执行流程,例如为来自外设的中断提供服务。在尝试处理异常之前,处理器会保留当前处理器状态的关键部分,以便在处理程序例程完成时原始程序能够恢复。
在实际情况中,异常主要可以分为以下几类:
中断(正常中断 IRQ 和快速中断 FIQ/NMI)
中止(数据中止、预取中止)
未定义指令 (UNDEF) 异常2 什么是异常优先级顺序?
当多个异常同时发生时,系统会按照固定的优先级顺序来处理这些异常。系统依次处理每个异常,然后再继续执行用户程序。并非所有异常都会同时发生。例如,未定义指令和 SVC 异常是互斥的,因为它们都是通过执行指令触发的。
由于数据中止异常的优先级高于 FIQ 异常,因此在处理 FIQ 之前实际上会注册数据中止。然后会进入数据中止处理程序,但随后会立即将控制权传递给 FIQ 处理程序。处理 FIQ 后,将控制权返回给数据中止处理程序。这意味着数据传输错误不会像在首先处理 FIQ 时那样无法被检测到。
异常
优先级
复位
1 (最高)
数据中止
2
FIQ
3
IRQ
4
预取中止
5
SVC
6
未定义中止
6(最低)
在进入所有异常时禁用 IRQ。在进入 FIQ 和复位时禁用 FIQ。
3 处理器对异常有何响应?
发生异常时,ARM CPU:
将 CPSR 复制到 SPSR_<模式> 中
设置相应的 CPSR 位如果内核当前处于 Thumb 状态,则进入 ARM 状态
模式字段位
中断禁用位(如果适用)将返回地址存储在 LR_<模式> 中
将 PC 设置为矢量地址4 中止(DABT、PABT 和 UNDEF)之间的差异
如果从受保护或有故障的存储位置读取数据或向其中写入数据,则处理器会接收到数据中止异常。数据中止可以是同步的,也可以是异步的。
导致数据中止的指令位于 R14_ABT – 8,这意味着指针指向导致中止的指令之后的两条指令。
如果处理器尝试执行来自受保护或有故障的存储器位置的指令,则会接收到预取中止异常。所有预取中止都是同步的。
导致数据中止的指令位于 R14_ABT – 4。lr_ABT 指向导致异常的指令的下一条指令。处理程序必须返回到 lr_ABT – 4
当处理器遇到相应版本的 ARM 指令集中未定义的指令或者在 VFP 被禁用时用于 VFP 的指令时,处理器会接收到未定义指令异常。未定义指令异常可用于模拟未定义的指令,或仅用于处理故障情况。
导致 UNDEF 中止的指令位于 R14_und – 4。
5 预取中止和数据中止的返回地址为何不同?
对于预取,返回地址为:R14_abt = 已中止指令的地址 + 4;对于数据中止,返回地址为:R14_abt = 已中止指令的地址 + 8。
CPU 程序计数器 (PC) 会在执行期间的特定点更新。在提取/解码/执行的不同阶段都可能会发生异常。
对于预取中止,只有当处理器实际尝试执行指令时才会发生此异常。在发出预取中止命令时不会更新程序计数器,lr_ABT 指向导致异常的指令的下一条指令。
对于数据中止,指令正在执行并且指令的执行才导致出现此异常。当加载或存储指令尝试访问存储器时,程序计数器已更新。lr_ABT 中存储的值 (pc – 4) 指向生成异常的地址后的第二条指令。
请参阅 ARM TRM 中的表 3-4。该表总结了进入异常时相关的 R14 中保存的 PC 值以及 ARM 建议的用于退出异常处理程序的指令。
6 我如何知道存在中止?
发生中止时,程序会在异常向量表处停止。如果在异常向量地址处设置了断点,程序计数器会在地址 0x0C (PABT)、0x10 (DABT) 或 0x04 (UNDEF) 处停止。
有三个重要的 ARM Cortex-R4/R5 寄存器可用于确认处理器的当前状态:
CPSR:CPSR 可用于验证处理器的当前模式。CPSR 寄存器的模式位可用于检查当前模式是否为中止。
M[4:0]
模式
10000
用户
10001
FIQ
10010
IRQ
10011
管理
10111
中止
11011
未定义
11111
系统
SPSR:SPSR 可用于检查进入异常之前的模式。例如,如果处理器从系统模式转换至中止模式,则 SPSR 将模式显示为“系统”,而 CPSR 将模式显示为“中止”。SPSR 寄存器的位定义与 CPSR 寄存器的位定义相同。
R14 寄存器:R14 寄存器用于查找导致同步中止的实际指令或函数调用。触发异常的指令的实际地址为 R14 – x,其中“x”取决于异常的类型。
有关详细信息、请参阅 Cortex-R4/R5 TRM 中的表 3.4“异常进入和退出”:https://developer.arm.com/documentation/ddi0363/e/
7 未定义指令异常 (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 读取的地址处的指令。a 如果该指令有效,则检查用于执行的模式(ARM 或 THUMB)是否正确(有效指令的模式不匹配可能会导致未定义指令异常)。
b 如果指令无效,则检查地址或 RAM 是否损坏。
7.3 示例:
如果 VFP 未启用,则在执行浮点运算时处理器会接收到未定义指令异常。CPSR[4:0] = b11011。
导致 UNDEF 异常的指令是位于 0x00007430 的 vldr s0, [r13, 0xc]。
r14_UND = 0x00007434。进入 UNDEF 中止前的模式为 SPSR_UND[4:0] = b11111(系统模式)。
8 数据中止异常 (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 常见的数据中止类型
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 数据中止异常示例
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 附近的一个“存储”指令,该指令可能会导致异常。11 由于 MPU 问题而导致的数据中止
您应该为应用中访问的区域定义有效的 MPU 设置,以便 CPU 能够相应地访问该区域。如果您未定义所用区域的 MPU,该 MPU 可能会导致后台故障数据中止异常,具体取决于使用的是特权访问还是非特权访问:
11.1 对于特权访问:
如果 BR 位(SCTLR Arm 寄存器的第 17 位)被置位,则默认存储器映射将用作任何未命中指定区域的访问的后台区域;如果 BR 位为 0,则对于指定区域之外的任何访问都将发生后台故障异常。
11.2 对于非特权访问:
对于指定 MPU 区域之外的任何访问,都会发生后台故障异常。为了防止针对此类访问发生后台故障异常,请将区域 0 定义为涵盖整个存储器映射的后台区域,然后将其用作定义的 MPU 以外区域的后台区域。
12 预取中止异常
在指令提取导致错误时会发生预取中止 (PABT) 异常。当发生预取中止时,处理器将预取指令标记为无效,但在要执行指令之前不会接收到异常。如果未执行指令,例如因为指令在流水线中时产生分支,则不会发生中止。所有预取中止都是同步的。
未定义指令中止异常和预取中止异常的区别在于:对于预取,CPU 无法从地址中提取指令;对于未定义指令异常,CPU 不知道指令的功能是什么。
可以通过读取指令故障状态寄存器 (IFSR)、指令故障地址寄存器 (IFAR) 和辅助指令故障状态寄存器 (AIFSR) 来分析预取中止的原因。
IFAR 包含 CPU 尝试从中提取指令的地址。IFAR 的内容对于预取中止始终有效,因为所有预取中止都是同步的。
AIFSR 记录有关故障性质和位置的附加信息,例如 ATCM(闪存)或 BTCM (SRAM)。
12.1 预取中止的可能原因
MPU 设置不正确:如果基于 IFSR 状态发生了权限故障,则可能发生了以下情况之一:
正在从设置了“禁止执行”属性的位置提取指令。
从 IFAR 读取的目标地址具有“器件”或“严格排序”存储器属性。这意味着这些区域没有可执行代码。读取指令时出现 ECC 错误:
读取指令时检测到 ECC 错误。IFAR 寄存器提供导致检测到错误的地址。辅助 IFSR 指示 ECC 错误的来源。
返回地址或分支地址错误 – 返回地址损坏 – 分支地址损坏
12.2 处理预取中止异常
可以通过检查停止地址来确认 CPU 控制权是否滞留在预取中止异常中。如果偏移量为 0x0C,则表示预取中止中的控制权已结束。
检查 IFSR 和 IFAR 中的状态,以确定故障类型和导致中止的地址。对于“权限”故障,请找到从 IFAR 寄存器读取的地址所在的区域。可以检查该区域中是否存在针对代码区域的 MPU 违规情况。(禁止执行设置、器件、严格排序存储器)。
12.3 预取中止异常示例
示例 1:
以下示例演示了调试预取中止的步骤。在这里,CPU 执行滞留在预取中止处理程序中。相关的寄存器值如下所示:
SPSR_Abt:0x8000011F:模式 – (11111) 系统模式。这意味着当中止被触发时,CPU 处于系统模式。
IFSR:0x0000000D:该状态指示权限中止。在 IFAR 中捕获的地址是有效的,是导致中止的实际地址。
IFAR:0x0013F800:该地址位于具有严格排序属性的 MPU 区域下。
示例 2:
示例 2 的相关寄存器值如下所示:
SPSR_Abt:0x600001D1:模式 – (10001) FIQ 模式。这意味着当中止被触发时,CPU 处于 FIQ 模式。
IFSR:0x00000409:该状态指示同步外部中止或 ECC 中止。在 IFAR 中捕获的地址是有效的,是导致中止的实际地址。
IFAR:0x00009000:该地址不包含有效指令,并且具有错误的 ECC 值。
AIFSR:0x00400000:该状态表示错误源来自 ATCM(闪存)。