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 = \