Miscellaneous System APIs

Software reset

To perform software reset of the chip, esp_restart() function is provided. When the function is called, execution of the program will stop, both CPUs will be reset, application will be loaded by the bootloader and started again.

Additionally, esp_register_shutdown_handler() function is provided to register a routine which needs to be called prior to restart (when done by esp_restart()). This is similar to the functionality of atexit POSIX function.

Reset reason

ESP-IDF application can be started or restarted due to a variety of reasons. To get the last reset reason, call esp_reset_reason() function. See description of esp_reset_reason_t for the list of possible reset reasons.

Heap memory

Two heap memory related functions are provided:

Note that ESP-IDF supports multiple heaps with different capabilities. Functions mentioned in this section return the size of heap memory which can be allocated using malloc family of functions. For further information about heap memory see Heap Memory Allocation.

Random number generation

ESP32-C3 contains a hardware random number generator, values from it can be obtained using esp_random().

When Wi-Fi or Bluetooth are enabled, numbers returned by hardware random number generator (RNG) can be considered true random numbers. Without Wi-Fi or Bluetooth enabled, hardware RNG is a pseudo-random number generator. At startup, ESP-IDF bootloader seeds the hardware RNG with entropy, but care must be taken when reading random values between the start of app_main and initialization of Wi-Fi or Bluetooth drivers.

MAC Address

These APIs allow querying and customizing MAC addresses for different network interfaces that supported (e.g. Wi-Fi, Bluetooth, Ethernet).

In ESP-IDF these addresses are calculated from Base MAC address. Base MAC address can be initialized with factory-programmed value from internal eFuse, or with a user-defined value. In addition to setting the base MAC address, applications can specify the way in which MAC addresses are allocated to devices. See Number of universally administered MAC address section for more details.

Base MAC address

To fetch MAC address for a specific interface (e.g. Wi-Fi, Bluetooth, Ethernet), you can simply use esp_read_mac() function.

By default, this function takes the eFuse value burned at a pre-defined block (e.g. BLK0 for ESP32, BLK1 for ESP32-S2) as the base MAC address. Per-interface MAC addresses will be calculated according to the table above.

Applications who want to customize base MAC address (not the one provided by Espressif) should call esp_base_mac_addr_set() before esp_read_mac(). The customized MAC address can be stored in any supported storage device (e.g. Flash, NVS, etc).

Note that, calls to esp_base_mac_addr_set() should take place before the initialization of network stack, for example, early in app_main.

Custom MAC address in eFuse

To facilitate the usage of custom MAC addresses, ESP-IDF provides esp_efuse_mac_get_custom() function, which loads MAC address from internal pre-defined eFuse block (e.g. BLK3 for ESP32). This function assumes that custom MAC address is stored in the following format:


# of bits

Range of bits





0: invalid, others — valid




MAC address



MAC address CRC



CRC-8-CCITT, polynomial 0x07

Once MAC address has been obtained using esp_efuse_mac_get_custom(), call esp_base_mac_addr_set() to set this MAC address as base MAC address.

Number of universally administered MAC address

Several MAC addresses (universally administered by IEEE) are uniquely assigned to the networking interfaces (Wi-Fi/BT/Ethernet). The final octet of each universally administered MAC address increases by one. Only the first one of them (which is called base MAC address) is stored in eFuse or external storage, the others are generated from it. Here, ‘generate’ means adding 0, 1, 2 and 3 (respectively) to the final octet of the base MAC address.

If the universally administered MAC addresses are not enough for all of the networking interfaces, locally administered MAC addresses which are derived from universally administered MAC addresses are assigned to the rest of networking interfaces.

See this article for the definition of local and universally administered MAC addresses.

Chip version

esp_chip_info() function fills esp_chip_info_t structure with information about the chip. This includes the chip revision, number of CPU cores, and a bit mask of features enabled in the chip.

SDK version

esp_get_idf_version() returns a string describing the IDF version which was used to compile the application. This is the same value as the one available through IDF_VER variable of the build system. The version string generally has the format of git describe output.

To get the version at build time, additional version macros are provided. They can be used to enable or disable parts of the program depending on IDF version.

App version

Application version is stored in esp_app_desc_t structure. It is located in DROM sector and has a fixed offset from the beginning of the binary file. The structure is located after esp_image_header_t and esp_image_segment_header_t structures. The field version has string type and max length 32 chars.

To set version in your project manually you need to set PROJECT_VER variable in your project CMakeLists.txt/Makefile:

  • In application CMakeLists.txt put set(PROJECT_VER "") before including project.cmake.

(For legacy GNU Make build system: in application Makefile put PROJECT_VER = "" before including project.mk.)

If CONFIG_APP_PROJECT_VER_FROM_CONFIG option is set, the value of CONFIG_APP_PROJECT_VER will be used. Otherwise if PROJECT_VER variable is not set in the project then it will be retrieved from either $(PROJECT_PATH)/version.txt file (if present) else using git command git describe. If neither is available then PROJECT_VER will be set to “1”. Application can make use of this by calling esp_ota_get_app_description() or esp_ota_get_partition_description() functions.

API Reference


esp_err_t esp_register_shutdown_handler(shutdown_handler_t handle)

Register shutdown handler.

This function allows you to register a handler that gets invoked before the application is restarted using esp_restart function.


  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if the handler has already been registered

  • ESP_ERR_NO_MEM if no more shutdown handler slots are available

  • handle: function to execute on restart

esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handle)

Unregister shutdown handler.

This function allows you to unregister a handler which was previously registered using esp_register_shutdown_handler function.

  • ESP_OK on success

  • ESP_ERR_INVALID_STATE if the given handler hasn’t been registered before

void esp_restart(void)

Restart PRO and APP CPUs.

This function can be called both from PRO and APP CPUs. After successful restart, CPU reset reason will be SW_CPU_RESET. Peripherals (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset. This function does not return.

esp_reset_reason_t esp_reset_reason(void)

Get reason of last reset.


See description of esp_reset_reason_t for explanation of each value.

uint32_t esp_get_free_heap_size(void)

Get the size of available heap.

Note that the returned value may be larger than the maximum contiguous block which can be allocated.


Available heap size, in bytes.

uint32_t esp_get_free_internal_heap_size(void)

Get the size of available internal heap.

Note that the returned value may be larger than the maximum contiguous block which can be allocated.


Available internal heap size, in bytes.

uint32_t esp_get_minimum_free_heap_size(void)

Get the minimum heap that has ever been available.


Minimum free heap ever available

void esp_system_abort(const char *details)

Trigger a software abort.

  • details: Details that will be displayed during panic handling.

Type Definitions

typedef void (*shutdown_handler_t)(void)

Shutdown handler type


enum esp_reset_reason_t

Reset reasons.



Reset reason can not be determined.


Reset due to power-on event.


Reset by external pin (not applicable for ESP32)


Software reset via esp_restart.


Software reset due to exception/panic.


Reset (software or hardware) due to interrupt watchdog.


Reset due to task watchdog.


Reset due to other watchdogs.


Reset after exiting deep sleep mode.


Brownout reset (software or hardware)


Reset over SDIO.


const char *esp_get_idf_version(void)

Return full IDF version string, same as ‘git describe’ output.


If you are printing the ESP-IDF version in a log file or other information, this function provides more information than using the numerical version macros. For example, numerical version macros don’t differentiate between development, pre-release and release versions, but the output of this function does.


constant string from IDF_VER



Major version number (X.x.x)


Minor version number (x.X.x)


Patch version number (x.x.X)

ESP_IDF_VERSION_VAL(major, minor, patch)

Macro to convert IDF version number into an integer

To be used in comparisons, such as ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)


Current IDF version, as an integer

To be used in comparisons, such as ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)