From e36e378e9b48832c1a5e2673e290410b60a741b9 Mon Sep 17 00:00:00 2001 From: Henrik Wahlqvist Date: Fri, 25 Oct 2024 14:06:15 +0200 Subject: [PATCH] Updates to be able to generate NVM RTE function calls Change-Id: If692ccdf96403b7132735b70bfd8be4a96458ff8 --- powertrain_build/build.py | 22 +- powertrain_build/build_proj_config.py | 15 +- powertrain_build/memory_section.py | 20 +- powertrain_build/nvm_def.py | 146 ++++++++- .../zone_controller/composition_yaml.py | 72 ++--- .../test_nvm_def/nvm_def_setup.py | 172 +++++++++++ .../test_nvm_def/zc_nvm_def.py | 55 ++++ .../composition_yaml_with_nvm.py | 13 +- .../nvm_structs_ref_critical_duplicate.json | 87 ------ .../cnfg_files/nvm_structs_ref_dcl.json | 109 ------- .../reference_files/nvm_structs_ref_dcl.json | 147 --------- tests/powertrain_build/test_build.py | 5 +- tests/powertrain_build/test_nvm_def.py | 285 ++++++------------ .../zone_controller/test_composition_yaml.py | 3 + 14 files changed, 536 insertions(+), 615 deletions(-) create mode 100644 test_data/powertrain_build/test_nvm_def/nvm_def_setup.py create mode 100644 test_data/powertrain_build/test_nvm_def/zc_nvm_def.py delete mode 100644 tests/powertrain_build/cnfg_files/nvm_structs_ref_critical_duplicate.json delete mode 100644 tests/powertrain_build/cnfg_files/nvm_structs_ref_dcl.json delete mode 100644 tests/powertrain_build/reference_files/nvm_structs_ref_dcl.json diff --git a/powertrain_build/build.py b/powertrain_build/build.py index fbb56b7..1d64d79 100644 --- a/powertrain_build/build.py +++ b/powertrain_build/build.py @@ -31,7 +31,7 @@ from powertrain_build.ext_var import ExtVarCsv, ExtVarYaml from powertrain_build.feature_configs import FeatureConfigs from powertrain_build.lib.helper_functions import get_repo_root, merge_dicts from powertrain_build.memory_section import MemorySection -from powertrain_build.nvm_def import NVMDef +from powertrain_build.nvm_def import NVMDef, ZCNVMDef from powertrain_build.problem_logger import ProblemLogger from powertrain_build.replace_compu_tab_ref import replace_tab_verb from powertrain_build.sched_funcs import SchedFuncs @@ -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(nvm_def, no_nvm_a2l): +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 @@ -382,12 +382,15 @@ def generate_nvm_def(nvm_def, no_nvm_a2l): created to minimize the needed model changes for access to the memory. Args: - nvm_def (NVMDef): Class holding the NVM definitions for the build. + 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. """ 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) LOG.info( "Finished generating NVMDefinitions (in %4.2f s)", time.time() - start_time @@ -774,10 +777,6 @@ def build( udt = UserDefinedTypes(build_cfg, unit_cfg) udt.generate_common_header_files() - tot_vars_nvm = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {}) - nvm_def = NVMDef(build_cfg, unit_cfg, tot_vars_nvm) - generate_nvm_def(nvm_def, no_nvm_a2l) - start_time = time.time() cnf_header = pjoin(src_dst_dir, build_cfg.get_feature_conf_header_name()) LOG.info("******************************************************") @@ -901,9 +900,11 @@ def build( if code_generation_config["generateYamlInterfaceFile"]: zc_core = ZCCore(build_cfg, unit_cfg) zc_dids = ZCDIDs(build_cfg, unit_cfg) + project_nvm_defintions = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {}) + zc_nvm = ZCNVMDef(build_cfg, unit_cfg, project_nvm_defintions) axis_data = merged_a2l.get_characteristic_axis_data() composition_yaml = CompositionYaml( - build_cfg, signal_if.composition_spec, unit_cfg, zc_core, zc_dids, nvm_def, axis_data + build_cfg, signal_if.composition_spec, unit_cfg, zc_core, zc_dids, zc_nvm, axis_data ) LOG.info("******************************************************") composition_yaml.generate_yaml() @@ -913,6 +914,9 @@ def build( LOG.info("******************************************************") LOG.info("Generating DID files") zc_dids.generate_did_files() + LOG.info("******************************************************") + LOG.info("Start generating NVMDefinitions") + zc_nvm.generate_nvm_rte_files() if code_generation_config["generateCalibrationInterfaceFiles"]: LOG.info("******************************************************") @@ -922,6 +926,7 @@ def build( ) zc_calibration.generate_calibration_interface_files() elif build_cfg.get_ecu_info()[0] == "HI": + generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l) LOG.info("******************************************************") LOG.info("Generating Core header") hi_core = HICore(build_cfg, unit_cfg) @@ -931,6 +936,7 @@ def build( dids = HIDIDs(build_cfg, unit_cfg) dids.generate_did_files() else: + generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l) generate_did_files(build_cfg, unit_cfg) # generate core dummy files if requested if core_dummy: diff --git a/powertrain_build/build_proj_config.py b/powertrain_build/build_proj_config.py index 6112103..4892bd3 100644 --- a/powertrain_build/build_proj_config.py +++ b/powertrain_build/build_proj_config.py @@ -250,7 +250,7 @@ class BuildProjConfig: def _parse_composition_config(self, file_config): """Parse the composition configuration from project config.""" a2lname = f"{self.get_a2l_cfg()['name']}_SC" - self._composition_config = { + composition_config = { 'compositionName': None, 'compositionEnding': 'yml', 'compositionArxml': file_config.get("compositionArxml", None), @@ -264,13 +264,14 @@ class BuildProjConfig: 'includeShared': file_config.get('includeShared', True), 'includeDiagnostics': file_config.get('includeDiagnostics', True), 'includeNvm': file_config.get('includeNvm', True), + 'nvmPortPattern': file_config.get('nvmPortPattern', None), } - 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 + composition_name = file_config.get("compositionName", None) + if composition_name is not None: + composition_config["compositionName"] = composition_name.split(".")[0] + if "." in composition_name: + composition_config["compositionEnding"] = composition_name.split(".")[1] + return composition_config def get_composition_config(self, key=None): """Get the composition configuration from project config.""" diff --git a/powertrain_build/memory_section.py b/powertrain_build/memory_section.py index ec5af21..8c56c4b 100644 --- a/powertrain_build/memory_section.py +++ b/powertrain_build/memory_section.py @@ -104,6 +104,15 @@ class MemorySection(ProblemLogger): ] return cvc_undefines, cvc_defines, memory_section_handling + def _get_nvm(self, section): + cvc_undefines = [] + cvc_defines = [] + memory_section_handling = [ + self.mem_map_config['projectDefines'][self._get_mem_map_section(section)]['nvm'] + '\n', + self.mem_map_include + ] + return cvc_undefines, cvc_defines, memory_section_handling + def _get_rest(self): cvc_undefines = [] cvc_defines = [] @@ -174,11 +183,16 @@ class MemorySection(ProblemLogger): with Path(src_dst_dir, section_file).open('w', encoding="utf-8") as header_file_handler: header_file_handler.writelines(lines_to_write) - for nvm_dict in build_defs.NVM_LEVEL_MAP.values(): + for nvm_type, nvm_dict in build_defs.NVM_LEVEL_MAP.items(): for section_dict in nvm_dict.values(): - for section_file in section_dict.values(): + for section, section_file in section_dict.items(): + section_config = self.mem_map_config['projectDefines'][self._get_mem_map_section(section)] + if nvm_type == "NORMAL" and "nvm" in section_config: + lines_to_write = self._get_nvm(section)[2] + else: + lines_to_write = [] header = self._get_header(section_file) if self.include_header_guards else [] footer = self._get_footer(section_file) if self.include_header_guards else [] with Path(src_dst_dir, section_file).open('w', encoding="utf-8") as header_file_handler: - header_file_handler.writelines(header + footer) + header_file_handler.writelines(header + lines_to_write + footer) self.info('Finished generating required header files (in %4.2f s)', time.time() - start_time) diff --git a/powertrain_build/nvm_def.py b/powertrain_build/nvm_def.py index 4e7f691..919e026 100644 --- a/powertrain_build/nvm_def.py +++ b/powertrain_build/nvm_def.py @@ -6,6 +6,7 @@ import re import os import json +from copy import deepcopy import powertrain_build.build_defs as bd from powertrain_build.types import byte_size, get_bitmask @@ -57,6 +58,10 @@ class NVMDef(ProblemLogger): self._area_section = {} self._mem_area_pragmas = tuple() self._nvm_header_head = self._get_nvm_header_head(unit_cfg) + src_file_dst = self._project_config.get_src_code_dst_dir() + self._file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"]) + self._predecl_start = bd.PREDECL_START + self._predecl_end = bd.PREDECL_END with open( os.path.join(project_config.get_root_dir(), self._nvm_defs["baseNvmStructs"]), "r", encoding="utf-8" @@ -430,8 +435,6 @@ class NVMDef(ProblemLogger): def _generate_nvm_structs_updated(self): self.info("Start generating updated nvm json file") - self._update_nvm_base_struct() - nvm_structs_updated_path = os.path.abspath( os.path.join(self._project_config.get_root_dir(), "output", "nvm_structs_updated.json") ) @@ -495,21 +498,19 @@ class NVMDef(ProblemLogger): hptr.write(f'#include "{section}_END.h"\n\n') def write_extern(): - hptr.write(f'#include "{bd.PREDECL_START}"\n') + hptr.write(f'#include "{self._predecl_start}"\n') for area in self._nvm_memory_areas: hptr.write(f"extern struct {prefix}{area.upper()} {prefix.lower()}{area.lower()};\n") - hptr.write(f'#include "{bd.PREDECL_END}"\n\n') + hptr.write(f'#include "{self._predecl_end}"\n\n') def write_defines(): hptr.write("\n") for var, define in defines: hptr.write(f"#define {var:40} {define}\n") - src_file_dst = self._project_config.get_src_code_dst_dir() - file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"]) defines = [] - with open(file_name + ".h", "w", encoding="utf-8") as hptr: + with open(self._file_name + ".h", "w", encoding="utf-8") as hptr: hptr.write(self._nvm_header_head) write_signals() write_extern() @@ -524,9 +525,7 @@ class NVMDef(ProblemLogger): # TODO: Add memory from previous builds!!! and mark old positions # self.info("Start generating nvm source file") 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: + with open(self._file_name + ".c", "w", encoding="utf-8") as cptr: cptr.write(f'#include "{self._nvm_defs["fileName"]}.h"\n\n') for area, pragma in zip(self._nvm_memory_areas, self._mem_area_pragmas): cptr.write(f'#include "{pragma[0]}"\n') @@ -536,12 +535,9 @@ class NVMDef(ProblemLogger): 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() a2l = A2l(a2l_dict, self._project_config) - a2l.gen_a2l(file_name + ".a2l") + a2l.gen_a2l(self._file_name + ".a2l") def generate_nvm_config_files(self, no_nvm_a2l): """Generate all files for variables in the NVM definition. @@ -549,6 +545,7 @@ class NVMDef(ProblemLogger): Args: no_nvm_a2l (bool): Do not generate a2l file. """ + self._update_nvm_base_struct() self._generate_nvm_structs_updated() self._generate_nvm_config_headers() self._generate_nvm_config_source() @@ -558,3 +555,124 @@ class NVMDef(ProblemLogger): @staticmethod def _get_signal_list(signals): return signals if isinstance(signals, list) else [signals] + + +class ZCNVMDef(NVMDef): + """A class for handling of ZC NVM definitions.""" + + def __init__(self, project_config, unit_cfg, nvm_vars): + """Init. + + Args: + project_config (BuildProjConfig): current project configuration. + unit_cfg (UnitConfigs): Unit configurations. + nvm_vars (dict): NVM variables from unit configurations. + """ + super().__init__(project_config, unit_cfg, nvm_vars) + self._valid_nvm_definitions = None + self._update_nvm_base_struct() + prefix = self._project_config.get_scheduler_prefix() + self.project_nvm_definitions = { + f"{prefix}{item['name']}": item for item in self.nvm_definitions + } + self._predecl_start = bd.PREDECL_NVM_START + self._predecl_end = bd.PREDECL_NVM_END + self.init_function = "void VcNvmInit(void)" + self.main_function = "void VcNvm(void)" + + @property + def valid_nvm_definitions(self): + """Get the valid NVM definitions.""" + return self._valid_nvm_definitions + + @valid_nvm_definitions.setter + def valid_nvm_definitions(self, yaml_nvm_definitions): + """Return a set of NVM definitions appearing in both the project and the project yaml file. + + Args: + yaml_nvm_definitions (dict): NVM lists listed in the NVM configuration yaml file. + Returns: + valid_nvm_definitions (dict): Validated NVM definitions, + listed in both NVM configuration yaml file as well as project. + """ + local_yaml_nvm_definitions = deepcopy(yaml_nvm_definitions) + nvms_not_in_project = set(local_yaml_nvm_definitions.keys()) - set(self.project_nvm_definitions.keys()) + nvms_not_in_yaml = set(self.project_nvm_definitions.keys()) - set(local_yaml_nvm_definitions.keys()) + for key in nvms_not_in_project: + self.warning(f'Ignoring NVM definition {key} since it does not appear in nvm_structs.json.') + del local_yaml_nvm_definitions[key] + for key in nvms_not_in_yaml: + self.warning(f'Ignoring NVM definition {key} since it does not appear in the project NVM yaml file.') + self._valid_nvm_definitions = local_yaml_nvm_definitions + + def _update_header_and_footer(self): + name = self._project_config.get_composition_config("softwareComponentName") + self._nvm_header_head += f'#include "Rte_{name}.h"\n' + self._nvm_header_footer = ( + "\n" + f'#include "{bd.PREDECL_CODE_ASIL_D_START}"\n' + f"{self.init_function};\n" + f"{self.main_function};\n" + f'#include "{bd.PREDECL_CODE_ASIL_D_END}"\n' + f"{self._nvm_header_footer}" + ) + + def _append_nvm_rte_function_calls(self): + """Append the NVM RTE function calls to the NVM config source file.""" + nvm_port_pattern = self._project_config.get_composition_config("nvmPortPattern") + if self.valid_nvm_definitions and nvm_port_pattern is None: + self.critical("NVM port pattern not defined in ProjectCfg.json. Cannot add NVM RTE function calls.") + return + + init_function_lines = [ + f'#include "{bd.CVC_CODE_ASIL_D_START}"\n' + f"{self.init_function} {{\n", + " //Call this function in the SWC init runnable\n" + ] + main_function_lines = [ + f'#include "{bd.CVC_CODE_ASIL_D_START}"\n' + f"{self.main_function} {{\n", + " //Call this function in the SWC main runnable\n", + " UInt8 errorStatus = 0;\n", + ] + footer = [ + "}\n", + f'#include "{bd.CVC_CODE_ASIL_D_END}"\n', + ] + + for nvm_name, nvm_data in self.valid_nvm_definitions.items(): + pim_call = f"Rte_Pim_{nvm_name}()" + function_prefix = f"Rte_Call_{nvm_port_pattern.format(NvName=nvm_name)}" + main_function_lines.append(f" *{pim_call} = {nvm_name.lower()};\n") + if nvm_data["type"] == "type1": + init_function_lines.append(f" {function_prefix}_SetRamBlockStatus(TRUE);\n") + elif nvm_data["type"] == "type2": + main_function_lines.extend([ + f" {function_prefix}_GetErrorStatus(&errorStatus);\n", + " if (errorStatus == 0) {\n", + f" {function_prefix}_WriteBlock({pim_call});\n", + " }\n", + ]) + else: + self.critical(f"Unknown NVM type: {nvm_data['type']} for NVM: {nvm_name}") + + with open(self._file_name + ".c", mode="a", encoding="utf-8") as cptr: + cptr.writelines(init_function_lines + footer + ["\n"] + main_function_lines + footer) + + def generate_nvm_rte_files(self): + """Generate the NVM RTE files.""" + if self.valid_nvm_definitions is None: + self.critical('Valid NVM definitions not set. Cannot generate NVM RTE files.') + return + + self._update_header_and_footer() + old_nvm_memory_areas = self._nvm_memory_areas + prefix = self._project_config.get_scheduler_prefix() + self._nvm_memory_areas = tuple(area.replace(f"{prefix}", "") for area in self.valid_nvm_definitions.keys()) + + self._generate_nvm_structs_updated() + self._generate_nvm_config_headers() + self._generate_nvm_config_source() + self._append_nvm_rte_function_calls() + + self._nvm_memory_areas = old_nvm_memory_areas diff --git a/powertrain_build/zone_controller/composition_yaml.py b/powertrain_build/zone_controller/composition_yaml.py index e0255bd..1ecaac3 100644 --- a/powertrain_build/zone_controller/composition_yaml.py +++ b/powertrain_build/zone_controller/composition_yaml.py @@ -15,7 +15,7 @@ from powertrain_build.zone_controller.calibration import ZoneControllerCalibrati class CompositionYaml(ProblemLogger): """Class for handling ZoneController composition yaml generation.""" - def __init__(self, build_cfg, composition_spec, unit_cfg, zc_core, zc_dids, nvm_def, a2l_axis_data): + def __init__(self, build_cfg, composition_spec, unit_cfg, zc_core, zc_dids, zc_nvm, a2l_axis_data): """Init. Args: @@ -24,7 +24,7 @@ class CompositionYaml(ProblemLogger): unit_cfg (UnitConfig): Object with unit configurations. zc_core (ZCCore): Object with zone controller diagnositic event information. zc_dids (ZCDIDs): Object with zone controller diagnostic DID information. - nvm_def (NVMDef): Object with NVM definition information. + zc_nvm (ZCNVMDef): Object with NVM definition information. a2l_axis_data (dict): Dict with characteristic axis data from A2L file. """ self.tl_to_autosar_base_types = { @@ -43,7 +43,7 @@ class CompositionYaml(ProblemLogger): self.unit_cfg = unit_cfg self.zc_core = zc_core self.zc_dids = zc_dids - self.nvm_def = nvm_def + self.zc_nvm = zc_nvm self.a2l_axis_data = a2l_axis_data base_data_types = self.get_base_data_types() # Might not be necessary in the long run self.data_types = { @@ -303,6 +303,7 @@ class CompositionYaml(ProblemLogger): def _get_diagnostic_info(self): """Get diagnostic information from composition spec. + NOTE: This function sets the valid_dids property of the ZCDIDs object. Returns: @@ -326,43 +327,34 @@ class CompositionYaml(ProblemLogger): def _get_nvm_info(self): """Creates a dict with NVM information. + NVM dicts also needs to be added to the "static" field in the generated yaml. + + NOTE: This function sets the valid_nvm_definitions property of the ZCNVMDef object. + Returns: nvm_dict (dict): Dict containing NVM information. + data_types (dict): Dict containing data types for NVM information. + static_variables (dict): Dict containing "static" variables to add to the "static" field. """ - prefix = self.build_cfg.get_scheduler_prefix() - yaml_nvm_definitions = self.composition_spec.get("nv-needs", {}) - project_nvm_definitions = { - f"{prefix}{item['name']}": item for item in self.nvm_def.nvm_definitions - } - nvms_not_in_project = set(yaml_nvm_definitions.keys()) - set(project_nvm_definitions.keys()) - nvms_not_in_yaml = set(project_nvm_definitions.keys()) - set(yaml_nvm_definitions.keys()) - for key in nvms_not_in_project: - self.warning(f'Ignoring NVM definition {key} since it does not appear in nvm_structs.json.') - del yaml_nvm_definitions[key] - for key in nvms_not_in_yaml: - self.warning(f'Ignoring NVM definition {key} since it does not appear in the project NVM yaml file.') - data_types = {} - for nvm_name, nvm_data in yaml_nvm_definitions.items(): - data_type_name = f"dt_{nvm_name}" - nr_of_unused_signals = project_nvm_definitions[nvm_name]["size"] + static_variables = {} + yaml_nvm_definitions = self.composition_spec.get("nv-needs", {}) + self.zc_nvm.valid_nvm_definitions = yaml_nvm_definitions + nvm_dict = self.zc_nvm.valid_nvm_definitions - nvm_data.update({ - "datatype": data_type_name, - "init": [] - }) - data_types[data_type_name] = { - "type": "RECORD", - "elements": {}, - } - for signal in project_nvm_definitions[nvm_name]["signals"]: + for nvm_name, nvm_data in nvm_dict.items(): + init = [] + nr_of_unused_signals = self.zc_nvm.project_nvm_definitions[nvm_name]["size"] + data_type_name = f"dt_{nvm_name}" + data_types[data_type_name] = {"type": "RECORD", "elements": {}} + for signal in self.zc_nvm.project_nvm_definitions[nvm_name]["signals"]: nr_of_unused_signals -= signal["x_size"] * signal["y_size"] size = max(signal["x_size"], 1) * max(signal["y_size"], 1) if size > 1: x_data_type_name = f"dt_{signal['name']}_x" y_data_type_name = f"dt_{signal['name']}_y" if signal["x_size"] > 1 and signal["y_size"] == 1: - nvm_data["init"].append([0] * signal["x_size"]) + init.append([0] * signal["x_size"]) data_types[data_type_name]["elements"][signal["name"]] = x_data_type_name data_types[x_data_type_name] = { "type": "ARRAY", @@ -370,7 +362,7 @@ class CompositionYaml(ProblemLogger): "element": signal["type"], } elif signal["x_size"] > 1 and signal["y_size"] > 1: - nvm_data["init"].append([[0] * signal["y_size"]] * signal["x_size"]) + init.append([[0] * signal["y_size"]] * signal["x_size"]) data_types[data_type_name]["elements"][signal["name"]] = y_data_type_name data_types[y_data_type_name] = { "type": "ARRAY", @@ -385,19 +377,29 @@ class CompositionYaml(ProblemLogger): else: self.critical("NVM signal size incorrect. x_size should not be 1 if y_size > 1.") else: - nvm_data["init"].append(0) + init.append(0) data_types[data_type_name]["elements"][signal["name"]] = signal["type"] + nvm_data.update({ + "datatype": data_type_name, + "init": init + }) + static_variables[nvm_name.lower()] = { + "type": data_type_name, + "access": "READ-ONLY", + "init": init, + } + if nr_of_unused_signals > 0: nvm_data["init"].append([0] * nr_of_unused_signals) data_types[data_type_name]["elements"]["unused"] = f"{data_type_name}_Unused" data_types[f"{data_type_name}_Unused"] = { "type": "ARRAY", "size": nr_of_unused_signals, - "element": project_nvm_definitions[nvm_name]["default_datatype"], + "element": self.zc_nvm.project_nvm_definitions[nvm_name]["default_datatype"], } - return yaml_nvm_definitions, data_types + return nvm_dict, data_types, static_variables def _get_ports_info(self): """Creates a dict containing port information. @@ -507,10 +509,12 @@ class CompositionYaml(ProblemLogger): diagnostic_info = self._get_diagnostic_info() if self.build_cfg.get_composition_config("includeDiagnostics"): swcs[software_component_name]["diagnostics"] = diagnostic_info - nvm_info, nvm_data_types_tmp = self._get_nvm_info() + nvm_info, nvm_data_types_tmp, static_variables = self._get_nvm_info() if self.build_cfg.get_composition_config("includeNvm"): swcs[software_component_name]["nv-needs"] = nvm_info nvm_data_types = nvm_data_types_tmp + if self.build_cfg.get_composition_config("includeStatic"): + swcs[software_component_name]["static"].update(static_variables) else: nvm_data_types = {} diff --git a/test_data/powertrain_build/test_nvm_def/nvm_def_setup.py b/test_data/powertrain_build/test_nvm_def/nvm_def_setup.py new file mode 100644 index 0000000..c6a6d8f --- /dev/null +++ b/test_data/powertrain_build/test_nvm_def/nvm_def_setup.py @@ -0,0 +1,172 @@ +# Copyright 2024 Volvo Car Corporation +# Licensed under Apache 2.0. + +"""Unit test data for powertrain_build.nvm_def.""" + +nvm_vars_test = { + 'sVcAcCtrl_t_CmprRunTiNVM': { + 'VcAcCtrl': { + 'class': 'CVC_DISP_NVM', + 'configs': ['all'], + 'description': 'Enter a nice description of your variable here', + 'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/' + '3_SystemInfo/36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAcCtrl_t_CmprRunTiNVM', + 'offset': 0, + 'type': 'UInt32', + 'unit': '-', + 'width': 1}}, + 'sVcAesHw_X_VntAdpnOffs': { + 'VcAesVnt': { + 'class': 'CVC_DISP_NVM', + 'configs': ['Vc_Aes_Vnt_B_CodeGenVntGvnr ' + '== 0'], + 'description': 'Enter a nice ' + 'description of your ' + 'variable here', + 'handle': 'VcAesVnt/VcAesVnt/Subsystem/VcAesVnt/VcAesVnt/1_Vnt/11_VntGvnr/' + '111_VntGvnrExe/1111_VntGvnrFct/11112_VntAdpn/sVcAesHw_X_VntAdpnOffs/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAesHw_X_VntAdpnOffs', + 'offset': 0, + 'type': 'Float32', + 'unit': '-', + 'width': 1 + } + }, + 'sVcAesMo_Ar_ArrayTest': { + 'VcAesMoAdp': { + 'class': 'CVC_DISP_NVM', + 'configs': ['all'], + 'description': 'Enter a nice ' + 'description of your ' + 'variable here', + 'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/' + '2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAesMo_Ar_NvmThrAdpn', + 'offset': 0, + 'type': 'Float32', + 'unit': '-', + 'width': [4, 2] + } + }, + 'sVcAesMo_Ar_NvmThrAdpn': { + 'VcAesMoAdp': { + 'class': 'CVC_DISP_NVM', + 'configs': ['all'], + 'description': 'Enter a nice ' + 'description of your ' + 'variable here', + 'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/' + '2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAesMo_Ar_NvmThrAdpn', + 'offset': 0, + 'type': 'Float32', + 'unit': '-', + 'width': 1 + } + }, + 'sVcAesMo_rt_NvmMafLrngLd1Ne1': { + 'VcAesMfl': { + 'class': 'CVC_DISP_NVM', + 'configs': ['all'], + 'description': 'Enter a nice ' + 'description of ' + 'your variable ' + 'here', + 'handle': 'VcAesMfl/VcAesMfl/Subsystem/VcAesMfl/VcAesMfl/4_Nvm/41_Ld1Ne1/' + 'sVcAesMo_rt_NvmMafLrngLd1Ne1/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAesMo_rt_NvmMafLrngLd1Ne1', + 'offset': 0, + 'type': 'Bool', + 'unit': '-', + 'width': 1 + } + }, + 'sVcAcCtrl_t_Test1': { + 'VcAcCtrl': { + 'class': 'CVC_DISP_NVM_P', + 'configs': ['all'], + 'description': 'Enter a nice description of your variable here', + 'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/' + '36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAcCtrl_t_Test1', + 'offset': 0, + 'type': 'UInt32', + 'unit': '-', + 'width': 1 + }, + 'VcAcCtrl2': { + 'class': 'CVC_DISP_NVM_P', + 'configs': ['all'], + 'description': 'Enter a nice description of your variable here', + 'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/' + '36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay', + 'lsb': 1, + 'max': 'nan', + 'min': 'nan', + 'name': 'sVcAcCtrl_t_Test1', + 'offset': 0, + 'type': 'UInt32', + 'unit': '-', + 'width': 1 + } + } +} + +nvm_configs_single = { + "fileName": "vcc_nvm_struct_single", + "baseNvmStructs": "nvm_structs_ref_single_signal.json" +} + +nvm_configs = { + "fileName": "vcc_nvm_struct", + "baseNvmStructs": "nvm_structs_ref_empty.json" +} + +nvm_configs_small = { + "fileName": "vcc_nvm_structs__small", + "baseNvmStructs": "nvm_structs_ref_small.json" +} + +nvm_configs_empty_small = { + "fileName": "vcc_nvm_structs_empty_small", + "baseNvmStructs": "nvm_structs_ref_empty_small.json" +} + +nvm_configs_signal_overwritten = { + "fileName": "vcc_nvm_structs_ref_used_positions", + "baseNvmStructs": "nvm_structs_ref_used_positions.json" +} + +nvm_configs_critical = { + "fileName": "vcc_nvm_structs_critical", + "baseNvmStructs": "nvm_structs_ref_critical.json" +} + +nvm_configs_critical_remove = { + "fileName": "vcc_nvm_struct_critical_remove", + "baseNvmStructs": "nvm_structs_ref_critical.json" +} + +nvm_configs_wrong_type = { + "fileName": "vcc_nvm_structs_ref_used_positions", + "baseNvmStructs": "nvm_structs_ref_wrong_type.json" +} diff --git a/test_data/powertrain_build/test_nvm_def/zc_nvm_def.py b/test_data/powertrain_build/test_nvm_def/zc_nvm_def.py new file mode 100644 index 0000000..997eae7 --- /dev/null +++ b/test_data/powertrain_build/test_nvm_def/zc_nvm_def.py @@ -0,0 +1,55 @@ +# Copyright 2024 Volvo Car Corporation +# Licensed under Apache 2.0. + +"""Unit test data for powertrain_build.nvm_def.ZCNVMDef.""" + +yaml_nvm_definitions = { + "NVM_LIST_8": { + "type": "type1", + "method": "DIRECT-CALL", + "runnables": ["Dummy"], + "attributes": { + "resistant-to-change": True, + "random-attribute": "Dummy", + }, + }, + "NVM_LIST_16": { + "type": "type2", + "method": "DIRECT-CALL", + "runnables": ["Dummy"], + "attributes": { + "resistant-to-change": True, + "random-attribute": "Dummy", + }, + }, +} + +yaml_nvm_definitions_one_not_in_project = { + "NVM_LIST_8": { + "type": "type1", + "method": "DIRECT-CALL", + "runnables": ["Dummy"], + "attributes": { + "resistant-to-change": True, + "random-attribute": "Dummy", + }, + }, + "NVM_LIST_16": { + "type": "type2", + "method": "DIRECT-CALL", + "runnables": ["Dummy"], + "attributes": { + "resistant-to-change": True, + "random-attribute": "Dummy", + }, + }, + "NVM_LIST_NOT_IN_PROJECT": { + "type": "type1", + "method": "DIRECT-CALL", + "runnables": ["Dummy"], + "attributes": { + "resistant-to-change": True, + "random-attribute": "Dummy", + }, + }, +} diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_nvm.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_nvm.py index 97c583b..5ebaf9e 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_nvm.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_nvm.py @@ -101,6 +101,14 @@ additional_data_types = { }, } +additional_static = { + "prefix_nvm_list_8": { + "type": "dt_prefix_NVM_LIST_8", + "access": "READ-ONLY", + "init": [0, [0, 0], [[0, 0], [0, 0]], [0]], + }, +} + expected_result = { "SoftwareComponents": { "testName_SC": { @@ -132,7 +140,10 @@ expected_result = { }, }, }, - "static": composition_yaml_setup.base_static, + "static": { + **composition_yaml_setup.base_static, + **additional_static, + }, "shared": composition_yaml_setup.base_shared, "ports": { "GlobSignNme": {"direction": "IN", "interface": "PIGlobSignNme"} diff --git a/tests/powertrain_build/cnfg_files/nvm_structs_ref_critical_duplicate.json b/tests/powertrain_build/cnfg_files/nvm_structs_ref_critical_duplicate.json deleted file mode 100644 index 4654f43..0000000 --- a/tests/powertrain_build/cnfg_files/nvm_structs_ref_critical_duplicate.json +++ /dev/null @@ -1,87 +0,0 @@ -[ - { - "signals": [ - { - "x_size": 1, - "type": "UInt32", - "name": "sVcTest_t_UInt32", - "y_size": 1 - } - ], - "name": "NVM_LIST_32", - "default_datatype": "UInt32", - "instanceName": "nvm_list_32", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": false, - "allowed_datatypes": [ - "Float32", - "UInt32", - "Int32" - ] - }, - { - "signals": [ - { - "x_size": 1, - "type": "UInt32", - "name": "sVcTest_t_UInt32", - "y_size": 1 - }, - { - "x_size": 1, - "type": "Int16", - "name": "sVcTest_t_Int16", - "y_size": 1 - }, - { - "x_size": 1, - "type": "UInt8", - "name": "sVcTest_t_UInt8", - "y_size": 1 - } - ], - "name": "NVM_LIST_CRITICAL1", - "default_datatype": "UInt16", - "instanceName": "nvm_list_critical1", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": false, - "allowed_datatypes": ["NotApplicable"] - }, - { - "signals": [ - { - "x_size": 1, - "type": "Int16", - "name": "sVcTest_t_Int16", - "y_size": 1 - } - ], - "name": "NVM_LIST_16", - "default_datatype": "UInt16", - "instanceName": "nvm_list_16", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": false, - "allowed_datatypes": [ - "UInt16", - "Int16" - ] - }, - { - "signals": [ - ], - "name": "NVM_LIST_8", - "default_datatype": "UInt8", - "instanceName": "nvm_list_8", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": false, - "allowed_datatypes": ["should_be_empty"] - } -] diff --git a/tests/powertrain_build/cnfg_files/nvm_structs_ref_dcl.json b/tests/powertrain_build/cnfg_files/nvm_structs_ref_dcl.json deleted file mode 100644 index 658d84f..0000000 --- a/tests/powertrain_build/cnfg_files/nvm_structs_ref_dcl.json +++ /dev/null @@ -1,109 +0,0 @@ -[ - { - "signals": [ - { - "x_size": 1, - "type": "UInt8", - "name": "sVcDclOil_D_BadDcysMEM", - "y_size": 1 - }, - { - "x_size": 1, - "type": "UInt8", - "name": "sVcDclEem_D_MvBattChrReqCarModTrp", - "y_size": 1 - }, - { - "x_size": 5, - "type": "UInt8", - "name": "VcDclEem_D_LvBattChrReqDenial", - "y_size": 1 - } - ], - "name": "NVM_LIST_8", - "default_datatype": "UInt8", - "instanceName": "nvm_list_8", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": false, - "allowed_datatypes": [ - "Bool", - "UInt8", - "Int8" - ] - }, - { - "signals": [], - "name": "NVM_LIST_16", - "default_datatype": "UInt16", - "instanceName": "nvm_list_16", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 240, - "persistent": false, - "allowed_datatypes": [ - "UInt16", - "Int16" - ] - }, - { - "signals": [], - "name": "NVM_LIST_32", - "default_datatype": "UInt32", - "instanceName": "nvm_list_32", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 975, - "persistent": false, - "allowed_datatypes": [ - "Float32", - "UInt32", - "Int32" - ] - }, - { - "signals": [], - "name": "NVM_LIST_8_PER", - "default_datatype": "UInt8", - "instanceName": "nvm_list_8_per", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": true, - "allowed_datatypes": [ - "Bool", - "UInt8", - "Int8" - ] - }, - { - "signals": [], - "name": "NVM_LIST_16_PER", - "default_datatype": "UInt16", - "instanceName": "nvm_list_16_per", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 240, - "persistent": true, - "allowed_datatypes": [ - "UInt16", - "Int16" - ] - }, - { - "signals": [], - "name": "NVM_LIST_32_PER", - "default_datatype": "UInt32", - "instanceName": "nvm_list_32_per", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 190, - "persistent": true, - "allowed_datatypes": [ - "Float32", - "UInt32", - "Int32" - ] - } -] diff --git a/tests/powertrain_build/reference_files/nvm_structs_ref_dcl.json b/tests/powertrain_build/reference_files/nvm_structs_ref_dcl.json deleted file mode 100644 index dc51ea9..0000000 --- a/tests/powertrain_build/reference_files/nvm_structs_ref_dcl.json +++ /dev/null @@ -1,147 +0,0 @@ -[ - { - "signals": [ - { - "x_size": 1, - "type": "UInt8", - "name": "sVcDclOil_D_BadDcysMEM", - "y_size": 1 - }, - { - "x_size": 1, - "type": "UInt8", - "name": "sVcDclEem_D_MvBattChrReqCarModTrp", - "y_size": 1 - }, - { - "x_size": 5, - "type": "UInt8", - "name": "VcDclEem_D_LvBattChrReqDenial", - "y_size": 1 - }, - { - "x_size": 1, - "type": "Bool", - "name": "sVcAesMo_rt_NvmMafLrngLd1Ne1", - "y_size": 1 - } - ], - "name": "NVM_LIST_8", - "default_datatype": "UInt8", - "instanceName": "nvm_list_8", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": false, - "allowed_datatypes": [ - "Bool", - "UInt8", - "Int8" - ] - }, - { - "signals": [], - "name": "NVM_LIST_16", - "default_datatype": "UInt16", - "instanceName": "nvm_list_16", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 240, - "persistent": false, - "allowed_datatypes": [ - "UInt16", - "Int16" - ] - }, - { - "signals": [ - { - "name": "sVcAcCtrl_t_CmprRunTiNVM", - "type": "UInt32", - "x_size": 1, - "y_size": 1 - }, - { - "name": "sVcAesHw_X_VntAdpnOffs", - "type": "Float32", - "x_size": 1, - "y_size": 1 - }, - { - "name": "sVcAesMo_Ar_ArrayTest", - "type": "Float32", - "x_size": 4, - "y_size": 2 - }, - { - "name": "sVcAesMo_Ar_NvmThrAdpn", - "type": "Float32", - "x_size": 1, - "y_size": 1 - } - ], - "name": "NVM_LIST_32", - "default_datatype": "UInt32", - "instanceName": "nvm_list_32", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 975, - "persistent": false, - "allowed_datatypes": [ - "Float32", - "UInt32", - "Int32" - ] - }, - { - "signals": [], - "name": "NVM_LIST_8_PER", - "default_datatype": "UInt8", - "instanceName": "nvm_list_8_per", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 56, - "persistent": true, - "allowed_datatypes": [ - "Bool", - "UInt8", - "Int8" - ] - }, - { - "signals": [], - "name": "NVM_LIST_16_PER", - "default_datatype": "UInt16", - "instanceName": "nvm_list_16_per", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 240, - "persistent": true, - "allowed_datatypes": [ - "UInt16", - "Int16" - ] - }, - { - "signals": [ - { - "name": "sVcAcCtrl_t_Test1", - "type": "UInt32", - "x_size": 1, - "y_size": 1 - } - ], - "name": "NVM_LIST_32_PER", - "default_datatype": "UInt32", - "instanceName": "nvm_list_32_per", - "includeStart": "MemMap_SDA_START.h", - "includeStop": "MemMap_SDA_STOP.h", - "size": 190, - "persistent": true, - "allowed_datatypes": [ - "Float32", - "UInt32", - "Int32" - ] - } -] \ No newline at end of file diff --git a/tests/powertrain_build/test_build.py b/tests/powertrain_build/test_build.py index 7fece0a..4fbe374 100644 --- a/tests/powertrain_build/test_build.py +++ b/tests/powertrain_build/test_build.py @@ -11,7 +11,6 @@ from pathlib import Path from powertrain_build import build_defs from powertrain_build.lib import helper_functions -from powertrain_build.nvm_def import NVMDef from powertrain_build.problem_logger import ProblemLogger from powertrain_build.build_proj_config import BuildProjConfig from powertrain_build.unit_configs import UnitConfigs @@ -223,8 +222,6 @@ class TestBuild(unittest.TestCase): """Check that NVM files are generated.""" unit_cfg = MagicMock(spec_set=UnitConfigs) type(unit_cfg).base_types_headers = '' - tot_vars_nvm = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {}) - nvm_def = NVMDef(self.build_cfg, unit_cfg, tot_vars_nvm) no_nvm_a2l = False filepath = str(Path(SRC_DIR, 'output')) files = [ @@ -232,7 +229,7 @@ class TestBuild(unittest.TestCase): filepath + '/vcc_nvm_struct.h', filepath + '/vcc_nvm_struct.a2l'] remove(*files) - build.generate_nvm_def(nvm_def, no_nvm_a2l) + build.generate_nvm_def(self.build_cfg, unit_cfg, no_nvm_a2l) self.build_cfg.get_src_code_dst_dir.assert_called() unit_cfg.get_per_cfg_unit_cfg.assert_called() exists(*files) diff --git a/tests/powertrain_build/test_nvm_def.py b/tests/powertrain_build/test_nvm_def.py index b341086..03a5b07 100644 --- a/tests/powertrain_build/test_nvm_def.py +++ b/tests/powertrain_build/test_nvm_def.py @@ -13,8 +13,9 @@ from unittest.mock import MagicMock, mock_open, patch, call from pathlib import Path from powertrain_build.lib import helper_functions -from powertrain_build.nvm_def import NVMDef +from powertrain_build.nvm_def import NVMDef, ZCNVMDef from powertrain_build.unit_configs import UnitConfigs +from test_data.powertrain_build.test_nvm_def import nvm_def_setup, zc_nvm_def SRC_DIR = Path(__file__).parent @@ -24,182 +25,6 @@ class TestNVMDef(unittest.TestCase): Test case for testing the TestNVMDef class """ - @classmethod - def setUpClass(cls): - """Set-up common data structures for all tests in the test case - """ - cls.create_new = False - cls.unit_cfg = MagicMock(spec_set=UnitConfigs) - type(cls.unit_cfg).base_types_headers = '#include "tl_basetypes.h"\n' - cls.nvm_vars_test = { - 'sVcAcCtrl_t_CmprRunTiNVM': { - 'VcAcCtrl': { - 'class': 'CVC_DISP_NVM', - 'configs': ['all'], - 'description': 'Enter a nice description of your variable here', - 'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/' - '3_SystemInfo/36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAcCtrl_t_CmprRunTiNVM', - 'offset': 0, - 'type': 'UInt32', - 'unit': '-', - 'width': 1}}, - 'sVcAesHw_X_VntAdpnOffs': { - 'VcAesVnt': { - 'class': 'CVC_DISP_NVM', - 'configs': ['Vc_Aes_Vnt_B_CodeGenVntGvnr ' - '== 0'], - 'description': 'Enter a nice ' - 'description of your ' - 'variable here', - 'handle': 'VcAesVnt/VcAesVnt/Subsystem/VcAesVnt/VcAesVnt/1_Vnt/11_VntGvnr/' - '111_VntGvnrExe/1111_VntGvnrFct/11112_VntAdpn/sVcAesHw_X_VntAdpnOffs/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAesHw_X_VntAdpnOffs', - 'offset': 0, - 'type': 'Float32', - 'unit': '-', - 'width': 1 - } - }, - 'sVcAesMo_Ar_ArrayTest': { - 'VcAesMoAdp': { - 'class': 'CVC_DISP_NVM', - 'configs': ['all'], - 'description': 'Enter a nice ' - 'description of your ' - 'variable here', - 'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/' - '2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAesMo_Ar_NvmThrAdpn', - 'offset': 0, - 'type': 'Float32', - 'unit': '-', - 'width': [4, 2] - } - }, - 'sVcAesMo_Ar_NvmThrAdpn': { - 'VcAesMoAdp': { - 'class': 'CVC_DISP_NVM', - 'configs': ['all'], - 'description': 'Enter a nice ' - 'description of your ' - 'variable here', - 'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/' - '2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAesMo_Ar_NvmThrAdpn', - 'offset': 0, - 'type': 'Float32', - 'unit': '-', - 'width': 1 - } - }, - 'sVcAesMo_rt_NvmMafLrngLd1Ne1': { - 'VcAesMfl': { - 'class': 'CVC_DISP_NVM', - 'configs': ['all'], - 'description': 'Enter a nice ' - 'description of ' - 'your variable ' - 'here', - 'handle': 'VcAesMfl/VcAesMfl/Subsystem/VcAesMfl/VcAesMfl/4_Nvm/41_Ld1Ne1/' - 'sVcAesMo_rt_NvmMafLrngLd1Ne1/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAesMo_rt_NvmMafLrngLd1Ne1', - 'offset': 0, - 'type': 'Bool', - 'unit': '-', - 'width': 1 - } - }, - 'sVcAcCtrl_t_Test1': { - 'VcAcCtrl': { - 'class': 'CVC_DISP_NVM_P', - 'configs': ['all'], - 'description': 'Enter a nice description of your variable here', - 'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/' - '36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAcCtrl_t_Test1', - 'offset': 0, - 'type': 'UInt32', - 'unit': '-', - 'width': 1 - }, - 'VcAcCtrl2': { - 'class': 'CVC_DISP_NVM_P', - 'configs': ['all'], - 'description': 'Enter a nice description of your variable here', - 'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/' - '36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay', - 'lsb': 1, - 'max': 'nan', - 'min': 'nan', - 'name': 'sVcAcCtrl_t_Test1', - 'offset': 0, - 'type': 'UInt32', - 'unit': '-', - 'width': 1 - } - } - } - - cls.nvm_configs_single = { - "fileName": "vcc_nvm_struct_single", - "baseNvmStructs": "nvm_structs_ref_single_signal.json" - } - cls.nvm_configs = { - "fileName": "vcc_nvm_struct", - "baseNvmStructs": "nvm_structs_ref_empty.json" - } - cls.nvm_configs_small = { - "fileName": "vcc_nvm_structs__small", - "baseNvmStructs": "nvm_structs_ref_small.json" - } - cls.nvm_configs_empty_small = { - "fileName": "vcc_nvm_structs_empty_small", - "baseNvmStructs": "nvm_structs_ref_empty_small.json" - } - cls.nvm_configs_signal_overwritten = { - "fileName": "vcc_nvm_structs_ref_used_positions", - "baseNvmStructs": "nvm_structs_ref_used_positions.json" - } - cls.nvm_configs_critical = { - "fileName": "vcc_nvm_structs_critical", - "baseNvmStructs": "nvm_structs_ref_critical.json" - } - cls.nvm_configs_critical_remove = { - "fileName": "vcc_nvm_struct_critical_remove", - "baseNvmStructs": "nvm_structs_ref_critical.json" - } - cls.nvm_configs_critical_duplicate = { - "fileName": "vcc_nvm_struct_critical_duplicate", - "baseNvmStructs": "nvm_structs_ref_critical_duplicate.json" - } - cls.nvm_configs_wrong_type = { - "fileName": "vcc_nvm_structs_ref_used_positions", - "baseNvmStructs": "nvm_structs_ref_wrong_type.json" - } - cls.nvm_configs_dcl = { - "fileName": "vcc_nvm_structs_ref_dcl", - "baseNvmStructs": "nvm_structs_ref_dcl.json" - } - def setUp(self): """Set-up common data structures for all tests in the test case """ @@ -209,10 +34,13 @@ class TestNVMDef(unittest.TestCase): projdir = Path(SRC_DIR, 'cnfg_files').resolve() 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_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs) 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.unit_cfg = MagicMock(spec_set=UnitConfigs) + type(self.unit_cfg).base_types_headers = '#include "tl_basetypes.h"\n' + self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test) + self.create_new = False self.small_nvm_struct = { "sVcDummy_t_DummyNvm": { @@ -244,8 +72,8 @@ class TestNVMDef(unittest.TestCase): project_config = MagicMock() projdir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'cnfg_files')) project_config.get_root_dir = MagicMock(return_value=projdir) - project_config.get_nvm_defs = MagicMock(return_value=self.nvm_configs_small) - nvm_def = NVMDef(project_config, self.unit_cfg, self.nvm_vars_test) + project_config.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_small) + nvm_def = NVMDef(project_config, self.unit_cfg, nvm_def_setup.nvm_vars_test) nvm_structs_signals = nvm_def._get_signals_in_nvm_structs() expected_signals_path = os.path.join(os.path.dirname(__file__), 'cnfg_files', @@ -262,7 +90,7 @@ class TestNVMDef(unittest.TestCase): """ no_nvm_a2l = False self.nvm_def.generate_nvm_config_files(no_nvm_a2l) - h_file_name = Path(SRC_DIR, 'output', self.nvm_configs['fileName'] + '.h') + h_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs['fileName'] + '.h') with h_file_name.open() as hfptr: h_file = hfptr.read() with Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref.h').open() as hfptr_ref: @@ -275,7 +103,7 @@ class TestNVMDef(unittest.TestCase): """ no_nvm_a2l = False self.nvm_def.generate_nvm_config_files(no_nvm_a2l) - c_file_name = Path(SRC_DIR, 'output', self.nvm_configs['fileName'] + '.c') + c_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs['fileName'] + '.c') with c_file_name.open() as cfptr: c_file = cfptr.read() with Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref.c').open() as cfptr_ref: @@ -287,7 +115,7 @@ class TestNVMDef(unittest.TestCase): """ no_nvm_a2l = False self.nvm_def.generate_nvm_config_files(no_nvm_a2l) - a_file_name = Path(SRC_DIR, 'output', self.nvm_configs['fileName'] + '.a2l') + a_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs['fileName'] + '.a2l') with a_file_name.open() as fptr: a2l_file = fptr.read() ref_file = Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref.a2l') @@ -431,9 +259,9 @@ class TestNVMDef(unittest.TestCase): def test_gen_h_file_fail(self): """test for generating the h-file for NVM definitions """ - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_empty_small) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_empty_small) NVMDef.init_logger(logging.getLogger()) - self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test) + self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test) with self.assertLogs(level='WARNING') as log: no_nvm_a2l = False self.nvm_def.generate_nvm_config_files(no_nvm_a2l) @@ -442,8 +270,8 @@ class TestNVMDef(unittest.TestCase): def test_gen_h_file_signal_is_overwritten(self): """test that the NVM definitions is overwritten if signal is named position_* """ - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_signal_overwritten) - self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_signal_overwritten) + self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test) nvm_list_32_pos = self.nvm_def._get_nvm_areas_index('NVM_LIST_32') dummy_signal = {'name': 'dummy', 'type': 'Int32', 'x_size': 1, 'y_size': 1} # find_empty_index should find next empty index to be 2 since that's @@ -458,7 +286,7 @@ class TestNVMDef(unittest.TestCase): self.assertNotEqual(index_after_generation, index_before_generation) self.assertEqual(index_after_generation, -1) - h_file_name = Path(SRC_DIR, 'output', self.nvm_configs_signal_overwritten['fileName'] + '.h') + h_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs_signal_overwritten['fileName'] + '.h') with h_file_name.open() as hfptr: h_file = hfptr.read() with Path(SRC_DIR, 'reference_files', 'vcc_nvm_structs_ref_used_positions.h').open() as hfptr_ref: @@ -469,7 +297,7 @@ class TestNVMDef(unittest.TestCase): def test_add_signal_with_nondefault_type_c(self): """Test that we can add different types of signals to critical area - c-file """ - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { 'VcTest': { @@ -532,7 +360,7 @@ class TestNVMDef(unittest.TestCase): def test_add_signal_with_nondefault_type_h(self): """Test that we can add different types of signals to critical area - h-file """ - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { 'VcTest': { @@ -596,7 +424,7 @@ class TestNVMDef(unittest.TestCase): """Test that we can add different types of signals to critical area - a2l-file """ self.proj_cnfg.get_code_generation_config = MagicMock(return_value=False) - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { 'VcTest': { @@ -665,7 +493,7 @@ class TestNVMDef(unittest.TestCase): Note: Denso does not have any area like this at the time of writing this test """ - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { 'VcTest': { @@ -732,15 +560,15 @@ class TestNVMDef(unittest.TestCase): def test_add_signal_with_wrong_type(self): """test that its not possible to add a signal of wrong type to a specific nwm area """ - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_wrong_type) - self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_wrong_type) + self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test) NVMDef.init_logger(logging.getLogger()) no_nvm_a2l = False self.assertRaises(NVMDef.WrongTypeException, self.nvm_def.generate_nvm_config_files, no_nvm_a2l) def test_add_duplicate_signal_different_attributes(self): - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_single) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_single) nvm_vars_test = { 'sVcAcCtrl_t_CmprRunTiNVM': { 'VcAcCtrl': { @@ -768,8 +596,8 @@ class TestNVMDef(unittest.TestCase): self.assertEqual(nvm_def.get_nbr_problems()['critical'], 1) def test_add_duplicate_signal_different_memory_area(self): - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_single) - self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_single) + self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test) nvm_vars_test = { 'sVcAcCtrl_t_CmprRunTiNVM': { 'VcAcCtrl': { @@ -798,7 +626,7 @@ class TestNVMDef(unittest.TestCase): def test_remove_signal_from_critical(self): """Test that a2l- and h-files are updated when removing a signal from the critical area.""" - self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical_remove) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical_remove) nvm_vars_test = { 'sVcTest_t_UInt32': { 'VcTest': { @@ -835,7 +663,7 @@ class TestNVMDef(unittest.TestCase): no_nvm_a2l = False self.nvm_def.generate_nvm_config_files(no_nvm_a2l) - h_file_name = Path(SRC_DIR, 'output', self.nvm_configs_critical_remove['fileName'] + '.h') + h_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs_critical_remove['fileName'] + '.h') with h_file_name.open() as h_ptr: h_file = h_ptr.read() with Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref_critical_remove.h').open() as h_ref_ptr: @@ -843,7 +671,7 @@ class TestNVMDef(unittest.TestCase): self.maxDiff = None self.assertEqual(h_ref_file, h_file) - a2l_file_name = Path(SRC_DIR, 'output', self.nvm_configs_critical_remove['fileName'] + '.a2l') + a2l_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs_critical_remove['fileName'] + '.a2l') with a2l_file_name.open() as a2l_ptr: a2l_file = a2l_ptr.read() ref_file = Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref_critical_remove.a2l') @@ -853,3 +681,58 @@ class TestNVMDef(unittest.TestCase): with ref_file.open() as a2l_ref_ptr: a2l_ref_file = a2l_ref_ptr.read() self.assertEqual(a2l_ref_file, a2l_file) + + +class TestZCNVMDef(unittest.TestCase): + """Class for testing ZCNVMDef.""" + + def setUp(self): + self.proj_cnfg = MagicMock() + projdir = Path(SRC_DIR, 'cnfg_files').resolve() + self.proj_cnfg.get_root_dir = MagicMock(return_value=projdir) + self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs) + self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='') + self.proj_cnfg.get_composition_config = MagicMock(return_value="Dummy_{NvName}") + self.unit_cfg = MagicMock(spec_set=UnitConfigs) + type(self.unit_cfg).base_types_headers = '#include "tl_basetypes.h"\n' + self.nvm_def = ZCNVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test) + + def test_valid_nvm_definitions_setter(self): + """Test setting property ZCNVMDef.valid_nvm_definitions.""" + self.nvm_def.valid_nvm_definitions = zc_nvm_def.yaml_nvm_definitions + self.assertDictEqual(self.nvm_def.valid_nvm_definitions, zc_nvm_def.yaml_nvm_definitions) + + def test_valid_nvm_definitions_setter_none(self): + """Test setting property ZCNVMDef.valid_nvm_definitions with no nvms.""" + self.nvm_def.valid_nvm_definitions = {} + self.assertDictEqual(self.nvm_def.valid_nvm_definitions, {}) + + def test_valid_nvm_definitions_etter_bad_project(self): + """Test setting property ZCNVMDef.valid_nvm_definitions with NVM definition not in project.""" + self.nvm_def.valid_nvm_definitions = zc_nvm_def.yaml_nvm_definitions_one_not_in_project + self.assertDictEqual(self.nvm_def.valid_nvm_definitions, zc_nvm_def.yaml_nvm_definitions) + + @patch("builtins.open", new_callable=mock_open()) + def test_append_nvm_rte_function_calls(self, mock_open_file): + """Test ZCNVMDef._append_nvm_rte_function_calls.""" + self.nvm_def.valid_nvm_definitions = zc_nvm_def.yaml_nvm_definitions + self.nvm_def._append_nvm_rte_function_calls() + expected = [ + '#include "CVC_CODE_ASIL_D_START.h"\nvoid VcNvmInit(void) {\n', + " //Call this function in the SWC init runnable\n", + " Rte_Call_Dummy_NVM_LIST_8_SetRamBlockStatus(TRUE);\n", "}\n", + '#include "CVC_CODE_ASIL_D_END.h"\n', + "\n", + '#include "CVC_CODE_ASIL_D_START.h"\nvoid VcNvm(void) {\n', + " //Call this function in the SWC main runnable\n", + " UInt8 errorStatus = 0;\n", + " *Rte_Pim_NVM_LIST_8() = nvm_list_8;\n", + " *Rte_Pim_NVM_LIST_16() = nvm_list_16;\n", + " Rte_Call_Dummy_NVM_LIST_16_GetErrorStatus(&errorStatus);\n", + " if (errorStatus == 0) {\n", + " Rte_Call_Dummy_NVM_LIST_16_WriteBlock(Rte_Pim_NVM_LIST_16());\n", + " }\n", + "}\n", + '#include "CVC_CODE_ASIL_D_END.h"\n' + ] + mock_open_file().__enter__().writelines.assert_called_once_with(expected) diff --git a/tests/zone_controller/test_composition_yaml.py b/tests/zone_controller/test_composition_yaml.py index 3ca836b..68e1574 100644 --- a/tests/zone_controller/test_composition_yaml.py +++ b/tests/zone_controller/test_composition_yaml.py @@ -248,6 +248,9 @@ class TestCompositionYaml(unittest.TestCase): def test_composition_yaml_with_nvm(self): """Checking that the dict is generated correctly, with NVM.""" self.nvm_def.nvm_definitions = composition_yaml_with_nvm.project_nvm_definitions + self.nvm_def.project_nvm_definitions = { + f"prefix_{item['name']}": item for item in self.nvm_def.nvm_definitions + } self.zc_spec["nv-needs"] = composition_yaml_with_nvm.yaml_nvm_definitions with patch.object( CompositionYaml,