防止重置内存分配失败。

⚠️
大家好. .感谢来到论坛。令人兴奋的消息!我们现在正在转移到新的论坛平台的过程中,它将提供更好的功能,并包含在主对话网站。所有的帖子和账号已经迁移。我们现在只接受新论坛的流量-请发布任何新的帖子在//www.xmece.com/support.我们会在接下来的几天修复bug /优化搜索和标记。
8个员额/0个新员额
最后发表
stawiski
离线
最后看到:3个月2周前
加入:2019-10-25 12:00
防止重置内存分配失败。

你好,

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

我已经到了一个地步,只要改变一个参数,我就可以用reset_MEM_ALLOC_FAIL error重置应用程序,或者不重置,我想知道如何防止这种情况。

我的申请代码如下:

  • 设置定时器0,以每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_对话框
离线
最后看到:5个月2个星期前
工作人员
加入:2019-04-03 02:54
嗨,斯塔维斯基,

嗨,斯塔维斯基,

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

顺便说一句,如果由于任何原因没有发送消息,应该使用ke_msg_free()释放空间。

比尔,

PW_对话框

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

嗨PW,

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

问候

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

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

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

我可能以后再谈这个问题。

PM_Dialog
离线
最后看到:1周3天前
工作人员
加入:2018-02-08 11:03
嗨,斯塔维斯基,

嗨,斯塔维斯基,

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

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

谢谢,PM_Dialog

stawiski
离线
最后看到:3个月2周前
加入: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()'签名,我希望函数在内存分配失败时返回空指针,为什么会产生重置?

总的来说,由于跳转到'platform_reset_func()'后调用堆栈被破坏,因此很难找到此故障的跟踪,我相信这是由于跳转表造成的。

问候

PM_Dialog
离线
最后看到:1周3天前
工作人员
加入:2018-02-08 11:03
嗨,斯塔维斯基,

嗨,斯塔维斯基,

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

请尝试增加连接间隔和堆大小,好吗?

谢谢,PM_Dialog

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

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

ke_check_malloc()

先呼后呼

KE_MSG_ALLOC_DYN ()

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

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

用户\u捕获\u剩余\u hndl()

以及在未收到确认的情况下丢弃要排队的数据包。我实现了一个简单的计数器,它在“ke_msg_send()”上递增,在“user_catch_rest_hndl()”的处理程序中递减。

这个解决方案的问题是,我开始看到大量丢弃的数据包。非常有趣的是,在Windows上我可以看到高达10%的丢包率,而在Mac上我根本看不到丢包。

无论如何,内存崩溃已经消失。我的程序中没有内存泄漏,我只使用

KE_MSG_ALLOC_DYN ()

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

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