PlatformIO Community

Why `impure_data` appears on custom build and eats 1K memory? Need fix

Short description: when stm32hal been built from CumeMX sources, with the same options as PIO use, .data.impure_data appears in output and eats 1K RAM.


I use CubeMX to generate chip init configs. For consistency reasons, i’l like to build HAL from CubeMX sources, instead of PIO built-ins. So, carefully inspected, and created post-script to patch output envs - make it look like after

In general, that works, but memory consumption increased for 1K due injected impure_data variable. CLI params of compiler/linker looks the same. HAL version is the same (F0 1.9.0). I did not edited HAL files and application files. Only added the same version, generated by CubeMX and builded project. Intrusion is zero.

Can anybody help to get rid of impure_data?


For compare - use dev branch and see memory report after build.

To see missed size, in directory with elf file run:

objdump -x ./pio/build/hardware_usb/firmware.elf | grep impure`
# or
nm --print-size --size-sort --demangle --radix=d .pio/build/hardware_usb/firmware.elf | grep "\s[bB]\s"

Found working solution is to remove -Wl, prefix from -Wl,-T<path> variable in LINKFLAGS.

But i could not understand why this help :(. Could anyone explain?

Here is final version of post-hook script:

Import("env", "projenv")

for e in [ env, projenv ]:
    # Fix options after ""
    e.Replace(LINKFLAGS = [i for i in e['LINKFLAGS'] if i not in [ '-nostartfiles', '-nostdlib' ]])
    e.Append(LINKFLAGS = [ "--specs=nano.specs", "--specs=nosys.specs" ])
    e.Replace(AS = '$CC', ASCOM = '$ASPPCOM')

    # .ld script should be passed to linker directly as "-T<path>"
    # instead of "-Wl,-T<path>", to avoid 1K RAM loss for ".data.impure_data"
    e.Replace(BUILD_FLAGS = [i for i in e['BUILD_FLAGS'] if not i.startswith('-Wl,-T')])
    e.Replace(LINKFLAGS = [(i[4:] if i.startswith('-Wl,-T') else i) for i in e['LINKFLAGS']])