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.

[参考译文] CC1352R:器件突然停止 BLE 通信

Guru**** 2539800 points
Other Parts Discussed in Thread: BLE-STACK, SYSCONFIG

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1128189/cc1352r-device-suddenly-stopps-ble-communication

器件型号:CC1352R
Thread 中讨论的其他器件:BLE-STACKSysConfig

大家好、

在一个行业项目中、我们目前面临着 BLE 通信方面的一个非常严重的错误。 我们使用 TI SDK 4.10.0.78

在发生错误之前、器件正在执行一些测量、但未处于连接状态。 然后建立连接、器件根据命令将测量数据发送到主器件。

在大多数情况下、它没有问题。 但在极少数情况下、器件会突然停止通信。 在 Wireshark 中、根据连接间隔、我可以看到大量"空 PDU"。 当通信中断时、我可以清楚地看到、我们的器件只是停止对主器件连接事件的应答-没有任何干净的终止程序。 在配置的监控超时后、主器件会将连接视为丢失。

然后、当我在正在运行的器件上启动调试会话时、我可以看到堆栈仍然认为连接处于活动状态- BLE 堆栈无法识别死连接。

我们实现了一个监视功能、通过观察连接事件来跟踪丢失的连接。 一旦我们在特定时间段内未发现任何连接事件、我们就会认为连接丢失。

发生这种情况时、我们调用 GAP_TerminateLinkReq、返回0x0 =成功。 然后、我们调用 GapAdv_enable、返回0x18 (bleInvalidRange)。

因此、我们无法激活广播、并且我们的器件不再可连接。

奇怪的是、我们始终使用相同的参数调用 GapAdv_enable。 在错误发生之前、返回状态始终为0x0成功。 只有在这种罕见的情况下、它才不会成功。 之前可能有数百次调用 GapAdv_enable、全部成功。

除了似乎混淆的 BLE-STACK、器件工作正常。 我们的 RTOS 任务在运行时没有遇到任何问题。

从 SDK 发行说明中、我们没有发现已知的错误、这可能会导致此行为。 有没有人知道这里可能会有什么问题?

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

    您好、Gabiel、

    您是否可以使用最新的6.20 SDK 进行测试、以查看问题是否仍然存在?

    此致、

    Arthur

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

    尊敬的 Arthur:

    我会尝试一下。 由于该错误很少出现、因此可能需要一段时间才能获得特定的结果。

    当我获得结果时、我将返回到这里。

    感谢您的支持!

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

    尊敬的 Arthur:

    更新需要很长时间、从 SDK 4.10开始有了很大的变化。

    我所做的:

    -更新了 SDK 4.10.0.78 -> 6.20.0.29

    -更改了编译器 TI v20.2.0.LTS -> TI Clang v1.3.1.LTS

    -已更新 TI-RTOS6 -> TI-RTOS7

    -已转换的 SYS/BIOS 配置 XCONF -> SysConfig

    -更改了路径、pragma 等...

    -动态创建的任务,以前是静态创建的

    现在、可以在我们的器件上构建并运行代码。

    从 ROV 中、我可以看到、所有任务、事件、邮箱等看起来都很好。

    在处理 SPI 时遇到一些困难(突然、您还必须在 GPIO 部分配置 SPI 引脚、而不再只在 SPI 部分配置 SPI 引脚)、器件启动得非常好。

    但是... 它不进行广播

    我可以看到,GAP_DeviceInit()返回成功,看起来很好。 稍后会出现 GAP_DEVICE_INIT_DONE_EVENT 并触发 GapAdv_create。 这反过来又反馈0x13 = bleMemAllocError。

    不用说、对 GapAdv 的后续调用由于0x34 = bleGAPNotFound 而失败。

    我已经尝试过示例项目 simple peripheral OAD offchip。

    在这里,GAP_DeviceInit()返回成功。 但 GAP_DEVICE_INIT_DONE_EVENT 从未出现过 APPERS、因此我也看不到任何广播。

    是否存在任何已知问题?

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

    尊敬的 Arthur:

    再说一次、我还有几步远...

    在我看来、iCall 并不是真正支持 TI-RTOS7的 heapTrack。

    示例工程中有一些预定义的 syms、看起来像是针对将在 app_pem4f.h 中为旧 RTOS 定义的符号的快速权变措施。

    默认情况下、iCall 将使用溢出在我的程序中的 osalheap。

    告知 ICall 像 SDK 更新之前一样使用 heapTrack 会导致编译时间错误、因为 RTOS_heaptrack 不适用于 TI-RTOS7。

    将其折弯一点后、我现在可以根据需要在 heapTrack 上运行 iCall。

    我为此所做的:

    • 在 iCall.c 中、第365行:将默认堆更改为 heapTrack (#include )
    • 在 rtos_heaptrack.h 中:
      • 当未定义 TIRTOS7_support 时、仅包括 XDC/cfg/global.h
      • 将 Memory_defaultHeapInstance 的数据类型更改为 IHeap_Handle
      • 使用 Memory_defaultHeapInstance 而不是 stackHeap

    现在、器件广播-非常酷。

    广播数据与 SDK 更新之前的数据相同。

    但是... 下一个问题:(我无法连接到设备(它被设置为可连接)。 约 在5次连接尝试中、有4次仍然完全未被重新配置到应用层-未发布 GAP_LINK_established _event。

    当事件最终弹出时、只有一小段时间后、应用程序才会接收 HCI_BLE_hardware_error_event_code 事件。 这里会发生什么情况?

    在这里、ROV 没有太大帮助。 "扫描错误"结果为"... 无错误..."

    BTW。 说到 ROV、我尝试观看 Stacks Graph -但它始终是空的-还有示例项目。 当前 SDK 是否会出现这种预期行为? 或者是否有任何新的配置需要调整、我还没有找到?

    感谢您的回答。

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

    一些附加信息;
    当 GAP_LINK_established 事件出现时,*pMsg 看起来不错。 结构内的所有参数都是有效的、符合预期。

    和 ROV 中的"Stacks Graph"视图。 很清楚-这与任务操作无关。 在 ROV 的"任务"视图中、我可以看到、所有任务都运行良好。 此外、所有用户任务都按预期接收事件。 它仅是 Stacks Graph 视图、不显示任何信息。

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

    您好、Gabiel、

    感谢您提供的所有信息、这将有所帮助、但正如您所看到的、这是一个非常复杂的问题、可以重现。

    您是否可以通过任何机会为我们提供重现问题的项目? (最好是 CCS、IAR 也可以工作)

    此致、

    Arthur

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

    尊敬的 Arthur:

    我有一个经过修改的示例项目、您可以查看它。

    我如何将该项目提供给您、而不将其发布到 www 中?

    此致

    Gabriel

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

    您好!
    我将通过 e2e 上的直接消息与您联系。 此致、

    Arthur

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

    尊敬的 Arthur:

    非常感谢您的支持。

    错误原因是设置和释放功率限制的使用不平衡。 当我们释放更多限制作为设置时、将发生错误。

    我可以在 SDK 的示例工程(simple_peripheral_oad_offchip_CC13X2R1_LAUNCHXL_tirtos_ccs)中重现错误。

    为了产生错误、时钟会限制功率的设置和释放。 设置的前10倍等于释放限制。 之后、它将执行每次1 set 和2 release 限制。 一小段时间后、错误发生。

    在此图形中、您可以看到设置(Test_SetCon应变)和释放(Test_ReleaseCon应变)约束的计数。 每次 RF_clkPowerUp 停止时、Test_RfClockOffCount 都会增加。 当 Test_RfClockOffCount 大于5时、测试将停止、射频时钟永远不会再次激活。

     simple_peripheral_oad_offchip.c 文件中的示例项目需要进行以下代码更改:

    在局部函数之前添加以下变量:

    /* Variables to reproduce the bug */
    static uint32_t Test_SetConstrain;
    static uint32_t Test_ReleaseConstrain;
    static uint32_t Test_RfClockOffCount;
    static Clock_Params Test_ClockParams;
    static Clock_Handle Test_ClockHandle;
    static ClockP_Struct *Test_RF_clkPowerUpObj;

    在局部函数的末尾添加此局部函数:

    static void Test_clockCb(UArg arg);

    在 SimplePeripheral_init()末尾添加:

    /* initialize the test variables */
      Clock_Params_init(&Test_ClockParams);
      Test_ClockParams.startFlag = true;
      Test_ClockParams.period = 1000 * (1000 / Clock_tickPeriod); //ms -> clock ticks
      Test_ClockHandle = Clock_create(&Test_clockCb, 5000 * (1000 / Clock_tickPeriod), &Test_ClockParams, NULL);
    
      Test_SetConstrain = 0u;
      Test_ReleaseConstrain = 0u;
      Test_RfClockOffCount = 0u;
      Test_RF_clkPowerUpObj = (ClockP_Struct*) 0x20003354; // check that address in memory browser

    在文件末尾添加:

    static void Test_clockCb(UArg arg)
    {
        if(Test_SetConstrain <= Test_ReleaseConstrain)
        {
            // set power constrain
            Power_setConstraint(PowerCC26XX_DISALLOW_IDLE);
            Power_setConstraint(PowerCC26XX_DISALLOW_STANDBY);
            Power_setConstraint(PowerCC26XX_DISALLOW_SHUTDOWN);
            Test_SetConstrain++;
        }
        else if(Test_SetConstrain > Test_ReleaseConstrain)
        {
            // release constrain
            Power_releaseConstraint(PowerCC26XX_DISALLOW_IDLE);
            Power_releaseConstraint(PowerCC26XX_DISALLOW_STANDBY);
            Power_releaseConstraint(PowerCC26XX_DISALLOW_SHUTDOWN);
            Test_ReleaseConstrain++;
    
            if(Test_SetConstrain > 10u)
            {
                // release constrain to occur a bug
                Power_releaseConstraint(PowerCC26XX_DISALLOW_IDLE);
                Power_releaseConstraint(PowerCC26XX_DISALLOW_STANDBY);
                Power_releaseConstraint(PowerCC26XX_DISALLOW_SHUTDOWN);
                Test_ReleaseConstrain++;
            }
        }
    
        /* check if the RF power up clock is activ */
        if(ClockP_isActive(Test_RF_clkPowerUpObj) == false)
        {
            /* rf clock stops, stop test */
            Test_RfClockOffCount++;
            if(Test_RfClockOffCount > 5u)
            {
                Clock_stop(Test_ClockHandle);
            }
        }
    
    }

    我希望您也能复制它。

    我们的问题如下:

    1. 是否有可能检测到设置和释放限制的不平衡使用?
    2. 是否可以重新激活 RF_clkPowerUp 时钟?

    此致、

    Karl

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

    您好、Karl、

    感谢您提供源代码。

    关于您的第一个问题:

    您实际上可以使用以下结构 PowerCC26XX_ModuleState 跟踪约束计数、尽管不建议这样做: https://dev.ti.com/tirex/explore/content/simplelink_cc13xx_cc26xx_sdk_6_30_01_03/docs/drivers/doxygen/html/struct_power_c_c26_x2___module_state.html#aea286d524dd4afd4b9a8bf2b8954e2c8

    还可以选择修改驱动程序以创建您自己的计数器。

    2.我认为在使用 BLE5堆栈时、射频驱动器时钟的控制中没有这种粒度。 如果尚未完成、您可以尝试在发生此类问题时正常重置设备。

    此致、

    Arthur