B_QuRT_User_Guide(29)
19 异常处理
QuRT 支持对软件错误和处理器检测到的硬件异常进行异常处理。
异常被视为致命或非致命,并进行相应处理。
QuRT 处理程序异常(致命或非致命)、内核异常和不精确异常 QuRT 程序代码引发程序异常——它们包括页面错误、未对齐的加载/存储操作和其他 Hexagon 处理器异常等情况。 QuRT API 还可以显式引发程序异常。
注册为程序异常处理程序的线程(第 3 节)处理程序异常。
非致命程序异常会导致 QuRT 采取以下措施:
- 将相关硬件线程的上下文保存在任务控制块 (TCB) 中。
- 调度已注册的程序异常处理线程(如果有),将错误信息分配给等待异常操作的参数。
程序异常处理程序可以通过重新加载 QuRT 程序(如果它有能力)或通过终止 QuRT 程序系统的执行来处理非致命异常。
注意:如果没有注册程序异常处理程序,或者注册的处理程序调用引发非致命异常,QuRT 会引发内核异常。
如果线程在主管模式下运行,则错误将被视为内核异常。
如果出现多个程序异常,则所有异常都按照异常发生的顺序转发给程序异常处理程序。 异常处理程序必须重复调用 qurt_exception_wait 以处理来自排队异常的错误信息。
致命程序异常终止 QuRT 程序系统的执行,而不调用程序异常处理程序。 使用程序处理所有系统关闭操作的致命程序异常。
通过调用 raise fatal exception 操作引发致命异常,该操作屏蔽 Hexagon 处理器中断并停止 Hexagon 处理器中的所有其他硬件线程。 该操作返回,因此程序可以执行必要的程序级关闭操作(数据记录等)。
一旦程序准备好关闭系统,它就会调用致命关闭操作来执行以下操作:
- 如果尚未调用引发致命异常操作,则屏蔽处理器中断并停止所有其他硬件线程。
- 保存所有硬件线程的上下文。
- 保存TCM的内容。
- 保存所有 TLB 条目。
- 刷新缓存并更新缓存刷新状态。
- 调用注册的致命通知处理程序。
- 在当前硬件线程中执行无限循环。
QuRT 内核会引发内核异常——它们包括主管模式异常以及页面错误和其他 Hexagon 处理器异常。
内核异常导致 QuRT 终止程序系统的执行并关闭系统处理器,同时保存处理器状态以协助调查导致异常的问题。
内核异常会导致 QuRT 执行以下操作:
- 将当前硬件线程的上下文保存到内核错误数据结构中。
- 将所有其他活动硬件线程的上下文保存到它们各自的 TCB。
- 停止其他硬件线程。
- 等到其他硬件线程停止。
- 刷新 Hexagon 处理器缓存。
- 屏蔽 Hexagon 处理器中断。
- 调用注册的致命通知处理程序。
- 在当前硬件线程中执行无限循环。
注意:内核异常不会调用程序异常处理程序。
非精确异常是可以在 QuRT 内核或程序代码中引发的严重且不可恢复的错误条件——它们包括存储错误地址、硬件奇偶校验错误或其他不精确的从属错误条件以及不可屏蔽中断( NMI) Hexagon 处理器外部引发的异常。
QuRT 不会将不精确的异常转发给程序异常处理程序。 相反,内核会在保存处理器状态的同时终止当前硬件线程的执行。
当发生不精确的异常时,QuRT 会执行与内核异常相同的过程,只是所有硬件线程的线程上下文都存储在内核错误数据结构中。
注意:不精确的异常处理程序会覆盖 Hexagon 处理器寄存器 R23。 程序或内核异常不会发生这种情况
浮点异常——用户程序可以选择性地启用特定浮点事件(不精确、下溢、溢出、被零除和无效)以生成 QuRT 程序异常。
程序异常处理支持以下操作:
- qurt_exception_enable_fp_exceptions()
- qurt_exception_raise_fatal()
- qurt_exception_raise_nonfatal()
- qurt_exception_wait()
- qurt_assert_error()
19.1 qurt_exception_enable_fp_exceptions()
19.1.1 功能文档
19.1.1.1 static unsigned int qurt_exception_enable_fp_exceptions ( unsigned int mask )
启用指定的浮点异常作为 QuRT 程序异常。
通过设置 Hexagon 控制寄存器 USR 中的相应位来启用异常。
mask 参数指定一个掩码值,用于标识要设置的各个浮点异常。 异常表示为映射到 32 位标志值的第 0 位到第 31 位的已定义符号。多个浮点异常是通过将各个异常符号“或”在一起来指定的。
注意:必须在执行任何浮点运算之前调用此函数。
参数
in | mask | 浮点异常类型。 返回值:QURT_FP_EXCEPTION_ALL QURT_FP_EXCEPTION_INEXACT QURT_FP_EXCEPTION_UNDERFLOW QURT_FP_EXCEPTION_OVERFLOW QURT_FP_EXCEPTION_DIVIDE0 QURT_FP_EXCEPTION_INVALID |
返回值
更新了 USR 寄存器的内容。
依赖项
None.
19.2 qurt_exception_raise_fatal()
19.2.1 功能文档
19.2.1.1 void qurt_exception_raise_fatal ( void )
在 QuRT 系统中引发致命的程序异常。
致命程序异常终止 QuRT 系统的执行,而不调用程序异常处理程序。
有关致命程序异常的更多信息,请参阅第 19 节。
此操作总是返回,因此调用程序可以执行必要的关闭操作(数据记录等)。
注意:调用此操作后,上下文切换不起作用。
返回值
None.
依赖项
None.
19.3 qurt_exception_raise_nonfatal()
19.3.1 功能文档
19.3.1.1 int qurt_exception_raise_nonfatal ( int error )
在 QuRT 程序系统中引发非致命程序异常。
有关程序例外的更多信息,请参阅第 19 节。
此操作永远不会返回 - 假定程序异常处理程序在终止或重新加载 QuRT 程序系统之前执行所有异常处理。
注意:C 库函数 abort() 调用此操作以指示软件错误。
参数
in | error | QuRT 错误结果代码(第 25 节)。 |
返回值
整数 - 未使用。
依赖项
None.
19.4 qurt_exception_wait()
19.4.1 功能文档
19.4.1.1 unsigned int qurt_exception_wait ( unsigned int ∗ ip, unsigned int ∗ sp,unsigned int ∗ badva, unsigned int ∗ cause )
注册程序异常处理程序。 该函数将当前线程指定为 QuRT 程序异常处理程序,并暂停线程直到发生程序异常。
当发生程序异常时,线程被唤醒,错误信息分配给该操作的参数。
注意:如果没有注册程序异常处理程序,或者注册的处理程序调用 exit,那么 QuRT 会引发内核异常。 如果线程在超级用户模式下运行,任何错误都将被视为内核异常。
参数
out | ip | 指向发生异常的指令内存地址的指针。 |
out | sp | 堆栈指针。 |
out | badva | 指向发生异常的虚拟数据地址的指针。 |
out | cause | 指向 QuRT 错误结果代码的指针。 |
返回值
注册状态:
- 线程标识符——处理程序成功注册。
- QURT_EFATAL – 注册失败。
依赖项
None.
19.5 qurt_assert_error()
19.5.1 功能文档
19.5.1.1 void qurt_assert_error ( const char ∗ filename, int lineno )
将诊断信息写入调试缓冲区,并向 QuRT 内核提出错误。
相关数据类型
None.
参数
in | filename | 指向文件名字符串的指针。 |
in | lineno | 行号。 |
返回值
None.
依赖项
None.