From fda739bc13a2cdd9a3a72e8762fe8443cf6a88da Mon Sep 17 00:00:00 2001 From: Henrik Wahlqvist Date: Thu, 5 Sep 2024 14:14:58 +0200 Subject: [PATCH] Refactor usage of ecu_supplier Removed most of the decisions based on ecu_supplier and made it more granular using individual configuration. Current project types will keep their config by adding templates in the BaseConfig.json file. Some usecases were kept for legacy reasons. Change-Id: I3d6199713006489baff0bf73751596770fd1f968 --- powertrain_build/a2l.py | 14 +- powertrain_build/build.py | 120 ++++++++--------- powertrain_build/build_proj_config.py | 75 ++++++++++- powertrain_build/core_dummy.py | 15 --- powertrain_build/interface/device_proxy.py | 4 +- powertrain_build/memory_section.py | 56 ++------ powertrain_build/signal_interfaces.py | 4 +- .../zone_controller/composition_yaml.py | 121 +++++++++--------- .../test_composition_yaml/composition_yaml.py | 39 +++++- .../composition_yaml_setup.py | 47 +++++++ .../composition_yaml_with_a2l_axis_data.py | 23 +--- .../composition_yaml_with_calls_all_fields.py | 5 - ...tion_yaml_with_calls_no_optional_fields.py | 5 - .../composition_yaml_with_dids.py | 5 - .../composition_yaml_with_dtcs.py | 5 - .../interface/test_interface_device_proxy.py | 2 +- .../cnfg_files/ProjectCfg_CodeGenConfig.json | 28 ++++ .../vcc_nvm_structs_critical_bosch.a2l | 6 +- tests/powertrain_build/test_a2l.py | 2 +- tests/powertrain_build/test_build.py | 5 +- .../test_build_proj_configs.py | 16 +++ tests/powertrain_build/test_memory_section.py | 24 +++- tests/powertrain_build/test_nvm_def.py | 7 +- .../zone_controller/test_composition_yaml.py | 27 ++-- 24 files changed, 387 insertions(+), 268 deletions(-) create mode 100644 tests/powertrain_build/cnfg_files/ProjectCfg_CodeGenConfig.json diff --git a/powertrain_build/a2l.py b/powertrain_build/a2l.py index de5391b..169822d 100644 --- a/powertrain_build/a2l.py +++ b/powertrain_build/a2l.py @@ -53,7 +53,7 @@ class A2l(ProblemLogger): """ super().__init__() self._var_dd = var_data_dict - self._prj_cf = prj_cfg + self._prj_cfg = prj_cfg self._axis_ref = None self._axis_data = None self._compu_meths = None @@ -344,20 +344,20 @@ class A2l(ProblemLogger): opt_data += '\n' + ' ' * 8 + \ self._array_to_a2l_string(data['array']) - ecu_supplier, _ = self._prj_cf.get_ecu_info() + use_symbol_links = self._prj_cfg.get_code_generation_config(item='useA2lSymbolLinks') if a2d.get('symbol'): - if ecu_supplier == 'Denso': + if use_symbol_links: opt_data += '\n' + ' ' * 8 + 'SYMBOL_LINK "%s" %s' % (a2d['symbol'], a2d.get('symbol_offset')) - LOG.debug('This a2l is for Denso %s', opt_data) - elif ecu_supplier in ['RB', 'CSP', 'HI', 'ZC']: + LOG.debug('This a2l is using SYMBOL_LINK for %s', opt_data) + else: var_name = a2d['symbol'] + '._' + var_name - LOG.debug('This a2l is for %s %s', ecu_supplier, var_name) + LOG.debug('This a2l is not using SYMBOL_LINK for %s', var_name) dtype = a2l_type(c_type) minlim, maxlim = self._get_a2d_minmax(a2d, c_type) conv = self._compu_meths[data['compu_meth']]['name'] - if a2d.get('symbol') and ecu_supplier == 'Denso': + if a2d.get('symbol') and use_symbol_links: res = self._meas_tmplt_nvm.substitute(Name=var_name, LongIdent=a2d['description'].replace('"', '\\"'), Datatype=dtype, diff --git a/powertrain_build/build.py b/powertrain_build/build.py index ca7fd8f..85a2d3d 100644 --- a/powertrain_build/build.py +++ b/powertrain_build/build.py @@ -271,12 +271,10 @@ def generate_core_dummy(build_cfg, core, unit_cfg): start_time = time.time() core_dummy = CoreDummy(core.get_current_core_config(), unit_cfg) ecu_supplier = build_cfg.get_ecu_info()[0] - if ecu_supplier == "Denso": + if ecu_supplier in ["Denso", "CSP"]: core_dummy.generate_dg2_core_dummy_files(core_dummy_fname) elif ecu_supplier == "RB": core_dummy.generate_rb_core_dummy_files(core_dummy_fname) - elif ecu_supplier == "CSP": - core_dummy.generate_csp_core_dummy_files(core_dummy_fname) else: msg = f"Could not generate VcCoreDummy, cannot identify the supplier {ecu_supplier}." LOG.critical(msg) @@ -284,7 +282,7 @@ def generate_core_dummy(build_cfg, core, unit_cfg): LOG.info("Finished generating Core Dummy (in %4.2f s)", time.time() - start_time) -def generate_ext_var(build_cfg, unit_cfg, signal_if, udt, debug_code=True): +def generate_ext_var(build_cfg, unit_cfg, signal_if, udt, asil_level_db, asil_level_dep, debug_code=True): """Generate two c-files that define the signal interface to the supplier. The VcExtVar function assigns all variables to the CVC_DISP memory area, @@ -299,24 +297,17 @@ def generate_ext_var(build_cfg, unit_cfg, signal_if, udt, debug_code=True): build_cfg (BuildProjConfig): Build project class holding where files should be stored. signal_if (SignalInterfaces): class holding signal interface information. udt (UserDefinedTypes): Class holding user defined data types. + asil_level_db (str): ASIL level for debug variables. + asil_level_dep (str): ASIL level for dependability variables. debug_code (boolean): If true, generate debug code. """ LOG.info("******************************************************") LOG.info("Start generating VcExtVar and VcDebug") start_time = time.time() - ecu_supplier = build_cfg.get_ecu_info()[0] - asil_level_dep = build_defs.ASIL_D if ecu_supplier == "HI" else build_defs.ASIL_B - asil_level_db = ( - build_defs.CVC_ASIL_D if ecu_supplier == "HI" else build_defs.CVC_ASIL_B - ) nrm_dict, dep_dict, sec_dict, dbg_dict = signal_if.get_external_io() - - _extract_external_var( - build_cfg, unit_cfg, udt, asil_level_dep, nrm_dict, dep_dict, sec_dict - ) + _extract_external_var(build_cfg, unit_cfg, udt, asil_level_dep, nrm_dict, dep_dict, sec_dict) if debug_code: _extract_debug(build_cfg, unit_cfg, asil_level_db, dep_dict, dbg_dict) - LOG.info( "Finished generating VcExtVar and VcDebug (in %4.2f s)", time.time() - start_time, @@ -759,7 +750,6 @@ def build( prj_cfgs = {} build_cfg = BuildProjConfig(os.path.normpath(project_config)) - ecu_supplier = build_cfg.get_ecu_info()[0] prj_cfgs.update({build_cfg.name: build_cfg}) build_cfg.create_build_dirs() @@ -806,10 +796,20 @@ def build( udt.generate_common_header_files() - generate_ext_var(build_cfg, unit_cfg, signal_if, udt) - if ecu_supplier in ["CSP", "HP", "HI", "ZC"]: + code_generation_config = build_cfg.get_code_generation_config() + + generate_ext_var( + build_cfg, + unit_cfg, + signal_if, + udt, + build_defs.CVC_ASIL_LEVEL_MAP[code_generation_config["generalAsilLevelDebug"]], + build_defs.ASIL_LEVEL_MAP[code_generation_config["generalAsilLevelDependability"]] + ) + + if not code_generation_config["generateDummyVar"]: LOG.info("******************************************************") - LOG.info("Skip generating VcDummy file for %s projects", ecu_supplier) + LOG.info("Skip generating VcDummy file") else: generate_dummy_var(build_cfg, unit_cfg, signal_if, udt) @@ -837,37 +837,8 @@ def build( else: LOG.warning("Cannot find desired custom sourcefile: %s", custom_src) - if ecu_supplier in ["HI"]: - LOG.info("******************************************************") - LOG.info("Generating Core header") - hi_core = HICore(build_cfg, unit_cfg) - hi_core.generate_dtc_files() - LOG.info("******************************************************") - LOG.info("Generating DID files") - dids = HIDIDs(build_cfg, unit_cfg) - dids.generate_did_files() - elif ecu_supplier in ["ZC"]: - LOG.info("******************************************************") - LOG.info("Generating Core header") - zc_core = ZCCore(build_cfg, unit_cfg) - zc_core.generate_dtc_files() - else: - generate_did_files(build_cfg, unit_cfg) - # generate core dummy files if requested - if core_dummy: - core_dummy_fname = os.path.basename(build_cfg.get_core_dummy_name()) - if CodeGenerators.embedded_coder in unit_cfg.code_generators: - LOG.info("******************************************************") - LOG.info("Skip generating %s for EC projects", core_dummy_fname) - elif ecu_supplier in ["HI", "ZC", "CSP"]: - LOG.info("******************************************************") - LOG.info("Skip generating %s for SPA2+ projects", core_dummy_fname) - else: - core = Core(build_cfg, unit_cfg) - generate_core_dummy(build_cfg, core, unit_cfg) - # generate NVM definitions - if ecu_supplier in ["ZC"]: + 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) @@ -911,20 +882,19 @@ def build( # Copy files to output folder copy_unit_src_to_src_out(build_cfg) - if ecu_supplier in ["ZC"]: + if code_generation_config["useSwcNameAsPrefix"]: 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_files_to_include(build_cfg) - if ecu_supplier in ["HI", "ZC"]: + if code_generation_config["generateInterfaceHeaders"]: memory_section = MemorySection(build_cfg) memory_section.generate_required_header_files() - # Propagate tag name for release builds - # TAG_NAME is set in release -> release-compile-denso/release-ecmsildll -> powertrain_build.build + # Propagate tag name for release builds, TAG_NAME must be set in environment tag_name = os.environ.get("TAG_NAME", "") - if tag_name and ecu_supplier == "Denso": + if tag_name and code_generation_config["propagateTagName"]: propagate_tag_name(build_cfg, tag_name, problem_logger) # Copy header files (subversion is using an external that points to @@ -936,23 +906,55 @@ def build( ctable_a2l = Path(build_cfg.get_src_code_dst_dir(), "custom_tabs.a2l") create_conversion_table(ctable_json, ctable_a2l) merged_a2l = merge_a2l_files(build_cfg, unit_cfg, complete_a2l, silver_a2l) - if ecu_supplier in ["ZC"]: + a2l_file_path = Path(build_cfg.get_src_code_dst_dir(), build_cfg.get_a2l_name()) + replace_tab_verb(a2l_file_path) + + # Generate interface files + if code_generation_config["generateYamlInterfaceFile"]: + zc_core = ZCCore(build_cfg, unit_cfg) zc_dids = ZCDIDs(build_cfg, unit_cfg) axis_data = merged_a2l.get_characteristic_axis_data() composition_yaml = CompositionYaml( build_cfg, signal_if.composition_spec, unit_cfg, zc_core, zc_dids, axis_data ) + LOG.info("******************************************************") composition_yaml.generate_yaml() + LOG.info("******************************************************") + LOG.info("Generating Core header") + zc_core.generate_dtc_files() + LOG.info("******************************************************") + LOG.info("Generating DID files") + zc_dids.generate_did_files() + elif build_cfg.get_ecu_info()[0] == "HI": + LOG.info("******************************************************") + LOG.info("Generating Core header") + hi_core = HICore(build_cfg, unit_cfg) + hi_core.generate_dtc_files() + LOG.info("******************************************************") + LOG.info("Generating DID files") + dids = HIDIDs(build_cfg, unit_cfg) + dids.generate_did_files() + else: + generate_did_files(build_cfg, unit_cfg) + # generate core dummy files if requested + if core_dummy: + core_dummy_fname = os.path.basename(build_cfg.get_core_dummy_name()) + if CodeGenerators.embedded_coder in unit_cfg.code_generators: + LOG.info("******************************************************") + LOG.info("Skip generating %s for EC projects", core_dummy_fname) + elif code_generation_config["generateCoreDummy"]: + LOG.info("******************************************************") + LOG.info("Skip generating %s for SPA2+ projects", core_dummy_fname) + else: + core = Core(build_cfg, unit_cfg) + generate_core_dummy(build_cfg, core, unit_cfg) + + if code_generation_config["generateCalibrationInterfaceFiles"]: zc_calibration = ZoneControllerCalibration( build_cfg, composition_yaml.cal_class_info["tl"] ) zc_calibration.generate_calibration_interface_files() - LOG.info("******************************************************") - LOG.info("Generating DID files") - zc_dids.generate_did_files() - a2l_file_path = Path(build_cfg.get_src_code_dst_dir(), build_cfg.get_a2l_name()) - replace_tab_verb(a2l_file_path) if problem_logger.errors(): problem_logger.info( "Critical errors were detected, aborting" " after %4.2f s.", diff --git a/powertrain_build/build_proj_config.py b/powertrain_build/build_proj_config.py index e2105f2..b727429 100644 --- a/powertrain_build/build_proj_config.py +++ b/powertrain_build/build_proj_config.py @@ -43,6 +43,7 @@ class BuildProjConfig: deep_dict_update(self._prj_cfg, base_cnfg) 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.has_yaml_interface = self._prj_cfg['ProjectInfo'].get('yamlInterface', False) self.device_domains = self._get_device_domains() self.services_file = self._get_services_file() @@ -60,6 +61,39 @@ class BuildProjConfig: """Get string representation of object.""" return pformat(self._prj_cfg['ProjectInfo']) + def _get_default_code_generation_config(self): + return { + 'generalAsilLevelDebug': 'B', + 'generalAsilLevelDependability': 'B', + 'generateCalibrationInterfaceFiles': False, + 'generateCoreDummy': False, + 'generateDummyVar': False, + 'generateInterfaceHeaders': False, + 'generateYamlInterfaceFile': False, + 'propagateTagName': False, + 'useA2lSymbolLinks': False, + 'useSwcNameAsPrefix': False, + } + + def _get_code_generation_config(self): + """ Get code generation configuration. + + Anything already set in CodeGenerationConfig in ProjectCfg.json takes priority. + If there is a project template for the ECU supplier, those values are used, + unless already set in ProjectCfg.json. + Finally, default values are inserted for missing keys. + + Args: + item (str): Item to get from the configuration. If None, the whole configuration is returned. + Returns: + (dict): Code generation configuration. + """ + code_generation_configuration = {} + ecu_supplier = self.get_ecu_info()[0] + deep_dict_update(code_generation_configuration, self._prj_cfg.get('ProjectTemplates', {}).get(ecu_supplier, {})) + deep_dict_update(code_generation_configuration, self._get_default_code_generation_config()) + return {'CodeGenerationConfig': code_generation_configuration} + def _get_device_domains(self): file_name = self._prj_cfg['ProjectInfo'].get('deviceDomains') full_path = pathlib.Path(self._prj_root_dir, file_name) @@ -137,6 +171,26 @@ class BuildProjConfig: if unit_cfg_outp is not None: os.makedirs(unit_cfg_outp) + def get_code_generation_config(self, item=None): + """ Get code generation configuration. + + Args: + item (str): Item to get from the configuration. If None, the whole configuration is returned. + Returns: + (dict): Code generation configuration. + """ + if item is not None: + return self._prj_cfg['CodeGenerationConfig'].get(item, {}) + return self._prj_cfg['CodeGenerationConfig'] + + def get_memory_map_config(self): + """ Get memory map configuration. + + Returns: + (dict): Memory map configuration. + """ + return self._prj_cfg.get('MemoryMapConfig', {}) + def get_a2l_cfg(self): """ Get A2L configuration from A2lConfig. @@ -152,6 +206,16 @@ class BuildProjConfig: 'asap2_version': a2l_config.get('asap2Version', "1 51") } + def get_enable_end_to_end_status_signals(self): + """Get the enable end-to-end status signals configuration. + + NOTE: Only appicable for device proxy type signal interfaces. + + Returns: + (bool): True if end-to-end status signals are enabled, False otherwise. + """ + return self._prj_cfg['ProjectInfo'].get('enableEndToEndStatusSignals', False) + def get_unit_cfg_deliv_dir(self): """Get the directory where to put the unit configuration files. @@ -208,6 +272,10 @@ class BuildProjConfig: a2lname = f"{self.get_a2l_cfg()['name']}_SC" return self._prj_cfg['ProjectInfo'].get('softwareComponentName', a2lname) + def get_swc_template(self): + """Returns the software component template to use.""" + return self._prj_cfg['ProjectInfo'].get('softwareComponentTemplate') + def get_car_com_dst(self): """Return the absolute path to the source output folder.""" return os.path.join(self.get_root_dir(), @@ -383,10 +451,11 @@ class BuildProjConfig: Returns: (ecuSupplier, ecuType) - """ - return (self._prj_cfg['ProjectInfo']['ecuSupplier'], - self._prj_cfg['ProjectInfo'].get('ecuType', '')) + return ( + self._prj_cfg['ProjectInfo'].get('ecuSupplier', None), + self._prj_cfg['ProjectInfo'].get('ecuType', '') + ) def get_xcp_enabled(self): """Return True/False whether XCP is enabled in the project or not. diff --git a/powertrain_build/core_dummy.py b/powertrain_build/core_dummy.py index 36e16b4..b099e89 100644 --- a/powertrain_build/core_dummy.py +++ b/powertrain_build/core_dummy.py @@ -341,18 +341,3 @@ class CoreDummy(ProblemLogger): self._gen_dg2_mode06_dummies() self._gen_dg2_rnk_dummies() self._gen_dg2_end(f_name) - - def generate_csp_core_dummy_files(self, file_name): - """Generate core API dummy files for Bosch projects.""" - cname = file_name + '.c' - hname = file_name + '.h' - with open(cname, 'w', encoding="utf-8") as self.fh_c: - with open(hname, 'w', encoding="utf-8") as self.fh_h: - _, f_name = os.path.split(hname) - self._gen_dg2_header(f_name) - self._gen_dg2_event_dummies() - self._gen_dg2_fid_dummies() - self._gen_dg2_iumpr_dummies() - self._gen_dg2_mode06_dummies() - self._gen_dg2_rnk_dummies() - self._gen_dg2_end(f_name) diff --git a/powertrain_build/interface/device_proxy.py b/powertrain_build/interface/device_proxy.py index 7db5cbc..b4f2d66 100644 --- a/powertrain_build/interface/device_proxy.py +++ b/powertrain_build/interface/device_proxy.py @@ -340,8 +340,8 @@ class DPAL(BaseApplication): ) ) - ecu_supplier, _unused = self.base_application.pybuild['build_cfg'].get_ecu_info() - if ecu_supplier in ['HI', 'ZC'] and is_safe_signal and group is not None: + enable_e2e_sts = self.base_application.pybuild['build_cfg'].get_enable_end_to_end_status_signals() + if enable_e2e_sts and is_safe_signal and group is not None: e2e_sts_property = f"{group}E2eSts" e2e_sts_signal_name = f"sVc{domain}_D_{e2e_sts_property}" diff --git a/powertrain_build/memory_section.py b/powertrain_build/memory_section.py index 0e10a16..ec5af21 100644 --- a/powertrain_build/memory_section.py +++ b/powertrain_build/memory_section.py @@ -31,46 +31,13 @@ class MemorySection(ProblemLogger): 'CVC_DISP_ASIL_C', 'CVC_DISP_ASIL_D' ] - project_defines = { - 'HI': { - 'START': { - 'const': '#define {software_component_name}_START_SEC_CONST_UNSPECIFIED\n', - 'disp': '#define {software_component_name}_START_SEC_VAR_INIT_UNSPECIFIED\n', - 'cal': '#pragma section ".XcpCalibrationSection"\n' - }, - 'STOP': { - 'const': '#define {software_component_name}_STOP_SEC_CONST_UNSPECIFIED\n', - 'disp': '#define {software_component_name}_STOP_SEC_VAR_INIT_UNSPECIFIED\n', - 'cal': '#pragma section\n' - } - }, - 'ZC': { - 'START': { - 'const': '#define {software_component_name}_START_SEC_VCC_CONST\n', - 'disp': '#define {software_component_name}_START_SEC_VCC_DISP\n', - 'cal': '#define {software_component_name}_START_SEC_VCC_CAL\n' - }, - 'STOP': { - 'const': '#define {software_component_name}_STOP_SEC_VCC_CONST\n', - 'disp': '#define {software_component_name}_STOP_SEC_VCC_DISP\n', - 'cal': '#define {software_component_name}_STOP_SEC_VCC_CAL\n' - }, - } - } def __init__(self, build_cfg): super().__init__() self.build_cfg = build_cfg - self.a2l_cfg_name = self.build_cfg.get_a2l_cfg()['name'] - self.ecu_supplier = self.build_cfg.get_ecu_info()[0] - if self.ecu_supplier == 'HI': - self.include_header_guards = True - self.software_component_name = self.a2l_cfg_name - self.mem_map_include = f'#include "{self.a2l_cfg_name}_MemMap.h"\n' - else: - self.include_header_guards = False - self.software_component_name = self.build_cfg.get_swc_name() - self.mem_map_include = f'#include "{self.software_component_name}_MemMap.h"\n' + self.mem_map_config = self.build_cfg.get_memory_map_config() + self.include_header_guards = self.mem_map_config['includeHeaderGuards'] + self.mem_map_include = f'#include "{self.mem_map_config["memMapPrefix"]}_MemMap.h"\n' self.xcp_enabled = self.build_cfg.get_xcp_enabled() self.use_volatile_globals = self.build_cfg.get_use_volatile_globals() @@ -100,11 +67,9 @@ class MemorySection(ProblemLogger): cvc_defines = [] section_type = 'cal' if self.xcp_enabled else 'disp' memory_section_handling = [ - self.project_defines[self.ecu_supplier][self._get_mem_map_section(section)][section_type].format( - software_component_name=self.software_component_name - ) + self.mem_map_config['projectDefines'][self._get_mem_map_section(section)][section_type] + '\n' ] - if self.ecu_supplier != 'HI' or not self.xcp_enabled: + if self.mem_map_config['includeMemMapForCalibration'] or not self.xcp_enabled: memory_section_handling.append(self.mem_map_include) return cvc_undefines, cvc_defines, memory_section_handling @@ -116,19 +81,16 @@ class MemorySection(ProblemLogger): else: cvc_defines = [] memory_section_handling = [ - self.project_defines[self.ecu_supplier][self._get_mem_map_section(section)]['disp'].format( - software_component_name=self.software_component_name - ), + self.mem_map_config['projectDefines'][self._get_mem_map_section(section)]['disp'] + '\n', self.mem_map_include ] return cvc_undefines, cvc_defines, memory_section_handling def _get_code(self, section): - mem_map_section = self._get_mem_map_section(section) cvc_undefines = [] cvc_defines = [] memory_section_handling = [ - f'#define {self.software_component_name}_{mem_map_section}_SEC_CODE\n', + self.mem_map_config['projectDefines'][self._get_mem_map_section(section)]['code'] + '\n', self.mem_map_include ] return cvc_undefines, cvc_defines, memory_section_handling @@ -137,9 +99,7 @@ class MemorySection(ProblemLogger): cvc_undefines = [] cvc_defines = [] memory_section_handling = [ - self.project_defines[self.ecu_supplier][self._get_mem_map_section(section)]['const'].format( - software_component_name=self.software_component_name - ), + self.mem_map_config['projectDefines'][self._get_mem_map_section(section)]['const'] + '\n', self.mem_map_include ] return cvc_undefines, cvc_defines, memory_section_handling diff --git a/powertrain_build/signal_interfaces.py b/powertrain_build/signal_interfaces.py index c053f16..07649a0 100644 --- a/powertrain_build/signal_interfaces.py +++ b/powertrain_build/signal_interfaces.py @@ -404,7 +404,7 @@ class YamlSignalInterfaces(SignalInterfaces): translation_files = app.get_translation_files() - ecu_supplier, _unused = prj_cfg.get_ecu_info() + ecu_supplier = prj_cfg.get_ecu_info()[0] self.zc_spec = {} self.hal_spec = {} self.dp_spec = {} @@ -412,7 +412,7 @@ class YamlSignalInterfaces(SignalInterfaces): self.sa_spec = {} self.service_spec = {} self.mthd_spec = {} - if ecu_supplier == 'ZC': + if prj_cfg.get_code_generation_config(item='generateYamlInterfaceFile'): zc_app = ZCAL(app) self.zc_spec = get_interface(app, zc_app) self.composition_spec = zc_app.composition_spec diff --git a/powertrain_build/zone_controller/composition_yaml.py b/powertrain_build/zone_controller/composition_yaml.py index 15e462b..446ef7a 100644 --- a/powertrain_build/zone_controller/composition_yaml.py +++ b/powertrain_build/zone_controller/composition_yaml.py @@ -53,16 +53,17 @@ class CompositionYaml(ProblemLogger): self.calibration_init_values = self.get_init_values(calibration_variables) self.cal_class_info = self._get_class_info(calibration_variables) self.meas_class_info = self._get_class_info(measurable_variables) - trigger_read_rte_cdata_signal_name = self._get_calibration_trigger_signal_name(calibration_variables) - self.cal_class_info["autosar"]["class_info"].update( - { - trigger_read_rte_cdata_signal_name: { - "type": ZCC.trigger_read_rte_cdata_signal['data_type'], - "access": "READ-WRITE", - "init": 0, + if self.build_cfg.get_code_generation_config(item="generateCalibrationInterfaceFiles"): + trigger_read_rte_cdata_signal_name = self._get_calibration_trigger_signal_name(calibration_variables) + self.cal_class_info["autosar"]["class_info"].update( + { + trigger_read_rte_cdata_signal_name: { + "type": ZCC.trigger_read_rte_cdata_signal["data_type"], + "access": "READ-WRITE", + "init": 0, + } } - } - ) + ) @staticmethod def _cast_init_value(value_str): @@ -73,7 +74,7 @@ class CompositionYaml(ProblemLogger): Returns: (int/float): Value casted to correct type. """ - if value_str.endswith('F'): + if value_str.endswith("F"): return float(value_str[:-1]) return int(value_str) @@ -172,17 +173,15 @@ class CompositionYaml(ProblemLogger): """ value_extraction_regexes = [ ( - re.compile(r'^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P\w+)\s*=\s*(?P[-\d\.e]+F?)\s*;'), - lambda regex_match, _: self._cast_init_value(regex_match.group('value')) + re.compile(r"^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P\w+)\s*=\s*(?P[-\d\.e]+F?)\s*;"), + lambda regex_match, _: self._cast_init_value(regex_match.group("value")) ), ( - re.compile(r'^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P\w+)\[(?P[\d]+)\]\s*=\s*'), + re.compile(r"^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P\w+)\[(?P[\d]+)\]\s*=\s*"), self._get_array_init_values ), ( - re.compile( - r'^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P\w+)\[(?P[\d]+)\]\[(?P[\d]+)\]\s*=\s*' - ), + re.compile(r"^\s*CVC_CAL[A-Z_]*\s+\w+\s+(?P\w+)\[(?P[\d]+)\]\[(?P[\d]+)\]\s*=\s*"), self._get_matrix_init_values ) ] @@ -194,14 +193,14 @@ class CompositionYaml(ProblemLogger): line = calibration_definitions.pop() for regex, extraction_function in value_extraction_regexes: regex_match = regex.match(line) - if regex_match is not None and regex_match.group('name') in calibration_variables: - if regex_match.group('name') in init_values: - self.critical('Variable definition for %s already found.', regex_match.group("name")) - init_values[regex_match.group('name')] = extraction_function(regex_match, calibration_definitions) + if regex_match is not None and regex_match.group("name") in calibration_variables: + if regex_match.group("name") in init_values: + self.critical("Variable definition for %s already found.", regex_match.group("name")) + init_values[regex_match.group("name")] = extraction_function(regex_match, calibration_definitions) missing_init_values = set(calibration_variables) - set(init_values.keys()) if missing_init_values: - self.critical('Missing init values for calibration variables:\n%s', '\n'.join(missing_init_values)) + self.critical("Missing init values for calibration variables:\n%s", "\n".join(missing_init_values)) return init_values @@ -212,16 +211,16 @@ class CompositionYaml(ProblemLogger): (iter): Iterator with calibration definitions. """ calibration_definitions = [] - end_of_definitions_regex = re.compile(r'^void\s*RESTART_.*') + end_of_definitions_regex = re.compile(r"^void\s*RESTART_.*") c_files = [Path(src_dir, unit.split("__")[0] + ".c").resolve() for unit, src_dir in self.unit_src_dirs.items()] for c_file in c_files: - read_lines = '' - with c_file.open(mode='r', encoding='latin-1') as file_handle: + read_lines = "" + with c_file.open(mode="r", encoding="latin-1") as file_handle: for line in file_handle: if end_of_definitions_regex.match(line): break read_lines += line - calibration_definitions.extend(re.sub(r'/\*.*?\*/', '', read_lines, flags=re.S).splitlines()) + calibration_definitions.extend(re.sub(r"/\*.*?\*/", "", read_lines, flags=re.S).splitlines()) return calibration_definitions def _get_array_init_values(self, array_regex_match, definitions_list): @@ -237,16 +236,16 @@ class CompositionYaml(ProblemLogger): Returns: (list): List of initialization values for the array. """ - array_init_values_str = '' + array_init_values_str = "" line = definitions_list.pop() # Skip array definition line - while '};' not in line: + while "};" not in line: array_init_values_str += line.strip() line = definitions_list.pop() array_init_values_str += line.strip() - array_init_values = re.findall(r'([-\d\.e]+F?),?', array_init_values_str) + array_init_values = re.findall(r"([-\d\.e]+F?),?", array_init_values_str) - if int(array_regex_match.group('size')) != len(array_init_values): - self.critical('Could not parse init values for array definition %s.', array_regex_match.group("name")) + if int(array_regex_match.group("size")) != len(array_init_values): + self.critical("Could not parse init values for array definition %s.", array_regex_match.group("name")) return [self._cast_init_value(value) for value in array_init_values] @@ -264,19 +263,19 @@ class CompositionYaml(ProblemLogger): (list(list)): List of initialization values for the matrix. """ matrix_init_values = [] - matrix_init_values_str = '' + matrix_init_values_str = "" line = definitions_list.pop() # Skip matrix definition line - while '};' not in line: + while "};" not in line: matrix_init_values_str += line.strip() - if '}' in line: - matrix_init_values.append(re.findall(r'([-\d\.e]+F?),?', matrix_init_values_str)) - matrix_init_values_str = '' + if "}" in line: + matrix_init_values.append(re.findall(r"([-\d\.e]+F?),?", matrix_init_values_str)) + matrix_init_values_str = "" line = definitions_list.pop() - row_check = int(matrix_regex_match.group('rows')) != len(matrix_init_values) - col_check = any(int(matrix_regex_match.group('cols')) != len(row) for row in matrix_init_values) + row_check = int(matrix_regex_match.group("rows")) != len(matrix_init_values) + col_check = any(int(matrix_regex_match.group("cols")) != len(row) for row in matrix_init_values) if row_check or col_check: - self.critical('Could not parse init values for matrix definition %s.', matrix_regex_match.group("name")) + self.critical("Could not parse init values for matrix definition %s.", matrix_regex_match.group("name")) return [[self._cast_init_value(value) for value in row] for row in matrix_init_values] @@ -317,7 +316,7 @@ class CompositionYaml(ProblemLogger): diag_dict["events"] = self.zc_core.get_diagnostic_trouble_codes(events) if rids: diag_dict["rids"] = rids - self.warning('Will not generate code for RIDs, add manually.') + self.warning("Will not generate code for RIDs, add manually.") return diag_dict def _get_ports_info(self): @@ -355,24 +354,24 @@ class CompositionYaml(ProblemLogger): Returns: dict: Dict containing runnables information. """ - swc_content = {} swc_name = self.build_cfg.get_swc_name() autosar_prefix = "AR_" swc_prefix = self.build_cfg.get_scheduler_prefix() init_function = autosar_prefix + swc_prefix + "VcExtINI" calibration_variables = list(self.cal_class_info["autosar"]["class_info"].keys()) - calibration_step_function = autosar_prefix + ZCC.calibration_function_step_template.format(swc_name=swc_name) + swc_content = {init_function: {"type": "INIT", "accesses": calibration_variables}} - swc_content.update( - { - calibration_step_function: { - "type": "PERIODIC", - "period": 0.1, - "accesses": calibration_variables, - }, - init_function: {"type": "INIT", "accesses": calibration_variables}, - } - ) + if self.build_cfg.get_code_generation_config(item="generateCalibrationInterfaceFiles"): + cal_step_function = autosar_prefix + ZCC.calibration_function_step_template.format(swc_name=swc_name) + swc_content.update( + { + cal_step_function: { + "type": "PERIODIC", + "period": 0.1, + "accesses": calibration_variables, + }, + } + ) call_dict = self._get_runnable_calls_info() runnables = self.build_cfg.get_units_raster_cfg()["SampleTimes"] @@ -396,17 +395,15 @@ class CompositionYaml(ProblemLogger): data_types (dict): Data types information. """ software_component_name = self.build_cfg.get_swc_name() + software_component_template = self.build_cfg.get_swc_template() data_types = { **self.cal_class_info["autosar"]["data_types"], **self.meas_class_info["autosar"]["data_types"], } - swcs = { - software_component_name: { - "type": "SWC", # Other types than swc?? - "template": "ARTCSC", - "runnables": {}, - }, - } + swcs = {software_component_name: {}} + swcs[software_component_name]["type"] = "SWC" # Other types than swc?? + if software_component_template is not None: + swcs[software_component_name]["template"] = software_component_template 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"] @@ -487,13 +484,13 @@ class CompositionYaml(ProblemLogger): upper = 1 lower = 0 else: - base_type_lower = self.data_types[info['type']]["limits"]["lower"] - base_type_upper = self.data_types[info['type']]["limits"]["upper"] + base_type_lower = self.data_types[info["type"]]["limits"]["lower"] + base_type_upper = self.data_types[info["type"]]["limits"]["upper"] lower = info["min"] if info["min"] != "-" else base_type_lower upper = info["max"] if info["max"] != "-" else base_type_upper if not isinstance(info["width"], list): class_info[signal_name] = { - "type": info['type'], + "type": info["type"], "access": "READ-ONLY" if info["class"] == "CVC_DISP" else "READ-WRITE", "init": self.calibration_init_values.get(signal_name, max(min(0, upper), lower)), } @@ -586,7 +583,7 @@ class CompositionYaml(ProblemLogger): new_data_type_data = { "type": "ARRAY", "size": info["width"][1], - "element": info['type'], + "element": info["type"], } else: self.critical("Signal config error for %s.", signal_name) diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml.py b/test_data/zone_controller/test_composition_yaml/composition_yaml.py index 4f822ca..c76a324 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml.py @@ -20,11 +20,6 @@ expected_result = { "type": "PERIODIC", "accesses": composition_yaml_setup.base_accesses }, - "AR_testName_SC_ZcCalibrationStep": { - "period": 0.1, - "type": "PERIODIC", - "accesses": composition_yaml_setup.base_accesses - } }, "diagnostics": {}, "static": composition_yaml_setup.base_static, @@ -38,3 +33,37 @@ expected_result = { "PortInterfaces": composition_yaml_setup.base_port_interfaces, "ExternalFiles": composition_yaml_setup.base_configuration } + +expected_cal_result = { + "SoftwareComponents": { + "testName_SC": { + "type": "SWC", + "template": "ARTCSC", + "runnables": { + "AR_prefix_VcExtINI": { + "type": "INIT", + "accesses": composition_yaml_setup.cal_accesses + }, + "AR_prefix_testRunnable": { + "period": 10, + "type": "PERIODIC", + "accesses": composition_yaml_setup.cal_accesses + }, + "AR_testName_SC_ZcCalibrationStep": { + "period": 0.1, + "type": "PERIODIC", + "accesses": composition_yaml_setup.cal_accesses + } + }, + "diagnostics": {}, + "static": composition_yaml_setup.base_static, + "shared": composition_yaml_setup.cal_shared, + "ports": { + "GlobSignNme": {"direction": "IN", "interface": "PIGlobSignNme"} + }, + } + }, + "DataTypes": composition_yaml_setup.base_data_types, + "PortInterfaces": composition_yaml_setup.base_port_interfaces, + "ExternalFiles": composition_yaml_setup.base_configuration +} diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_setup.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_setup.py index da1fd93..7c8b7d5 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_setup.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_setup.py @@ -16,6 +16,14 @@ base_port_interfaces = { } base_accesses = [ + "tVcGpaDemo_X_DummyOne_x", + "tVcGpaDemo_X_DummyOne", + "mVcGpaDemo_X_DummyTwo_r", + "mVcGpaDemo_X_DummyTwo_c", + "mVcGpaDemo_X_DummyTwo" +] + +cal_accesses = [ "tVcGpaDemo_X_DummyOne_x", "tVcGpaDemo_X_DummyOne", "mVcGpaDemo_X_DummyTwo_r", @@ -25,6 +33,45 @@ base_accesses = [ ] base_shared = { + "tVcGpaDemo_X_DummyOne_x": { + "access": "READ-WRITE", + "type": "dt_tVcGpaDemo_X_DummyOne_x", + "init": [0.0, 0.0, 0.0, 0.0, 0.0] + }, + "tVcGpaDemo_X_DummyOne": { + "access": "READ-WRITE", + "type": "dt_tVcGpaDemo_X_DummyOne", + "init": [0.0, 0.0, 0.0, 0.0, 0.0] + }, + "mVcGpaDemo_X_DummyTwo_r": { + "access": "READ-WRITE", + "type": "dt_mVcGpaDemo_X_DummyTwo_r", + "init": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "mVcGpaDemo_X_DummyTwo_c": { + "access": "READ-WRITE", + "type": "dt_mVcGpaDemo_X_DummyTwo_c", + "init": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + }, + "mVcGpaDemo_X_DummyTwo": { + "access": "READ-WRITE", + "type": "dt_mVcGpaDemo_X_DummyTwo", + "init": [ + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5] + ] + } +} + +cal_shared = { "ctestName_SC_TriggerReadRteCData": { "access": "READ-WRITE", "type": "Float32", diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_a2l_axis_data.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_a2l_axis_data.py index cf7085f..4f6f809 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_a2l_axis_data.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_a2l_axis_data.py @@ -159,8 +159,7 @@ expected_result = { "tVcGpaDemo_X_NotSameAsAxisOne", "mVcGpaDemo_X_DummyTwo_r", "mVcGpaDemo_X_DummyTwo_c", - "mVcGpaDemo_X_NotSameAsAxisTwo", - "ctestName_SC_TriggerReadRteCData" + "mVcGpaDemo_X_NotSameAsAxisTwo" ] }, "AR_prefix_testRunnable": { @@ -171,31 +170,13 @@ expected_result = { "tVcGpaDemo_X_NotSameAsAxisOne", "mVcGpaDemo_X_DummyTwo_r", "mVcGpaDemo_X_DummyTwo_c", - "mVcGpaDemo_X_NotSameAsAxisTwo", - "ctestName_SC_TriggerReadRteCData" - ] - }, - "AR_testName_SC_ZcCalibrationStep": { - "period": 0.1, - "type": "PERIODIC", - "accesses": [ - "tVcGpaDemo_X_DummyOne_x", - "tVcGpaDemo_X_NotSameAsAxisOne", - "mVcGpaDemo_X_DummyTwo_r", - "mVcGpaDemo_X_DummyTwo_c", - "mVcGpaDemo_X_NotSameAsAxisTwo", - "ctestName_SC_TriggerReadRteCData" + "mVcGpaDemo_X_NotSameAsAxisTwo" ] } }, "diagnostics": {}, "static": composition_yaml_setup.base_static, "shared": { - "ctestName_SC_TriggerReadRteCData": { - "access": "READ-WRITE", - "type": "Float32", - "init": 0 - }, "tVcGpaDemo_X_DummyOne_x": { "access": "READ-WRITE", "type": "dt_tVcGpaDemo_X_DummyOne_x", diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_all_fields.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_all_fields.py index 20f1eec..d2aa516 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_all_fields.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_all_fields.py @@ -25,11 +25,6 @@ expected_result = { "timeout": 0.1, } } - }, - "AR_testName_SC_ZcCalibrationStep": { - "period": 0.1, - "type": "PERIODIC", - "accesses": composition_yaml_setup.base_accesses } }, "diagnostics": {}, diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_no_optional_fields.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_no_optional_fields.py index 265a59b..a0c98ce 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_no_optional_fields.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_calls_no_optional_fields.py @@ -24,11 +24,6 @@ expected_result = { "operation": "OperationOne", } } - }, - "AR_testName_SC_ZcCalibrationStep": { - "period": 0.1, - "type": "PERIODIC", - "accesses": composition_yaml_setup.base_accesses } }, "diagnostics": {}, diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dids.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dids.py index 766d6a8..b37ae62 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dids.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dids.py @@ -51,11 +51,6 @@ expected_result = { "period": 10, "type": "PERIODIC", "accesses": composition_yaml_setup.base_accesses, - }, - "AR_testName_SC_ZcCalibrationStep": { - "period": 0.1, - "type": "PERIODIC", - "accesses": composition_yaml_setup.base_accesses } }, "diagnostics": { diff --git a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dtcs.py b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dtcs.py index 44a2260..56cbcbb 100644 --- a/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dtcs.py +++ b/test_data/zone_controller/test_composition_yaml/composition_yaml_with_dtcs.py @@ -42,11 +42,6 @@ expected_result = { "period": 10, "type": "PERIODIC", "accesses": composition_yaml_setup.base_accesses, - }, - "AR_testName_SC_ZcCalibrationStep": { - "period": 0.1, - "type": "PERIODIC", - "accesses": composition_yaml_setup.base_accesses } }, "diagnostics": { diff --git a/tests/interface/test_interface_device_proxy.py b/tests/interface/test_interface_device_proxy.py index 9c0f305..aa22a03 100644 --- a/tests/interface/test_interface_device_proxy.py +++ b/tests/interface/test_interface_device_proxy.py @@ -226,7 +226,7 @@ class TestDPAL(unittest.TestCase): ] app = mock.MagicMock() app.get_domain_mapping.return_value = {"test": "test_domain"} - app.pybuild['build_cfg'].get_ecu_info.return_value = ("HI", None) + app.pybuild['build_cfg'].get_code_generation_config.return_value = True self.dummy_app = app self.maxDiff = None diff --git a/tests/powertrain_build/cnfg_files/ProjectCfg_CodeGenConfig.json b/tests/powertrain_build/cnfg_files/ProjectCfg_CodeGenConfig.json new file mode 100644 index 0000000..3f32da5 --- /dev/null +++ b/tests/powertrain_build/cnfg_files/ProjectCfg_CodeGenConfig.json @@ -0,0 +1,28 @@ +{ + "ConfigFileVersion": "0.0.1", + "BaseConfig": "./BaseConfig.json", + "ProjectInfo": { + "projConfig": "GEP3_BEV", + "a2LFileName": "VEA_VED4_SPA.a2l", + "baseNvmStructs": "nvm_structs_ref_empty.json", + "ecuSupplier": "dummy", + "ecuType": "dummy", + "unitCfgDeliveryDir": "../output/UnitCfgs", + "prjUnitCfgDir": "./cnfg_files/unit_cfgs/" + }, + "CodeGenerationConfig": { + "generateInterfaceHeaders": true, + "generateYamlInterfaceFile": true, + "useSwcNameAsPrefix": true + }, + "ProjectTemplates": { + "dummy": { + "generalAsilLevelDebug": "D", + "generalAsilLevelDependability": "D", + "generateInterfaceHeaders": false, + "generateYamlInterfaceFile": false, + "useSwcNameAsPrefix": false + } + }, + "UnitCfgs": "./rasters.json" +} \ No newline at end of file diff --git a/tests/powertrain_build/reference_files/vcc_nvm_structs_critical_bosch.a2l b/tests/powertrain_build/reference_files/vcc_nvm_structs_critical_bosch.a2l index fcfe5f2..544928e 100644 --- a/tests/powertrain_build/reference_files/vcc_nvm_structs_critical_bosch.a2l +++ b/tests/powertrain_build/reference_files/vcc_nvm_structs_critical_bosch.a2l @@ -1,6 +1,6 @@ /begin MEASUREMENT - sVcTest_t_UInt32 /* Name */ + nvm_list_critical1._sVcTest_t_UInt32 /* Name */ "Enter a nice description of your variable here" /* LongIdentifier */ ULONG /* Datatype */ VcNvm_2_1_0_s /* Conversion */ @@ -13,7 +13,7 @@ /end MEASUREMENT /begin MEASUREMENT - sVcTest_t_Int16 /* Name */ + nvm_list_critical1._sVcTest_t_Int16 /* Name */ "Enter a nice description of your variable here" /* LongIdentifier */ SWORD /* Datatype */ VcNvm_1_0_0_None /* Conversion */ @@ -26,7 +26,7 @@ /end MEASUREMENT /begin MEASUREMENT - sVcTest_t_UInt8 /* Name */ + nvm_list_critical1._sVcTest_t_UInt8 /* Name */ "Enter a nice description of your variable here" /* LongIdentifier */ UBYTE /* Datatype */ VcNvm_1_0_0_None /* Conversion */ diff --git a/tests/powertrain_build/test_a2l.py b/tests/powertrain_build/test_a2l.py index 2e83202..b31ac4b 100644 --- a/tests/powertrain_build/test_a2l.py +++ b/tests/powertrain_build/test_a2l.py @@ -366,7 +366,7 @@ class TestA2l(unittest.TestCase): def setUp(self): """Set-up common data structures for all tests in the test case.""" self.build_cfg = MagicMock(spec_set=BuildProjConfig) - self.build_cfg.get_ecu_info = MagicMock(return_value=('Denso', 'G2')) + self.build_cfg.get_code_generation_config = MagicMock(return_value=False) self.a2l = A2l(A2L_DATA, self.build_cfg) def test_init_a2l(self): diff --git a/tests/powertrain_build/test_build.py b/tests/powertrain_build/test_build.py index d90163e..4fbe374 100644 --- a/tests/powertrain_build/test_build.py +++ b/tests/powertrain_build/test_build.py @@ -9,6 +9,7 @@ import unittest from unittest.mock import MagicMock, patch, PropertyMock from pathlib import Path +from powertrain_build import build_defs from powertrain_build.lib import helper_functions from powertrain_build.problem_logger import ProblemLogger from powertrain_build.build_proj_config import BuildProjConfig @@ -209,7 +210,9 @@ class TestBuild(unittest.TestCase): remove(*files) with patch('powertrain_build.user_defined_types.UserDefinedTypes') as udt_mock: udt_mock.return_value.common_header_files = PropertyMock(return_value=[]) - build.generate_ext_var(self.build_cfg, self.unit_cfg, signal_if, udt_mock) + build.generate_ext_var( + self.build_cfg, self.unit_cfg, signal_if, udt_mock, build_defs.CVC_ASIL_B, build_defs.ASIL_B + ) signal_if.get_external_io.assert_called_once() self.build_cfg.get_src_code_dst_dir.assert_called() exists(*files) diff --git a/tests/powertrain_build/test_build_proj_configs.py b/tests/powertrain_build/test_build_proj_configs.py index 71043e9..dd3820e 100644 --- a/tests/powertrain_build/test_build_proj_configs.py +++ b/tests/powertrain_build/test_build_proj_configs.py @@ -30,3 +30,19 @@ class TestReadCodeSw(unittest.TestCase): result = self.build_prj_cfg.get_included_units() expected = ['VcScBCoord', 'VcScCVehMtn', 'VcScFeh', 'VcConst'] self.assertEqual(result, expected) + + def test_get_code_generation_config_default(self): + """Test build_proj_config._get_code_generation_config with not input.""" + expected = {'CodeGenerationConfig': self.build_prj_cfg._get_default_code_generation_config()} + self.assertDictEqual(self.build_prj_cfg._get_code_generation_config(), expected) + + def test_get_code_generation_config_project_template_and_custom(self): + """Test build_proj_config._get_code_generation_config with project template and custom changes.""" + self.build_prj_cfg = BuildProjConfig(str(Path(CNFG_DIR, 'ProjectCfg_CodeGenConfig.json'))) + expected = self.build_prj_cfg._get_default_code_generation_config() + expected['generalAsilLevelDebug'] = 'D' + expected['generalAsilLevelDependability'] = 'D' + expected['generateInterfaceHeaders'] = True + expected['generateYamlInterfaceFile'] = True + expected['useSwcNameAsPrefix'] = True + self.assertDictEqual(self.build_prj_cfg._prj_cfg['CodeGenerationConfig'], expected) diff --git a/tests/powertrain_build/test_memory_section.py b/tests/powertrain_build/test_memory_section.py index aa378e9..da69e4f 100644 --- a/tests/powertrain_build/test_memory_section.py +++ b/tests/powertrain_build/test_memory_section.py @@ -23,11 +23,29 @@ class TestMemorySection(TestCase): cnfg_files_folder = Path(SRC_DIR, 'cnfg_files') build_cfg = mock.MagicMock(spec_set=BuildProjConfig(Path(cnfg_files_folder, 'ProjectCfg.json'))) - build_cfg.get_a2l_cfg = mock.MagicMock(return_value={'name': 'MOCK_HI'}) - build_cfg.get_ecu_info = mock.MagicMock(return_value=('HI', 'dummy')) - build_cfg.get_swc_name = mock.MagicMock(return_value='MOCK_HI_SC') build_cfg.get_src_code_dst_dir = mock.MagicMock(return_value=self.src_code_dir) build_cfg.get_use_volatile_globals = mock.MagicMock(return_value=False) + build_cfg.get_memory_map_config = mock.MagicMock( + return_value={ + 'includeHeaderGuards': True, + 'includeMemMapForCalibration': False, + 'memMapPrefix': 'MOCK_HI', + 'projectDefines': { + "START": { + "code": "#define MOCK_HI_START_SEC_CODE", + "const": "#define MOCK_HI_START_SEC_CONST_UNSPECIFIED", + "disp": "#define MOCK_HI_START_SEC_VAR_INIT_UNSPECIFIED", + "cal": "#pragma section \".XcpCalibrationSection\"" + }, + "STOP": { + "code": "#define MOCK_HI_STOP_SEC_CODE", + "const": "#define MOCK_HI_STOP_SEC_CONST_UNSPECIFIED", + "disp": "#define MOCK_HI_STOP_SEC_VAR_INIT_UNSPECIFIED", + "cal": "#pragma section" + } + } + } + ) self.memory_section = MemorySection(build_cfg) def test_generate_cvc_header_cal(self): diff --git a/tests/powertrain_build/test_nvm_def.py b/tests/powertrain_build/test_nvm_def.py index ced5a24..75ee586 100644 --- a/tests/powertrain_build/test_nvm_def.py +++ b/tests/powertrain_build/test_nvm_def.py @@ -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_ecu_info = MagicMock(return_value=('Denso', 'G2')) self.proj_cnfg.get_swc_name = 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) self.small_nvm_struct = { @@ -466,7 +466,6 @@ 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_ecu_info = MagicMock(return_value=('Bosch', '')) self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { @@ -530,7 +529,6 @@ 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_ecu_info = MagicMock(return_value=('Bosch', '')) self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { @@ -594,7 +592,7 @@ class TestNVMDef(unittest.TestCase): def test_add_signal_with_nondefault_type_a2l_bosch(self): """Test that we can add different types of signals to critical area - a2l-file """ - self.proj_cnfg.get_ecu_info = MagicMock(return_value=('Bosch', '')) + self.proj_cnfg.get_code_generation_config = MagicMock(return_value=False) self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { @@ -664,7 +662,6 @@ class TestNVMDef(unittest.TestCase): Note: Denso does not have any area like this at the time of writing this test """ - self.proj_cnfg.get_ecu_info = MagicMock(return_value=('Denso', 'G2')) self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical) nvm_vars_test = { 'sVcTest_t_UInt32': { diff --git a/tests/zone_controller/test_composition_yaml.py b/tests/zone_controller/test_composition_yaml.py index 5d24ab4..8e140e4 100644 --- a/tests/zone_controller/test_composition_yaml.py +++ b/tests/zone_controller/test_composition_yaml.py @@ -35,8 +35,6 @@ class BuildProjConfigMock(BuildProjConfig): class TestCompositionYaml(unittest.TestCase): """Test case for testing composition_yaml.""" - maxDiff = None - def setUp(self): """Set-up common data structures for all tests in the test case.""" self.build_cfg = MagicMock(spec_set=BuildProjConfigMock) @@ -51,7 +49,9 @@ class TestCompositionYaml(unittest.TestCase): ) 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_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) self.unit_cfg.get_per_cfg_unit_cfg.return_value = copy.deepcopy( @@ -77,14 +77,6 @@ class TestCompositionYaml(unittest.TestCase): self.build_cfg, self.zc_spec, self.unit_cfg, self.zc_core, self.zc_dids, {} ) - # Common expected results variables - self.base_configuration = copy.deepcopy(composition_yaml_setup.base_configuration) - self.base_port_interfaces = copy.deepcopy(composition_yaml_setup.base_port_interfaces) - self.base_accesses = copy.deepcopy(composition_yaml_setup.base_accesses) - self.base_shared = copy.deepcopy(composition_yaml_setup.base_shared) - self.base_static = copy.deepcopy(composition_yaml_setup.base_static) - self.base_data_types = copy.deepcopy(composition_yaml_setup.base_data_types) - def test_check_unsupported_fields(self): """Test CompositionYaml.check_unsupported_fields.""" self.composition_yaml.warning = MagicMock() @@ -107,6 +99,21 @@ class TestCompositionYaml(unittest.TestCase): result = self.composition_yaml.gather_yaml_info() self.assertDictEqual(composition_yaml.expected_result, result) + def test_composition_yaml_with_calibration(self): + """Checking that the dict is generated correctly including calibration data, + setting generateCalibrationInterfaceFiles to true (sort of).""" + self.build_cfg.get_code_generation_config = MagicMock(return_value=True) + with patch.object( + CompositionYaml, + "_get_all_calibration_definitions", + return_value=self.calibration_definitions + ): + self.composition_yaml = CompositionYaml( + self.build_cfg, self.zc_spec, self.unit_cfg, self.zc_core, self.zc_dids, {} + ) + result = self.composition_yaml.gather_yaml_info() + self.assertDictEqual(composition_yaml.expected_cal_result, result) + def test_composition_yaml_with_a2l_axis_data(self): """Checking that the dict is generated correctly, including a2l axis data.""" self.unit_cfg.get_per_cfg_unit_cfg.return_value = \