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.

[参考译文] RTOS/AM5716:DSP 操作码异常

Guru**** 2555630 points
Other Parts Discussed in Thread: AM5716, SYSBIOS, SYSCONFIG

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/619392/rtos-am5716-dsp-opcode-exception

器件型号:AM5716
Thread 中讨论的其他器件: SysBIOSSysConfig

工具/软件:TI-RTOS

大家好、我的 SYS/BIOS 应用程序有一个间歇性(但可重复)问题。 我希望有人能帮助我确定如何以最佳方式跟踪这一异常问题。

我在 AM5716处理器的 C66x 内核上运行 SYS/BIOS。 我在系统中有一个中断;它在 GPIO 引脚的上升沿触发。 我发现系统有时无响应、当我使用 XDS200 JTAG 仿真器中断时、我总是会发现以下错误签名:

  • PC 位于 exit.c 中的 abort()处,这意味着 SYS/BIOS 已关闭。
  • ROV 中的异常模块表明发生了内部异常。
    • 解码后的异常为:内部:取指令异常;操作码异常;

    • 异常的地址(ERP 寄存器)是 ti_sysbios_family_c64p_Hwi_int15的地址;这是我正在使用的中断的向量。
  • 异常 TSR 快照寄存器(ETSR)的值为0x10204、表示发生异常时正在处理中断。
  • 堆栈指针处于有效范围内、ROV 不显示堆栈或堆溢出。
  • 中断返回指针(IRP)设置为我的固件中特定 trampoline 函数的地址(让我们将其称为$Tramp$S$MyFunctionName)。 trampoline 的目标是函数  MyFunctionName、该函数位于外部存储器(DDR)中。

我最想知道的是异常发生时中断返回指针的一致性。 根据异常返回指针、在到达  ti_sysbios_family_c64p_hwi_int15时发生异常、而不是从该异常返回(即、在中断处理的开始而不是结束时)。 我已经验证 了 ti_SysBIOS_family_c64p_Hwi_int15处的操作码没有任何问题、但解码后的内部异常值是 取指令异常 和 操作码异常

因此、似乎只有在 PC 位于地址 $Tramp$S$MyFunctionName (trampoline 的起始位置、即使在分支之后也不是如此)的精确时刻发生中断时、才会发生异常。。。。 但这对我来说毫无意义! 提前感谢您对调试此问题的其他操作有任何猜测或想法。

此致、
Dave

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    RTOS 团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Dave、

    您的 GPIO 中断是否连接到 HWI15? 当您连接到可能触发中断的 JTAG 时、您是否观察到 GPIO 线路上的任何变化、或者您的假设是这样。 此问题是否仅在您使用调试器停止内核时发生、或者您是否认为即使在运行时也会发生? 您能否指出、当您在 DSP 上运行代码时、ARM 内核上正在运行什么? SysBIOS 配置中是否有任何计时器/时钟正在运行。

    您能否检查您是否正在为您可能使用的任何计时器更改暂停源:
    processors.wiki.ti.com/.../AM572x_GP_EVM_Hardware_Setup

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

    您好、Rahul、

    是的、GPIO 中断连接到 Hwi_int15。 中断定期发生、并且在错误发生之前多次正确处理中断(我的中断服务例程递增计数器、因此我可以看到它已经运行了一段时间)。

    问题实际上是在运行时发生的;在问题发生之前、我不会中断仿真器。 我只是使用仿真器在发生错误后询问系统的状态。 我可以告诉错误发生的时间、因为我用于与系统通信的通信协议将停止响应。

    我没有在 ARM 上运行任何代码;它只是在器件加电后处于 while (1)状态时运行引导加载程序。

    我不使用任何硬件计时器;GPIO 中断提供系统检测信号、并且我读取 TSC (时间戳计数器)寄存器的值以在必要时跟踪"实时"的通过。

    谢谢、
    Dave

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不是答案、而是关于调试的建议。 当遇到类似的问题时,我查看了从 Abort()函数返回调试器的跟踪。 然后、我返回函数调用、直到调试器显示我、并在该最早的函数处设置断点。 然后、当异常下次发生时、我可以看到更多的回溯、有时可以更好地了解调用中止时实际发生的情况。 此外、请务必打开 ROV 工具并检查 SysMin 日志。

    此外、BIOS 可以使用中断、而无需告诉您。 从 Processor SDK 1.0.6开始、GPIO 驱动程序使用事件组合器、而不是以前使用的专用中断15。 请参阅 GPIO_SoC.c 文件 切换到新的处理器 SDK 可能会解决您的问题。

    此外、当我使用较旧的 SDK (最高为1.0.5)时、我必须重新映射 GPIO_SoC.c 文件中的 EventID。 例如、对于 GPIO2、它们指定 line1EventId = 56。 但是,"通知"也使用了56个。 因此、我将其更改为76、我相信任何人都不会使用它。 我相信 GPIO1、GPIO3、GPIO6、GPIO7都有 EventID 冲突。 GPIO8使用我认为未映射的 EventID 0、因此您也需要为此选择一个新的事件 ID。 此外、我已将 GPIO_SoC.c 文件中的中断13更改为中断13、不确定原因、但它似乎对 GPIO 中断有很大帮助。 这些问题可能不是较新的 Processor SDK 1.0.6的问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    另一个问题。 您的中断速率是多少? 在调用任何用户回调之前、我已经看到大约5-8 μ s 的中断响应时间。 但是、如果 GPIO 模块未设置为"无空闲模式"、则该时间可能会更长。 我正在使用 GPIO8和 GPIO8、并使用以下代码强制无空闲模式并大大加速 GPIO 延迟。

    //手动设置 GPIO_SysConfig 寄存器以强制无空闲模式
    //并极大地缩短中断响应时间。
    *(volatile UINT32*)(0x48053010)= 0x00000008;// GPIO8
    *(volatile UINT32*)(0x4805D010)= 0x00000008;// GPIO6

    下面是讨论这一点的主题:

    e2e.ti.com/.../557865

    下面是有关 GPIO 中断的相当长的详细讨论、您可能会发现它很有趣。

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

    Dave、

    IRP 在解码异常时没有那么有用。 IRP 只指向执行的最后一个中断、该中断可能但很可能与异常无关。 您需要查看的是 NRP 和 B3寄存器。

    NRP (这类似于异常的 IRP)可让您了解异常发生的位置。 通常、在 NRP 之前有几个指令周期、因为当发生异常时、它需要几个周期才能跳转到异常处理程序。 B3是返回指针、它可以为您提供它希望返回到哪个函数的线索。

    默认情况下、SYSBIOS 应打印出这些内容。  您是否在控制台窗口中获得了这些打印件?


    犹大

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

    Christopher Peters、非常感谢您的想法。 我将查看您提供的 GPIO 信息。

    犹大,虽然我当然同意 IRP 在解码一个例外时一般不有用,但我倾向于相信这是一个合法的线索,因为在我的软件的不同版本中,有数十次例外发生, IRP 始终 准确地指向 $Tramp$S$MyFunctionName 的地址 (即使该符号的地址在软件构建过程中发生更改)。 我觉得这不可能是巧合。

    NRP  始终 指向 ti_SysBIOS_family_c64p_Hwi_int15  ()的地址;这是我认为异常与我的系统中断有关的另一个原因。   ROV 中的异常上下文数据显示 B3指向调用 trampoline 之后的指令、如反汇编窗口的这一部分所示(我的注释以蓝色添加):


    008295c0: C61002E5  [ A0] LDW/D2T1   *+B4[0]、A12

    008295c4: 102CBA13 ||     CallP.S2   $Tramp$S$MyFunctionName (PC+91600 = 0x0083fb90) XV (EA>;C?  <-这个红色的文本是奇怪的...?
    008295c8: 91C6  ||     MV.L1x    B3、A4
    008295ca: 2586         MV.L1     A11、A1  <- B3指向这里。

    我想知道我用红色突出显示的文本是关于什么... 我希望看到此处的文本"、B3"

    感谢您的持续支持、
    Dave

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

    您能在 CallP 前后显示更多代码片段吗? 更重要。

    您说您的函数是在 DDR 中。 是否正在缓存? 您可以将函数放在 L2存储器中吗? 如果不是、您可以尝试为代码当前位于的存储器禁用高速缓存吗? 因为它听起来像是计时问题。

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

    犹大,这更多是在 CallP 前后的反汇编窗口:

    BeginningOfFunction():
    0082953c:1FE67C10 CallP.S1 __PUSH_RTS (PC-52256 = 0x0081c900)、A3
    00829540:A246 MV.L1 A4、A5
    00829542:4647 || MV.L2 B4、B10
    00829544:07FFF052 || ADDK-S2 -32、B15
    00829548:00946324 LDNDW.d1T1 *+A5[3]、A1:A0
    0082954c:01944324 LDNDW.d1T1 *+A5[2]、A3:A2
    00829550:03942324 LDNDW.d1T1 *+A5[1]、A7:A6
    00829554:04940324 LDNDW.d1T1 *+A5[0]、A9:A8
    00829558:023C805A ADD.L2 4、B15、B4
    0082955c:E0200003 fphead N、L、W、BU、nobr>、 Nosat、0000001b
    00829560:009063F4 STNDW.d2T1 A1:A0、*+ B4[3]
    00829564:019043F4 STNDW.d2T1 A3:A2、*+ B4[2]
    00829568:039023F4 STNDW/D2T1 A7:A6、*+B4[1]
    0082956c:049003F4 STNDW/D2T1 A9:A8、*+B4[0]
    00829570:DC4D LDW/D2T2 *B15[2]、B4
    00829572:B5C6 MV.L1x B3、A13
    00829574:02BC202A MVK.S2 0x7840、B5
    00829578:0280406A MVKH.S2 0x800000、B5
    0082957c:E2000000 fphead N、L、W、BU、nobr>、 Nosat、0010000b
    00829580:018C876E LDW/D2T2 *+B14[3207]、B3
    00829584:00110BDA CMPLTL.L2 0x8、B4、B0
    00829588:2052A121 [B0] BNOP.S1 $C$L84 (PC+328 = 0x008296c8)、5
    0082958c:30148AE6 ||[!B0] LDW/D2T2 *+B5[B4]、B0
    00829590:0080A362 BNOP.S2 B0、5
    $C$L80:
    00829594:0005022A MVK.S2 0x0a04、B0
    00829598:030C0572 MPYLI.M2 B0、B3、B7:B6
    0082959c:12856E7E ADDAL.D2 B14、1390、B5
    008295a0:058C59D8 CMPGT1.L1x 0x2、B3、A11
    008295a4:82C7 MV.L2 B5、B4
    008295a6:0586 MV.L1 A11、A0
    008295a8:0298A07A || ADD.L2 B5、B6、B5
    008295ac:C2107C43 [A0] ADDAL.D2 B4、B3、B4
    008295b0:02850052 || ADDK-S2 2560、B5
    008295b4:C20A0453 [A0] ADDK-S2 5128、B4
    008295b8:059402E6 || LDW/D2T2 *+B5[0]、B11
    008295bc:E0400008 fphead N、L、W、BU、nobr>、 Nosat、0000010b
    008295c0:C61002E5 [A0] LDW/D2T1 *+B4[0]、A12
    008295c4:102CBA13 || CallP.S2 $Tramp$S$$MyFunctionName (PC+91600 = 0x0083fb90)“S (ˆê);ÒB
    008295c8:91C6 || MV.L1x B3、A4
    008295ca:2586 MV.L1 A11、A1
    008295cc:9184A35A [!A1] MVK.L2 1、B3
    008295d0:00AC1FDA MV.L2X A11、B1
    008295d4:960C1FD8 [!A1] MV.L1x B3、A12
    008295d8:2606 MV.L1 A12、A1
    008295da:1607 MV.L2X A12、B0
    008295DC:E8800000 fphead N、L、W、BU、nobr>、 Nosat、1000100b
    008295e0:5000A35B [!B1] MVK.L2 0、B0
    008295e4:9508A358 ||[!A1] MVK.L1 2、A10
    008295e8:2500A359 [B0] MVK.L1 0、A10
    008295ec:2427 || MVK.L2 1、B0
    008295ee:024E || MV.S1 A4、A0
    008295f0:00AC49A2 || SHRU.S2 B11、0x2、B1
    008295f4:01840F9B AND.L2 B0、B1、B3
    008295f8:C190A359 ||[A0] MVK.L1 4、A3
    008295fc:E10000C0 fphead N、L、W、BU、nobr>、 Nosat、0001000b 

    是的、是 trampoline 目标的函数位于 DDR 中。 DSP L1和 L2高速缓存均已禁用。

    我可以尝试移动功能、但根据我的经验、这几乎肯定 会暂时 解决问题。 基本上、如果我对软件进行任何更改、这个问题可能会消失一周左右、直到其他一些不相关的更改导致它再次出现。 这就是为什么我渴望最终确定问题的原因----因此我可以相信,它不会在一周、一个月或一年后回来。

    谢谢、
    Dave

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

    Dave、

    我查看了代码片段、但我没有看到任何跳转及其编译的代码、因此我希望它通常是正确的。

    您对异常的描述与发生的情况完全相同。
    代码正在对函数执行 trampoline、然后发生中断并生成异常(在实际执行函数之前看起来是这样)

    由于 NRP 是 Hwi_int15、我假设 PC 在那里并且 IFR 已针对这个中断被清除(如果它没有被清除会很有趣)。

    如果您能够连接调试器并重现问题、我会在 Hwi1 (异常处理程序)处设置断点并查看的状态
    遇到断点时的寄存器/存储器。

    我觉得您在 DDR 中的功能是其中的一个变量。

    我认为不应禁用 L1P 缓存(仅用于代码)。  我没有什么比建议尝试的东西更好的了。

    犹大

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

    犹大

    我不确定您是否亲自熟悉 C66x DSP 的内部架构,但如果您(或知道 TI 的某个人是谁),也许我会得到个例外--取指令异常操作码异常-- 可以提供有关 DSP 在硬件级别发生的情况的线索。 我想知道、您是否可以接受这些由此产生的异常、并向后工作以得出一个理论、说明它们首先是如何发生的。 这个问题是可重复的、因此我相信可以找到最终的原因、但我不具备解决这个问题所需的内部 DSP 知识。 您认为这是我们可以采取的方法吗?

    谢谢、
    Dave

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

    Dave、

    我在硬件层面上不熟悉 C66x DSP。  我是一名软件人员、从软件角度来看、我在 C66x 工作了多年。

    我的直觉认为、这听起来像是硬件问题、因为您在 IRP、NRP 和 B3中看到的是什么。
    我将尝试让硬件方面的人员关注。

    犹大

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Dave:
    我将根据 SYSBIOS 的预期回顾到目前为止已完成的症状和调试。 请给我1-2天的时间进行报告。
    Jian
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Jian、您好、感谢您的帮助、但我有好消息! 我们最终通过当地的 TI FAE 提供额外帮助、找出问题的原因。 我昨天刚刚通过额外测试确认了该解决方案。 我们发现、当我禁用 L2 EDC (错误检测和校正)时、不会出现此问题。 为了确认这一点、我进入了我的二进制映像、找到启用 L2 EDC 的 STW 指令、并将其替换为 NOP。 然后、我运行了几个小时的测试、但异常没有发生一次。

    我们认为问题的原因是我们的软件中出现错误、我们未正确遵循 C66x DSP CorePac 用户指南 EDC 章节中的所有"L2 EDC 设置序列"步骤。 在修复软件和问题再次出现的不太可能的情况下、我将在此时创建一个新的论坛帖子。

    再次感谢阅读此帖子并提出想法的所有人、以及 TI 通过我们当地的 FAE 为我们提供支持的人员。

    此致、
    Dave

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

    默认情况下是否启用 L2 EDC?它是您 打开的吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    默认情况下、Christopher、NO、L2 EDC 处于禁用状态。 我们通过修改 GEL 文件中的某些代码来打开它、但我们一定不能仔细查看它。 如果要检查系统、如果启用 EDC、L2EDSTAT 寄存器(DSP 存储器中的位置0x01846004)将设置位0;如果禁用 EDC、则设置位2。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢你。