"DRAM segment data does not fit" after splitting Files into .h and .cpp

Hello,

I’m encountering a really stupid problem at the moment i really cannot wrap my head around.
The Project is a PlatformIO project, here is the platformio.ini:

[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino
monitor_speed = 115200

lib_deps =
    IRremoteESP8266
    Adafruit NeoPixel
    ArduinoJson
    PubSubClient
    EEPROM

build_flags =
    -D MQTT_MAX_PACKET_SIZE=512
    -D MQTT_KEEPALIVE=5
    -D ARDUINOJSON_USE_LONG_LONG=1

I am working on a project to use ESP32s as smarthome devices. Beeing a newbie in C++ at the time i simply threw all of the code into the .h files.
Learning more about C++, i decided to properly structure the project, moving method implementations to .cpp files. After a few Files i ran into the following error:

/Users/jklink/.platformio/packages/toolchain-xtensa32/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: .pio/build/esp32cam/firmware.elf section `.dram0.bss' will not fit in region `dram0_0_seg'
/Users/jklink/.platformio/packages/toolchain-xtensa32/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: DRAM segment data does not fit.
/Users/jklink/.platformio/packages/toolchain-xtensa32/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: region `dram0_0_seg' overflowed by 4896 bytes

The error disappears when i revert the changes (remove one .cpp and move the code back into the .h).
It reappears when splitting up ANY other file.

What kinda wonders me is that after building the project it displays the following message:
RAM: [==== ] 37.0% (used 121328 bytes from 327680 bytes)
Flash: [=== ] 27.1% (used 852254 bytes from 3145728 bytes)
esptool.py v2.6

The RAM usage looks all good there.
The PlatformIO Home Inspection Tool tells me there are 100% (347.9kb) RAM used, but only 22% Flash.

There is not a single additional line Code written, so the compiled code should not be longer than the original one only stored in .h Files.
The complete src directory has a size of 246kb.

Has anyone a suggestion how to handle that?

Thanks in advance,
J. Klink

Are you sure that 's not from aprevious compilation run? Have you cleaned the project beforehand? If linking fails, the firmware.elf should not be created at all.

This is the section for global uninitialized variables / objects, usually buffers who are declared in the style

uint8_t data_buf[5 * 1024];

maybe you have a problem where you have two buffers of a large size after the refactoring was done, while you think you completely removed it from the .h file? For buffers, you do declare them as extern .. in the header file, right? Without that it’s creating another buffer.

Hard to say without seeing the code though. Is the offending cpp file that causes the error presentable?

1 Like

Thanks for the answer.

I have changed the Repository to public, i planned on making that step when the code doesn’t look that bad anymore but it seems like its kinda necessary now :wink:

Im really sure, im switching back and forth all the time to find out whats the matter.
The problem is not caused by any special class, the code in fb_9_refactor codebase can be compiled and uploaded but the code analysis on pio home produces the following output:

If i split up any other .h file in .h and .cpp the code does not build anymore and the compiler throws the error mentioned in my initial post.

Feel free to check out the code or download it and see if you can find anything, i have no deep understanding of the way the ESP internally works yet and i have no idea what to do about that error. Going back to header only does not sound like a great idea to me :wink:

You can use draw.io desktop or in browser to check the uml.xml in the ‘documentation’-directory to get an overview of the class hierarchy, sadly its not complete and the sequence chart on the second page is completely outdated but maybe it gives you an idea of what we want to achieve there.

Thank you very much,
J. Klink

Can you create a branch in which you have done that refactoring so that it doesn’t build anymore?

Of course, thank you for your commitment.
The branch is called ‘temp_broken_refactor’.
If you replace any pair of .h/.cpp files with a header only version (for example from the master branch, which is just before we started refactoring) the code compiles again.

Do you have any idea what’s going wrong there?

That was the Problem. In console_logger.h an instance on the Console_Logger is defined to be used by every other class. The logger is indeed only defined as “static”, not “extern” - but switching to “extern” produces an error, that made us switch to static in the first place.

The error is as follows:

Linking .pio/build/esp32cam/firmware.elf
.pio/build/esp32cam/src/connectors/connectors.cpp.o:(.literal._ZN12IR_Connector9sendRawIREPKth+0x4): undefined reference to `logger'

Does anyone have an idea how i could solve that? “extern” seems to be the right way to do this…