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.

[参考译文] CC2652R:CC2652R:ZigBee 源路由故障

Guru**** 1633940 points
Other Parts Discussed in Thread: Z-STACK, CC2538, CC2652R
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1324931/cc2652r-cc2652r-zigbee-source-routing-failure

器件型号:CC2652R
主题中讨论的其他器件:Z-stackCC2538

  TI 的源路由实现中存在故障(似乎是竞争条件/使用了未定义的存储器)。 特别是在某些情况下,发送带有源路由的数据包时使用的 MAC 层目的地不正确。 被寻址到将接收数据包的器件、而不是下一个中继。

数据包包含正确的源路由信息(因为协调员在数据库中具有源路由并且未过期)。 不过、它会被寻址到错误的器件。

我圈出了错误的 MAC 目的字段、并在正确的值(源路由继电器)旁边放了一行。 以黑色突出显示的 packlet 是 ZC 已错误地解决的那些问题。

这是我们的 ZNP (simplelink)项目中经常发生的情况、使用源路由实现99%以上的所有通信。 这样做是因为表很大,而且源路由过期时间很大。 当许多设备同时通信时、很可能会发生此问题。

我已经完成了一些调试、目前怀疑问题出在   libZstack blob 中 NLDE_DataReqSend 中的 NLDE_BuildSrcRtgFrame 调用方面或在调用中。 然而,这是很难肯定地说,因为斑点的封闭性质。

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

    您好、Mathew:

    感谢您报告此行为。  您能否提供所显示的监听器日志、以及是否有任何其他数据包表现出这种行为?  您要评估哪个 SDK 版本、以及您的 SRC_RTG_EXPIRATION_TIME/MAX_RTG_SRC_ENTRINTS 值是多少?  您是否曾尝试增加堆内存、或者在重置 ZNP 器件后是否临时缓解此行为?  您认为必须连接多少个设备并进行通信才能重现此问题?  这可能与之前的 E2E 主题 https://e2e.ti.com/f/1/t/1289742?相关 

    此致、
    瑞安

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

    >>是否可以提供所显示的监听器日志,以及是否有任何其他数据包表现出这种行为?

    此后我复位了 Wireshark、不过这里是针对同一问题的嗅探器日志

    drive.google.com/.../view


    >>您评估的是哪个 SDK 版本

    simplelink_cc13xx_cc26xx_sdk_6_41_00_17

    >>您的 SRC_RTG_EXPIREL_TIME/MAX_RTG_SRC_ENTRIES 值是多少?

    -DMX_RTG_SRC_entry=40
    -dsrc_rtg_expirate_time=180

    >>您是否尝试过增加堆内存、或者在重置 ZNP 器件时是否暂时缓解了这种行为?

    我还没有调整堆内存。 如有必要、请提供建议。

    我没有看到任何指示内存压力的 MT 命令的错误代码

    >>您认为必须连接多少台设备并进行通信才能重现此问题?

    我们有17个 ZED + 4 ZR、其中大多数 ZED 连接到链中的最终 ZR

    常见的传出路由有:
    - ZC -> ZR1或 ZR4 -> ZR2 -> ZED
    - ZC -> ZR1或 ZR4 -> ZR3 -> ZED

    这是为了强制 ZED 保持与 ZR 的连接(因为它们不在 ZC 的范围内)。 我们将在大约150米的范围内进行测试。

    我不知道是否需要大量 ZED 来重现问题、或者由于相对频率低(~2-3个事件/小时、17个器件每个器件通常每分钟至少通信一次或两次)、仅在较大的数字下才会出现此问题。

    我们使用 AF:dataReqSrcRtg 发送每个数据包,我们有已知的 srcrtg,因此我们几乎只使用源路由,因为我们发现这是必要的,以防止路由请求过载下游 ZRS (主要是由于 ZRS 有限的去复用广播能力导致广播风暴) 处理大量路由器时(4个以上)。

    >>可能与之前的 E2E 主题 e2e.ti.com/.../1289742相关

    我们后来缓解了这个问题(通过难看的权变措施)、该问题位于接收路径上、很显然、maclib 构建中使用的不正确的预处理器定义的结果不太可能与其相关。 如果 TI 希望构建能够以任何合理的性能支持超过5个直接连接的 ZED 的 ZC (否则、性能会迅速下降)、则应增加 Mac src 挂起表的大小。

    在我们通过解决方法修补 自动挂起表问题之前、我们首先注意到了该问题。 然而,对 srcrtg 问题的全面调查在本周才开始。

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

    感谢您提供此详细帐户。  我已确认您在监听器日志中看到的内容与 Z-Stack 期望不一致、并且已提交错误单、让 TI 的 Z-Stack 开发团队对此进行进一步调查。  您可以提供的任何其他堆栈更改、如果您认为有助于此设置、将非常感谢。

    由于您正在使用 SDK v6.41、Z-Stack 的堆是动态分配的、因此不应成为问题。  另外、值得一提的是、您还没有通过 MT 界面看到任何堆或内存错误。

    此致、
    瑞安

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

    我们添加的大部分内容是用于揭示更多 ZNP 状态见解的附加 MT 命令。 另外一些 TI 问题已经得到修补、主要是在接收路径上。 我们还审查并应用了  https://github.com/Koenkk/Z-Stack-firmware 提供的许多补丁 (也涵盖了已知问题)。 在这里应该不相关。

    在这一级别、我们不能对 TI blobs 进行太多的修改。 不幸的是,在寻找这个问题和解决方法后,我们对问题的确切领域有很强的信心,并不得不诉诸一个相当糟糕的黑客来解决这个情况。

    对于后面的用户、则会编写一个古怪的补丁、直接在 MAC 层重新写入故障帧。

    MAC_INTERNAL_API void macTxFrameHook(uint8 txType)
    {
    if(pMacDataTx->internal.frameType == 1) {
    // not broadcast
    if(pMacDataTx->internal.dest.dstAddr.addrMode == ApiMac_addrType_short && pMacDataTx->internal.dest.dstAddr.addr.shortAddr < 0xFFF8) {
    // pan 3,4
    // dst, src 5,6,7,8
    // nwkfc = 9,10
    uint16_t nwk_fctrl = BUILD_UINT16(pMacDataTx->msdu.p[9], pMacDataTx->msdu.p[10]);
    if(nwk_fctrl & 0x0400 && pMacDataTx->msdu.len > 18) {
    
    uint8_t relay_count = pMacDataTx->msdu.p[11 + 6];
    if(relay_count != 0 && pMacDataTx->msdu.len > 18 + (relay_count * 2)) {
    uint8_t relay_index = pMacDataTx->msdu.p[11 + 7];
    if(relay_index + 1 > relay_count) {
    relay_index = relay_count - 1;
    }
    
    uint16_t correct_destination = BUILD_UINT16(pMacDataTx->msdu.p[11 + 8 + (relay_index * 2)], pMacDataTx->msdu.p[11 + 8 + (relay_index * 2) + 1]);
    
    if(correct_destination != 0) {
    //debug_uint32("sending with srcrtg ", correct_destination);
    
    if(correct_destination != pMacDataTx->internal.dest.dstAddr.addr.shortAddr) {
    //debug_uint32("found srcfail mac ", pMacDataTx->internal.dest.dstAddr.addr.shortAddr);
    //debug_uint32("correct_dest ", correct_destination);
    
    // then we need to change the destination address
    pMacDataTx->msdu.p[5] = LO_UINT16(correct_destination);
    pMacDataTx->msdu.p[6] = HI_UINT16(correct_destination);
    
    pMacDataTx->internal.dest.dstAddr.addr.shortAddr = correct_destination;
    }
    }
    }
    //debug_uint32("frame counter ", pMacDataTx->msdu.p[2]);
    }
    }
    }
    
    macTxFrame(txType);
    }

    它和丑陋的黑客最好,如果你不知道如何集成该功能到 Z-Stack 你可能不应该使用它。

    这样、我们在拥有大量 ZR 的现场器件就最终 实现稳定。

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

    感谢您提供这些信息!  我已要求 检查这一点、他们可能会跟进测试您的基本 Zigbee2MQTT 补丁。

    此致、
    瑞安

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

    感谢补丁!

    自从某个 SDK 发布以来、您是否遇到过此问题? 对于 Z2M、从6.20开始出现不稳定问题、这似乎与网络/路由请求中的许多 Tuya 设备有关。

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

    嘿、Koen、

    除非另有说明、否则 Mathew 通过 SDK v6.41观察到问题

    Mathew、

    Koen 认为、您是否知道 SDK v6.10或更早版本中包含此特定问题吗?

    此致、
    瑞安

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

    我们没有使用 v6.41之前的版本。 在 v6.41之前、我们在 CC2538硬件上使用了3.x 堆栈。 在我们测试的所有堆栈版本中、都可以观察到此问题的影响、但是上周是我第一次坐下来进行适当调查。


    我们从未见过此问题导致崩溃。 然而、事实并非如此、似乎 TI 也确实存在一些故障、以便在发生分配错误时保持结构一致。 我们相信、在 CC2652R 上、它并没有影响到我们、我们有足够的内存来满足我们的需求。

       我唯一可以访问的 Tuya 器件(PIR 温度湿度传感器)是休眠 ZED。 我目前已将其加入测试网络、但它没有对我造成任何崩溃、但我只有其中一个。 由于此设备处于休眠状态(在每个事件结束时静默断开连接)、您确实需要注意如何 与它进行传出通信(不要使用排队的数据包等阻止 Z-Stack 网络缓冲区)。

    测试网络上的其他传感器是 ZRS (Ikea ZRS 和 Philips Hue ZRS)和 DEVECO 传感器混合使用的 ZED。 这些是大量持续连接的器件。

     

    TI 正在源路由领域积极开展工作、但我不认为这是问题、我报告说、他们还应该修复在收到源路由时、如果 ZNP 内存不足、旧路由将被释放的问题。 (并且 RELAYLIST 设置为 NULL)但是、RelayCount 字段将保留为非零。 RTG_ProcessRrec 和 RTG_AddSrcRtg Entry_Guaranteed 中都应该改进此逻辑、如果模块内存不足、可能会导致使用 NULL RELAYLIST、因为 relayCount 不为零、这似乎在大多数情况下是要保护的、但可能不是全部。

    我还建议:

    1.在释放旧的分配之前,将为新的 RELAYLIST 创建分配。 这样、如果 分配 失败、则可以保留旧路由

    2.当替换 RELAYLIST 大小相同时,只需使用 memcpy 即可,不需要新的分配。


    我的分析仅基于读取 RTG_ProcessRrec 和 RTG_AddSrcRtg Entry_Guarantee 的汇编代码。 我无法访问 TI 的这些博客源代码。

    我并不认为这些潜在的存储器安全问题就是我所报告的问题、但它们 可能是问题、可以在相同的工作范围内进行修复、因为它们只是简单的修复。

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

    感谢您的反馈、这些信息已传递给软件开发团队进行审核。

    此致、
    瑞安

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

    -您是在哪里应用此更改的?

     另外一些 TI 问题已经得到修补、主要是在接收路径上。  

    "你是不是也想知道?"

    我感兴趣的是在固件中应用这些更改。