Does it build normally, outside of the PlatformIO inspect function, either release or debug builds? It if does, what is the reported size from that build? There are several sections involved, any one of them being exceeded will prevent the linker, and knowing which section overflows is a clue to where your issue is.
Yeah, release build compiles and works - depending on which features of my project I enable, I can end up with anything from ~10K upwards free in the working build, eg my current configuration with a lot of things disabled gives me:-
Code:
Building .pio\build\pcb_go\firmware_pcb_go.hex
teensy_size: Memory Usage on Teensy 4.1:
teensy_size: FLASH: code:331872, data:103584, headers:8956 free for files:7682052
teensy_size: RAM1: variables:158304, code:312632, padding:15048 free for local variables:38304
teensy_size: RAM2: variables:17568 free for malloc/new:506720
While an 'Inspect' build of the same configuration consistently comes out at a larger size and refuses to finish because of it:-
Code:
teensy_size: Memory Usage on Teensy 4.1:
teensy_size: FLASH: code:459256, data:94372, headers:8544 free for files:7564292
RAM1: variables:146048, code:423000, padding:2984 free for local variables:-47744
teensy_size: RAM2: variables:17568 free for malloc/new:506720
Error program exceeds memory space
*** [size] Error 4294967295
========================= [FAILED] Took 14.47 seconds =========================
Environment Status Duration
------------- -------- ------------
pcb_go FAILED 00:00:14.467
==================== 1 failed, 0 succeeded in 00:00:14.467 ===================="
Relevant
Post on platformio forum about why debug build is required for 'Inspect':-
At the moment the “Project Inspector” only works with ELF files compiled in debug mode. The main reason is that we need additional information (like symbol locations) to prepare a comprehensive report. A map file is a potential workaround, but we support so many different platforms with different toolchain versions that makes parsing map files a pretty complicated task.
Avoiding the 'Inspect' tool and using some of these other map-based tools instead might be my best approach from here, although I have dabbled with those before and they're not as convenient as the 'Inspect' tool. (And maybe the platformio people will be able to advise better on whether I can do anything to ignore the 'exceeds memory space' error and continue inspection, thanks
@PaulStoffregen )
It does seem quite strange to me that platformio will quite happily compile, link and upload a too-large firmware file that won't run on the hardware when using the 'Upload' task, but refuses to finish analysing a too-large firmware file in the 'Inspect' tool where it shouldn't even matter!
Perhaps these are things best solved by understanding how the platformio tasks are defined and seeing if I can solve this discrepancy there. I'm just quite hazy on how much of this is done by the platformio team and how much by pjrc and who to ask and where to find such information.
(As another example, 'Upload' task never displays the teensy_size output, and will blindly upload the firmware to the Teensy even if it is too large to run -- I have to use 'Build' task to see the teensy_size output to be told that it exceeds size.)
Do you have one or two obviously large data structures than you can temporarily reduce, or large functions / libraries that you can temporarily stub out, to get it to build under Inspect, so you can see all the details on all the rest? It doesn't have to run, just compile and link....
No obviously large data structures -- I've long since optimised all the obvious things away in order to make more space (by instantiating objects at setup and malloc'ing large arrays)!
My project has at least a dozen different build-time switches that turn on or off different functionality (eg enable/disable the 'custom behaviours' for all the different USB-MIDI devices that can be attached, different types of USB device support, disable the MIDI looper behaviour, etc...) -- picking and choosing which features/devices to support for a particular build is the only way that I can build something that'll run now as I've crammed so many things into it!
I use quite a lot of (sub-)classes and templated classes in this project too, and the 'Inspect' output was previously quite useful for understanding when such approaches were inflating binary size (eg by duplicating code for each template type) -- figuring out which coding styles end up generating the largest/most redundant code is where I'm having to focus now it seems, rather than looking for long-hanging data structures
(A previous attempt of mine to solve some low-hanging static data.. 2 years old.. this is a long journey I have been on with a project whose features are creeping like nobody's business!:
https://forum.pjrc.com/index.php?th...cate-midi-tx-rx-buffers-non-statically.71610/)
Thanks for the thoughts and help, everybody, if nothing else it has been useful to articulate where I am with this!