Variying Output Format when Building for rp2040

Hi All,

I am using PlatformIO to build a firmware for rp2040 devices, for my OTA procedure I need a .bin file.

Now for a long time PlatformIO did create .bin files, but for some time now it seemingly randomly switches between creating only .elf files and .bin files.

First of all I wonder why this is happening. I have the hunch that it is related to the size of the firmware, but I could not verify that yet.

Here is my platformio.ini:

[env:pico]
platform = GitHub - maxgerhardt/platform-raspberrypi: Raspberry Pi: development platform for PlatformIO
board = pico
framework = arduino
board_build.core = earlephilhower
lib_deps = adafruit/Adafruit NeoPixel@^1.12.0
monitor_speed = 115200
build_flags =
-DUSE_TINYUSB
-DCFG_TUSB_CONFIG_FILE="myConf.h"
-Iinclude/

board_build.filesystem_size = 1.6m
extra_scripts =
pre:buildscript_versioning.py
; post:build_script.py

as you can see I tried to force the creation of a .bin file with a post build script, but when I run that I run into output that I cant make sense of, here’s the script:

from os.path import join
Import(“env”, “projenv”)

# Custom BIN from ELF
env.AddPostAction(
“$BUILD_DIR/${PROGNAME}.elf”,
env.VerboseAction(" ".join([
“$OBJCOPY”,
“-O”,
“binary”,
“$TARGET”,
“$BUILD_DIR/${PROGNAME}.bin”
]), “Building $TARGET”))

the output is:

Linking .pio\build\pico\firmware.elf
Generating UF2 image
elf2uf2 “.pio\build\pico\firmware.elf” “.pio\build\pico\firmware.uf2”
Building .pio\build\pico\firmware.elf
Usage: arm-none-eabi-objcopy [option(s)] in-file [out-file]
Copies a binary file, possibly transforming it in the process
The options are:
-I --input-target Assume input file is in format
-O --output-target Create an output file in format
-B --binary-architecture Set output arch, when input is arch-less
-F --target Set both input and output format to
–debugging Convert debugging information, if possible
-p --preserve-dates Copy modified/access timestamps to the output
-D --enable-deterministic-archives
Produce deterministic output when stripping archives
-U --disable-deterministic-archives
Disable -D behavior (default)
-j --only-section Only copy section into the output
–add-gnu-debuglink= Add section .gnu_debuglink linking to
-R --remove-section Remove section from the output
–remove-relocations Remove relocations from section
-S --strip-all Remove all symbol and relocation information
-g --strip-debug Remove all debugging symbols & sections
–strip-dwo Remove all DWO sections
–strip-unneeded Remove all symbols not needed by relocations
-N --strip-symbol Do not copy symbol
–strip-unneeded-symbol
Do not copy symbol unless needed by
relocations
–only-keep-debug Strip everything but the debug information
–extract-dwo Copy only DWO sections
–extract-symbol Remove section contents but keep symbols
–keep-section Do not strip section
-K --keep-symbol Do not strip symbol
–keep-section-symbols Do not strip section symbols
–keep-file-symbols Do not strip file symbol(s)
–localize-hidden Turn all ELF hidden symbols into locals
-L --localize-symbol Force symbol to be marked as a local
–globalize-symbol Force symbol to be marked as a global
-G --keep-global-symbol Localize all symbols except
-W --weaken-symbol Force symbol to be marked as a weak
–weaken Force all global symbols to be marked as weak
-w --wildcard Permit wildcard in symbol comparison
-x --discard-all Remove all non-global symbols
-X --discard-locals Remove any compiler-generated symbols
-i --interleave[=] Only copy N out of every bytes
–interleave-width Set N for --interleave
-b --byte Select byte in every interleaved block
–gap-fill Fill gaps between sections with
–pad-to Pad the last section up to address
–set-start Set the start address to
{–change-start|–adjust-start}
Add to the start address
{–change-addresses|–adjust-vma}
Add to LMA, VMA and start addresses
{–change-section-address|–adjust-section-vma} {=|+|-}
Change LMA and VMA of section by
–change-section-lma {=|+|-}
Change the LMA of section by
–change-section-vma {=|+|-}
Change the VMA of section by
{–[no-]change-warnings|–[no-]adjust-warnings}
Warn if a named section does not exist
–set-section-flags =
Set section 's properties to
–set-section-alignment =
Set section 's alignment to bytes
–add-section = Add section found in to output
–update-section =
Update contents of section with
contents found in
–dump-section = Dump the contents of section into
–rename-section =[,] Rename section to
–long-section-names {enable|disable|keep}
Handle long section names in Coff objects.
–change-leading-char Force output format’s leading character style
–remove-leading-char Remove leading character from global symbols
–reverse-bytes= Reverse bytes at a time, in output sections with content
–redefine-sym = Redefine symbol name to
–redefine-syms --redefine-sym for all symbol pairs
listed in
–srec-len Restrict the length of generated Srecords
–srec-forceS3 Restrict the type of generated Srecords to S3
–strip-symbols -N for all symbols listed in
–strip-unneeded-symbols
–strip-unneeded-symbol for all symbols listed
in
–keep-symbols -K for all symbols listed in
–localize-symbols -L for all symbols listed in
–globalize-symbols --globalize-symbol for all in
–keep-global-symbols -G for all symbols listed in
–weaken-symbols -W for all symbols listed in
–add-symbol =[:][,] Add a symbol
–alt-machine-code Use the target’s 'th alternative machine
–writable-text Mark the output text as writable
–readonly-text Make the output text write protected
–pure Mark the output file as demand paged
–impure Mark the output file as impure
–prefix-symbols Add to start of every symbol name
–prefix-sections Add to start of every section name
–prefix-alloc-sections
Add to start of every allocatable
section name
–file-alignment Set PE file alignment to
–heap [,] Set PE reserve/commit heap to /

–image-base Set PE image base to
–section-alignment Set PE section alignment to
–stack [,] Set PE reserve/commit stack to /

–subsystem [:]
Set PE subsystem to [& ]
–compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]
Compress DWARF debug sections
–decompress-debug-sections Decompress DWARF debug sections using zlib
–elf-stt-common=[yes|no] Generate ELF common symbols with STT_COMMON
type
–verilog-data-width Specifies data width, in bytes, for verilog output
-M --merge-notes Remove redundant entries in note sections
–no-merge-notes Do not attempt to remove redundant notes (default)
-v --verbose List all object files modified
@ Read options from
-V --version Display this program’s version number
-h --help Display this output
–info List object formats & architectures supported
arm-none-eabi-objcopy: supported targets: elf32-littlearm elf32-littlearm-fdpic elf32-bigarm elf32-bigarm-fdpic elf32-little elf32-big srec symbolsrec verilog tekhex binary ihex plugin
*** [.pio\build\pico\firmware.elf] Error 1

So my main question is, How can I make sure that i always get .bin file output, what am I missing here?

Thanks!

That’s weird. Any way to reproduce that?

That is not right according to docs. Make

env.AddPostAction(
    "$BUILD_DIR/${PROGNAME}.elf",
    env.VerboseAction(" ".join([
        "$OBJCOPY", "-O", "binary", "-R", ".eeprom",
        "$BUILD_DIR/${PROGNAME}.elf", "$BUILD_DIR/${PROGNAME}.bin"
    ]), "Building $BUILD_DIR/${PROGNAME}.hex")
)

Thanks a lot for looking into this!

I have not found a way to reproduce this reliably.

I had actually tried different versions of the post script including the one from the docs (I think I found the one I posted on this forums too).

Unfortunately the Ouput remains the same:

from os.path import join
Import(“env”)
env.AddPostAction(
“$BUILD_DIR/${PROGNAME}.elf”,
env.VerboseAction(" ".join([
“$OBJCOPY”, “-O”, “binary”, “-R”, “.eeprom”,
“$BUILD_DIR/${PROGNAME}.elf”, “$BUILD_DIR/${PROGNAME}.bin”
]), “Converting to .bin”)
)

Generating UF2 image
elf2uf2 “.pio\build\pico\firmware.elf” “.pio\build\pico\firmware.uf2”
Converting to .bin
Usage: arm-none-eabi-objcopy [option(s)] in-file [out-file]
Copies a binary file, possibly transforming it in the process
The options are:
-I --input-target Assume input file is in format
-O --output-target Create an output file in format
-B --binary-architecture Set output arch, when input is arch-less
-F --target Set both input and output format to
–debugging Convert debugging information, if possible
-p --preserve-dates Copy modified/access timestamps to the output
-D --enable-deterministic-archives
Produce deterministic output when stripping archives
-U --disable-deterministic-archives
Disable -D behavior (default)
-j --only-section Only copy section into the output
–add-gnu-debuglink= Add section .gnu_debuglink linking to
-R --remove-section Remove section from the output
–remove-relocations Remove relocations from section
-S --strip-all Remove all symbol and relocation information
-g --strip-debug Remove all debugging symbols & sections
–strip-dwo Remove all DWO sections
–strip-unneeded Remove all symbols not needed by relocations
-N --strip-symbol Do not copy symbol
–strip-unneeded-symbol
Do not copy symbol unless needed by
relocations
–only-keep-debug Strip everything but the debug information
–extract-dwo Copy only DWO sections
–extract-symbol Remove section contents but keep symbols
–keep-section Do not strip section
-K --keep-symbol Do not strip symbol
–keep-section-symbols Do not strip section symbols
–keep-file-symbols Do not strip file symbol(s)
–localize-hidden Turn all ELF hidden symbols into locals
-L --localize-symbol Force symbol to be marked as a local
–globalize-symbol Force symbol to be marked as a global
-G --keep-global-symbol Localize all symbols except
-W --weaken-symbol Force symbol to be marked as a weak
–weaken Force all global symbols to be marked as weak
-w --wildcard Permit wildcard in symbol comparison
-x --discard-all Remove all non-global symbols
-X --discard-locals Remove any compiler-generated symbols
-i --interleave[=] Only copy N out of every bytes
–interleave-width Set N for --interleave
-b --byte Select byte in every interleaved block
–gap-fill Fill gaps between sections with
–pad-to Pad the last section up to address
–set-start Set the start address to
{–change-start|–adjust-start}
Add to the start address
{–change-addresses|–adjust-vma}
Add to LMA, VMA and start addresses
{–change-section-address|–adjust-section-vma} {=|+|-}
Change LMA and VMA of section by
–change-section-lma {=|+|-}
Change the LMA of section by
–change-section-vma {=|+|-}
Change the VMA of section by
{–[no-]change-warnings|–[no-]adjust-warnings}
Warn if a named section does not exist
–set-section-flags =
Set section 's properties to
–set-section-alignment =
Set section 's alignment to bytes
–add-section = Add section found in to output
–update-section =
Update contents of section with
contents found in
–dump-section = Dump the contents of section into
–rename-section =[,] Rename section to
–long-section-names {enable|disable|keep}
Handle long section names in Coff objects.
–change-leading-char Force output format’s leading character style
–remove-leading-char Remove leading character from global symbols
–reverse-bytes= Reverse bytes at a time, in output sections with content
–redefine-sym = Redefine symbol name to
–redefine-syms --redefine-sym for all symbol pairs
listed in
–srec-len Restrict the length of generated Srecords
–srec-forceS3 Restrict the type of generated Srecords to S3
–strip-symbols -N for all symbols listed in
–strip-unneeded-symbols
–strip-unneeded-symbol for all symbols listed
in
–keep-symbols -K for all symbols listed in
–localize-symbols -L for all symbols listed in
–globalize-symbols --globalize-symbol for all in
–keep-global-symbols -G for all symbols listed in
–weaken-symbols -W for all symbols listed in
–add-symbol =[:][,] Add a symbol
–alt-machine-code Use the target’s 'th alternative machine
–writable-text Mark the output text as writable
–readonly-text Make the output text write protected
–pure Mark the output file as demand paged
–impure Mark the output file as impure
–prefix-symbols Add to start of every symbol name
–prefix-sections Add to start of every section name
–prefix-alloc-sections
Add to start of every allocatable
section name
–file-alignment Set PE file alignment to
–heap [,] Set PE reserve/commit heap to /

–image-base Set PE image base to
–section-alignment Set PE section alignment to
–stack [,] Set PE reserve/commit stack to /

–subsystem [:]
Set PE subsystem to [& ]
–compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]
Compress DWARF debug sections
–decompress-debug-sections Decompress DWARF debug sections using zlib
–elf-stt-common=[yes|no] Generate ELF common symbols with STT_COMMON
type
–verilog-data-width Specifies data width, in bytes, for verilog output
-M --merge-notes Remove redundant entries in note sections
–no-merge-notes Do not attempt to remove redundant notes (default)
-v --verbose List all object files modified
@ Read options from
-V --version Display this program’s version number
-h --help Display this output
–info List object formats & architectures supported
arm-none-eabi-objcopy: supported targets: elf32-littlearm elf32-littlearm-fdpic elf32-bigarm elf32-bigarm-fdpic elf32-little elf32-big srec symbolsrec verilog tekhex binary ihex plugin
*** [.pio\build\pico\firmware.elf] Error 1

If I randomly change buffer sizes or the size of the filesystem (
board_build.filesystem_size = X) it goes back to creating .bin files for a while.