103 lines
3.3 KiB
Python
103 lines
3.3 KiB
Python
Import("env", "projenv")
|
|
import os
|
|
import glob
|
|
|
|
print("##post script running")
|
|
|
|
def getString(buffer, offset, length):
|
|
return buffer[offset:offset+length].rstrip(b'\0').decode('utf-8')
|
|
|
|
def getFirmwareInfo(fwfile):
|
|
"""
|
|
ESP-IDF firmware descriptor
|
|
|
|
typedef struct {
|
|
uint32_t magic_word;
|
|
uint32_t secure_version;
|
|
uint32_t reserv1;
|
|
uint32_t reserv2;
|
|
char version[32];
|
|
char project_name[32];
|
|
char time[16];
|
|
char date[16];
|
|
char idf_ver[32];
|
|
uint8_t app_elf_sha256[32];
|
|
} esp_app_desc_t
|
|
|
|
"""
|
|
print(f"checking firmware {fwfile}")
|
|
with open(fwfile, "rb") as fh:
|
|
MAGIC = b"\x32\x54\xcd\xab" # little endian
|
|
buffer = fh.read(1024)
|
|
idx = buffer.find(MAGIC, 288) # find MAGIC
|
|
if idx < 0:
|
|
raise Exception("no app descriptor found")
|
|
else:
|
|
print("found app descriptor at {}".format(idx))
|
|
version = getString(buffer, idx + 16, 32)
|
|
name = getString(buffer, idx + 48, 32)
|
|
fwtime = getString(buffer, idx + 80, 16)
|
|
fwdate = getString(buffer, idx + 96, 16)
|
|
idf_ver = getString(buffer, idx + 112, 16)
|
|
print(f" name: '{name}'")
|
|
print(f" version: '{version}'")
|
|
print(f" time: '{fwtime}'")
|
|
print(f" date: '{fwdate}'")
|
|
print(f" idf: '{idf_ver}'")
|
|
return (name, version)
|
|
|
|
def postbuild(source, target, env):
|
|
print("##postbuild")
|
|
print("source={}".format(source[0]))
|
|
print("target={}".format(target[0]))
|
|
firmware = env.subst("$BUILD_DIR/${PROGNAME}.bin")
|
|
(fwname, fwversion) = getFirmwareInfo(firmware)
|
|
|
|
esptool = env.get('UPLOADER')
|
|
uploaderflags = env.subst("${UPLOADERFLAGS}")
|
|
base = env.subst("$PIOENV")
|
|
appoffset = env.subst("$ESP32_APP_OFFSET")
|
|
python = env.subst("$PYTHONEXE")
|
|
|
|
print("base=%s,esptool=%s,appoffset=%s,uploaderflags=%s"%(base,esptool,appoffset,uploaderflags))
|
|
|
|
uploadparts = uploaderflags.split(" ")
|
|
|
|
chip = "esp32"
|
|
if len(uploadparts) < 6:
|
|
print("uploaderflags does not have enough parameter")
|
|
return
|
|
for i in range(0, len(uploadparts)):
|
|
if uploadparts[i] == "--chip":
|
|
if i < (len(uploadparts) - 1):
|
|
chip = uploadparts[i+1]
|
|
uploadfiles = uploadparts[-6:]
|
|
for i in range(1, len(uploadfiles), 2):
|
|
if not os.path.isfile(uploadfiles[i]):
|
|
print("file %s for combine not found"%uploadfiles[i])
|
|
return
|
|
offset = uploadfiles[0]
|
|
|
|
outdir = env.subst("$BUILD_DIR")
|
|
for f in glob.glob(os.path.join(outdir, base + "*.bin")):
|
|
print("removing old file {}".format(f))
|
|
os.unlink(f)
|
|
|
|
outfile = os.path.join(outdir, "{}-all.bin".format((base)))
|
|
cmd = [python, esptool, "--chip", chip, "merge_bin", "--target-offset", offset, "-o", outfile]
|
|
cmd += uploadfiles
|
|
cmd += [appoffset, firmware]
|
|
print("running {}".format(' '.join(cmd)))
|
|
env.Execute(' '.join(cmd), "#merging bin files")
|
|
|
|
# Create symlinks to better identify firmware
|
|
fw_update = os.path.join(outdir, f"{base}-{fwversion}-update.bin")
|
|
os.symlink(firmware, fw_update)
|
|
fw_full = os.path.join(outdir, f"{base}-{fwversion}-all.bin")
|
|
os.symlink(outfile, fw_full)
|
|
|
|
env.AddPostAction(
|
|
"$BUILD_DIR/${PROGNAME}.bin",
|
|
postbuild
|
|
)
|