powertrain-build/pybuild/interface/generation_utils.py
Henrik Wahlqvist 65c1d746a7 Copy from Volvo Cars local project
We don't transfer git history since it may contain proprietary data that
we cannot have in an open sources version.

Change-Id: I9586124c1720db69a76b9390e208e9f0ba3b86d4
2024-05-29 08:03:54 +02:00

145 lines
4.6 KiB
Python

# Copyright 2024 Volvo Car Corporation
# Licensed under Apache 2.0.
"""Module with generation utils."""
import argparse
from ruamel.yaml import YAML
from pathlib import Path
from pybuild.interface.application import Application, get_internal_domain
from pybuild.interface.base import filter_signals
from pybuild.lib import logger
LOGGER = logger.create_logger("CSP interface generation utils")
def base_parser():
""" Base parser that adds config argument.
Returns:
parser (ArgumentParser): Base parser
"""
parser = argparse.ArgumentParser()
parser.add_argument("config", help="The project configuration file", type=Path)
return parser
def get_client_name(args, app):
""" Get client name for app.
Args:
app (Application): Parsed project configuration
Returns:
name (str): Name of the project
"""
return args.client_name if args.client_name else app.name
def process_app(config):
""" Get an app specification for the current project
Entrypoint for external scripts.
Args:
config (pathlib.Path): Path to the ProjectCfg.json
Returns:
app (Application): pybuild project
"""
app = Application()
app.parse_definition(config)
return app
def get_interface(app, interface_type):
"""Get interface(hal/dp/zc/service) to application
Args:
app (Application): Pybuild project
interface_type (BaseApplication): A type of interface
Returns:
spec (obj): obj for hal/dp/zc/service class
"""
spec = {}
rasters = app.get_rasters()
LOGGER.debug("Rasters: %s", rasters)
translation_files = app.get_translation_files()
interface_type.parse_definition(translation_files)
internal = get_internal_domain(rasters)
properties_from_json = [
{"destination": "min", "source": "min", "default": "-"},
{"destination": "max", "source": "max", "default": "-"},
{"destination": "variable_type", "source": "type"},
{"destination": "offset", "source": "offset", "default": "-"},
{"destination": "factor", "source": "lsb", "default": 1},
{"destination": "description", "source": "description"},
{"destination": "unit", "source": "unit", "default": "-"},
]
# TODO We read all yaml files at once, should we "add_signals" for all rasters at once?
# For example, service.check_endpoints will miss endpoint mismatches that reside in different rasters.
for raster in rasters:
interface_type.name = raster.name
interface_type.clear_signal_names()
interface_type.add_signals(
filter_signals(raster.insignals, internal), "insignals", properties_from_json)
interface_type.add_signals(raster.outsignals, "outsignals", properties_from_json)
LOGGER.debug("Current communication interface: %s", interface_type)
spec[raster.name] = interface_type.to_dict()
return spec
def get_method_interface(app):
""" Get method interface
Args:
app (Application): Application
Returns:
spec (dict): Specification for csp methods
"""
spec = {}
for method in app.get_methods():
method_spec = {}
method_spec['name'] = method.name
method_spec['primitive'] = method.get_primitive(method.name)
method_spec['namespace'] = method.namespace
if method.description:
method_spec['description'] = method.description
inports = {}
outports = {}
for signal in method.signals:
signal_spec = {
'primitive': method.get_primitive(signal.name),
'type': signal.properties['type'],
'variable_type': signal.properties['type'],
'variable': signal.name,
'range': signal.properties['range'],
'init': 0,
'description': '',
'unit': ''
}
if signal in method.outsignals:
outports[signal.name] = signal_spec
else:
inports[signal.name] = signal_spec
ports = {'in': inports, 'out': outports}
method_spec['ports'] = ports
spec[method.name] = method_spec
return spec
def write_to_file(content, output, is_yaml=False):
""" Write to cmake.
Args:
content (str): cmake
output (Path): File to write.
yaml (bool): Dump yaml
"""
output.parent.mkdir(parents=True, exist_ok=True)
with open(output, "w", encoding="utf-8") as file_handler:
if is_yaml:
yaml = YAML()
yaml.dump(content, file_handler)
else:
file_handler.write(content)