ESP32 Arduino: Getting the Free Heap

The objective of this post is to explain how to obtain and print the ESP32 free heap, using the Arduino core. The tests of this ESP32 tutorial were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.

Introduction

The objective of this post is to explain how to obtain and print the ESP32 free heap memory, using the Arduino core.

The tests of this ESP32 tutorial were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.

If you prefer a video version of this tutorial, please check below my YouTube channel.

The code

The code for this will be very simple, since we already have defined in the EspClass a method for obtaining the free heap value. Note that the methods of this class are exposed in an extern variable called ESP.

So, in the Arduino setup function, we starting by opening a serial connection, so we can output the value of the free heap.

Serial.begin(115200);

Next, to obtain the free heap, we simply call the getFreeHeap method of the ESP extern variable. This method takes no arguments and returns as output the free heap, in bytes.

One important note is that, due to memory fragmentation, it may not be possible to allocate the total amount of memory returned by this function.

Serial.println(ESP.getFreeHeap());

You can check the full source code below. Note that we left the main loop function empty since we don’t need to use it for this tutorial.

void setup() {
  Serial.begin(115200);
  Serial.println(ESP.getFreeHeap());
}

void loop() {}

Testing the code

To test, simply open the Arduino IDE serial monitor after compiling and uploading the code to your ESP32 device. You should get an output similar to figure 1, which shows the available heap space on the device.

ESP32 Arduino core getting free heap.png

Figure 1 – Output of the program.

13 thoughts on “ESP32 Arduino: Getting the Free Heap”

  1. Pingback: ESP32 Arduino web server: Get free heap and reset device remotely | techtutorialsx

  2. Pingback: ESP32 Arduino web server: Get free heap and reset device remotely | techtutorialsx

  3. What exactly is the difference in calculating the heap with esp_get_free_heap_size() or with esp_get_minimum_free_heap_size()? To me, the return value of the heap with esp_get_free_heap_size() doesn’t seem realistic enough, but when the value is used to allocate memory, there are crashes that indicate that apparently more than the largest possible memory that can be allocated is mentioned. So what use is esp_get_free_heap_size()?

    1. Hi!

      At the time I’ve written this post I think there were not so many different heap related functions available and the implementation of the getFreeHeap would call the esp_get_free_heap_size function under the hood.

      I haven’t yet analyzed in depth the new implementation and functions but if you take a look at the header file that contains the definition of the esp_get_free_heap_size(), it says the following:
      “Get the size of available heap. Note that the returned value may be larger than the maximum contiguous block which can be allocated.”
      Source: https://github.com/espressif/arduino-esp32/blob/39fb8c30440a4abd5fe0e2c87609ba6798ae8013/tools/sdk/include/esp32/esp_system.h

      This function seems to be similar to the heap_caps_get_free_size, which has an even more illustrating description:
      /**
      * @brief Get the total free size of all the regions that have the given capabilities
      *
      * This function takes all regions capable of having the given capabilities allocated in them
      * and adds up the free space they have.
      *
      * Note that because of heap fragmentation it is probably not possible to allocate a single block of memory
      * of this size. Use heap_caps_get_largest_free_block() for this purpose.
      * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
      * of memory
      *
      * @return Amount of free bytes in the regions
      */”

      So the crashes that you are experiencing may be related to the fact that although this function call indicates an x amount of total memory available, then maybe there is not a chunk big enough for what you are trying to allocate.

      In the same file, if you read the header of the esp_get_minimum_free_heap_size, it says the following:
      “Get the minimum heap that has ever been available”.

      So that function has kind of a misleading name, but it seems that it returns the minimum value ever available.

      Again, there’s a similar one: heap_caps_get_minimum_free_size which says:
      /**
      * @brief Get the total minimum free memory of all regions with the given capabilities
      *
      * This adds all the low water marks of the regions capable of delivering the memory
      * with the given capabilities.
      *
      * Note the result may be less than the global all-time minimum available heap of this kind, as “low water marks” are
      * tracked per-region. Individual regions’ heaps may have reached their “low water marks” at different points in time. However
      * this result still gives a “worst case” indication for all-time minimum free heap.
      *
      * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
      * of memory
      *
      * @return Amount of free bytes in the regions
      */

      Additionally, there’s a function called heap_caps_get_largest_free_block (defined here: https://github.com/espressif/arduino-esp32/blob/a59eafbc9dfa3ce818c110f996eebf68d755be24/tools/sdk/include/heap/esp_heap_caps.h) that says the following:

      “Get the largest free block of memory able to be allocated with the given capabilities. Returns the largest value of “s“ for which “heap_caps_malloc(s, caps)“ will succeed”

      So this probably is the one that can be used to know the maximum value you can allocate without problems, even though the total heap size available is bigger.

      In short, from my understanding, the use of the esp_get_free_heap_size should be to get the total amount of heap available, not necessarily the total value you can allocate due to memory fragmentation.

      Nonetheless, these are lower level APIs from IDF. The Arduino core has some wrappers around in the esp.h file, which contains the following functions. I think they are easier to understand.

      //Internal RAM
      uint32_t getHeapSize(); //total heap size
      uint32_t getFreeHeap(); //available heap
      uint32_t getMinFreeHeap(); //lowest level of free heap since boot
      uint32_t getMaxAllocHeap(); //largest block of heap that can be allocated at once

      the esp.h file: https://github.com/espressif/arduino-esp32/blob/80c110ece70b179ddfe686e8ee45b6c808779454/cores/esp32/Esp.h

      Please note that I haven’t tested this and these are guesses from a quick reading I’ve done to the header files after reading your comment.

      Also, there are some questions that I don’t know how to answer:
      Why is there a esp_system.h and a esp_heap_caps.h file on the SDK with heap related functions that seem to be similar? Do they return the same values, are some of them going to be deprecated?

      Probably the best place to find answers is on the IDF GitHub page or documentation, since these are SDK functions.

      Hope this helps getting you on the right track and in case you have the change to test or find more about it let us know, since it would be very interesting to understand these functions better 🙂

      I will also update the post to remove the sentence that says that the getFreeHeap function uses the esp_get_free_heap_size under the hood since that no longer applies.

      Best regards,
      Nuno Santos

  4. What exactly is the difference in calculating the heap with esp_get_free_heap_size() or with esp_get_minimum_free_heap_size()? To me, the return value of the heap with esp_get_free_heap_size() doesn’t seem realistic enough, but when the value is used to allocate memory, there are crashes that indicate that apparently more than the largest possible memory that can be allocated is mentioned. So what use is esp_get_free_heap_size()?

    1. Hi!
      At the time I’ve written this post I think there were not so many different heap related functions available and the implementation of the getFreeHeap would call the esp_get_free_heap_size function under the hood.
      I haven’t yet analyzed in depth the new implementation and functions but if you take a look at the header file that contains the definition of the esp_get_free_heap_size(), it says the following:
      “Get the size of available heap. Note that the returned value may be larger than the maximum contiguous block which can be allocated.”
      Source: https://github.com/espressif/arduino-esp32/blob/39fb8c30440a4abd5fe0e2c87609ba6798ae8013/tools/sdk/include/esp32/esp_system.h
      This function seems to be similar to the heap_caps_get_free_size, which has an even more illustrating description:
      /**
      * @brief Get the total free size of all the regions that have the given capabilities
      *
      * This function takes all regions capable of having the given capabilities allocated in them
      * and adds up the free space they have.
      *
      * Note that because of heap fragmentation it is probably not possible to allocate a single block of memory
      * of this size. Use heap_caps_get_largest_free_block() for this purpose.
      * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
      * of memory
      *
      * @return Amount of free bytes in the regions
      */”

      So the crashes that you are experiencing may be related to the fact that although this function call indicates an x amount of total memory available, then maybe there is not a chunk big enough for what you are trying to allocate.
      In the same file, if you read the header of the esp_get_minimum_free_heap_size, it says the following:
      “Get the minimum heap that has ever been available”.
      So that function has kind of a misleading name, but it seems that it returns the minimum value ever available.
      Again, there’s a similar one: heap_caps_get_minimum_free_size which says:
      /**
      * @brief Get the total minimum free memory of all regions with the given capabilities
      *
      * This adds all the low water marks of the regions capable of delivering the memory
      * with the given capabilities.
      *
      * Note the result may be less than the global all-time minimum available heap of this kind, as “low water marks” are
      * tracked per-region. Individual regions’ heaps may have reached their “low water marks” at different points in time. However
      * this result still gives a “worst case” indication for all-time minimum free heap.
      *
      * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
      * of memory
      *
      * @return Amount of free bytes in the regions
      */
      Additionally, there’s a function called heap_caps_get_largest_free_block (defined here: https://github.com/espressif/arduino-esp32/blob/a59eafbc9dfa3ce818c110f996eebf68d755be24/tools/sdk/include/heap/esp_heap_caps.h) that says the following:
      “Get the largest free block of memory able to be allocated with the given capabilities. Returns the largest value of “s“ for which “heap_caps_malloc(s, caps)“ will succeed”
      So this probably is the one that can be used to know the maximum value you can allocate without problems, even though the total heap size available is bigger.
      In short, from my understanding, the use of the esp_get_free_heap_size should be to get the total amount of heap available, not necessarily the total value you can allocate due to memory fragmentation.
      Nonetheless, these are lower level APIs from IDF. The Arduino core has some wrappers around in the esp.h file, which contains the following functions. I think they are easier to understand.
      //Internal RAM
      uint32_t getHeapSize(); //total heap size
      uint32_t getFreeHeap(); //available heap
      uint32_t getMinFreeHeap(); //lowest level of free heap since boot
      uint32_t getMaxAllocHeap(); //largest block of heap that can be allocated at once
      the esp.h file: https://github.com/espressif/arduino-esp32/blob/80c110ece70b179ddfe686e8ee45b6c808779454/cores/esp32/Esp.h
      Please note that I haven’t tested this and these are guesses from a quick reading I’ve done to the header files after reading your comment.
      Also, there are some questions that I don’t know how to answer:
      Why is there a esp_system.h and a esp_heap_caps.h file on the SDK with heap related functions that seem to be similar? Do they return the same values, are some of them going to be deprecated?
      Probably the best place to find answers is on the IDF GitHub page or documentation, since these are SDK functions.
      Hope this helps getting you on the right track and in case you have the change to test or find more about it let us know, since it would be very interesting to understand these functions better 🙂
      I will also update the post to remove the sentence that says that the getFreeHeap function uses the esp_get_free_heap_size under the hood since that no longer applies.
      Best regards,
      Nuno Santos

  5. Hi, since I use Strings in my sketches, which eventually fragment the memory and cause the esp32 to freeze, would using this function to monitor free memory left and if it drops down to something like 2KB, then forcing a reboot, be a good way to ensure the esp32 keep working without intervention? thanks

    1. Hi!

      I’m not sure if this would work, as I’ve never tested such scenario.

      Nonetheless, I would say that if you are in such need, it would be best to find an alternative way to handle the strings in your program, to ensure it keeps working continuously.

      Isn’t using char * instead of string a possibility, or do you have a particular need for using Strings?

      Best regards,
      Nuno Santos

  6. Hi, since I use Strings in my sketches, which eventually fragment the memory and cause the esp32 to freeze, would using this function to monitor free memory left and if it drops down to something like 2KB, then forcing a reboot, be a good way to ensure the esp32 keep working without intervention? thanks

    1. Hi!
      I’m not sure if this would work, as I’ve never tested such scenario.
      Nonetheless, I would say that if you are in such need, it would be best to find an alternative way to handle the strings in your program, to ensure it keeps working continuously.
      Isn’t using char * instead of string a possibility, or do you have a particular need for using Strings?
      Best regards,
      Nuno Santos

  7. Hello there,
    Thanks for this post, it helped me.
    What I am missing here is in what unit the getFreeHeap() returns its value. I suppose it is Kb but that is what I was looking for in this post.
    Best Regards
    Jannik

Leave a Reply

Discover more from techtutorialsx

Subscribe now to keep reading and get access to the full archive.

Continue reading