PlatformIO Community

Trouble with Custom Firmware Naming


#1

I have referenced the Custom firmware/program name section of the Advanced Scripting doc. I’ve got a start on things, but some of it is not clicking. I’m trying to concatenate the firmware name from:

  • Framework
  • Board
  • Pre-processor flag
  • Git tag

So far I am using this platformio.ini:

[env:uno]
platform = atmelavr
board = uno
framework = arduino
build_flags = !python git_rev.py
extra_scripts = pre:name_firmware.py

My git_rev.py is as follows:

import subprocess
tagcmd = "git describe --tags --abbrev=0"
version = subprocess.check_output(tagcmd).decode().strip()
revcmd = "git log --pretty=format:'%h' -n 1"
commit = subprocess.check_output(revcmd).decode().strip()
print "-DPIO_SRC_TAG=%s" % version
print "-DPIO_SRC_REV=%s" % commit

And my name_firmware.py is as follows (so far):

import subprocess
Import("env")
my_flags = env.ParseFlags(env['BUILD_FLAGS'])
defines = {k: v for (k, v) in my_flags.get("CPPDEFINES")}
env.Replace(PROGNAME="myfile-%s-%s-%s-%s" % (
    defines.get("PIOFRAMEWORK"),
    defines.get("PIOENV"),
    "PreProcDef",
    defines.get("PIO_SRC_TAG")))

So far, the compiled file is named myfile-None-None-PreProcDef-1.2.3.hex

As you can see I get the PIO_SRC_TAG from my Git tag, but I am not getting the framework (expecting “arduino”) and I am not getting the board (expecting “uno”). Hopefully someone can help me with those two?

Also, is there any way to get a pre-processor definition? Where I currently have “PreProcDef” I’d like to get a #define out of one of my config.h file. For instance I have a define like this:

#define STATIC_CONFIG SHIELD_TWI

I’d like to just get the “TWI” portion if possible, but I can always do a case statement if I have to get the whole SHIELD_TWI part… Hopefully there’s a snazzy way to do that without grep/sed hell.

Desired end result would be: myfile-arduino-uno-twi-1.2.3.hex

Banging my head on this but I’m pretty sure it’s possible. Any assistance would be highly appreciated!

Thank you for reading.


#2

Stored in env not the defines.

Import("env")

framework = env["PIOFRAMEWORK"][0]
env_name = str(env["PIOENV"])

print("Framework: %s Environment: %s" % (framework, env_name))

Gives for an mbed-nucleol476rg project

Framework: mbed Environment: nucleo_l476rg

Evaluating the #defines from a python script might not be the best way to do it. It might make sense to move this into the build_flags and then makek different environments based on the configurations. But If you don’t, parsing the .h file might be an option, though an unclean one. Another option would be to invoke gcc with -E on the file, see here, and parse its output.


#3

Thank you so much Max! I’m completely new to PlatformIO so while the answer makes absolute sense now, it eluded me when I was staring at it previously.

I understand what you mean about the #defines but I had to hope. Moving that to build_flags would be a pretty large change in the way things are constructed now, but it’s an option.

Thank you again for your help.


#4

Best way to start is by doing print(env.Dump()) and looking at what the environment has to offer. See http://docs.platformio.org/en/latest/projectconf/advanced_scripting.html#construction-environments

Either the macros in by including your configuration header file or the compiler injects it via a -D MACRO=XY flag, but in the end you still have the same macro and can do all the things on it, like #ifdef.. etc.


#5

I ended up getting the last bit I wanted via python:

shields = []
linenum = 0
define = "#define STATIC_CONFIG".lower()
with open (str(env["PROJECTINCLUDE_DIR"]) + '/Config.h', 'rt') as config:
    for line in config:
        linenum += 1
        if line.lower().startswith(define):
            shields.append(line.rstrip('\n'))
for variant in shields:
    shield = variant.split(" ")[-1].split("_")[-1].lower()

Not glamorous, but it works.

Thanks again!