Aggregate project settings for ARXML specifications in ProjectCfg
Change-Id: Ia54f7ae0164aeb62361b0839b79b178779616402
This commit is contained in:
parent
971bd262d3
commit
7888ebe2b7
5
NOTICE
5
NOTICE
@ -31,6 +31,7 @@ python-certifi 2024.7.4: https://certifiio.readthedocs.io/en/latest/ : Mozilla P
|
||||
python-pluggy 1.5.0: https://pypi.python.org/pypi/pluggy : MIT License
|
||||
RonnyPfannschmidt/iniconfig 2.0.0: https://github.com/RonnyPfannschmidt/iniconfig : MIT License
|
||||
ruamel-yaml 0.18.6: https://pypi.org/project/ruamel.yaml/ : MIT License
|
||||
ruamel.yaml.clib 0.2.12: https://sourceforge.net/p/ruamel-yaml-clib/code/ci/default/tree/ : MIT License
|
||||
SciPy 1.9.1: http://www.scipy.org : BSD 3-clause "New" or "Revised" License
|
||||
smmap 5.0.1: https://github.com/gitpython-developers/smmap : BSD 3-clause "New" or "Revised" License
|
||||
tomli 2.0.2: https://github.com/hukkin/tomli : MIT License
|
||||
@ -2692,6 +2693,8 @@ from typing import (
|
||||
|
||||
ruamel-yaml 0.18.6 pypi:ruamel.yaml/0.18.6: https://pypi.org/project/ruamel.yaml/
|
||||
No Copyrights found
|
||||
ruamel.yaml.clib 0.2.12 pypi:ruamel.yaml.clib/0.2.12: https://sourceforge.net/p/ruamel-yaml-clib/code/ci/default/tree/
|
||||
No Copyrights found
|
||||
SciPy 1.9.1 pypi:scipy/1.9.1: http://www.scipy.org
|
||||
(c) (Col
|
||||
|
||||
@ -13615,7 +13618,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
---
|
||||
|
||||
MIT License
|
||||
(exceptiongroup 1.2.2, flake8 7.1.1, pycodestyle 2.12.1, Pyflakes 3.2.0, pytest 8.3.3, python-pluggy 1.5.0, python3-charset-normalizer 3.4.0, RonnyPfannschmidt/iniconfig 2.0.0, ruamel-yaml 0.18.6, tomli 2.0.2, urllib3 2.2.3)
|
||||
(exceptiongroup 1.2.2, flake8 7.1.1, pycodestyle 2.12.1, Pyflakes 3.2.0, pytest 8.3.3, python-pluggy 1.5.0, python3-charset-normalizer 3.4.0, RonnyPfannschmidt/iniconfig 2.0.0, ruamel-yaml 0.18.6, ruamel.yaml.clib 0.2.12, tomli 2.0.2, urllib3 2.2.3)
|
||||
|
||||
The MIT License
|
||||
===============
|
||||
|
@ -187,7 +187,7 @@ Default is False.
|
||||
#### useSwcNameAsPrefix
|
||||
|
||||
Use the software component name as prefix in the "common" functions and structs generated by powertrain-build.
|
||||
"softwareComponentName" needs to be set in [ProjectInfo](#projectinfo).
|
||||
"softwareComponentName" needs to be set in [CompositionConfig](#compositionconfig).
|
||||
Default is False.
|
||||
|
||||
## Rasters json File
|
||||
@ -304,6 +304,54 @@ Use the field to choose specific code generation options in powertrain-build.
|
||||
Key value pairs specified in this struct takes priority over the ones specified in [ProjectTemplates](#projecttemplates).
|
||||
Afformentioned chapter also describes the available options and their default values.
|
||||
|
||||
### CompositionConfig
|
||||
|
||||
Collection of config options for autosar arxml based scheduling in the project configuration or base config.
|
||||
These options affect the content of a configuration file used to complement the arxml file of the project
|
||||
when building with conan.
|
||||
|
||||
#### compositionName
|
||||
|
||||
Name of the composition file used by conan to complement the arxml file.
|
||||
Will be .yml unless name is given with file ending.
|
||||
|
||||
#### compositionArxml
|
||||
|
||||
Name of the arxml file containing autosar packages and elements, specifying signal interfaces, data types etc.
|
||||
|
||||
#### customYamlInitFunctionName
|
||||
|
||||
Name of Init function. Default: "AR_<scheduler_prefix>_VcExtINI"
|
||||
|
||||
#### generateExternalImplementationType
|
||||
|
||||
Specifies if external implementation types should be generated or not at the build stage (conan). Default: True
|
||||
|
||||
#### softwareComponentName
|
||||
|
||||
Name of the software component. Needs to match the software component name in the arxml.
|
||||
Default: matching "A2lConfig/name".
|
||||
|
||||
#### softwareComponentTemplate
|
||||
|
||||
Name of template used by the software component. Default: None.
|
||||
|
||||
#### softwareComponentBase
|
||||
|
||||
Name of software component base used by the software component. Default: 'QM'.
|
||||
|
||||
#### includeStatic
|
||||
|
||||
Include static elements or not. Default: True.
|
||||
|
||||
#### includeShared
|
||||
|
||||
Include shared elements or not. Default: True.
|
||||
|
||||
#### includeDiagnostics
|
||||
|
||||
Include diagnostics elements or not. Default: True.
|
||||
|
||||
### MemoryMapConfig
|
||||
|
||||
This configuration is required when [generateInterfaceHeaders](#generateinterfaceheaders) is set to true.
|
||||
|
@ -44,6 +44,7 @@ class BuildProjConfig:
|
||||
if not Version.is_compatible(self._prj_cfg.get('BaseConfigFileVersion')):
|
||||
raise ValueError('Incompatible base config file version.')
|
||||
deep_dict_update(self._prj_cfg, self._get_code_generation_config())
|
||||
self._composition_config = self._parse_composition_config(self._prj_cfg.get('CompositionConfig', {}))
|
||||
self.has_yaml_interface = self._prj_cfg['ProjectInfo'].get('yamlInterface', False)
|
||||
self.device_domains = self._get_device_domains()
|
||||
self.services_file = self._get_services_file()
|
||||
@ -247,42 +248,34 @@ class BuildProjConfig:
|
||||
os.path.normpath(self._prj_cfg['ProjectInfo']
|
||||
['srcCodeDstDir']))
|
||||
|
||||
def get_composition_name(self):
|
||||
"""Return the composition name."""
|
||||
name, _ = os.path.splitext(self._prj_cfg['ProjectInfo']['compositionName'])
|
||||
return name
|
||||
|
||||
def get_composition_ending(self):
|
||||
"""Return the composition ending."""
|
||||
_, ending = os.path.splitext(self._prj_cfg['ProjectInfo']['compositionName'])
|
||||
if ending:
|
||||
return ending
|
||||
return 'yml'
|
||||
|
||||
def get_composition_arxml(self):
|
||||
"""Return the relative composition arxml path."""
|
||||
return self._prj_cfg['ProjectInfo']['compositionArxml']
|
||||
|
||||
def get_custom_yaml_init_function_name(self):
|
||||
"""Return the custom yaml init function name."""
|
||||
return self._prj_cfg['ProjectInfo'].get('customYamlInitFunctionName')
|
||||
|
||||
def get_gen_ext_impl_type(self):
|
||||
"""Return the generate external implementation type."""
|
||||
return self._prj_cfg['ProjectInfo'].get('generateExternalImplementationType', True)
|
||||
|
||||
def get_swc_name(self):
|
||||
"""Returns the software component name."""
|
||||
def _parse_composition_config(self, file_config):
|
||||
"""Parse the composition configuration from project config."""
|
||||
a2lname = f"{self.get_a2l_cfg()['name']}_SC"
|
||||
return self._prj_cfg['ProjectInfo'].get('softwareComponentName', a2lname)
|
||||
self._composition_config = {
|
||||
'compositionName': None,
|
||||
'compositionEnding': 'yml',
|
||||
'compositionArxml': file_config.get("compositionArxml", None),
|
||||
'customYamlInitFunctionName': file_config.get("customYamlInitFunctionName", None),
|
||||
'generateExternalImplementationType': file_config.get("generateExternalImplementationType", True),
|
||||
'softwareComponentName': file_config.get("softwareComponentName", a2lname),
|
||||
'softwareComponentTemplate': file_config.get('softwareComponentTemplate', None),
|
||||
'softwareComponentBase': file_config.get('softwareComponentBase', 'QM'),
|
||||
'includeStatic': file_config.get('includeStatic', True),
|
||||
'includeShared': file_config.get('includeShared', True),
|
||||
'includeDiagnostics': file_config.get('includeDiagnostics', True),
|
||||
}
|
||||
compositionName = file_config.get("compositionName", None)
|
||||
if compositionName is not None:
|
||||
self._composition_config["compositionName"] = compositionName.split(".")[0]
|
||||
if "." in compositionName:
|
||||
self._composition_config["compositionEnding"] = compositionName.split(".")[1]
|
||||
return self._composition_config
|
||||
|
||||
def get_swc_template(self):
|
||||
"""Returns the software component template to use."""
|
||||
return self._prj_cfg['ProjectInfo'].get('softwareComponentTemplate')
|
||||
|
||||
def get_swc_base(self):
|
||||
"""Returns the software component base to use (ASIL classification)."""
|
||||
return self._prj_cfg['ProjectInfo'].get('softwareComponentBase', 'QM')
|
||||
def get_composition_config(self, key=None):
|
||||
"""Get the composition configuration from project config."""
|
||||
if key is None:
|
||||
return self._composition_config
|
||||
return self._composition_config[key]
|
||||
|
||||
def get_car_com_dst(self):
|
||||
"""Return the absolute path to the source output folder."""
|
||||
|
@ -364,7 +364,7 @@ class ZCCore(ProblemLogger):
|
||||
Returns:
|
||||
(list(str)): List of lines to write to the DTC header file.
|
||||
"""
|
||||
name = self._prj_cfg.get_swc_name()
|
||||
name = self._prj_cfg.get_composition_config("softwareComponentName")
|
||||
header_guard = f'{self.FILE_NAME.upper()}_H'
|
||||
header = [
|
||||
f'#ifndef {header_guard}\n',
|
||||
|
@ -708,7 +708,7 @@ class ZCDIDs(ProblemLogger):
|
||||
Returns:
|
||||
(list(str)): List of lines to write to DID API header file.
|
||||
"""
|
||||
name = self._build_cfg.get_swc_name()
|
||||
name = self._build_cfg.get_composition_config("softwareComponentName")
|
||||
header_guard = f'{self.FILE_NAME.upper()}_H'
|
||||
header = [
|
||||
f'#ifndef {header_guard}\n',
|
||||
|
@ -157,7 +157,7 @@ class NVMDef(ProblemLogger):
|
||||
use_prefix (bool): Patch the nvm header file definitions with the SWC name as prefix.
|
||||
"""
|
||||
res = {}
|
||||
prefix = f"{self._project_config.get_swc_name()}_" if use_prefix else ""
|
||||
prefix = f"{self._project_config.get_composition_config('softwareComponentName')}_" if use_prefix else ""
|
||||
for var, var_attrib in self._nvm_signals.items():
|
||||
res[var] = {
|
||||
"var": {"var": var, "type": var_attrib["type"], "cvc_type": "CVC_NVM"},
|
||||
@ -449,7 +449,7 @@ class NVMDef(ProblemLogger):
|
||||
use_prefix (bool): Patch the nvm header file definitions with the SWC name as prefix.
|
||||
"""
|
||||
self.info("Start generating nvm header file")
|
||||
prefix = f"{self._project_config.get_swc_name()}_" if use_prefix else ""
|
||||
prefix = f"{self._project_config.get_composition_config('softwareComponentName')}_" if use_prefix else ""
|
||||
|
||||
def write_signals():
|
||||
for memory_area in self._nvm_memory_areas:
|
||||
@ -526,7 +526,7 @@ class NVMDef(ProblemLogger):
|
||||
"""
|
||||
# TODO: Add memory from previous builds!!! and mark old positions #
|
||||
self.info("Start generating nvm source file")
|
||||
prefix = f"{self._project_config.get_swc_name()}_" if use_prefix else ""
|
||||
prefix = f"{self._project_config.get_composition_config('softwareComponentName')}_" if use_prefix else ""
|
||||
src_file_dst = self._project_config.get_src_code_dst_dir()
|
||||
file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"])
|
||||
with open(file_name + ".c", "w", encoding="utf-8") as cptr:
|
||||
|
@ -23,7 +23,7 @@ class ZoneControllerCalibration(ProblemLogger):
|
||||
build_cfg (BuildProjConfig): Object with build configuration settings.
|
||||
calib_data (dict): Dictionary containing calibration data for a ZoneController project.
|
||||
"""
|
||||
self.swc_name = build_cfg.get_swc_name()
|
||||
self.swc_name = build_cfg.get_composition_config("softwareComponentName")
|
||||
self.src_code_dst_dir = build_cfg.get_src_code_dst_dir()
|
||||
self.calibration_variables = calib_data['class_info']
|
||||
self.calibration_interface_header = 'calibration_interface.h'
|
||||
|
@ -118,8 +118,8 @@ class CompositionYaml(ProblemLogger):
|
||||
|
||||
def generate_yaml(self):
|
||||
"""Generates a yaml from project/model information."""
|
||||
composition_name = self.build_cfg.get_composition_name()
|
||||
composition_ending = self.build_cfg.get_composition_ending()
|
||||
composition_name = self.build_cfg.get_composition_config("compositionName")
|
||||
composition_ending = self.build_cfg.get_composition_config("compositionEnding")
|
||||
all_info = self.gather_yaml_info()
|
||||
|
||||
output_directory = self.build_cfg.get_src_code_dst_dir()
|
||||
@ -153,8 +153,10 @@ class CompositionYaml(ProblemLogger):
|
||||
|
||||
all_info = {
|
||||
"ExternalFiles": {
|
||||
"Composition": self.build_cfg.get_composition_arxml(),
|
||||
"GenerateExternalImplementationTypes": self.build_cfg.get_gen_ext_impl_type(),
|
||||
"Composition": self.build_cfg.get_composition_config("compositionArxml"),
|
||||
"GenerateExternalImplementationTypes": self.build_cfg.get_composition_config(
|
||||
"generateExternalImplementationType"
|
||||
),
|
||||
},
|
||||
"SoftwareComponents": software_components,
|
||||
"DataTypes": {**self.data_types, **pt_build_data_types},
|
||||
@ -174,16 +176,16 @@ class CompositionYaml(ProblemLogger):
|
||||
value_extraction_regexes = [
|
||||
(
|
||||
re.compile(r"^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P<name>\w+)\s*=\s*(?P<value>[-\d\.e]+F?)\s*;"),
|
||||
lambda regex_match, _: self._cast_init_value(regex_match.group("value"))
|
||||
lambda regex_match, _: self._cast_init_value(regex_match.group("value")),
|
||||
),
|
||||
(
|
||||
re.compile(r"^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P<name>\w+)\[(?P<size>[\d]+)\]\s*=\s*"),
|
||||
self._get_array_init_values
|
||||
self._get_array_init_values,
|
||||
),
|
||||
(
|
||||
re.compile(r"^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P<name>\w+)\[(?P<rows>[\d]+)\]\[(?P<cols>[\d]+)\]\s*=\s*"),
|
||||
self._get_matrix_init_values
|
||||
)
|
||||
self._get_matrix_init_values,
|
||||
),
|
||||
]
|
||||
|
||||
init_values = {}
|
||||
@ -289,7 +291,7 @@ class CompositionYaml(ProblemLogger):
|
||||
Returns:
|
||||
trigger_signal (str): Name of variable for triggering calibration.
|
||||
"""
|
||||
software_component_name = self.build_cfg.get_swc_name()
|
||||
software_component_name = self.build_cfg.get_composition_config("softwareComponentName")
|
||||
trigger_signal = ZCC.trigger_read_rte_cdata_signal["name_template"].format(swc_name=software_component_name)
|
||||
|
||||
if trigger_signal in calibration_variables:
|
||||
@ -354,10 +356,10 @@ class CompositionYaml(ProblemLogger):
|
||||
Returns:
|
||||
dict: Dict containing runnables information.
|
||||
"""
|
||||
swc_name = self.build_cfg.get_swc_name()
|
||||
swc_name = self.build_cfg.get_composition_config("softwareComponentName")
|
||||
autosar_prefix = "AR_"
|
||||
swc_prefix = self.build_cfg.get_scheduler_prefix()
|
||||
custom_init_function = self.build_cfg.get_custom_yaml_init_function_name()
|
||||
custom_init_function = self.build_cfg.get_composition_config("customYamlInitFunctionName")
|
||||
standard_init_function = autosar_prefix + swc_prefix + "VcExtINI"
|
||||
init_function = custom_init_function if custom_init_function is not None else standard_init_function
|
||||
calibration_variables = list(self.cal_class_info["autosar"]["class_info"].keys())
|
||||
@ -396,9 +398,9 @@ class CompositionYaml(ProblemLogger):
|
||||
swcs (dict): SWC information.
|
||||
data_types (dict): Data types information.
|
||||
"""
|
||||
software_component_name = self.build_cfg.get_swc_name()
|
||||
software_component_template = self.build_cfg.get_swc_template()
|
||||
software_component_base = self.build_cfg.get_swc_base()
|
||||
software_component_name = self.build_cfg.get_composition_config("softwareComponentName")
|
||||
software_component_template = self.build_cfg.get_composition_config("softwareComponentTemplate")
|
||||
software_component_base = self.build_cfg.get_composition_config("softwareComponentBase")
|
||||
data_types = {
|
||||
**self.cal_class_info["autosar"]["data_types"],
|
||||
**self.meas_class_info["autosar"]["data_types"],
|
||||
@ -410,10 +412,14 @@ class CompositionYaml(ProblemLogger):
|
||||
if software_component_base is not None:
|
||||
swcs[software_component_name]["swcbase"] = software_component_base
|
||||
swcs[software_component_name]["runnables"] = self._get_runnable_info()
|
||||
swcs[software_component_name]["shared"] = self.cal_class_info["autosar"]["class_info"]
|
||||
swcs[software_component_name]["static"] = self.meas_class_info["autosar"]["class_info"]
|
||||
if self.build_cfg.get_composition_config("includeShared"):
|
||||
swcs[software_component_name]["shared"] = self.cal_class_info["autosar"]["class_info"]
|
||||
if self.build_cfg.get_composition_config("includeStatic"):
|
||||
swcs[software_component_name]["static"] = self.meas_class_info["autosar"]["class_info"]
|
||||
swcs[software_component_name]["ports"] = self._get_ports_info()
|
||||
swcs[software_component_name]["diagnostics"] = self._get_diagnostic_info()
|
||||
diagnostic_info = self._get_diagnostic_info()
|
||||
if self.build_cfg.get_composition_config("includeDiagnostics"):
|
||||
swcs[software_component_name]["diagnostics"] = diagnostic_info
|
||||
return swcs, data_types
|
||||
|
||||
def _get_variables(self):
|
||||
|
@ -213,7 +213,7 @@ class TestZCCore(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set-up common data structures for all tests in the test case."""
|
||||
project_config = MagicMock()
|
||||
project_config.get_swc_name.return_value = 'DUMMY'
|
||||
project_config.get_composition_config.return_value = 'DUMMY'
|
||||
unit_configs = MagicMock()
|
||||
unit_configs.get_per_unit_cfg.return_value = {}
|
||||
|
||||
|
@ -984,7 +984,7 @@ class TestZCDIDs(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
build_cfg = MagicMock()
|
||||
build_cfg.get_swc_name.return_value = 'DUMMY'
|
||||
build_cfg.get_composition_config.return_value = "DUMMY"
|
||||
unit_cfg = MagicMock()
|
||||
self.zc_dids = ZCDIDs(build_cfg, unit_cfg)
|
||||
self.zc_dids.project_dids = dummy_project_dids
|
||||
|
@ -210,7 +210,7 @@ class TestNVMDef(unittest.TestCase):
|
||||
self.proj_cnfg.get_root_dir = MagicMock(return_value=projdir)
|
||||
self.proj_cnfg.get_src_code_dst_dir = MagicMock(return_value=str(Path(SRC_DIR, 'output')))
|
||||
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs)
|
||||
self.proj_cnfg.get_swc_name = MagicMock(return_value='DummySwc')
|
||||
self.proj_cnfg.get_composition_config = MagicMock(return_value='DummySwc')
|
||||
self.proj_cnfg.get_code_generation_config = MagicMock(return_value=True)
|
||||
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
|
||||
|
||||
|
@ -18,7 +18,7 @@ class TestZoneControllerCalibration(TestCase):
|
||||
build_cfg = MagicMock()
|
||||
build_cfg.name = "XVC"
|
||||
build_cfg.get_src_code_dst_dir.return_value = None
|
||||
build_cfg.get_swc_name.return_value = "testName_SC"
|
||||
build_cfg.get_composition_config.return_value = "testName_SC"
|
||||
dummy_calib_data = {
|
||||
"class_info": {
|
||||
"dummy_signal_one": {
|
||||
|
@ -32,27 +32,37 @@ class BuildProjConfigMock(BuildProjConfig):
|
||||
name = ""
|
||||
|
||||
|
||||
def mocked_get_composition_config(key):
|
||||
return {
|
||||
"compositionArxml": "some_arxml.arxml",
|
||||
"compositionName": "compositionName",
|
||||
'compositionEnding': 'yml',
|
||||
"softwareComponentName": "testName_SC",
|
||||
"softwareComponentTemplate": "ARTCSC",
|
||||
"softwareComponentBase": "QM",
|
||||
"customYamlInitFunctionName": None,
|
||||
"generateExternalImplementationType": True,
|
||||
'includeStatic': True,
|
||||
'includeShared': True,
|
||||
'includeDiagnostics': True,
|
||||
}[key]
|
||||
|
||||
|
||||
class TestCompositionYaml(unittest.TestCase):
|
||||
"""Test case for testing composition_yaml."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set-up common data structures for all tests in the test case."""
|
||||
self.build_cfg = MagicMock(spec_set=BuildProjConfigMock)
|
||||
self.build_cfg.get_composition_config.side_effect = mocked_get_composition_config
|
||||
self.build_cfg.name = "XVC"
|
||||
self.build_cfg.get_scheduler_prefix = MagicMock(return_value="prefix_")
|
||||
self.build_cfg.get_src_code_dst_dir = MagicMock(
|
||||
return_value=os.path.abspath("output")
|
||||
)
|
||||
self.build_cfg.get_composition_arxml = MagicMock(return_value="some_arxml.arxml")
|
||||
self.build_cfg.get_units_raster_cfg = MagicMock(
|
||||
return_value=({"SampleTimes": {"testRunnable": 10}})
|
||||
)
|
||||
self.build_cfg.get_composition_name = MagicMock(return_value="compositionName")
|
||||
self.build_cfg.get_swc_name = MagicMock(return_value="testName_SC")
|
||||
self.build_cfg.get_swc_template = MagicMock(return_value="ARTCSC")
|
||||
self.build_cfg.get_swc_base = MagicMock(return_value="QM")
|
||||
self.build_cfg.get_custom_yaml_init_function_name = MagicMock(return_value=None)
|
||||
self.build_cfg.get_gen_ext_impl_type = MagicMock(return_value=True)
|
||||
self.build_cfg.get_code_generation_config = MagicMock(return_value=False)
|
||||
|
||||
self.unit_cfg = MagicMock(spec_set=UnitConfigs)
|
||||
|
Loading…
x
Reference in New Issue
Block a user