Why Did Templating a Function Free Up Space in drom0_0_seg?
Posted: Fri May 30, 2025 8:01 pm
Hello!
I'm currently making a project using a FireBeetle 2 ESP32-E using PlatformIO through VSCode, inspired by this project:
https://github.com/lmarzen/esp32-weather-epd
Instead of using this project directly, I wanted to stretch my skills and learn what it's like to develop for a more restrictive platform.
To speed up some of the boilerplate work, I copied the "esp32-weather-epd-assets" library provided in the above repo. This is a library of fonts and bitmaps of varying sizes converted into header files.
I wrote a function that takes an unsigned short ID, an unsigned short for the bitmap size requested, and a bool to determine which version of the bitmap to return. Below is a (very truncated) snippet of the code:
(ICON_TYPE is defined in a separate header.)
However, when I called this function I received the following error:
My understanding is that "drom" is where read-only data is stored. My assumption is that something about this function caused the compiler to store too much data in the drom segment of memory.
I looked back and forth between my code and the repo my project is based on, and I was struggled to figure out the difference. I first added the following to my platformio.ini:
However, I still ran into the same error.
Eventually I noticed that the repo's version of this function is not called directly. It's located in a CPP file (not declared in a header), and is templated. It's then called by other functions.
I tried putting it solely in the CPP file and calling it from a different function, but I still ran into the same error. However, Once I templated the function everything worked.
In fact provided me with more space than I had before.
I was wondering if anyone had any insight as to why templating this function solved my issue? I have some guesses, but I'd like to improve my understanding of C++ and compilers, so any insight would be helpful!
Thanks!
I'm currently making a project using a FireBeetle 2 ESP32-E using PlatformIO through VSCode, inspired by this project:
https://github.com/lmarzen/esp32-weather-epd
Instead of using this project directly, I wanted to stretch my skills and learn what it's like to develop for a more restrictive platform.
To speed up some of the boilerplate work, I copied the "esp32-weather-epd-assets" library provided in the above repo. This is a library of fonts and bitmaps of varying sizes converted into header files.
I wrote a function that takes an unsigned short ID, an unsigned short for the bitmap size requested, and a bool to determine which version of the bitmap to return. Below is a (very truncated) snippet of the code:
Code: Select all
const uint8_t* GetBitmapFromCode(const uint16_t code, const uint16_t bitmapSize, const bool isDay)
{
switch(code)
{
case 200:
if (ICON_TYPE == IT_DAY_NIGHT) { return isDay ? getBitmap(wi_day_storm_showers, bitmapSize) : getBitmap(wi_night_storm_showers, bitmapSize); }
else if (ICON_TYPE == IT_DAY_NIGHT_ALT) { return isDay ? getBitmap(wi_day_storm_showers, bitmapSize) : getBitmap(wi_night_alt_storm_showers, bitmapSize); }
return getBitmap(wi_storm_showers, bitmapSize);
case 221:
if (ICON_TYPE == IT_DAY_NIGHT) { return isDay ? getBitmap(wi_day_thunderstorm, bitmapSize) : getBitmap(wi_night_thunderstorm, bitmapSize); }
else if (ICON_TYPE == IT_DAY_NIGHT_ALT) { return isDay ? getBitmap(wi_day_thunderstorm, bitmapSize) : getBitmap(wi_night_alt_thunderstorm, bitmapSize); }
return getBitmap(wi_thunderstorm, bitmapSize);
// Etc...
default:
return getBitmap(wi_na, bitmapSize);
}
}
However, when I called this function I received the following error:
section `.flash.rodata' will not fit in region `drom0_0_seg'
My understanding is that "drom" is where read-only data is stored. My assumption is that something about this function caused the compiler to store too much data in the drom segment of memory.
I looked back and forth between my code and the repo my project is based on, and I was struggled to figure out the difference. I first added the following to my platformio.ini:
Code: Select all
board_build.partitions = huge_app.csvHowever, I still ran into the same error.
Eventually I noticed that the repo's version of this function is not called directly. It's located in a CPP file (not declared in a header), and is templated. It's then called by other functions.
I tried putting it solely in the CPP file and calling it from a different function, but I still ran into the same error. However, Once I templated the function everything worked.
Code: Select all
template<int bitmapSize>
const uint8_t* GetBitmapFromCode(const uint16_t code, const bool isDay)
{
// Code...
}
// Instead of calling GetBitmapFromCode directly from other parts of the code, we call GetCurrentConditionBitmap instead.
const uint8_t* GetCurrentConditionBitmap(const Weather::Forecast& forecast)
{
return GetBitmapFromCode<160>(forecast.weather.weatherCode, true);
}In fact provided me with more space than I had before.
Code: Select all
RAM: [=== ] 28.8% (used 94320 bytes from 327680 bytes)
Flash: [=== ] 32.6% (used 1025661 bytes from 3145728 bytes)I was wondering if anyone had any insight as to why templating this function solved my issue? I have some guesses, but I'd like to improve my understanding of C++ and compilers, so any insight would be helpful!
Thanks!