Merge "Join the use of useSwcAsPrefix and get_scheduler_prefix"

This commit is contained in:
Zuul 2024-10-30 07:27:25 +00:00 committed by Gerrit Code Review
commit 03ac4c732a
5 changed files with 48 additions and 68 deletions

@ -184,12 +184,6 @@ Default is False.
Use "SYMBOL_LINK" in the generated A2L file.
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 [CompositionConfig](#compositionconfig).
Default is False.
## Rasters json File
### SampleTimes
@ -293,6 +287,10 @@ Defines the file names of the dummy Core Identifier c code, which is generated b
If declared, this module is included in the build. If the string is empty no module is included.
#### schedulerPrefix
Supply a prefix to use in the "common" functions and structs generated by powertrain-build.
### includesPaths
Use this key to list files that should be included in the source code.

@ -373,7 +373,7 @@ def generate_dummy_var(build_cfg, unit_cfg, signal_if, udt):
LOG.info("Finished generating VcDummy (in %4.2f s)", time.time() - start_time)
def generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l, use_prefix=False):
def generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l):
"""Generate the c&h-files which declares the NVM-ram.
The NVM-ram is declared in a struct per datatype length, in order
@ -381,20 +381,17 @@ def generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l, use_prefix=False):
communication service. Furthermore, # defines with the variables are
created to minimize the needed model changes for access to the memory.
Optionally, also patch the defined functions with the SWC name as prefix.
Args:
build_cfg (BuildProjConfig): Build project class holding where files should be stored.
unit_cfg (UnitConfigs): class holding units definitions, and which units to include.
no_nvm_a2l (bool): Do not generate A2L for NVM structs.
use_prefix (bool): Patch the nvm source file definitions with the SWC name as prefix.
"""
LOG.info("******************************************************")
LOG.info("Start generating NVMDefinitions")
start_time = time.time()
tot_vars_nvm = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {})
nvm_def = NVMDef(build_cfg, unit_cfg, tot_vars_nvm)
nvm_def.generate_nvm_config_files(no_nvm_a2l, use_prefix)
nvm_def.generate_nvm_config_files(no_nvm_a2l)
LOG.info(
"Finished generating NVMDefinitions (in %4.2f s)", time.time() - start_time
)
@ -429,21 +426,21 @@ def copy_unit_src_to_src_out(build_cfg):
)
def copy_common_src_to_src_out(build_cfg, patch=False):
def copy_common_src_to_src_out(build_cfg):
"""Copy source code to delivery folder.
Function to copy all relevant .c and .h files to the src
delivery folder (defined in the config file for the project),
from the units that are included in the project.
Optionally, also patch the defined functions with the SWC name as prefix.
Optionally, also patch the defined functions with the "schedulerPrefix".
Args:
build_cfg (BuildProjConfig): Build project class holding where files should be stored.
patch (bool): Patch the common source file functions with the SWC name as prefix.
"""
LOG.info("******************************************************")
if patch:
prefix = build_cfg.get_scheduler_prefix()
if prefix:
LOG.info("Start copying and patching common source files")
else:
LOG.info("Start copying common source files")
@ -462,9 +459,8 @@ def copy_common_src_to_src_out(build_cfg, patch=False):
files_to_copy = filter(os.path.isfile, files)
for file_ in files_to_copy:
if patch:
swc_name = build_cfg.get_composition_config("softwareComponentName")
patch_and_copy_common_src_to_src_out(swc_name, Path(file_), Path(src_dst_dir))
if prefix:
patch_and_copy_common_src_to_src_out(prefix, Path(file_), Path(src_dst_dir))
else:
shutil.copy2(file_, src_dst_dir)
LOG.debug("copied %s to %s", file_, src_dst_dir)
@ -474,18 +470,18 @@ def copy_common_src_to_src_out(build_cfg, patch=False):
)
def patch_and_copy_common_src_to_src_out(swc_name, file_path, dest_dir):
"""Copy common source code to delivery folder, patched with SWC prefix.
def patch_and_copy_common_src_to_src_out(prefix, file_path, dest_dir):
"""Copy common source code to delivery folder, patched with "schedulerPrefix" as prefix.
Args:
swc_name (str): Software component name to use as prefix.
prefix (str): Prefix.
file_path (Path): Path to file to patch and copy.
dest_dir (Path): Destination directory for the patched file.
"""
with file_path.open(mode="r", encoding="utf-8") as file_handle:
content = file_handle.read()
new_function = f"{swc_name}_{file_path.stem}"
new_function = f"{prefix}{file_path.stem}"
new_content = content.replace(f"{file_path.stem}(", f"{new_function}(")
new_content_lines = new_content.splitlines()
@ -776,7 +772,12 @@ def build(
time.time() - start_time,
)
code_generation_config = build_cfg.get_code_generation_config()
udt = UserDefinedTypes(build_cfg, unit_cfg)
udt.generate_common_header_files()
generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l)
start_time = time.time()
cnf_header = pjoin(src_dst_dir, build_cfg.get_feature_conf_header_name())
@ -795,10 +796,6 @@ def build(
if interface:
interface_report(build_cfg, unit_cfg, signal_if)
udt.generate_common_header_files()
code_generation_config = build_cfg.get_code_generation_config()
generate_ext_var(
build_cfg,
unit_cfg,
@ -838,12 +835,6 @@ def build(
else:
LOG.warning("Cannot find desired custom sourcefile: %s", custom_src)
# generate NVM definitions
if code_generation_config["useSwcNameAsPrefix"]:
generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l, True)
else:
generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l)
LOG.info("******************************************************")
LOG.info("Start generating the scheduling functions")
start_time = time.time()
@ -883,10 +874,7 @@ def build(
# Copy files to output folder
copy_unit_src_to_src_out(build_cfg)
if code_generation_config["useSwcNameAsPrefix"]:
copy_common_src_to_src_out(build_cfg, True)
else:
copy_common_src_to_src_out(build_cfg)
copy_common_src_to_src_out(build_cfg)
copy_unit_cfgs_to_output(build_cfg)
copy_files_to_include(build_cfg)
if code_generation_config["generateInterfaceHeaders"]:

@ -73,7 +73,6 @@ class BuildProjConfig:
'generateYamlInterfaceFile': False,
'propagateTagName': False,
'useA2lSymbolLinks': False,
'useSwcNameAsPrefix': False,
}
def _get_code_generation_config(self):

@ -150,14 +150,13 @@ class NVMDef(ProblemLogger):
if nvm_attributes["area"] == nvm_area_name:
yield nvm_attributes.get("type"), nvm_signal_name, nvm_attributes.get("width", 1)
def _a2l_dict(self, use_prefix):
def _a2l_dict(self):
"""Return a dict defining all parameters for a2l-generation.
Args:
use_prefix (bool): Patch the nvm header file definitions with the SWC name as prefix.
Optionally, also patch the defined variables with the "schedulerPrefix".
"""
res = {}
prefix = f"{self._project_config.get_composition_config('softwareComponentName')}_" if use_prefix else ""
prefix = self._project_config.get_scheduler_prefix()
for var, var_attrib in self._nvm_signals.items():
res[var] = {
"var": {"var": var, "type": var_attrib["type"], "cvc_type": "CVC_NVM"},
@ -442,14 +441,13 @@ class NVMDef(ProblemLogger):
with open(nvm_structs_updated_path, "w", encoding="utf-8") as nvm_structs_file:
json.dump(self.nvm_definitions, nvm_structs_file, indent=4)
def _generate_nvm_config_headers(self, use_prefix):
def _generate_nvm_config_headers(self):
"""Generate nvm config h file.
Args:
use_prefix (bool): Patch the nvm header file definitions with the SWC name as prefix.
Optionally, also patch the defined variables with the "schedulerPrefix".
"""
self.info("Start generating nvm header file")
prefix = f"{self._project_config.get_composition_config('softwareComponentName')}_" if use_prefix else ""
prefix = self._project_config.get_scheduler_prefix()
def write_signals():
for memory_area in self._nvm_memory_areas:
@ -518,15 +516,14 @@ class NVMDef(ProblemLogger):
write_defines()
hptr.write(self._nvm_header_footer)
def _generate_nvm_config_source(self, use_prefix):
def _generate_nvm_config_source(self):
"""Generate the c-file containing the NVM definition.
Args:
use_prefix (bool): Patch the nvm source file definitions with the SWC name as prefix.
Optionally, also patch the defined variables with the "schedulerPrefix".
"""
# TODO: Add memory from previous builds!!! and mark old positions #
self.info("Start generating nvm source file")
prefix = f"{self._project_config.get_composition_config('softwareComponentName')}_" if use_prefix else ""
prefix = self._project_config.get_scheduler_prefix()
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:
@ -536,32 +533,27 @@ class NVMDef(ProblemLogger):
cptr.write(f"struct {prefix}{area.upper()} {prefix.lower()}{area.lower()};\n")
cptr.write(f'#include "{pragma[1]}"\n\n')
def _generate_nvm_config_a2l(self, use_prefix):
"""Generate the a2l-file describing the NVM definition.
Args:
use_prefix (bool): Patch the nvm header file definitions with the SWC name as prefix.
"""
def _generate_nvm_config_a2l(self):
"""Generate the a2l-file describing the NVM definition."""
self.info("Start generating nvm a2l file")
src_file_dst = self._project_config.get_src_code_dst_dir()
file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"])
a2l_dict = self._a2l_dict(use_prefix)
a2l_dict = self._a2l_dict()
a2l = A2l(a2l_dict, self._project_config)
a2l.gen_a2l(file_name + ".a2l")
def generate_nvm_config_files(self, no_nvm_a2l, use_prefix=False):
def generate_nvm_config_files(self, no_nvm_a2l):
"""Generate all files for variables in the NVM definition.
Args:
no_nvm_a2l (bool): Do not generate a2l file.
use_prefix (bool): Patch the nvm header file definitions with the SWC name as prefix.
"""
self._generate_nvm_structs_updated()
self._generate_nvm_config_headers(use_prefix)
self._generate_nvm_config_source(use_prefix)
self._generate_nvm_config_headers()
self._generate_nvm_config_source()
if not no_nvm_a2l:
self._generate_nvm_config_a2l(use_prefix)
self._generate_nvm_config_a2l()
@staticmethod
def _get_signal_list(signals):

@ -210,8 +210,8 @@ 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_composition_config = MagicMock(return_value='DummySwc')
self.proj_cnfg.get_code_generation_config = MagicMock(return_value=True)
self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='')
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.small_nvm_struct = {
@ -301,7 +301,8 @@ class TestNVMDef(unittest.TestCase):
@patch('builtins.open', new_callable=mock_open())
def test_generate_nvm_config_a2l_patch(self, mock_open_file):
"""Test nvm_def.NVMDef._generate_nvm_config_a2l with use_prefix=True."""
"""Test nvm_def.NVMDef._generate_nvm_config_a2l with prefix."""
self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='DummySwc_')
expected = (
'\n'
' /begin MEASUREMENT\n'
@ -339,12 +340,13 @@ class TestNVMDef(unittest.TestCase):
' /end RECORD_LAYOUT\n'
)
self.nvm_def._nvm_signals = self.small_nvm_struct
self.nvm_def._generate_nvm_config_a2l(True)
self.nvm_def._generate_nvm_config_a2l()
mock_open_file().__enter__().write.assert_called_once_with(expected)
@patch('builtins.open', new_callable=mock_open())
def test_generate_nvm_config_headers_patch(self, mock_open_file):
"""Test nvm_def.NVMDef._generate_nvm_config_headers with use_prefix=True."""
"""Test nvm_def.NVMDef._generate_nvm_config_headers with prefix."""
self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='DummySwc_')
expected = [
call(
'/*\n * vcc_nvm_struct.h - struct for NVM signals\n */\n\n'
@ -394,12 +396,13 @@ class TestNVMDef(unittest.TestCase):
call('\n#endif /* VCC_NVM_STRUCT_H */\n')
]
self.nvm_def._nvm_signals = self.small_nvm_struct
self.nvm_def._generate_nvm_config_headers(True)
self.nvm_def._generate_nvm_config_headers()
mock_open_file().__enter__().write.assert_has_calls(expected)
@patch('builtins.open', new_callable=mock_open())
def test_generate_nvm_config_source_patch(self, mock_open_file):
"""Test nvm_def.NVMDef._generate_nvm_config_source with use_prefix=True."""
"""Test nvm_def.NVMDef._generate_nvm_config_source with prefix."""
self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='DummySwc_')
expected = [
call('#include "vcc_nvm_struct.h"\n\n'),
call('#include "CVC_NVM_START.h"\n'),
@ -422,7 +425,7 @@ class TestNVMDef(unittest.TestCase):
call('#include "CVC_NVM_P_END.h"\n\n')
]
self.nvm_def._nvm_signals = self.small_nvm_struct
self.nvm_def._generate_nvm_config_source(True)
self.nvm_def._generate_nvm_config_source()
mock_open_file().__enter__().write.assert_has_calls(expected)
def test_gen_h_file_fail(self):