devicetree: use edt.pickle more

Consolidate creation of edtlib.EDT objects from a build directory's
devicetree into one place by loading it from build/zephyr/edt.pickle
everywhere. A previous commit creates edt.pickle from gen_defines.py.

In addition to probably speeding things up slightly by not reparsing
the devicetree, the main benefit of this approach is creating a single
point of truth for the bindings directories and warnings
configuration, meaning we don't have to worry about them getting out
of sync while being passed around between devicetree creation and
usage time.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2020-07-08 14:43:07 -07:00 committed by Kumar Gala
parent 6d9d60ce60
commit 9c92baa73f
4 changed files with 25 additions and 49 deletions

View file

@ -204,7 +204,7 @@ if(SUPPORTS_DTS)
endif(DTC)
#
# Run gen_defines.py to create a header file and zephyr.dts.
# Run gen_defines.py to create a header file, zephyr.dts, and edt.pickle.
#
set(CMD_EXTRACT ${PYTHON_EXECUTABLE} ${GEN_DEFINES_SCRIPT}
@ -222,9 +222,7 @@ if(SUPPORTS_DTS)
#
set(CMD_LEGACY_EXTRACT ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/dts/gen_legacy_defines.py
--dts ${BOARD}.dts.pre.tmp
--dtc-flags '${EXTRA_DTC_FLAGS}'
--bindings-dirs ${DTS_ROOT_BINDINGS}
--edt-pickle ${EDT_PICKLE}
--header-out ${DEVICETREE_UNFIXED_LEGACY_H}
)

View file

@ -14,9 +14,7 @@
import argparse
import os
import pathlib
import sys
import edtlib
import pickle
# Set this to True to generated deprecated macro warnings. Since this
# entire file is deprecated and must be explicitly enabled with
@ -31,15 +29,8 @@ def main():
args = parse_args()
try:
edt = edtlib.EDT(args.dts, args.bindings_dirs,
# Suppress this warning if it's suppressed in dtc
warn_reg_unit_address_mismatch=
"-Wno-simple_bus_reg" not in args.dtc_flags,
default_prop_types=False,
support_fixed_partitions_on_any_bus = False)
except edtlib.EDTError as e:
sys.exit(f"devicetree error: {e}")
with open(args.edt_pickle, 'rb') as f:
edt = pickle.load(f)
header_file = open(args.header_out, "w", encoding="utf-8")
flash_area_num = 0
@ -83,13 +74,8 @@ def parse_args():
# Returns parsed command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument("--dts", required=True, help="DTS file")
parser.add_argument("--dtc-flags",
help="'dtc' devicetree compiler flags, some of which "
"might be respected here")
parser.add_argument("--bindings-dirs", nargs='+', required=True,
help="directory with bindings in YAML format, "
"we allow multiple")
parser.add_argument("--edt-pickle", required=True,
help="pickle file containing EDT object")
parser.add_argument("--header-out", required=True,
help="path to write header to")

View file

@ -30,6 +30,7 @@ import pty
from pathlib import Path
from distutils.spawn import find_executable
from colorama import Fore
import pickle
import platform
import yaml
try:
@ -59,8 +60,8 @@ ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
if not ZEPHYR_BASE:
sys.exit("$ZEPHYR_BASE environment variable undefined")
# This is needed to load edt.pickle files.
sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "dts"))
import edtlib
hw_map_local = threading.Lock()
report_lock = threading.Lock()
@ -1900,12 +1901,12 @@ class FilterBuilder(CMake):
filter_data.update(self.defconfig)
filter_data.update(self.cmake_cache)
dts_path = os.path.join(self.build_dir, "zephyr", self.platform.name + ".dts.pre.tmp")
edt_pickle = os.path.join(self.build_dir, "zephyr", "edt.pickle")
if self.testcase and self.testcase.tc_filter:
try:
if os.path.exists(dts_path):
edt = edtlib.EDT(dts_path, [os.path.join(ZEPHYR_BASE, "dts", "bindings")],
warn_reg_unit_address_mismatch=False)
if os.path.exists(edt_pickle):
with open(edt_pickle, 'rb') as f:
edt = pickle.load(f)
else:
edt = None
res = expr_parser.parse(self.testcase.tc_filter, filter_data, edt)

View file

@ -6,6 +6,7 @@ import abc
import argparse
import os
import pathlib
import pickle
import shutil
import subprocess
import sys
@ -20,10 +21,9 @@ from zcmake import CMakeCache
from zephyr_ext_common import Forceable, cached_runner_config, \
ZEPHYR_SCRIPTS
# This is needed to load edt.pickle files.
sys.path.append(str(ZEPHYR_SCRIPTS / 'dts'))
import edtlib
SIGN_DESCRIPTION = '''\
This command automates some of the drudgery of creating signed Zephyr
binaries for chain-loading by a bootloader.
@ -208,7 +208,7 @@ class ImgtoolSigner(Signer):
vtoff = self.get_cfg(command, bcfg, 'CONFIG_ROM_START_OFFSET')
# Flash device write alignment and the partition's slot size
# come from devicetree:
flash = self.edt_flash_node(b, cache)
flash = self.edt_flash_node(b)
align, addr, size = self.edt_flash_params(flash)
runner_config = cached_runner_config(build_dir, cache)
@ -280,30 +280,21 @@ class ImgtoolSigner(Signer):
return None
@staticmethod
def edt_flash_node(b, cache):
def edt_flash_node(b):
# Get the EDT Node corresponding to the zephyr,flash chosen DT
# node.
# Retrieve the list of devicetree bindings from cache.
try:
bindings = cache.get_list('CACHED_DTS_ROOT_BINDINGS')
log.dbg('DTS bindings:', bindings, level=log.VERBOSE_VERY)
except KeyError:
log.die('CMake cache has no CACHED_DTS_ROOT_BINDINGS.'
'\n Try again after re-building your application.')
# node; 'b' is the build directory as a pathlib object.
# Ensure the build directory has a compiled DTS file
# where we expect it to be.
dts = b / 'zephyr' / (cache['CACHED_BOARD'] + '.dts.pre.tmp')
if not dts.is_file():
log.die("can't find DTS; expected:", dts)
dts = b / 'zephyr' / 'zephyr.dts'
log.dbg('DTS file:', dts, level=log.VERBOSE_VERY)
edt_pickle = b / 'zephyr' / 'edt.pickle'
if not edt_pickle.is_file():
log.die("can't load devicetree; expected to find:", edt_pickle)
# Parse the devicetree using bindings from cache.
try:
edt = edtlib.EDT(dts, bindings)
except edtlib.EDTError as e:
log.die("can't parse devicetree:", e)
# Load the devicetree.
with open(edt_pickle, 'rb') as f:
edt = pickle.load(f)
# By convention, the zephyr,flash chosen node contains the
# partition information about the zephyr image to sign.