防止RESET_MEM_ALLOC_FAIL。

了解更多常见问题教程

8个职位/ 0个新职位
最后发表
stawiski
离线
最后看到:3周3天前
加入:2019-10-25 12:00
防止RESET_MEM_ALLOC_FAIL。

你好,

我正在使用示例应用程序“da14531-ble- notification -button-wakeup”,我对它进行了一些修改。

现在,只需更改一个参数,就可以使用RESET_MEM_ALLOC_FAIL错误或不使用RESET_MEM_ALLOC_FAIL错误重置应用程序,我想了解如何防止这种情况发生。

我的申请代码如下:

  • 设置timer0每10ms/15ms触发一次中断
  • 在计时器回调中,如果用户已连接,强制BLE唤醒并使用app_easy_wakeup函数安排我的发送函数
  • 在我的发送函数中,用一些数据填充JSON字符串,使用KE_MSG_ALLOC_DYN分配内存,填充结构并发送它

现在是这样的:

  • 如果timer0回调被设置为10ms,就像上面的例子一样。连接10s后复位
  • 如果timer0回调设置为15ms,一切都正常(没有重置)

经过一些挖掘之后,当分配内存失败时,导致重置的唯一函数似乎是attm_svc_create_db()。

它在分配失败时崩溃的事实是有意义的(甚至在doxygen中有记录),但是,我希望我的程序能够检查是否可以分配足够的内存。我希望KE_MSG_ALLOC_DYN在失败时返回nullptr,但从我的实验来看,KE_MSG_ALLOC_DYN似乎可以成功,并且在ke_msg_send()之后触发重置。

我似乎不能做一个检查,看看是否向下调用堆栈的服务缓冲区将被分配。

问候

设备:
PW_Dialog
离线
最后看到:8小时55分钟前
工作人员
加入:2019-04-03 02:54
嗨Stawiski,

嗨Stawiski,

你能确认你想在任务之间发送消息分配消息缓冲区由KE_MSG_ALLOC_DYN,并且KE_MSG_ALLOC_DYN的返回不是nullptr时重置发生?您检查过如果减少或扩大分配大小会发生什么吗?可能还可以检查KE_MSG_ALLOC。它从KE_MEM_KE_MSG中分配堆内存。

顺便说一下,如果消息没有被发送,应该使用ke_msg_free()来释放空间。

Br,

PW_Dialog

stawiski
离线
最后看到:3周3天前
加入:2019-10-25 12:00
嗨PW,

嗨PW,

我将进一步调查此事,并让你知道。

问候

stawiski
离线
最后看到:3周3天前
加入:2019-10-25 12:00
我在调查,结果

我在调查,这与睡眠中断和睡眠模式有关。当我为UART设置DMA,然后进入休眠,并在外围init中重新初始化DMA时,我遇到了非常类似的问题。在一些DMA回调被触发后,我实际上一直在获得回调,就像DMA崩溃时一样。

现在我已经在我的应用程序中禁用了睡眠,这完全解决了这个问题,并解除了我进一步开发应用程序的障碍。

我可能过会儿会再讲这个。

PM_Dialog
离线
最后看到:1小时3分钟前
工作人员
加入:2018-02-08 11:03
嗨stawiski,

嗨stawiski,

谢谢你的指点。如果你有任何额外的反馈,请给我们。非常欢迎您的反馈。

如果您有任何其他问题,请提出一个新的论坛帖子。

谢谢,PM_Dialog

stawiski
离线
最后看到:3周3天前
加入:2019-10-25 12:00
你好再次,

你好再次,

不幸的是,这个问题仍然存在完全禁用睡眠模式。

这是现在开发我的应用程序的主要障碍。

我注意到这还会随机发生如果我让我的应用程序运行足够长的时间,而流数据从“通知”特征。有时几分钟后就会崩溃,有时需要15-20分钟。

我能够追踪到我认为是这个问题的根源,我需要Dialog的确认以及如何防止这一问题的建议。以下是我的发现:

  • 堆栈跟踪显示在使用0xF2F2F2F2参数调用' platform_reset_func() '之前调用' ke_msg_alloc() '
  • ' ke_msg_alloc() '在我的应用程序中由' KE_MSG_ALLOC_DYN() '宏使用

以下是我的问题:

  • 扫描SDK,只有一个提到的RESET_MEM_ALLOC_FAIL在' attm_svc_create_db() ',但似乎有其他地方产生这个重置,是那些?
  • 你提到' ke_msg_alloc() '使用KE_MEM_KE_MSG,我可以只配置内存更大吗?
  • 通过' ke_msg_alloc() '签名,我希望函数在内存分配失败时返回NULL指针,为什么会产生重置?

总的来说,由于跳转到' platform_reset_func() '后调用堆栈被损坏,很难找到这个失败的跟踪,我认为这是由于跳转表。

问候

PM_Dialog
离线
最后看到:1小时3分钟前
工作人员
加入:2018-02-08 11:03
嗨stawiski,

嗨stawiski,

Τhe platform_reset_func()由platform_reset()调用,它在ROM代码中实现。得到这个断言的最可能的原因是内存不足,因为您分配的消息永远不会被消耗。例如,如果您正在分配通知消息,并且您有一个小的连接间隔,那么消息将被堆起来直到连接事件到达,但是如果连接间隔较大,则在连接事件到达之前就会耗尽内存。您可以增加连接间隔。在您的应用程序中,在每个连接之后可能会出现某种内存泄漏堆积,因为错误代码是RESET_MEM_ALLOC_FAIL。为此,请检查是否有任何挂起消息,并确保您正在使用在处理消息时获得的消息,或者您正在分配应该释放它们的数据。

你能试着增加连接间隔和堆大小吗?

谢谢,PM_Dialog

stawiski
离线
最后看到:3周3天前
加入:2019-10-25 12:00
谢谢你的解释。

谢谢你的解释。根据堆大小的建议,我实现了一些在程序崩溃时调用的帮助函数,实际上,该程序运行时KE MSG的内存不足。我没有深入了解的是,执行

ke_check_malloc ()

先呼后呼

KE_MSG_ALLOC_DYN ()

没有帮助,就好像在传递消息之后有更多的内存试图在内部分配。

最后,为我的通知实现一个自定义处理程序有什么帮助吗

user_catch_rest_hndl ()

如果没有收到确认,则丢弃要排队的数据包。我已经实现了一个简单的计数器,它在' ke_msg_send() '上递增,在我的处理程序' user_catch_rest_hndl() '中递减。

这个解决方案的问题是,我开始看到很多丢失的数据包。非常有趣的是,在Windows上,我将看到高达10%的数据包丢失率,而在Mac上,我将看不到任何数据包丢失。

在任何情况下,内存崩溃都不会发生。我的程序中没有内存泄漏,我只使用

KE_MSG_ALLOC_DYN ()

在单数位置-与示例代码相同。

此外,增加KE MSG的堆大小确实有助于减少Windows客户端丢弃的包,但它没有完全消除丢弃。