【问题标题】:Checking memory footprint in Arduino检查 Arduino 中的内存占用
【发布时间】:2020-09-09 22:00:09
【问题描述】:

我正在用我的 Arduino 做一个简单的项目。最近我不得不将我的一个变量转换为 long 而不是 int,为了简单起见,我只是移动了它与之交互的所有数字(所以我不必担心跨类型比较和数学)。这看起来很浪费,但它只是我自己的时钟,我并不在乎。

然而,它让我想知道我正在使用多少内存。我怀疑这是个问题,但我意识到我不知道有什么方法可以检查。

那么,有没有办法检查 Arduino 使用的内存量?

理想情况下,我想通过串行连接打印出当前可用的内存/总量。

【问题讨论】:

标签: memory-management arduino


【解决方案1】:

尝试使用MemoryFree。这个库对我来说效果很好。

【讨论】:

    【解决方案2】:

    你可以用这个。它会让你知道你在哪里:

    Serial.print(availableMemory());
    
    // free RAM check for debugging. SRAM for ATmega328p = 2048Kb.
    int availableMemory() {
        // Use 1024 with ATmega168
        int size = 2048;
        byte *buf;
        while ((buf = (byte *) malloc(--size)) == NULL);
            free(buf);
        return size;
    }
    

    【讨论】:

    • 这仅测量堆使用情况(忽略堆栈和全局变量),如果堆碰巧被碎片化,则会失败。
    【解决方案3】:

    Arduino Playground 上有关于此的详细信息,我在那里找到了我一直在使用的方法:

    MemoryFree.h:

    // MemoryFree library based on code posted here:
    // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15
    //
    // Extended by Matthew Murdoch to include walking of the free list.
    
    #ifndef MEMORY_FREE_H
    #define MEMORY_FREE_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
      int freeMemory();
    
    #ifdef  __cplusplus
    }
    #endif
    
    #endif
    

    MemoryFree.cpp:

    #if (ARDUINO >= 100)
    #include <Arduino.h>
    #else
    #include <WProgram.h>
    #endif
    
    extern unsigned int __heap_start;
    extern void *__brkval;
    
    /*
     * The free list structure as maintained by the 
     * avr-libc memory allocation routines.
     */
    struct __freelist {
      size_t sz;
      struct __freelist *nx;
    };
    
    /* The head of the free list structure */
    extern struct __freelist *__flp;
    
    #include "MemoryFree.h";
    
    /* Calculates the size of the free list */
    int freeListSize() {
      struct __freelist* current;
      int total = 0;
    
      for (current = __flp; current; current = current->nx) {
        total += 2; /* Add two bytes for the memory block's header  */
        total += (int) current->sz;
      }
    
      return total;
    }
    
    int freeMemory() {
      int free_memory;
    
      if ((int)__brkval == 0) {
        free_memory = ((int)&free_memory) - ((int)&__heap_start);
      } else {
        free_memory = ((int)&free_memory) - ((int)__brkval);
        free_memory += freeListSize();
      }
      return free_memory;
    }
    

    示例草图:

    #include &lt;MemoryFree.h&gt;
    
    // On Arduino Duemilanove with ATmega328:
    //
    // Reported free memory with str commented out:
    // 1824 bytes
    //
    // Reported free memory with str and Serial.println(str) uncommented:
    // 1810
    //
    // Difference: 14 bytes (13 ascii chars + null terminator)
    
    // 14-bytes string
    //char str[] = "Hello, world!";
    
    
    void setup() {
        Serial.begin(115200);
    }
    
    
    void loop() {
        //Serial.println(str);
    
        Serial.print("freeMemory()=");
        Serial.println(freeMemory());
    
        delay(1000);
    }
    

    【讨论】:

      【解决方案4】:

      根据 Esben 的回答,我编写了这个优化版本:

      int biggestMemoryBlock(uint16_t min,uint16_t max)
      {
        if (min==max-1)
          return min;
      
        int size=max;
        int lastSize=size;
        byte *buf;
        while ((buf = (byte *) malloc(size)) == NULL)
        {
          lastSize=size;
          size-=(max-min)/2;
        };
      
        free(buf);
        return biggestMemoryBlock(size,lastSize);
      };
      
      
      int biggestMemoryBlock() 
      {
          return biggestMemoryBlock(0,4096);
      }
      

      在 Arduino Uno 上,它只需 1 毫秒或更短的时间,而不是原始功能的 13-20 毫秒。该常量必须至少是板上的总内存(以字节为单位)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        相关资源
        最近更新 更多