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.

[参考译文] CC2340R5:通过 persistent 应用程序实现的大映像下载失败:GATT_Notification ()返回0x16 (blePending)且下载过程停止。

Guru**** 2595805 points
Other Parts Discussed in Thread: CC2340R5, CC2640

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1352895/cc2340r5-oad-download-fails-on-large-image-transfers-through-the-persistent-app-with-gatt_notification-returning-0x16-blepending-and-the-download-process-stalls

器件型号:CC2340R5
主题中讨论的其他器件: CC2640

我们的问题是、在187K 中的大约128K 需要通过 persistent 应用程序遍历到主应用后、固件映像块的 OAD 传输失败。 无论出于何种原因、 我们都 对堆栈和周围细节进行了深入研究、并对我们的应用程序进行了许多测试/诊断构建(该应用程序与 CC2640姊妹产品兼容、 而不是 CC2340R5 [SDK 7_40],进程在 OAD_SetParameter ()内停止和 GATT_Notification ()返回0x16 (blePending )使传输进程结束。

创建时钟并设置事件以重试通知调用不会纠正问题,因为每次后续调用 GATT_Notification ()都会返回0x16 ,直到启动新的调试会话。  

这是非常意外的情况、因为通过持久应用程序从应用程序传输到设备的每个块都处于锁定步骤。 Essential SDK 示例(无一个加密/步骤)中存储的模型使用通知应用程序通过 WriteCharacteristic 请求发送下一个块,而 WriteCharacteristic 又生成调用 BLEAppUtil_invokeFunction() ,将块发送到应用程序级别以编程到闪存。 这种锁定步骤方法意味着,在没有其他 BLE 操作同时运行到 OAD 下载的情况下,内部队列应该从根本上被耗尽,并且没有可能导致来自 GATT_Notification ()的 blePending 返回状态的未决指示或步骤。

如果我们看到从 Gatt_Notification ()返回0x16 ,我们会设置一个计时器,以重新发送所需块的通知,但向 GATT_Notification()发出的后续调用(稍后为250mSec )也会返回0x16的状态,此后每次重试也会返回。

该问题通常发生在 主片上应用的 FW 映像(~187K)中的802个块中的400-600个块(每个块236字节)之后。 但有趣的是、我们每次测试过程时都不会在同一点发生失速。

检查 ROV 中的细节显示了每个线程的健康堆栈、并且堆的分配率略高于50%、在12K 个运算中、分配的不足大约为99 malloc/释放、因此这些似乎与正常使用一致。  

我们另一个基于 CC2640的器件在其 OAD 更新中仅包含约44KB 并使用相同的应用;CC2340R5始终使其超过44K 点、在传输大约100-130K 后卡住。 我们可以看到在其退出点之前闪存到 mainapp 区域的正确代码。

因此, 在 API 级别中,许多人关注内存泄漏的降低。  除了在 OAD_service.c 和 OAD_profile.c 中进行一些微调以添加一些诊断计数器(这些计数器尚未揭示明显的资源问题)之外、这些是 SLP SDK 7_40中提供的示例源代码版本。    

尚未弄清楚如何使用 ROV 来检查队列的运行状况(有些说明需要在那里的人)、但我们以缓慢的动作(在通知后在应用程序端增加延迟)操作了传输过程、这没有产生影响。

我的想法是那里的团队没有尝试过一个大的固件映像过 OAD,但保持迅速较小的映像(如< 80KB),并且没有看到这个问题。

您怎么看?

P.S.在 OAD_service 中发现了另一个可疑的 malloc/free 泄漏路径。 C 在过程 OadWriteAttrCB()的两个地方(我不认为它们对我的问题有贡献(我将在单独的线程中发布) ,但如果 iCall_malloc()的正文至 BLEAppUtil_invokeFunction()失败,为 pOADSrvWriteReq 对象分配的内存未释放, 同样,如果对  BLEAppUtil_invokeFunction()的调用失败(例如如果队列已满),则这两个对象不会按其应有的方式释放。 在测试期间、我们将错误计数器放置在正确的位置、虽然我们获得0x16返回代码、但我们不会获得 malloc 错误的任何命中点。

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

    尊敬的 Stuart:

    感谢您获得支持、

    您能否提供您使用的 SDK 的确切版本?

    您面临的 blePending 问题会提醒我、我正在处理另一个问题、在继续进行调试之前、我希望确保它们是不同的。

    您可以在此处查看我的答案: (+) CC2340R5:CC2340发挥了核心作用、而且经常遇到数据传输故障的问题。 - Bluetooth 论坛- BluetoothRegistered︎- TI E2E 支持论坛 和监视  l2capNumDataPkts 的值,它不应超过其初始值(最大 PDU 数量)。 如果您发现溢出、可以报告给我吗?

    同时、我将调查您报告的可能的内存泄漏。

    此致

    丹桂语

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

    您好、Tanguy:

    SDK:simplelink_lowpower_f3_sdk_7_40_00_64

    一些额外的输入...

    1、我已经把 num PDU 增加到20没有效果,我已经尝试把准备好的写入次数增加到10次,没有帮助的效果。

    2、我已经尝试暂停传输过程中发生的闪存操作、以使擦除扇区步长静音(最多可能需要2.2mSec)、从而查看是否有任何与问题相关的阻塞性质。 注释掉之后:

       状态=(O3852 Profile_Status_) Update_Write (blkStartAddr、(len - OAD_BLK_NUM_HDR_SZ)、(pValue+OAD_BLK_NUM_HDR_SZ);

    持久性应用程序可以在没有擦除延迟作为潜在影响因素的情况下启动块传输过程;传输仍会停止、GATT_Notification ()仍将在为先前的块发送大约500条通知后每250mSec 通过重复调用返回0x16。

    希望这有助于... 在此目的应尽最大努力 快速解决此问题、解决我们希望 OAD 处于活动状态的逾期工厂工程构建问题。

    运行上面的第二个点以检查 L2capNumDataPkts 浮点级别。 很快就会报告该情况。

    请让我知道我还能为你挖掘什么...  

    谢谢。

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

    是的、它看起来像是溢出!

    l2capNumDataPkts 的状态:

    在 basic_persistent.syscfg 中- PDU 的最大数量设置为"20"、准备写入的最大数量设置为"10"。

    1.在调试器中启动程序-> 在运行后、但在建立任何连接或启动广播之前。

       l2capNumDataPkts = 20

    2.在广告后,但没有连接:

       l2capNumDataPkts = 20

    3、连接到中央客户端(移动应用- iOS )特征后,中央读取 device_info ,少量低带宽读写。

       l2capNumDataPkts = 20

    4.在 OAD 块传输期间(块大小240、更新长度236字节)、但问题发生之前:

    • l2capNumDataPkts 从大约20开始(前20-30个块的变化19、20、21)、然后在块传输期间逐渐上升
    • 在更新过程中、此数值持续上升、超过60、并继续稳步上升(主观上呈线性)
    • 经过100 ,然后接近"绳的末端"得到高达182当 GATT_Notification ()失败,并返回 blePending。

    似乎我们正处于此处重要的方面。 接下来如何操作?

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

    尊敬的 Stuart:

    感谢您测试溢出、恐怕我暂时没有针对此问题的任何权变措施。 正如我在另一主题中提到的、我现在将 问题重点放在研发。 当我有更多信息要分享时、我会尽快回复您。

    我希望你明白,

    此致

    丹桂语

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

    Tanguy,

    我为您提供了可帮助研发团队解决此问题的最新信息(并可以解决此问题)。

    1.我们使用的默认 OAD_default_block_size 为240字节、这导致 l2capNumPkts 在传输过程中爆炸、链接挂起为  l2capNumPkts 将达到值182到200+。

    2.出于绝望,我认为这可能是堆栈中的分段问题,所以我将提供的"#define OAD_default_block_size 240"改为16,只是为了尝试一下。 OAD 映像传输需要一些时间才能完成、但发生了溢出 l2capNumPkts! 链路有效!

    3.逐渐将大小从16增加到32到128、这些值不会造成任何溢出、OAD 传输逐渐加快。

    4.我发现我可以使用"#define OAD_default_block_size 230"、但它不会溢出(可能有23的倍数帮助?)

    5.我将值返回到240、溢出返回。 因此、我认为这种尺寸变化会对更深层次的问题产生一定影响、或者可能意味着需要的解决方法或必须调整的配置。

    6.不确定这是 MTU 问题还是 LL 层的一些分段错误,但这一事实应该可以帮助研发团队采取纠正措施。 对于其他设计人员而言、这可能是堆栈中存在其他问题的迹象?

    7.作为一项变通办法,我可以用每块230字节完成我的 OAD 测试;也许有一天,一个补丁会加速它。

    请告诉我您的想法。

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

    尊敬的 Stuart:

    感谢您的反馈、这将有助于我们找到问题的根本原因、我将您提供的信息添加到错误报告中、我们正在积极地进行处理。  

    有了补丁后、我会立即回复您。  

    此致、

    丹桂语