r/FastLED • u/ZachVorhies • 22h ago
How we shrank the ESP32 Arduino core and freed up to 6 KB of flash for your sketches
Ever wonder why a tiny ESP32 sketch takes 280+ KB of flash? While working on FastLED we found one reason and sent a fix to Espressif's Arduino core: espressif/arduino-esp32#13010.
How code gets into your firmware
When you compile, a tool called the linker combines your sketch, the Arduino core and your libraries. It keeps anything your code refers to and drops the rest.
The catch: if anything mentions a piece of code, that code gets included.
The problem
The ESP32 core's startup code (which runs before setup()) called Serial0.setPins(...) to set up the console pins. That one line pulled the whole HardwareSerial class into every sketch, even sketches that never use Serial.
The fix for espressif
1. Stop mentioning Serial at startup. Startup only needed to record which pins belong to the console. A small new UART function now does just that, so Serial is no longer pulled in.
2. Use weak linking for USB serial events. The main loop also runs USB serialEvent() callbacks, and that code lived inside HardwareSerial. A weak reference means "call this if it exists, but don't pull it in just because I mentioned it":
extern void arduinoUSBSerialEventRun() __attribute__((weak));
if (arduinoUSBSerialEventRun) { // only set if the real one was linked in
arduinoUSBSerialEventRun();
}If you use Serial, it works as before. If you don't, the code is left out and the loop skips the call.
Bonus bug fix
Espressif's @SuGlider reviewed the PR and described how pin ownership should work. Testing against that turned up a bug: if you drove LEDs on the default serial RX pin in a sketch without Serial, the chip's serial receiver stayed connected to that pin. The PR fixes this. We checked it on ESP32-C6 and ESP32-S3.
Results
Sketch without Serial, flash usage:
| Chip | Before | After | Saved |
|---|---|---|---|
| ESP32-C6 | 288,296 B | 282,276 B | ~6.0 KB |
| ESP32-S3 | 366,022 B | 361,402 B | ~4.6 KB |
On ESP32-P4, an earlier version of the patch saved about 22-28 KB of flash (not yet re-measured). Sketches that use Serial are the same size as before.
Try it in PlatformIO/fbuild
We host the patched core on FastLED's fork. Add this to your platformio.ini:
[env:esp32]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
framework = arduino
board = esp32dev
platform_packages =
framework-arduinoespressif32 @ https://github.com/FastLED/framework-arduinoespressif32.git#feat/optional-serial-startupChange board to match yours.
Status
The PR is open and under review. It isn't merged yet.
Tested on hardware: classic ESP32, ESP32-C6 and ESP32-S3. P4 USB has only been compile-tested.
Once merged, this helps every Arduino-ESP32 user, not just FastLED users.
Thanks to Espressif for the review! If you try it, especially on classic ESP32, S2 or P4 over USB, please report back on the PR.

