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/PROCESSOR-SDK-AM437X:NDK 线程中止异常

Guru**** 2924030 points

Other Parts Discussed in Thread: SYSBIOS

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/658551/rtos-processor-sdk-am437x-ndk-thread-abort-exception

器件型号:PROCESSOR-SDK-AM437X
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

您好!

在某些情况下、RTOS 会引发与 NDK 线程相关的异常中断。

ThreadType_Task 中发生异常。
任务句柄:0x80061eec。
任务堆栈基地址:0x800eaab0。
任务堆栈大小:0x2000。
R0 = 0x6000015f R8 = 0x800b2d84
R1 = 0x80065728 R9 = 0x800903a2
R2 = 0x00000000 R10 = 0x00000080
R3 = 0x0000003d R11 = 0x0000002a
R4 = 0x80065728 R12 = 0x4b5a6978
R5 = 0x8018f0dc SP (R13)= 0x8003c67c
R6 = 0x00000000 LR (R14)= 0x800e964
R7 = 0x8018f018 PC (R15)= 0x8003c67c
PSR = 0x0000002a
DFSR = 0x00000805 IFSR = 0x0000000f
DFAR = 0x00000008 IFAR = 0x833cfc91
TI.SYSBIOS.family.ARM.exc.exception:第205行:E_dataAbort:PC = 0x8003c67c、LR = 0x800ee964。
xdc.runtime.Error.raise:终止执行

´ve 次我也会看到此错误:
01037.645 NIMUReceivePacket:错误大小;有效载荷为0字节
ThreadType_Task 中发生异常。
任务句柄:0x8006205c。
任务堆栈基地址:0x800eac70。
任务堆栈大小:0x2000。
R0 = 0x6000015f R8 = 0x80063db8
R1 = 0x80070f60 R9 = 0x8018eff0
R2 = 0x00000000 R10 = 0x8018eff0
R3 = 0x0000005e R11 = 0x800ecbbc
R4 = 0x80070f60 R12 = 0x4b5a6978
R5 = 0x8018f29c SP (R13)= 0x8003c678
R6 = 0x00000000 LR (R14)= 0x800eeb24
R7 = 0x8018f32c PC (R15)= 0x8003c678
PSR = 0x800ecbbc
DFSR = 0x00000805 IFSR = 0x0000040f
DFAR = 0x00000008 IFAR = 0x833cff91
TI.SYSBIOS.family.ARM.exc.exception:第205行:E_dataAbort:PC = 0x8003c678、LR = 0x800eeb24。
xdc.runtime.Error.raise:终止执行

在我的测试环境中、AM437x 入门套件板和 PC 的 eth0连接到100Mbps 全双工的交换机。 PC 每15ms (平均值)发送1280字节的 UDP 数据报。

我认为接收错误或数据报峰值导致了问题。

问题是、这两个事件都不会导致软件中止。

已安装的组件:

CCS 7.2
GCC ARM 编译器4.9.3
PROCESSOR_SDK_RTOS_AM437X 4.00.04
AM437x PDK v1.0.7
BIOS 6.46.05.55
xdctools 3.32.02.25_core
电路板:AM437X 入门套件

此致、
Marcio。

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

    您是否尝试启动 ROV 以查看任何有助于缩小异常原因范围的有用信息? 此外、PC 指针、例如 PC = 0x8003c67c、是否给出了一些关于异常的提示? 您可能能够从存储器映射或单步执行反汇编中找到函数。

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

    我仅使用 ROV 检查任务句柄(NDK 线程)。

    遗憾的是、当故障发生时、我没有检查 PC、但检查映射文件、我可以看到 PC (PC = 0x8003c67c)指向 PBM.oa9fg

    text.PBM_Close
    0x8003c63c 0x14 C:\ti\ndk_2_25_01_11\packages/ti\ndk\stk.aa9fg (PBM.oa9fg)
    0x8003c63c PBM_Close
    text.PBMQ_enq
    0x8003c650 0x84 C:\ti\ndk_2_25_01_11\packages/ti\ndk\stk.aa9fg (PBM.oa9fg)
    0x8003c650 PBMQ_enq
    text.pbm_open
    0x8003c6d4 0x9C:\ti\ndk_2_25_01_11\packages/ti\ndk\stk.aa9fg (PBM.oa9fg)
    0x8003c6d4 PBM_OPEN


    我´ll 重现错误并获取更多信息。

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

    此外、LR 寄存器(0x800e964)也是一个有趣的寄存器、可能有助于缩小问题范围。

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

    LR 寄存器似乎指向 ti_sysbios_family_arm_exc_exception_Module_State_0_exStack_0___A

    共模 0x800edb70 0xa1410 C:\Alstom\CED2\Workspace\ced2_skAM437x_17\Debug\configPkg\package\cg\startup_pa9fg.oa9fg
    0x800edb70 TI_SYSBIOS_KNL_Task_Instance_State_0_hookEnv__A
    0x800edb78 TI_SYSBIOS_family_ARM_exc_exception_Module_State_0_exStack_0___A
    0x800eeb78 xdc_runtime_sysmin_Module_State_0_outbuf__A
    0x800eef78 TI_SYSBIOS_KNL_Task_Instance_State_1_HookEnv__A
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Marcio、

    检查这些提示是否有帮助:

    processors.wiki.ti.com/.../Processor_SDK_RTOS:_TI_RTOS_Tips_And_Tricks
    processors.wiki.ti.com/.../Processor_SDK_RTOS:_TI_RTOS_Tips_And_Tricks

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

    感谢 Garrett、


    这肯定会有所帮助。

    我的软件已将异常报告转储到 UART。

    我忘记说发行版发生了故障、在没有仿真器的情况下运行、并从 SD 卡引导。

    我相信 NDK 上存在未处理的情况。

    此致、

    Marcio

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

    您好、Garrett、

    我´ve 重现问题、在不到10微秒的时间内发送256个 UDP 封包。

    随附的屏幕截图显示了 Debug 和 ROV 视图。 所有内容都指向 cpsw_Nimu_eth.c 中的 Nimu_pktService

    编辑了1:

    快速分析后:

    函数 EMAC_rxPacket (在 EMAC_drv_v4.c 中)接收数据包描述符(p_cslPKT_desc)并将其传递到 Nimu、调用 Nimu_Rx_pkt_CB (在 cpsw_Nimu_eth.c 中)。

    我相信其他一些函数将在描述符(领域 AppPrivate)内使用缓冲区并将其释放。

    函数 EMAC_rxPacket 随后调用 Nimu_alloc_pkt(在 cpsw_Nimu_eth.c 中)以分配新的缓冲区,该缓冲区被复制到 p_cslPkt_desc,该缓冲区是 EMAC_rxPacket 的返回参数。

    如果 NIMU_alloc_pktt 未能分配缓冲区、则 p_new_pkt_desc 将为空、p_cslPkt_desc 将指向同一个缓冲区。

    在某个时间点、EMAC_rxPacket 将再次接收相同的描述符、并将其传递给 NIMU_Rx_pkt_CB、这将导致尝试再次释放相同的缓冲区并产生错误、我不确定是否已处理该缓冲区。

    编辑了2:

    ´ve 将 EMAC_rxPacket 更改为以下内容。 问题似乎已解决。 这不是一个好的解决方案、因为它仍然会丢失数据包、但至少程序不会崩溃。

    静态 EMAC_PKT_DESC_T* EMAC_rxPacket (句柄 hApplication、emac_PKT_Desc_T* p_cslPKT_desc)
    {
    EMAC_PKT_DESC_T* p_new_pkt_desc;
    uint32_t far_port = 0U;
    
    floor_port =((p_cslPkt_desc->Flags & EMAC_PKT_FLAG_FLOG_FOR_PORT_MASK)>> EMAC_PKT_FLAG_FORT_PORT_SHIFT)-1U;
    if (FOR_PORT < EMAC_NUM_MAX_MAC_PORT)
    {
    // MB:2018-01-29
    #if 0
    EMAC_RX_PKT (floe_port、p_cslPKT_desc);
    p_new_pkt_desc = EMAC_ALLOC_PKT (fin_port、EMAC_PKT_size (fin_port));
    
    if (p_new_pkt_desc!= NULL)
    {
    memcpy ((void *) p_cslPkt_desc、(void *) p_new_pkt_desc、sizeof (emac_PKT_Desc_T));
    }
    }
    #else
    p_new_pkt_desc = EMAC_ALLOC_PKT (fin_port、EMAC_PKT_size (fin_port));
    if (p_new_pkt_desc!= NULL)
    {
    EMAC_RX_PKT (floe_port、p_cslPKT_desc);
    
    memcpy ((void *) p_cslPkt_desc、(void *) p_new_pkt_desc、sizeof (emac_PKT_Desc_T));
    }
    }
    #endif
    返回 p_cslPKT_desc;
    } 

    此致、

    Marcio。

    e2e.ti.com/.../Capture_5F00_Exception_5F00_20180129.zip

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

    您描述的呼叫流程是正确的、您的分析是合理的。 您是否曾尝试添加一条语句来调试条件是否确实可以达到? 即 p_new_pkt_desc = NULL。 同时、我将与驱动程序开发人员进行讨论、以查看是否有任何意见。

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

    是的、我可以确认 p_new_pkt_desc == NULL 真的发生了。 我相信 p_new_pkt_desc == NULL 的原因与消息量、缓冲器数量、应用程序消耗数据的容量有关。 问题是这种情况不能破坏软件。 在 EMAC_COUNTERING_T 中为这种情况添加一个错误计数器很有意思

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

    你(们)好、Marcio。

    p_new_pkt_desc == NULL 实际上已经从最新的 PRSDK 4.2中在 PDK 1.0.9中进行了寻址、  请升级到最新的。

    静态 EMAC_PKT_DESC_T* EMAC_rxPacket (处理   hApplication、EMAC_PKT_DESC_T* p_cslPKT_desc)

      EMAC_PKT_DESC_T*  p_new_pkt_desc;

      uint32_t far_port = 0U;

      uint32_t bufLen = 0U;

      uint8_t* bufPtr =空;

      floor_port =((p_cslPkt_desc->Flags & EMAC_PKT_FLAG_FLOG_FOR_PORT_MASK)>> EMAC_PKT_FLAG_FORT_PORT_SHIFT)-1U;

      if (FOR_PORT < EMAC_NUM_MAX_MAC_PORT)

      {

        /*分配 PKT 以首先补充 RX_FREE_queue。

         *仅在 EMAC_ALLOC_PKT 成功时向应用程序提供数据包,

         *否则重新使用数据包描述符*/

        p_new_pkt_desc = EMAC_ALLOC_PKT (fin_port、EMAC_PKT_size (fin_port));

        if (p_new_pkt_desc!= NULL)

        {

          EMAC_RX_PKT (floe_port、p_cslPKT_desc);

          memcpy ((void *) p_cslPkt_desc、(void *) p_new_pkt_desc、sizeof (emac_PKT_Desc_T);

        }

        其他

        {

          bufLen = p_cslPkt_desc->BufferLen;

          bufPtr = p_cslPkt_desc->pDataBuffer;

          memset (p_cslPkt_desc、0、sizeof (emac_PKT_DESC_T));

          p_cslPkt_desc->BufferLen = bufLen;

          p_cslPkt_desc->pDataBuffer = bufPtr;

          p_cslPKT_desc->AppPrivate =(uint32_t) p_cslPKT_desc;

          gRxDropCounter++;

        }

      }

      返回 p_cslPkt_desc;

    此致、Garrett

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

    好的。 谢谢!