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

View File

@ -184,12 +184,6 @@ Default is False.
Use "SYMBOL_LINK" in the generated A2L file. Use "SYMBOL_LINK" in the generated A2L file.
Default is False. 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 ## Rasters json File
### SampleTimes ### 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. 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 ### includesPaths
Use this key to list files that should be included in the source code. Use this key to list files that should be included in the source code.

View File

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

View File

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

View File

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

View File

@ -210,8 +210,8 @@ class TestNVMDef(unittest.TestCase):
self.proj_cnfg.get_root_dir = MagicMock(return_value=projdir) 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_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_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_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.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.small_nvm_struct = { self.small_nvm_struct = {
@ -301,7 +301,8 @@ class TestNVMDef(unittest.TestCase):
@patch('builtins.open', new_callable=mock_open()) @patch('builtins.open', new_callable=mock_open())
def test_generate_nvm_config_a2l_patch(self, mock_open_file): 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 = ( expected = (
'\n' '\n'
' /begin MEASUREMENT\n' ' /begin MEASUREMENT\n'
@ -339,12 +340,13 @@ class TestNVMDef(unittest.TestCase):
' /end RECORD_LAYOUT\n' ' /end RECORD_LAYOUT\n'
) )
self.nvm_def._nvm_signals = self.small_nvm_struct 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) mock_open_file().__enter__().write.assert_called_once_with(expected)
@patch('builtins.open', new_callable=mock_open()) @patch('builtins.open', new_callable=mock_open())
def test_generate_nvm_config_headers_patch(self, mock_open_file): 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 = [ expected = [
call( call(
'/*\n * vcc_nvm_struct.h - struct for NVM signals\n */\n\n' '/*\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') call('\n#endif /* VCC_NVM_STRUCT_H */\n')
] ]
self.nvm_def._nvm_signals = self.small_nvm_struct 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) mock_open_file().__enter__().write.assert_has_calls(expected)
@patch('builtins.open', new_callable=mock_open()) @patch('builtins.open', new_callable=mock_open())
def test_generate_nvm_config_source_patch(self, mock_open_file): 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 = [ expected = [
call('#include "vcc_nvm_struct.h"\n\n'), call('#include "vcc_nvm_struct.h"\n\n'),
call('#include "CVC_NVM_START.h"\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') call('#include "CVC_NVM_P_END.h"\n\n')
] ]
self.nvm_def._nvm_signals = self.small_nvm_struct 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) mock_open_file().__enter__().write.assert_has_calls(expected)
def test_gen_h_file_fail(self): def test_gen_h_file_fail(self):