Custom UPLOAD CMD help

I am trying to make PIO run a custom upload/program command (for a board that’s not supported), it’s a custom NRF32 board with a serial loader instead of JLINK; it has it’s own custom serial upload program to interface with the serial bootloader on the board.

I read through the Advanced Scripting page of the documentation and see there is an UPLOADCMD setting, but I don’t understand the script that sets it; the page says you need to learn python to create the scripts (I don’t know python and I’m trying not to learn it right now), instead I’m just looking for a simple setting to put in platformio.ini, like “uploader = serialtool.exe ${hexfile}”. Is that possible or is creating the python script the only way?

Since I don’t understand python and the example script for overriding the upload command doesn’t have any documentation, I don’t understand what all the parts of that script are for, i.e. what is the bare minimum needed to override the upload command, or is the script showing 4 separate examples of how to do the same thing?


I needed to do something similar (although it was more minor, just some custom upload settings), so did the extra_scripts = in platformio.ini and the following in

env.Replace(FUSESCMD="avrdude $UPLOADERFLAGS -e -U lfuse:w:0xFF:m -U hfuse:w:0xDE:m -U efuse:w:0xFF:m -U lock:w:0xFF:m")

Since you want to completely replace the uploader, probably have a look at the “Custom openOCD command” on the Advanced Scripting page for syntax closer to what you want, which is also a bit simpler to follow. The below is loosely based on that and may be close to what you need… brain’s not working tonight or I’ll go through properly and test it…

=== platformio.ini ===
extra_scripts =
upload_protocol = custom
; each flag in a new line
upload_flags =
=== ===


If you don’t want to be able to toggle any command line flags to the uploader, you can completely omit upload_flags from platformio.ini, and also the $UPLOADERFLAGS variable in the script. You could even get it down to a two line script…

env.Replace(UPLOADCMD="$PROJECTDIR\serialtool.exe '$BUILD_DIR/${PROGNAME}.hex'")

It’s just a matter of how flexible and easily readable you want to make it.

1 Like

Hi there, thanks a lot for the example, that helped quite a bit.
I realized that I have to do an additional step before doing the custom serial upload (zipping the hex) so I was trying the before_upload hook as well, and also for the actual upload I have to append the upload port but I don’t know what the correct port variable name is.

Something’s not working, so I’m trying to debug it by outputting the env values to see what is actually being executed, but I can’t find any documentation on how to properly print out the values. For example, I have:


def before_upload(source, target, env):
    print "************* before_upload"
    print "*************"

env.AddPreAction("upload", before_upload)

However this just prints:
************* before_upload

So I can’t figure out what is actually being run. Is there another way to display the env variable value?

Also, once I have this working, is it possible to create a new global upload_protocol (i.e. serial) and define it in some global config, so in every project I just set upload_protocol = serial and then the upload script and settings are automatically applied to the project?


You’re not printing the Dump() :wink:

print env.Dump("UPLOADCMD")
print env.Dump("UPLOAD_PORT")

As far as a global_upload_protocol… I don’t know… This level is really project level customisation, so it that would probably require some tinkering in the support files for the framework in question. Or just the copying of the custom upload .py and the inclusion of appropriate platformio.ini entries… which do make the projects self-contained also.

Lol, go python… Thanks for that, never would have figured it out.

I didn’t really understand your last comment, unless you meant to copy the customization to each project? That’s actually what I’m trying to avoid. I’m sure there is something in the board support package that will allow making a reusable protocol possible…