Flash Diet
My ESP32 Flash Went on a Diet: A Tale of Shrinking Binaries
I’ve been on a quest. A quest to shrink the flash size of my ESP32 application. After many hours of tweaking, compiling, and measuring, I’m excited to share my results. I managed to reduce my binary size from a hefty 1,256,240 bytes down to a lean 973,024 bytes, a saving of 283,216 bytes!
Here’s a breakdown of my journey, from the biggest wins to the final few bytes I could squeeze out. I’ve also researched the potential consequences of each optimization so you can decide if these trade-offs are right for your project.
The Heavy Hitters: Where the Real Savings Are
These are the optimizations that made the biggest difference. If you’re looking to make a serious dent in your flash usage, start here.
- Minimal Build (69,408 bytes saved): This was the single biggest saving. By enabling the “minimal build” option in the ESP-IDF, you’re telling the compiler to strip out a lot of features that you might not be using.
- Consequences: None really, performance may be suffering in some theoretical scenario. Just go for it!
- Removing Major Components (49,664 bytes saved): I ripped out MQTT, SPI Ethernet, and Soft AP support.
- Consequences:
- MQTT: You lose the ability to use this popular IoT protocol. If you’re not using it, it’s a no-brainer to remove it.
- SPI Ethernet: If you’re not using a wired Ethernet connection, this is safe to remove.
- Soft AP: Your ESP32 can no longer act as a Wi-Fi access point. This is often used for initial configuration, so make sure you have an alternative provisioning method if you disable this.
- Consequences:
- Embrace the NanoLib (46,992 bytes saved): I enabled the
newlib-nano
library. This is a smaller version of the standard C library.- Consequences:
newlib-nano
has some limitations. For example, it has limited support for floating-point operations inprintf
. You might also encounter issues with some libraries that expect the fullnewlib
.
- Consequences:
- Goodbye IPv6 (29,120 bytes saved): I disabled IPv6 support.
- Consequences: Your device will not be able to communicate over IPv6 networks. In most home networks, this is not an issue, but if your application needs to work in an IPv6-only environment, this is not an option for you.
- Downgrading Wi-Fi Security (19,968 bytes saved): I disabled WPA3 Personal support.
- Consequences: This is a security trade-off. WPA3 is the latest and most secure Wi-Fi security protocol. By disabling it, you are making your device less secure and more vulnerable to attacks. Only do this if you are on a private, trusted network.
The Nitty-Gritty: Smaller Tweaks, Big Impact
These optimizations don’t save as much space individually, but they add up.
- BLE Diet (17,712 bytes, 15,808 bytes, 11,648 bytes, and 10,336 bytes saved): I made several changes to the Bluetooth Low Energy stack:
- No BLE 5 features: Disabling BLE 5 features.
- Removed BLE security feature: This will make your BLE communication insecure.
- Removed nimble central role: This may break the MTU (Maximum Transmission Unit) size negotiation.
- No nimble logs: Disabling logs from the NimBLE stack.
- Consequences: These changes will significantly impact your BLE functionality. You’ll have a less secure, less feature-rich, and potentially less reliable BLE implementation.
- ECC on a Diet (9,632 bytes saved): I removed a lot of ECC (Elliptic Curve Cryptography) curve support.
- Consequences: This will limit the types of TLS certificates your device can use. If you are connecting to a server that uses a certificate with an unsupported curve, the connection will fail.
The Final Squeeze: Every Byte Counts
These are the smallest optimizations, but they still contributed to the final result.
- Silent Asserts (2,208 bytes saved): I enabled silent asserts.
- Consequences: This will make debugging more difficult. When an assert fails, the device will simply crash without printing a message.
- Less Wi-Fi Security (528 bytes saved): I disabled enterprise WPA2.
- Consequences: If you are not connecting to an enterprise Wi-Fi network that uses WPA2, this is safe to disable.
- Certificate Pruning (272 bytes saved): I enabled only PEM certificate reading.
- Consequences: Your device will only be able to read certificates in the PEM format.
- Wi-Fi AMPDU Tweaks (80 bytes saved): I disabled
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED
.- Consequences: This may slightly reduce Wi-Fi throughput.
Was It Worth It?
That’s the big question, isn’t it? For my project, absolutely. The flash space I saved allows me to add more features and have more breathing room for future development. However, many of these optimizations come with significant trade-offs in terms of security, functionality, and ease of debugging.
Before you go on your own flash-shrinking adventure, carefully consider the consequences of each optimization and whether it’s a price you’re willing to pay. Happy optimizing!
Got some other ideas? Comments are open!
tags: programming - esp32 - flash - optimization - size - development
💬 Comments
Post comment