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.

[参考译文] AM6441:工业通信 SDK、EthernetIP 和隧道随机崩溃

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1629460/am6441-industrial-comms-sdk-ethernetip-and-tunneling-random-crash

器件型号: AM6441

您好、

我们有一个 AM64 器件、它在 R5 内核上使用工业通信 SDK 中的 EthernetIP、在 A53 内核上使用 Linux。  
我们的应用与 TI 示例不同、因为我们的现场总线应用在 Linux 上运行、并通过 RpMsg 连接到 R5 内核上的 EthernetIP 应用。  
这种做法没有任何问题。  

根据 SDK 中的 TI 隧道示例在 R5 和 A53 内核之间添加原始以太网隧道后、我们观察到应用启动期间 R5 上发生随机崩溃、并在 Linux 端生成以下日志:
image.png

这种情况非常不可靠(带有~10 个设备的测试系统不断重新启动会导致在一天的测试中至少出现一种情况)

由于我们已经在现场总线 IPC 中使用了 R5 内核上的 RpMsg、因此那里已经有人调用 waitForLinuxReady。 集成 TI 隧道示例时、在隧道任务中添加了对 waitForLinuxReady 的第二个调用。
似乎 waitForLinuxReady 不仅不会等待,而且还会重置 R5 和 A53 之间的 vring ,因此我们从隧道任务中删除了调用,只是在信标上等待,直到另一个对 waitForLinux 的调用继续进行。  
随着这一变化,我们在几天内没有看到任何进一步的崩溃。  

对我来说、不清楚两个对 waitForLinuxReady 的调用如何会导致这种情况、因为我们的应用程序保证在两个 waitForLinux 调用都完成之前没有向 Linux 宣布终结点、因此没有发生可能影响 vring 状态的 RpMsg 通信 (?)。

由于即使在发生此更改之前、我们也无法可靠地重现崩溃、因此我们无法确定它是否已可靠地修复。 如果有人对 RpMsg 驱动程序有更深入的了解、可以让我们找到可能导致屏幕截图中出现的行为的机制、当 2 次调用 waitForLinuxReady 重置 vrings 两次时、这将是很好的。

谢谢、此致
Philip Kees

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

    嗨、Philip

    我们已将该线程重新分配给相关专家。 如果几天内没有响应、请再次 ping 该线程。

    此致
    Archit

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

    您好、Philip、

    由于我主要是 Linux 新手、而不是 MCU+小人、我会给出一些初步想法、然后将您的问题交给另一位团队成员讨论。

    您需要两个单独的 waitForLinuxReady 呼叫的具体原因是什么?

    即使您的 R5F 代码有多个任务、我也希望整个 R5F 实例具有单个资源表文件。 我们的 ipc_rpmsg_echo_linux 示例将 waitForLinuxReady 置于 main 函数的开头、然后在 Linux 确认其就绪后从各个任务中产生。
    https://github.com/TexasInstruments/mcupsdk-core/blob/next/examples/drivers/ipc/ipc_rpmsg_echo_linux/ipc_rpmsg_echo.c 

    我尝试使用单个 waitForLinuxReady 调用代码、或者在启动不同的任务之前、或者通过执行类似您的系统(其中一个任务等待 waitForLinuxReady 返回)的操作、然后另一个任务不会尝试初始化 RPMsg 端点、直到第一个任务向其发出信号、表明 Linux 已就绪。

    但为什么我的系统会崩溃呢?

    我预计不一致的行为可能与某个地方的竞争条件有关。 但根据您的描述、我不确定应该在哪里查看。

    一些与您的用例无关的想法:

    (rscTable->vdev.status == 0x7U) 由 waitForLinuxReady 使用。 如果 Linux 设置了该值、一个 MCU+任务读取此值、然后在另一个 MCU+任务读取该值之前修改该值、这可能会强制第二个运行的任务卡在 waitForLinuxReady 函数内的无限循环中。

    如果您的任务之间存在其他依赖关系、如果您无法强制执行执行顺序、让任务在稍微不同的时间开始运行可能会导致问题。

    还有事吗?  

    我没有花任何时间使用此 rpmsg_eth 代码、但请检查您的代码以发送数据。 “收到的消息太大“让我担心您正在丢失数据。 请记住、Linux + MCU+内核之间的每个 RPMsg 消息都限制为 496 字节(512 字节 — 16 字节标头)

    此致、

    Nick

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

    您好:
    感谢您的查询。 有关专家因** TI 印度**假期而离职。
    请预计响应会延迟。 感谢您的耐心和理解。

    此致、
    TI E2E 支持团队
    ——
    *这是一个自动通知。*

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们的应用程序保证、在 waitForLinux 调用完成之前、没有向 Linux 宣布终结点、因此没有发生可能影响 vring 状态的 RpMsg 通信。

    如何确保 RPMsg 仅在 waitForReadyLinux 调用完成执行后发生?

    在您的应用程序中、Task1 从 waitForReadyLinux () 调用中出来并开始执行 IPC、同时任务 2 仍在等待 waitForLinuxReady () 调用完成吗?

    当 WaitForReadyLinux() API 重置 Linux 端的 VRING 缓冲区时。 假设 Task1 启动 IPC 并更改了 vring 缓冲区的索引、但 waitForReadyLinux 调用后的 task2 将重置 vring 缓冲区索引。 由于 vring 缓冲区索引的这种不一致、可能会发生崩溃。

    此致、

    Tushar

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

    尊敬的 Tushar:

    您如何确保 RPMsg 仅在 waitForReadyLinux 调用完成执行后才发生?

    我们来考虑以下情况:

    • 任务 A. (优先级 3)开始 任务 B (优先级 6)。
    • 立即安排任务 B 并输入waitForLinuxReady
    • 之后waitForLinuxReady、任务 B 在任务 A 必须发出信号的信标上等待。
    • 任务 A 然后到达waitForLinuxReady
    • 一旦 Linux 准备就绪、任务 A 将宣布其端点并开始通信。
    • 任务 A 向任务 B 发出信标信号
    • 任务 B 恢复并宣布其端点。

    此设置应适用于这两种情况:

    1. Linux 尚未就绪 →中的两个任务块waitForLinuxReady
    2. Linux 已经准备就绪 →任务 BwaitForLinuxReady 立即通过并在信标上等待。

    理论上,由于任务 B 具有较高的优先级,它应该始终在任务 A 完成之前到达信标waitForLinuxReady。 这可确保在导致的任何潜在虚拟复位之前不会公布任何端点waitForLinuxReady

    再次思考之后、此排序可能中断的唯一情况是以下时序边沿情况:

    • 任务 B 阻止waitForLinuxReady执行一个 FreeRTOS 周期、因为 Linux 尚未就绪。
    • 在任务 A 到达之前、Linux 在该周期waitForLinuxReady内准备就绪。
    • 这将为任务提供一个高达的窗口 一个 FreeRTOS 周期 (1ms) 若要继续、请通知端点、并在计划任务 B 并触发虚拟环复位之前开始通信。

    此窗口非常细长、这可能说明为什么问题在许多(几百到几千)成功重新启动时很少发生。

    由于您提到在 IPC 启动后重置振铃可能会产生我们所看到的行为、因此这种时序场景在我看来似乎是合理的。

    如果这也符合您的理解、我认为我们可以考虑问题已解决。

    此致
    Philip

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

    是的、以上内容解释了您正在观察的行为。 由于 满足时序要求非常罕见、因此问题的重现性是随机的或罕见的。

    不要从两个不同的任务调用 WaitForLinuxReady API 两次、而是执行以下操作。

    1. 从具有最高优先级的 TaskB 调用 WaitForLinuxReady。
    2. 在  WaitForLinuxReady API 调用后从 TaskB 发出信标。
    3. 在 TaskA 内部等待 TaskB 发出信标信号。

    上述序列将确保 WaitForLinuxReady API 仅被调用一次、并且在任务之间也实现了适当的同步。

    希望以上内容有所帮助。  

    此致、

    Tushar