PyYAML 5.1 was just released and it doesn't support !include as
previous versions do. This breaks our DTS bindings parsing.
Let's fix our extract_dts_include.py script to work with both
3.13 and 5.1.
Also, update the pyyaml requirement to >=3.13 to be sure we're
compatible.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/14496
Signed-off-by: Michael Scott <mike@foundries.io>
To reproduce the issue this addresses, run "cmake -B96b_nitrogen"
twice with Python 3.5. Observe the order of the flash partition table
changing in:
"build{1,2}/zephyr/include/generated/generated_dts_board.conf" and
"generated_dts_board_unfixed.h"
Dictionaries are iterated in a random order by Python 3.5 and before.
This could have caused "Unstable" CI in PR #13921 and maybe others.
Anyway we want builds to be determimistic by default. Explicit
randomness can be added for better coverage but not by default.
Signed-off-by: Marc Herbert <marc.herbert@intel.com>
insert_defs() is the only function that adds keys to 'defs', and they
always get added with an 'aliases' key.
This function could get super simple if the duplicate-removal code could
be removed. It only seems to be needed to prevent duplicates for some
(unfortunately tricky) flash-related stuff now.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
- No deep copying is needed. The deepcopy() is just a hack to work
around that the value might not be a list. That deserves a comment at
least.
- A catch-all try/except will hide stuff like misspelled variables as
well. It's usually a bad idea.
Rewrite things to be more explicit, and add some comments.
reg.py was indirectly using the deepcopy() imported in global.py,
because it does 'from global import *'. Have it import deepcopy() itself
instead. reg.py is the only remaining user of deepcopy().
reg.py relying on the deepcopy() import in global.py was super hard to
discover, due to another catch-all try/except around the deepcopy()
call.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
All nodes have a 'children' key.
Also simplify a bit. The loop is copying a dictionary verbatim.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
'/foo' was turned into ''. Turn it into '/' instead. That's how the root
is represented in 'reduced' too.
Also remove some code from get_addr_size_cells() that was only there to
work around the bug.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
If a binding specifies 'generate: define' for 'interrupt-names' (like
some bindings do), then that ought to generate #defines for it, but the
scripts/dts code currently hardcodes 'interrupt-names' to be ignored
(along with some other properties).
Maybe the 'generate: define' in those bindings is a mistake, but the
code still ought to respect it. That also gets rid of some mystery code.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Add some short doc comments at the beginning so that people can quickly
get an idea of what they're about.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
It's confusing that "address" is often used within the same function to
refer to both node paths and e.g. address cells.
Make things easier to understand by calling /foo/bar a path instead.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
extract_property() is meant to generate #defines for a single property,
like 'foo = <1 2 3>'. Currently, it also generates node-level #defines
related to parent buses.
That makes the intent of the code hard to understand, and also means
that identical node-level #defines get redundantly added multiple times
(once per property).
Generate the node-level bus #defines before processing properties, in
generate_node_defines(). Use a new generate_bus_defines() helper.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Due to the way the code was structured,
flash.extract_partition(node_path) was called multiple times for the
same 'node_path'.
That must've been a mistake to begin with (but was hard to spot before
the code was cleaned up). Move the generation of per-node #defines out
of the property loop.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
generate_node_defines() immediately returns if the node's 'compatible'
is not in the binding.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Derive 'node_compat' and 'prop_val' (the dictionary for the property
from the YAML binding) inside extract_property().
That gives it just two parameters and makes it clearer that it's just
generating #define's for a single device tree property. 'prop_val' was
only used to look up prop_val['type'].
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Moves it closer to where it's used, and will allow other simplifications
in generate_node_defines().
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
After lots of reverse-engineering, I understand why deepcopy() is used:
1) Various functions defined in scripts/dts/extract/* modify the list
of names in-place
2) A plain list.copy() won't work when the *-names property happens to
have a single name in it, because devicetree.py gives a string
instead of a list in that case
Using deepcopy() to solve (2) is very confusing (especially with no
comments), because no deep copying is actually needed.
Get rid of deepcopy(), add a helper function for fetching the names, and
some comments.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
- Remove dead "if 'props' in nodes" check
- Rename the 'nodes' parameter to 'node'. It represents a single node.
- Use a defaultdict(int) for 'last_used_id' (makes unset keys give 0)
- Use a global for 'last_used_id'
- Move some related code so it appears together
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Turn
if a:
if b:
...
into
if a and b:
...
Simplify some error messages with .format() as well, and get rid of some
redundant str()s. '{0} {1} {1}'.format('foo', 'bar') gives
'foo bar bar'.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
- Reduce the indentation and remove the awkward line breaks. This is
possible now that there's no recursion.
- Be consistent with quotes
- Move some initialization closer to where it's used
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
The recursion was used to implement 'properties:' within 'properties:'
in binding files, which seems to be a dead leftover (and undocumented).
Removing it gets rid of code and makes things more transparent.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Use more descriptive naming, get rid of unused 'v' variable, and an
unnecessary None check (None won't appear in get_binding_compats()).
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
...to generate_node_defines().
More explicit. "extract node include info" can be read in many ways:
- Extract a node's "include info"
- Extract node and include info
- etc.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
That way it consistently generates all #define's.
Add some related clarifying comments to main() too.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
It's special-cased for merging bindings and not a general dictionary
merging function.
Also simplify the documentation a bit.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
The Bindings class was only used to implement '!include foo.yaml'
(easier to see after some things were moved out of it). Use plain
functions instead, which might be a bit more transparent and gives
simpler code.
Also remove the recursive '!include' detection for now, which is broken
in that the same .yaml being included twice will always trigger it, even
for non-circular cases.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
As written, this function could take e.g. '!include bar', find 'foo-bar'
(due to the endswith()), and include it. This is undocumented and
doesn't seem to be used, so I'm guessing that it isn't intentional.
Removing that bug/feature also makes the code much simpler.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
load_bindings() is trivial, and it allows some stuff to simplified, like
the check for no bindings being found, and the assignments to the
extract.globals.{bindings,bus_bindings,bindings_compat}.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
This is (probably) a temporary change just to be able to move some stuff
out of the Bindings class.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Only write out to the .conf file if the define starts with "DT_". The
the conf file should only be used by sanitycheck, west, and
kconfigfunctions at this time. In the future we should remove it, so
lets limit what's it exposing at this time.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
DT_FLASH_AREA_<X>_DEV should be the label of the flash controller. For
flashes that are "jedec,spi-nor" the flash itself is considered the
controller. For "soc-nv-flash" the parent of the flash is assumed to be
the controller.
Rework the logic in how we determined DT_FLASH_AREA_<X>_DEV to handle
both cases.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>