近期发现在执行完sqrt开方操作前后小概率跳转进ILLEGAL_ISR中断里面,查看RPC寄存器发现是在sqrt函数跳转出来给局部变量赋值结果的位置,但是想不通哪里会触发非法指令或者溢出等进入异常中断的原因。进入中断的那一刻见下图,概率极低,大概运行一两天才会进入一次,而且如果加入一些不相关代码改变了.text段的长度和存储位置就不会出现。很奇怪的问题
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.
近期发现在执行完sqrt开方操作前后小概率跳转进ILLEGAL_ISR中断里面,查看RPC寄存器发现是在sqrt函数跳转出来给局部变量赋值结果的位置,但是想不通哪里会触发非法指令或者溢出等进入异常中断的原因。进入中断的那一刻见下图,概率极低,大概运行一两天才会进入一次,而且如果加入一些不相关代码改变了.text段的长度和存储位置就不会出现。很奇怪的问题
Hi,
抱歉回复晚了。
先请您确认下目前的问题和情况是否如下:
1. 进入了非法 ISR
2. 调用 sqrt 后,RPC 指向 MOV32指令
您想要知道为什么会调用非法 ISR -非法指令或寻址模式。
我们假设故障是在一段时间后发生的,并且此代码在大多数情况下执行正常。
Thanks
您好,
当进入TRAP ISR 时,返回的 PC 将会保存在stack上,而不是 RPC。 您可以尝试在Illegal TRAP ISR 的开始处停止并读取栈中的返回地址。 CPU Instruction Set document section 3.5.2, table 3-5中有关于堆栈上在哪个位置具有返回地址的具体信息:
https://www.ti.com/lit/spru430
您需要使用此返回地址来了解非法指令的发生位置。 RPC 仅具有 LCR 指令的返回地址,因此指向 LCR 之后的指令与最后执行的指令无关。
Thanks
您好,
我曾试图修改ILLEGAL_ISR内容来查看获取到的返回PC值,但是如果修改ILLEGAL_ISR中原有的内容,该情况则不会出现。上述附图中有堆栈当时的情况,经过查阅文档应该是刚执行完INTR指令将一些必要寄存器压入当前堆栈中,且可排除在此处的堆栈异常,此任务的堆栈起始地址为0x8800大小为2Kb。所以是怀疑在sqrt函数中跳转到中断时发生了异常,但无法解释通的是仅仅修改一些别处无关紧要的代码迫使.text段各函数存储地址发生变化,此BUG便不会发生,还请相关工程师予以帮助,谢谢!
但无法解释通的是仅仅修改一些别处无关紧要的代码迫使.text段各函数存储地址发生变化,此BUG便不会发生
听起来像是一个计时循环问题,添加代码 .txt 部分会减慢访问 Sqrt() 问题循环的速度。因此,通常需要在高速服务循环中添加延迟时间,其中 ISR 可能会随机访问 LSRAM 以进行堆栈数据的 POP/PUSH。我们注意到类似的异常问题 x49c 经常发生在访问 ePIE 的较慢 ISR 循环中,其中另一个高速 ISR 正在运行后台任务。当 ePIE 介入时,C+ 高级语言似乎掩盖了低级指令解码器问题。难道是本地总线仲裁器需要重做?
您提到有 2 个 ISR。是否为这些 ISR 启用了任何软件中断嵌套,或者是否使用默认的无嵌套行为(请参阅Interrupt Nesting以获取参考)。
以下是一些有助于缩小问题范围的建议:
1. 在设备勘误表中,请参阅Memory: Prefetching Beyond Valid Memory部分。对于用于文本且紧邻保留空间的内存部分,请更新链接器命令文件以更改内存块的大小,以便最后 8 个字不会按照勘误表中的说明进行分配。然后编译并重新运行代码,看看是否可以解决问题。
如果上述情况没有出现,请执行步骤 2 和 3,看看是否观察到任何不同的行为。
2. 请确保所有未使用的中断都分配给具有 ESTOP0 的默认 ISR。这将确保系统在任何未使用的中断被无意触发的情况下停止,并且还确保不会由于未使用的中断升级而进入非法陷阱。
3. 使用 CCS 选项用 ESTOP0 填充内存。请参阅这个帖子了解如何执行此操作。完成后,加载应用程序。这将确保如果发生任何意外的获取,CPU 将立即停止,而不是发出非法操作码陷阱,并将确保我们能够查明问题发生的位置。
如果这些都没有帮助,请您分享以下内容,以便我们可以帮助确认存储在堆栈中的返回地址是非法地址 0x117701。
这是一个example供您参考:
正如您所看到的,在 L7 SARAM 块之后有一个保留空间。如果 L7SARAM 用于存储程序,并且预取最后几个字,使得保留地址也被预取,则可能会导致陷阱。
为了防止这种情况,在链接器命令文件中,如果 L7 SARAM 分配给程序/代码 (.text),则不要定义完整大小的块,如下所示
RAML7 : origin = 0x00F000, length = 0x00 1000 /* on-chip RAM block L1 */
Change the size to be smaller by 8 words
RAML7 : origin = 0x00F000, length = 0x00 0FF8 /* on-chip RAM block L1 */
对于保存程序且靠近保留空间(例如 M1 SARAM)的所有内存块,也应该执行同样的操作。