mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 06:28:27 -04:00
a14fb9ab28
Ensures the sdkconfig does not get out of date as updates are made to the defaults. The sdkconfig can still be manually changed for testing.
214 lines
7.8 KiB
Python
214 lines
7.8 KiB
Python
# encoding: utf-8
|
|
|
|
"""
|
|
Waf tool for ESP32 build
|
|
"""
|
|
|
|
from waflib import Build, ConfigSet, Configure, Context, Task, Utils
|
|
from waflib import Errors, Logs
|
|
from waflib.TaskGen import before, after_method, before_method, feature
|
|
from waflib.Configure import conf
|
|
from collections import OrderedDict
|
|
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import re
|
|
import pickle
|
|
import subprocess
|
|
|
|
def configure(cfg):
|
|
mcu_esp32s3 = True if (cfg.variant[0:7] == "esp32s3") else False
|
|
target = "esp32s3" if mcu_esp32s3 else "esp32"
|
|
bldnode = cfg.bldnode.make_node(cfg.variant)
|
|
def srcpath(path):
|
|
return cfg.srcnode.make_node(path).abspath()
|
|
def bldpath(path):
|
|
return bldnode.make_node(path).abspath()
|
|
|
|
#Load cmake builder and make
|
|
cfg.load('cmake')
|
|
|
|
#define env and location for the cmake esp32 file
|
|
env = cfg.env
|
|
env.AP_HAL_ESP32 = srcpath('libraries/AP_HAL_ESP32/targets/'+target+'/esp-idf')
|
|
env.AP_PROGRAM_FEATURES += ['esp32_ap_program']
|
|
|
|
env.ESP_IDF_PREFIX_REL = 'esp-idf'
|
|
|
|
prefix_node = bldnode.make_node(env.ESP_IDF_PREFIX_REL)
|
|
env.ESP32_TARGET = target
|
|
env.BUILDROOT = bldpath('')
|
|
env.SRCROOT = srcpath('')
|
|
env.APJ_TOOL = srcpath('Tools/scripts/apj_tool.py')
|
|
|
|
#Check if esp-idf env are loaded, or load it
|
|
try:
|
|
env.IDF = os.environ['IDF_PATH']
|
|
except:
|
|
env.IDF = cfg.srcnode.abspath()+"/modules/esp_idf"
|
|
print("USING EXPRESSIF IDF:"+str(env.IDF))
|
|
|
|
try:
|
|
env.DEFAULT_PARAMETERS = os.environ['DEFAULT_PARAMETERS']
|
|
except:
|
|
env.DEFAULT_PARAMETERS = cfg.srcnode.abspath()+"/libraries/AP_HAL_ESP32/boards/defaults.parm"
|
|
print("USING DEFAULT_PARAMETERS:"+str(env.DEFAULT_PARAMETERS))
|
|
|
|
#env.append_value('GIT_SUBMODULES', 'esp_idf')
|
|
|
|
# delete the output sdkconfig file when the input defaults changes. we take the
|
|
# stamp as the output so we can compute the path to the sdkconfig, yet it
|
|
# doesn't have to exist when we're done.
|
|
class clean_sdkconfig(Task.Task):
|
|
def keyword(self):
|
|
return "delete sdkconfig generated from"
|
|
|
|
def run(self):
|
|
prefix = ".clean-stamp-"
|
|
for out in self.outputs:
|
|
if not out.name.startswith(prefix):
|
|
raise ValueError("not a stamp file: "+out)
|
|
dest = out.parent.abspath()+"/"+out.name[len(prefix):]
|
|
if os.path.exists(dest):
|
|
os.unlink(dest)
|
|
|
|
# waf needs the output to exist after the task, so touch it
|
|
open(out.abspath(), "w").close()
|
|
|
|
def pre_build(self):
|
|
"""Configure esp-idf as lib target"""
|
|
lib_vars = OrderedDict()
|
|
lib_vars['ARDUPILOT_CMD'] = self.cmd
|
|
lib_vars['WAF_BUILD_TARGET'] = self.targets
|
|
lib_vars['ARDUPILOT_LIB'] = self.bldnode.find_or_declare('lib/').abspath()
|
|
lib_vars['ARDUPILOT_BIN'] = self.bldnode.find_or_declare('lib/bin').abspath()
|
|
target = self.env.ESP32_TARGET
|
|
esp_idf = self.cmake(
|
|
name='esp-idf',
|
|
cmake_vars=lib_vars,
|
|
cmake_src='libraries/AP_HAL_ESP32/targets/'+target+'/esp-idf',
|
|
cmake_bld='esp-idf_build',
|
|
)
|
|
|
|
esp_idf_showinc = esp_idf.build('showinc', target='esp-idf_build/includes.list')
|
|
|
|
# task to delete the sdkconfig (thereby causing it to be regenerated) when
|
|
# the .defaults changes. it uses a stamp to find the sdkconfig. changing
|
|
# the sdkconfig WILL NOT cause it to be deleted as it's not an input. this
|
|
# is by design so the user can tweak it for testing purposes.
|
|
clean_sdkconfig_task = esp_idf_showinc.create_task("clean_sdkconfig",
|
|
src=self.srcnode.find_or_declare(self.env.AP_HAL_ESP32+"/sdkconfig.defaults"),
|
|
tgt=self.bldnode.find_or_declare("esp-idf_build/.clean-stamp-sdkconfig"))
|
|
|
|
esp_idf_showinc.post()
|
|
|
|
# ensure the sdkconfig will be deleted before the cmake configure occurs
|
|
# that regenerates it
|
|
esp_idf_showinc.cmake_config_task.set_run_after(clean_sdkconfig_task)
|
|
|
|
from waflib import Task
|
|
class load_generated_includes(Task.Task):
|
|
"""After includes.list generated include it in env"""
|
|
always_run = True
|
|
def run(tsk):
|
|
bld = tsk.generator.bld
|
|
includes = bld.bldnode.find_or_declare('esp-idf_build/includes.list').read().split()
|
|
#print(includes)
|
|
bld.env.prepend_value('INCLUDES', includes)
|
|
|
|
tsk = load_generated_includes(env=self.env)
|
|
tsk.set_inputs(self.path.find_resource('esp-idf_build/includes.list'))
|
|
self.add_to_group(tsk)
|
|
|
|
|
|
@feature('esp32_ap_program')
|
|
@after_method('process_source')
|
|
def esp32_firmware(self):
|
|
self.link_task.always_run = True
|
|
esp_idf = self.bld.cmake('esp-idf')
|
|
|
|
build = esp_idf.build('all', target='esp-idf_build/ardupilot.bin')
|
|
build.post()
|
|
|
|
build.cmake_build_task.set_run_after(self.link_task)
|
|
|
|
# tool that can update the default params in a .bin or .apj
|
|
#self.default_params_task = self.create_task('set_default_parameters',
|
|
# src='esp-idf_build/ardupilot.bin')
|
|
#self.default_params_task.set_run_after(self.generate_bin_task)
|
|
|
|
# optional upload is last
|
|
if self.bld.options.upload:
|
|
flasher = esp_idf.build('flash')
|
|
flasher.post()
|
|
|
|
|
|
class set_default_parameters(Task.Task):
|
|
color='CYAN'
|
|
always_run = True
|
|
def keyword(self):
|
|
return "setting default params"
|
|
def run(self):
|
|
|
|
# TODO: disabled this task outright as apjtool appears to destroy checksums and/or the esp32 partition table
|
|
# TIP: if u do try this, afterwards, be sure to 'rm -rf build/esp32buzz/idf-plane/*.bin' and re-run waf
|
|
return
|
|
|
|
# (752) esp_image: Checksum failed. Calculated 0xd3 read 0xa3
|
|
# (752) boot: OTA app partition slot 0 is not bootable
|
|
# (753) esp_image: image at 0x200000 has invalid magic byte
|
|
# (759) boot_comm: mismatch chip ID, expected 0, found 65535
|
|
# (766) boot_comm: can't run on lower chip revision, expected 1, found 255
|
|
# (773) esp_image: image at 0x200000 has invalid SPI mode 255
|
|
# (779) esp_image: image at 0x200000 has invalid SPI size 15
|
|
# (786) boot: OTA app partition slot 1 is not bootable
|
|
# (792) boot: No bootable app partitions in the partition table
|
|
|
|
|
|
# skip task if nothing to do.
|
|
if not self.env.DEFAULT_PARAMETERS:
|
|
return
|
|
|
|
default_parameters = self.env.get_flat('DEFAULT_PARAMETERS').replace("'", "")
|
|
#print("apj defaults file:"+str(default_parameters))
|
|
|
|
_bin = str(self.inputs[0])
|
|
|
|
# paranoia check before and after apj_tool to see if file hash has changed...
|
|
cmd = "shasum -b {0}".format( _bin )
|
|
result = subprocess.check_output(cmd, shell=True)
|
|
prehash = str(result).split(' ')[0][2:]
|
|
|
|
cmd = "{1} {2} --set-file {3}".format(self.env.SRCROOT, self.env.APJ_TOOL, _bin, default_parameters )
|
|
print(cmd)
|
|
result = subprocess.check_output(cmd, shell=True)
|
|
if not isinstance(result, str):
|
|
result = result.decode()
|
|
for i in str(result).split('\n'):
|
|
print("\t"+i)
|
|
|
|
# paranoia check before and after apj_tool to see if file hash has changed...
|
|
cmd = "shasum -b {0}".format( _bin )
|
|
result = subprocess.check_output(cmd, shell=True)
|
|
posthash = str(result).split(' ')[0][2:]
|
|
|
|
# display --show output, helpful.
|
|
cmd = "{1} {2} --show ".format(self.env.SRCROOT, self.env.APJ_TOOL, _bin )
|
|
print(cmd)
|
|
result = subprocess.check_output(cmd, shell=True)
|
|
if not isinstance(result, str):
|
|
result = result.decode()
|
|
for i in str(result).split('\n'):
|
|
print("\t"+i)
|
|
|
|
# were embedded params updated in .bin?
|
|
if prehash == posthash:
|
|
print("Embedded params in .bin unchanged (probably already up-to-date)")
|
|
else:
|
|
print("Embedded params in .bin UPDATED")
|
|
|
|
|
|
|
|
|