[PATCH RFC v3 02/11] ti: tools: config: Add board config class to generate config binaries

Neha Malcom Francis n-francis at ti.com
Wed Jun 15 08:47:55 CEST 2022


For validating config files and generating binary config artifacts, here
board specific config class is added.

Add function cfgBinaryGen() in tibcfg_gen.py. It uses TIBoardConfig
class to load given schema and config files in YAML, validate them and
generate binaries.

Signed-off-by: Tarun Sahu <t-sahu at ti.com>
[n-francis at ti.com: prepared patch for upstreaming]
Signed-off-by: Neha Malcom Francis <n-francis at ti.com>
---
 test/py/requirements.txt |   1 +
 tools/tibcfg_gen.py      | 114 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 tools/tibcfg_gen.py

diff --git a/test/py/requirements.txt b/test/py/requirements.txt
index 33c5c0bbc4..a91ba64563 100644
--- a/test/py/requirements.txt
+++ b/test/py/requirements.txt
@@ -4,6 +4,7 @@ coverage==4.5.4
 extras==1.0.0
 fixtures==3.0.0
 importlib-metadata==0.23
+jsonschema==4.0.0
 linecache2==1.0.0
 more-itertools==7.2.0
 packaging==19.2
diff --git a/tools/tibcfg_gen.py b/tools/tibcfg_gen.py
new file mode 100644
index 0000000000..e5fa2690c8
--- /dev/null
+++ b/tools/tibcfg_gen.py
@@ -0,0 +1,114 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+#
+# TI Board Configuration Class for Schema Validation and Binary Generation
+#
+
+import os
+import getopt
+import sys
+
+import yaml
+
+from jsonschema import validate
+
+
+class TIBoardConfig:
+
+    """ Texas Instruments Board Configuration File"""
+
+    def __init__(self, file, schema, data_rules=""):
+        """Load a YAML configuration file and YAML schema
+
+        Validation of the config file against the schema is also done."""
+        with open(file, 'r') as f:
+            self.file_yaml = yaml.safe_load(f)
+        with open(schema, 'r') as sch:
+            self.schema_yaml = yaml.safe_load(sch)
+        self.data_rules = data_rules
+        try:
+            validate(self.file_yaml, self.schema_yaml)
+        except Exception as e:
+            print(e)
+
+    def _convert_to_byte_chunk(self, val, data_type):
+        """Convert value into byte array"""
+        size = 0
+        if(data_type == "#/definitions/u8"):
+            size = 1
+        elif(data_type == "#/definitions/u16"):
+            size = 2
+        elif(data_type == "#/definitions/u32"):
+            size = 4
+        else:
+            raise Exception("Data type not present in definitions")
+        if type(val) == int:
+            br = val.to_bytes(size, byteorder="little")
+        return br
+
+    def _compile_yaml(self, schema_yaml, file_yaml):
+        """Convert YAML file into byte array based on YAML schema"""
+        br = bytearray()
+        for key in file_yaml.keys():
+            node = file_yaml[key]
+            node_schema = schema_yaml['properties'][key]
+            node_type = node_schema.get('type')
+            if not 'type' in node_schema:
+                br += self._convert_to_byte_chunk(node,
+                                                  node_schema.get('$ref'))
+            elif node_type == 'object':
+                br += self._compile_yaml(node_schema, node)
+            elif node_type == 'array':
+                for item in node:
+                    if not isinstance(item, dict):
+                        br += self._convert_to_byte_chunk(
+                            item, schema_yaml['properties'][key]['items']["$ref"])
+                    else:
+                        br += self._compile_yaml(node_schema.get('items'), item)
+        return br
+
+    def generate_binaries(self, out_path=""):
+        """Generate config binary artifacts from the loaded YAML configuration file"""
+        if not os.path.isdir(out_path):
+            os.mkdir(out_path)
+        for key in self.file_yaml.keys():
+            node = self.file_yaml[key]
+            node_schema = self.schema_yaml['properties'][key]
+            br = self._compile_yaml(node_schema, node)
+            path = os.path.join(out_path, key + ".bin")
+            with open(path, 'wb') as cfg:
+                cfg.write(br)
+
+    def delete_binaries(self, out_path=""):
+        """Delete generated binaries"""
+        if os.path.isdir(out_path):
+            for key in self.file_yaml.keys():
+                path = os.path.join(out_path, key + ".bin")
+                if os.path.isfile(path):
+                    os.remove(path)
+
+
+def cfgBinaryGen():
+    """Generate config binaries from YAML config file and YAML schema
+        Arguments:
+            - config_yaml: board config file in YAML
+            - schema_yaml: schema file in YAML to validate config_yaml against
+            - output_dir: output directory where generated binaries can be populated
+    Pass the arguments along with the filename in the Makefile.
+    """
+    opts, args = getopt.getopt(sys.argv[1:], "c:s:o")
+    for opt, val in opts:
+        if opt == "-c":
+            config_yaml = val
+        elif opt == "-s":
+            schema_yaml = val
+        elif opt == "-o":
+            output_dir = os.path.abspath(val)
+    try:
+        tibcfg = TIBoardConfig(config_yaml, schema_yaml)
+        tibcfg.generate_binaries(output_dir)
+    except:
+        raise ValueError("Could not find config files!")
+
+
+cfgBinaryGen()
-- 
2.17.1



More information about the U-Boot mailing list