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:OAD 处理可能的内存分配/释放错误?

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1349261/cc2340r5-oad-service-possible-memory-alloc-free-bug

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

嗨、大家好、

在调试基于基本 BLE 项目的持久应用模型 OAD 片上项目时、我想知道 SDK 7_40版本中的默认代码是否存在意外问题:  

该代码位于 [OADService_SetParameter (oadServiceChar_e srvChar、uint8 len、void * value)的 bStatus_t OADService_SetParameter (oadServiceChar_e srvChar、len、void * value)函数中、似乎是为通知结构分配的内存

   attHandleValueNoti_t 通知;

使用这行代码:  

    notification.pValue = GATT_BM_alloc (ACTIVeOadCxnHandle、ATT_Handle_Value_Noti、 len、NULL);

如果你检查函数中的错误路径、有两条路径、其中分配的内存(在本例中是应用发出 BLK 大小请求时)可能无法返回堆。

其中一种情况可能会导致泄漏:

   pAttr = GATTclg App_Find 11ntr (oadAttrTbl、GATT_NUM_ATTRS(oadAttrTbl)、 oadCharVals+srvChar);

   if (pAttr == NULL)
   {
     //如果找不到属性,则报告错误
     返回(ATT_ERR_ATTR_NOT_FOUND);
   }

另一个是在这里、其中在 free 函数中使用了错误的指针:

   状态= GATT_Notification (activeOadCxnHandle、&notification、false);

   if (状态!=成功)
   {
     //堆栈将为我们释放内存,如果
     //通知成功,否则我们
     //手动释放内存
     GATT_BM_FREE ((gattMsg_t *)&NOTIFICATION、ATT_Handle_Value_Noti);
   }

在后一种情况下,调用 GATT_BM_FREE()会尝试传递在栈上创建的本地地址,而 FREE 命令最有可能避免对其执行操作(这可能会导致另一个泄漏)。

问:我在这里遗漏了什么? 是否需要修改此源文件的本地工作副本以更正这两个错误路径?  

提前感谢。

路径 C:\ti\simplelink_lowpower_f3_sdk_7_40_00_64\source\ti\bleapp\services\oad\oad_service.c

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

    嗨、

    好的抓住内存泄漏在第一个路径,我报告给维护人员。 在等待补丁时、我建议在返回之前添加 GATT_BM_FREE。

    if(pAttr == NULL)
    {
        // If we cannot find the attribute, report an error
        GATT_bm_free((gattMsg_t *)&notification, ATT_HANDLE_VALUE_NOTI);
        return (ATT_ERR_ATTR_NOT_FOUND);
    }

    在您确定的第二个路径中、GATT_BM_FREE 函数不存在问题、因为它释放通知的有效载荷、而不是指针本身。 有关 GATT 过程的内存分配的更多详细信息、请查看以下文档: https://software-dl.ti.com/simplelink/esd/simplelink_lowpower_f3_sdk/7.40.00.64/exports/docs/ble5stack/ble_user_guide/html/ble-stack-5.x/gatt-cc23xx.html#allocating-memory-for-gatt-procedures

    此致

    丹桂语

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

    谢谢! 最好知道 GATT_BM_FREE ()正在处理有效负载存储器!

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

    在 OAD_service 中发现了另一个可疑的 malloc/free 泄漏路径。 C 在过程 OadWriteAttrCB()的两个地方(我不认为它们对我的问题有贡献(我将在单独的线程中发布) ,但如果 iCall_malloc()的正文至 BLEAppUtil_invokeFunction()失败,为 pOADSrvWriteReq 对象分配的内存未释放, 同样,如果对  BLEAppUtil_invokeFunction()的调用失败(例如如果队列已满),则这两个对象不会按其应有的方式释放。

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

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

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

    该问题通常在主片上应用的固件映像中的802个字节中的400-600个块(每个块236字节)之后某处开始。 但有趣的是、失速并不是每次都在同一点发生。

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

    我们另一个基于 CC2640的器件的 OAD 更新仅约为44K、CC2340R5始终使其超过44K 点、在传输大约100-130K 后卡住。 我们可以看到在发生故障之前一直刷写到 mainapp 区域中的正确代码。

    因此,所有的外观在 API 级别的记忆泄漏的衰减。  除了在 OAD_service.c 和 OAD_profile.c 中进行一些微调以添加一些诊断计数器(这些计数器尚未揭示明显的资源问题)之外、这些是 SLP SDK 7_40中提供的示例源代码版本。    

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

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

    您怎么看?

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

    Stuart、您好!

    感谢您提出宝贵的见解。

    请允许我今天详细介绍一下、然后再给您回复。

    Br、

    大卫。

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

    尊敬的 David:

    有关我们通过 l2capNumDataPkts 和溢出发现的问题的成功解决方法和一些关键详细信息、请参阅此处:

    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/5160793#5160793

    希望这对您的努力有所帮助。

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

    Stuart、您好!

    谢谢。 我看到 R&D 团队根据已发布到另一个主题的内容解决了该问题。

    至于这个其他潜在的问题,如果 iCall_malloc ()函数失败,那么它将不会分配内存并返回 NULL ,因此无需释放。 你正在引用的两个分配也是 iCall_malloc()在条件 if (oadWriteCB != NULL)正确吗?

    Br、

    大卫。