123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- '''
- This script uses edtlib and the devicetree data in the build directory
- to generate a CMake file which contains devicetree data.
- That data can then be used in the rest of the build system.
- The generated CMake file looks like this:
- add_custom_target(devicetree_target)
- set_target_properties(devicetree_target PROPERTIES
- "DT_PROP|/soc|compatible" "vnd,soc;")
- ...
- It defines a special CMake target, and saves various values in the
- devicetree as CMake target properties.
- Be careful:
- "Property" here can refer to a CMake target property or a
- DTS property. DTS property values are stored inside
- CMake target properties, along with other devicetree data.
- The build system includes this generated file early on, so
- devicetree values can be used at CMake processing time.
- Accss is not done directly, but with Zephyr CMake extension APIs,
- like this:
- # sets 'compat' to "vnd,soc" in CMake
- dt_prop(compat PATH "/soc" PROPERTY compatible INDEX 0)
- This is analogous to how DTS values are encoded as C macros,
- which can be read in source code using C APIs like
- DT_PROP(node_id, foo) from devicetree.h.
- '''
- import argparse
- import os
- import pickle
- import sys
- sys.path.append(os.path.join(os.path.dirname(__file__), 'python-devicetree',
- 'src'))
- def parse_args():
-
- parser = argparse.ArgumentParser()
- parser.add_argument("--cmake-out", required=True,
- help="path to write the CMake property file")
- parser.add_argument("--edt-pickle", required=True,
- help="path to read the pickled edtlib.EDT object from")
- return parser.parse_args()
- def main():
- args = parse_args()
- with open(args.edt_pickle, 'rb') as f:
- edt = pickle.load(f)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- cmake_props = []
- for node in edt.chosen_nodes:
- path = edt.chosen_nodes[node].path
- cmake_props.append(f'"DT_CHOSEN|{node}" "{path}"')
- for node in edt.nodes:
- cmake_props.append(f'"DT_NODE|{node.path}" TRUE')
- for label in node.labels:
- cmake_props.append(f'"DT_NODELABEL|{label}" "{node.path}"')
- for item in node.props:
-
- if "phandle" not in node.props[item].type:
- if "array" in node.props[item].type:
-
- cmake_value = ''
- for val in node.props[item].val:
- cmake_value = f'{cmake_value}{val};'
- else:
- cmake_value = node.props[item].val
-
-
- cmake_prop = f'DT_PROP|{node.path}|{item}'
- cmake_props.append(f'"{cmake_prop}" "{cmake_value}"')
- if node.regs is not None:
- cmake_props.append(f'"DT_REG|{node.path}|NUM" "{len(node.regs)}"')
- cmake_addr = ''
- cmake_size = ''
- for reg in node.regs:
- if reg.addr is None:
- cmake_addr = f'{cmake_addr}NONE;'
- else:
- cmake_addr = f'{cmake_addr}{hex(reg.addr)};'
- if reg.size is None:
- cmake_size = f'{cmake_size}NONE;'
- else:
- cmake_size = f'{cmake_size}{hex(reg.size)};'
- cmake_props.append(f'"DT_REG|{node.path}|ADDR" "{cmake_addr}"')
- cmake_props.append(f'"DT_REG|{node.path}|SIZE" "{cmake_size}"')
- with open(args.cmake_out, "w", encoding="utf-8") as cmake_file:
- print('add_custom_target(devicetree_target)', file=cmake_file)
- print(file=cmake_file)
- for prop in cmake_props:
- print(
- f'set_target_properties(devicetree_target PROPERTIES {prop})',
- file=cmake_file
- )
- if __name__ == "__main__":
- main()
|