FreeRTOS上的堆内存不足

问题描述

我正在使用FreeRTOS V9.0.0在Marvell MW300板上运行我的应用程序。 在我的应用程序中,当我尝试连接HTTPS服务器时,mbedtls显示错误

[wm_mbedtls] ssl_tls.c:5431: |1| 0x00121188: alloc(4429 in bytes) (4429 out bytes) Failed.

在调试过程中,观察者认为这是由于堆内存不足所致。这是堆内存状态

Heap size ---------------------- : 305536
Free size ---------------------- : 17888
Peak Heap Usage since bootup --- : 291048
Total allocations -------------- : 136
Failed allocations ------------- : 0
Min overhead per allocation ---- : 16
Biggest free block available Now : 8040

在尝试连接HTTPS服务器之前,我会打印此堆内存信息。 可以观察到,当设备尝试连接HTTPS服务器时,mbedtls希望分配两个4429字节缓冲区(输入和输出),但是由于最大可用空闲块是8040,因此它失败了 这是mbedtls的代码

/*
  * Prepare base structures
   */
     if( ( ssl-> in_buf = mbedtls_calloc( 1,MbedTLS_SSL_IN_BUFFER_LEN( ssl->conf ) ) ) == NULL ||
         ( ssl->out_buf = mbedtls_calloc( 1,MbedTLS_SSL_OUT_BUFFER_LEN( ssl->conf ) ) ) == NULL )
     {
                 MbedTLS_SSL_DEBUG_MSG( 1,( "alloc(%d in bytes) (%d out  bytes) Failed",MbedTLS_SSL_IN_BUFFER_LEN( ssl->conf ),MbedTLS_SSL_OUT_BUFFER_LEN( ssl->conf ) ) );
              mbedtls_free( ssl->in_buf );
                 ssl->in_buf = NULL;
             return( MbedTLS_ERR_SSL_ALLOC_Failed );
     }

板载的可用内存为17888。 是否可以在“可用块”中添加一些“可用内存”? 或有任何建议,如何处理此问题?

我正在使用堆4方案。

谢谢。

解决方法

根据您发布的日志,您总共有305536个字节可用于堆,其中您使用了287648个字节,仅剩下17888个字节记忆。换句话说,您会使用超过94%的可用“动态”内存。

对于通过TLS连接的应用程序(您已经提到了HTTPS,它是基于TLS的HTTP),拥有大约18KB的可用内存可能不够。我遇到的大多数TCP / IP堆栈实现中的TLS连接往往非常“繁重”,因为它们倾向于分配用于数据包加密和解密的内部缓冲区。 TLS握手过程中的证书验证步骤也不太“轻巧”,因为服务器可能会决定向您发送一整串的证书以进行验证,仅凭其本身就可能是千字节大小。所有这些至少必须暂时存储在内存中。

要回答您的Is it possible to add some “Free memory” into “free blocks available?问题,您有两种选择:

  1. 获得具有更多RAM的硬件:具有更多内部RAM的MCU或使用外部RAM芯片,

  2. 优化您的应用程序。

第一个选项是不言自明的。我首先建议选择第二种选择。我假设您提供的数字(17888个字节可用)适用于处于空闲状态/“什么都不做”的应用程序。如果是这样-那是很多,您应该研究导致这种情况下使用太多RAM的原因。这将涉及到调试应用程序的所有部分,这些部分可能会在某个时候动态分配内存。