Merge "Updates to be able to generate NVM RTE function calls"

This commit is contained in:
Zuul 2024-11-07 09:48:26 +00:00 committed by Gerrit Code Review
commit bf352ef7e1
14 changed files with 536 additions and 615 deletions

View File

@ -31,7 +31,7 @@ from powertrain_build.ext_var import ExtVarCsv, ExtVarYaml
from powertrain_build.feature_configs import FeatureConfigs
from powertrain_build.lib.helper_functions import get_repo_root, merge_dicts
from powertrain_build.memory_section import MemorySection
from powertrain_build.nvm_def import NVMDef
from powertrain_build.nvm_def import NVMDef, ZCNVMDef
from powertrain_build.problem_logger import ProblemLogger
from powertrain_build.replace_compu_tab_ref import replace_tab_verb
from powertrain_build.sched_funcs import SchedFuncs
@ -373,7 +373,7 @@ def generate_dummy_var(build_cfg, unit_cfg, signal_if, udt):
LOG.info("Finished generating VcDummy (in %4.2f s)", time.time() - start_time)
def generate_nvm_def(nvm_def, no_nvm_a2l):
def generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l):
"""Generate the c&h-files which declares the NVM-ram.
The NVM-ram is declared in a struct per datatype length, in order
@ -382,12 +382,15 @@ def generate_nvm_def(nvm_def, no_nvm_a2l):
created to minimize the needed model changes for access to the memory.
Args:
nvm_def (NVMDef): Class holding the NVM definitions for the build.
build_cfg (BuildProjConfig): Build project class holding where files should be stored.
unit_cfg (UnitConfigs): class holding units definitions, and which units to include.
no_nvm_a2l (bool): Do not generate A2L for NVM structs.
"""
LOG.info("******************************************************")
LOG.info("Start generating NVMDefinitions")
start_time = time.time()
tot_vars_nvm = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {})
nvm_def = NVMDef(build_cfg, unit_cfg, tot_vars_nvm)
nvm_def.generate_nvm_config_files(no_nvm_a2l)
LOG.info(
"Finished generating NVMDefinitions (in %4.2f s)", time.time() - start_time
@ -774,10 +777,6 @@ def build(
udt = UserDefinedTypes(build_cfg, unit_cfg)
udt.generate_common_header_files()
tot_vars_nvm = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {})
nvm_def = NVMDef(build_cfg, unit_cfg, tot_vars_nvm)
generate_nvm_def(nvm_def, no_nvm_a2l)
start_time = time.time()
cnf_header = pjoin(src_dst_dir, build_cfg.get_feature_conf_header_name())
LOG.info("******************************************************")
@ -901,9 +900,11 @@ def build(
if code_generation_config["generateYamlInterfaceFile"]:
zc_core = ZCCore(build_cfg, unit_cfg)
zc_dids = ZCDIDs(build_cfg, unit_cfg)
project_nvm_defintions = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {})
zc_nvm = ZCNVMDef(build_cfg, unit_cfg, project_nvm_defintions)
axis_data = merged_a2l.get_characteristic_axis_data()
composition_yaml = CompositionYaml(
build_cfg, signal_if.composition_spec, unit_cfg, zc_core, zc_dids, nvm_def, axis_data
build_cfg, signal_if.composition_spec, unit_cfg, zc_core, zc_dids, zc_nvm, axis_data
)
LOG.info("******************************************************")
composition_yaml.generate_yaml()
@ -913,6 +914,9 @@ def build(
LOG.info("******************************************************")
LOG.info("Generating DID files")
zc_dids.generate_did_files()
LOG.info("******************************************************")
LOG.info("Start generating NVMDefinitions")
zc_nvm.generate_nvm_rte_files()
if code_generation_config["generateCalibrationInterfaceFiles"]:
LOG.info("******************************************************")
@ -922,6 +926,7 @@ def build(
)
zc_calibration.generate_calibration_interface_files()
elif build_cfg.get_ecu_info()[0] == "HI":
generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l)
LOG.info("******************************************************")
LOG.info("Generating Core header")
hi_core = HICore(build_cfg, unit_cfg)
@ -931,6 +936,7 @@ def build(
dids = HIDIDs(build_cfg, unit_cfg)
dids.generate_did_files()
else:
generate_nvm_def(build_cfg, unit_cfg, no_nvm_a2l)
generate_did_files(build_cfg, unit_cfg)
# generate core dummy files if requested
if core_dummy:

View File

@ -250,7 +250,7 @@ class BuildProjConfig:
def _parse_composition_config(self, file_config):
"""Parse the composition configuration from project config."""
a2lname = f"{self.get_a2l_cfg()['name']}_SC"
self._composition_config = {
composition_config = {
'compositionName': None,
'compositionEnding': 'yml',
'compositionArxml': file_config.get("compositionArxml", None),
@ -264,13 +264,14 @@ class BuildProjConfig:
'includeShared': file_config.get('includeShared', True),
'includeDiagnostics': file_config.get('includeDiagnostics', True),
'includeNvm': file_config.get('includeNvm', True),
'nvmPortPattern': file_config.get('nvmPortPattern', None),
}
compositionName = file_config.get("compositionName", None)
if compositionName is not None:
self._composition_config["compositionName"] = compositionName.split(".")[0]
if "." in compositionName:
self._composition_config["compositionEnding"] = compositionName.split(".")[1]
return self._composition_config
composition_name = file_config.get("compositionName", None)
if composition_name is not None:
composition_config["compositionName"] = composition_name.split(".")[0]
if "." in composition_name:
composition_config["compositionEnding"] = composition_name.split(".")[1]
return composition_config
def get_composition_config(self, key=None):
"""Get the composition configuration from project config."""

View File

@ -104,6 +104,15 @@ class MemorySection(ProblemLogger):
]
return cvc_undefines, cvc_defines, memory_section_handling
def _get_nvm(self, section):
cvc_undefines = []
cvc_defines = []
memory_section_handling = [
self.mem_map_config['projectDefines'][self._get_mem_map_section(section)]['nvm'] + '\n',
self.mem_map_include
]
return cvc_undefines, cvc_defines, memory_section_handling
def _get_rest(self):
cvc_undefines = []
cvc_defines = []
@ -174,11 +183,16 @@ class MemorySection(ProblemLogger):
with Path(src_dst_dir, section_file).open('w', encoding="utf-8") as header_file_handler:
header_file_handler.writelines(lines_to_write)
for nvm_dict in build_defs.NVM_LEVEL_MAP.values():
for nvm_type, nvm_dict in build_defs.NVM_LEVEL_MAP.items():
for section_dict in nvm_dict.values():
for section_file in section_dict.values():
for section, section_file in section_dict.items():
section_config = self.mem_map_config['projectDefines'][self._get_mem_map_section(section)]
if nvm_type == "NORMAL" and "nvm" in section_config:
lines_to_write = self._get_nvm(section)[2]
else:
lines_to_write = []
header = self._get_header(section_file) if self.include_header_guards else []
footer = self._get_footer(section_file) if self.include_header_guards else []
with Path(src_dst_dir, section_file).open('w', encoding="utf-8") as header_file_handler:
header_file_handler.writelines(header + footer)
header_file_handler.writelines(header + lines_to_write + footer)
self.info('Finished generating required header files (in %4.2f s)', time.time() - start_time)

View File

@ -6,6 +6,7 @@
import re
import os
import json
from copy import deepcopy
import powertrain_build.build_defs as bd
from powertrain_build.types import byte_size, get_bitmask
@ -57,6 +58,10 @@ class NVMDef(ProblemLogger):
self._area_section = {}
self._mem_area_pragmas = tuple()
self._nvm_header_head = self._get_nvm_header_head(unit_cfg)
src_file_dst = self._project_config.get_src_code_dst_dir()
self._file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"])
self._predecl_start = bd.PREDECL_START
self._predecl_end = bd.PREDECL_END
with open(
os.path.join(project_config.get_root_dir(), self._nvm_defs["baseNvmStructs"]), "r", encoding="utf-8"
@ -430,8 +435,6 @@ class NVMDef(ProblemLogger):
def _generate_nvm_structs_updated(self):
self.info("Start generating updated nvm json file")
self._update_nvm_base_struct()
nvm_structs_updated_path = os.path.abspath(
os.path.join(self._project_config.get_root_dir(), "output", "nvm_structs_updated.json")
)
@ -495,21 +498,19 @@ class NVMDef(ProblemLogger):
hptr.write(f'#include "{section}_END.h"\n\n')
def write_extern():
hptr.write(f'#include "{bd.PREDECL_START}"\n')
hptr.write(f'#include "{self._predecl_start}"\n')
for area in self._nvm_memory_areas:
hptr.write(f"extern struct {prefix}{area.upper()} {prefix.lower()}{area.lower()};\n")
hptr.write(f'#include "{bd.PREDECL_END}"\n\n')
hptr.write(f'#include "{self._predecl_end}"\n\n')
def write_defines():
hptr.write("\n")
for var, define in defines:
hptr.write(f"#define {var:40} {define}\n")
src_file_dst = self._project_config.get_src_code_dst_dir()
file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"])
defines = []
with open(file_name + ".h", "w", encoding="utf-8") as hptr:
with open(self._file_name + ".h", "w", encoding="utf-8") as hptr:
hptr.write(self._nvm_header_head)
write_signals()
write_extern()
@ -524,9 +525,7 @@ class NVMDef(ProblemLogger):
# TODO: Add memory from previous builds!!! and mark old positions #
self.info("Start generating nvm source file")
prefix = self._project_config.get_scheduler_prefix()
src_file_dst = self._project_config.get_src_code_dst_dir()
file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"])
with open(file_name + ".c", "w", encoding="utf-8") as cptr:
with open(self._file_name + ".c", "w", encoding="utf-8") as cptr:
cptr.write(f'#include "{self._nvm_defs["fileName"]}.h"\n\n')
for area, pragma in zip(self._nvm_memory_areas, self._mem_area_pragmas):
cptr.write(f'#include "{pragma[0]}"\n')
@ -536,12 +535,9 @@ class NVMDef(ProblemLogger):
def _generate_nvm_config_a2l(self):
"""Generate the a2l-file describing the NVM definition."""
self.info("Start generating nvm a2l file")
src_file_dst = self._project_config.get_src_code_dst_dir()
file_name = os.path.join(src_file_dst, self._nvm_defs["fileName"])
a2l_dict = self._a2l_dict()
a2l = A2l(a2l_dict, self._project_config)
a2l.gen_a2l(file_name + ".a2l")
a2l.gen_a2l(self._file_name + ".a2l")
def generate_nvm_config_files(self, no_nvm_a2l):
"""Generate all files for variables in the NVM definition.
@ -549,6 +545,7 @@ class NVMDef(ProblemLogger):
Args:
no_nvm_a2l (bool): Do not generate a2l file.
"""
self._update_nvm_base_struct()
self._generate_nvm_structs_updated()
self._generate_nvm_config_headers()
self._generate_nvm_config_source()
@ -558,3 +555,124 @@ class NVMDef(ProblemLogger):
@staticmethod
def _get_signal_list(signals):
return signals if isinstance(signals, list) else [signals]
class ZCNVMDef(NVMDef):
"""A class for handling of ZC NVM definitions."""
def __init__(self, project_config, unit_cfg, nvm_vars):
"""Init.
Args:
project_config (BuildProjConfig): current project configuration.
unit_cfg (UnitConfigs): Unit configurations.
nvm_vars (dict): NVM variables from unit configurations.
"""
super().__init__(project_config, unit_cfg, nvm_vars)
self._valid_nvm_definitions = None
self._update_nvm_base_struct()
prefix = self._project_config.get_scheduler_prefix()
self.project_nvm_definitions = {
f"{prefix}{item['name']}": item for item in self.nvm_definitions
}
self._predecl_start = bd.PREDECL_NVM_START
self._predecl_end = bd.PREDECL_NVM_END
self.init_function = "void VcNvmInit(void)"
self.main_function = "void VcNvm(void)"
@property
def valid_nvm_definitions(self):
"""Get the valid NVM definitions."""
return self._valid_nvm_definitions
@valid_nvm_definitions.setter
def valid_nvm_definitions(self, yaml_nvm_definitions):
"""Return a set of NVM definitions appearing in both the project and the project yaml file.
Args:
yaml_nvm_definitions (dict): NVM lists listed in the NVM configuration yaml file.
Returns:
valid_nvm_definitions (dict): Validated NVM definitions,
listed in both NVM configuration yaml file as well as project.
"""
local_yaml_nvm_definitions = deepcopy(yaml_nvm_definitions)
nvms_not_in_project = set(local_yaml_nvm_definitions.keys()) - set(self.project_nvm_definitions.keys())
nvms_not_in_yaml = set(self.project_nvm_definitions.keys()) - set(local_yaml_nvm_definitions.keys())
for key in nvms_not_in_project:
self.warning(f'Ignoring NVM definition {key} since it does not appear in nvm_structs.json.')
del local_yaml_nvm_definitions[key]
for key in nvms_not_in_yaml:
self.warning(f'Ignoring NVM definition {key} since it does not appear in the project NVM yaml file.')
self._valid_nvm_definitions = local_yaml_nvm_definitions
def _update_header_and_footer(self):
name = self._project_config.get_composition_config("softwareComponentName")
self._nvm_header_head += f'#include "Rte_{name}.h"\n'
self._nvm_header_footer = (
"\n"
f'#include "{bd.PREDECL_CODE_ASIL_D_START}"\n'
f"{self.init_function};\n"
f"{self.main_function};\n"
f'#include "{bd.PREDECL_CODE_ASIL_D_END}"\n'
f"{self._nvm_header_footer}"
)
def _append_nvm_rte_function_calls(self):
"""Append the NVM RTE function calls to the NVM config source file."""
nvm_port_pattern = self._project_config.get_composition_config("nvmPortPattern")
if self.valid_nvm_definitions and nvm_port_pattern is None:
self.critical("NVM port pattern not defined in ProjectCfg.json. Cannot add NVM RTE function calls.")
return
init_function_lines = [
f'#include "{bd.CVC_CODE_ASIL_D_START}"\n'
f"{self.init_function} {{\n",
" //Call this function in the SWC init runnable\n"
]
main_function_lines = [
f'#include "{bd.CVC_CODE_ASIL_D_START}"\n'
f"{self.main_function} {{\n",
" //Call this function in the SWC main runnable\n",
" UInt8 errorStatus = 0;\n",
]
footer = [
"}\n",
f'#include "{bd.CVC_CODE_ASIL_D_END}"\n',
]
for nvm_name, nvm_data in self.valid_nvm_definitions.items():
pim_call = f"Rte_Pim_{nvm_name}()"
function_prefix = f"Rte_Call_{nvm_port_pattern.format(NvName=nvm_name)}"
main_function_lines.append(f" *{pim_call} = {nvm_name.lower()};\n")
if nvm_data["type"] == "type1":
init_function_lines.append(f" {function_prefix}_SetRamBlockStatus(TRUE);\n")
elif nvm_data["type"] == "type2":
main_function_lines.extend([
f" {function_prefix}_GetErrorStatus(&errorStatus);\n",
" if (errorStatus == 0) {\n",
f" {function_prefix}_WriteBlock({pim_call});\n",
" }\n",
])
else:
self.critical(f"Unknown NVM type: {nvm_data['type']} for NVM: {nvm_name}")
with open(self._file_name + ".c", mode="a", encoding="utf-8") as cptr:
cptr.writelines(init_function_lines + footer + ["\n"] + main_function_lines + footer)
def generate_nvm_rte_files(self):
"""Generate the NVM RTE files."""
if self.valid_nvm_definitions is None:
self.critical('Valid NVM definitions not set. Cannot generate NVM RTE files.')
return
self._update_header_and_footer()
old_nvm_memory_areas = self._nvm_memory_areas
prefix = self._project_config.get_scheduler_prefix()
self._nvm_memory_areas = tuple(area.replace(f"{prefix}", "") for area in self.valid_nvm_definitions.keys())
self._generate_nvm_structs_updated()
self._generate_nvm_config_headers()
self._generate_nvm_config_source()
self._append_nvm_rte_function_calls()
self._nvm_memory_areas = old_nvm_memory_areas

View File

@ -15,7 +15,7 @@ from powertrain_build.zone_controller.calibration import ZoneControllerCalibrati
class CompositionYaml(ProblemLogger):
"""Class for handling ZoneController composition yaml generation."""
def __init__(self, build_cfg, composition_spec, unit_cfg, zc_core, zc_dids, nvm_def, a2l_axis_data):
def __init__(self, build_cfg, composition_spec, unit_cfg, zc_core, zc_dids, zc_nvm, a2l_axis_data):
"""Init.
Args:
@ -24,7 +24,7 @@ class CompositionYaml(ProblemLogger):
unit_cfg (UnitConfig): Object with unit configurations.
zc_core (ZCCore): Object with zone controller diagnositic event information.
zc_dids (ZCDIDs): Object with zone controller diagnostic DID information.
nvm_def (NVMDef): Object with NVM definition information.
zc_nvm (ZCNVMDef): Object with NVM definition information.
a2l_axis_data (dict): Dict with characteristic axis data from A2L file.
"""
self.tl_to_autosar_base_types = {
@ -43,7 +43,7 @@ class CompositionYaml(ProblemLogger):
self.unit_cfg = unit_cfg
self.zc_core = zc_core
self.zc_dids = zc_dids
self.nvm_def = nvm_def
self.zc_nvm = zc_nvm
self.a2l_axis_data = a2l_axis_data
base_data_types = self.get_base_data_types() # Might not be necessary in the long run
self.data_types = {
@ -303,6 +303,7 @@ class CompositionYaml(ProblemLogger):
def _get_diagnostic_info(self):
"""Get diagnostic information from composition spec.
NOTE: This function sets the valid_dids property of the ZCDIDs object.
Returns:
@ -326,43 +327,34 @@ class CompositionYaml(ProblemLogger):
def _get_nvm_info(self):
"""Creates a dict with NVM information.
NVM dicts also needs to be added to the "static" field in the generated yaml.
NOTE: This function sets the valid_nvm_definitions property of the ZCNVMDef object.
Returns:
nvm_dict (dict): Dict containing NVM information.
data_types (dict): Dict containing data types for NVM information.
static_variables (dict): Dict containing "static" variables to add to the "static" field.
"""
prefix = self.build_cfg.get_scheduler_prefix()
yaml_nvm_definitions = self.composition_spec.get("nv-needs", {})
project_nvm_definitions = {
f"{prefix}{item['name']}": item for item in self.nvm_def.nvm_definitions
}
nvms_not_in_project = set(yaml_nvm_definitions.keys()) - set(project_nvm_definitions.keys())
nvms_not_in_yaml = set(project_nvm_definitions.keys()) - set(yaml_nvm_definitions.keys())
for key in nvms_not_in_project:
self.warning(f'Ignoring NVM definition {key} since it does not appear in nvm_structs.json.')
del yaml_nvm_definitions[key]
for key in nvms_not_in_yaml:
self.warning(f'Ignoring NVM definition {key} since it does not appear in the project NVM yaml file.')
data_types = {}
for nvm_name, nvm_data in yaml_nvm_definitions.items():
data_type_name = f"dt_{nvm_name}"
nr_of_unused_signals = project_nvm_definitions[nvm_name]["size"]
static_variables = {}
yaml_nvm_definitions = self.composition_spec.get("nv-needs", {})
self.zc_nvm.valid_nvm_definitions = yaml_nvm_definitions
nvm_dict = self.zc_nvm.valid_nvm_definitions
nvm_data.update({
"datatype": data_type_name,
"init": []
})
data_types[data_type_name] = {
"type": "RECORD",
"elements": {},
}
for signal in project_nvm_definitions[nvm_name]["signals"]:
for nvm_name, nvm_data in nvm_dict.items():
init = []
nr_of_unused_signals = self.zc_nvm.project_nvm_definitions[nvm_name]["size"]
data_type_name = f"dt_{nvm_name}"
data_types[data_type_name] = {"type": "RECORD", "elements": {}}
for signal in self.zc_nvm.project_nvm_definitions[nvm_name]["signals"]:
nr_of_unused_signals -= signal["x_size"] * signal["y_size"]
size = max(signal["x_size"], 1) * max(signal["y_size"], 1)
if size > 1:
x_data_type_name = f"dt_{signal['name']}_x"
y_data_type_name = f"dt_{signal['name']}_y"
if signal["x_size"] > 1 and signal["y_size"] == 1:
nvm_data["init"].append([0] * signal["x_size"])
init.append([0] * signal["x_size"])
data_types[data_type_name]["elements"][signal["name"]] = x_data_type_name
data_types[x_data_type_name] = {
"type": "ARRAY",
@ -370,7 +362,7 @@ class CompositionYaml(ProblemLogger):
"element": signal["type"],
}
elif signal["x_size"] > 1 and signal["y_size"] > 1:
nvm_data["init"].append([[0] * signal["y_size"]] * signal["x_size"])
init.append([[0] * signal["y_size"]] * signal["x_size"])
data_types[data_type_name]["elements"][signal["name"]] = y_data_type_name
data_types[y_data_type_name] = {
"type": "ARRAY",
@ -385,19 +377,29 @@ class CompositionYaml(ProblemLogger):
else:
self.critical("NVM signal size incorrect. x_size should not be 1 if y_size > 1.")
else:
nvm_data["init"].append(0)
init.append(0)
data_types[data_type_name]["elements"][signal["name"]] = signal["type"]
nvm_data.update({
"datatype": data_type_name,
"init": init
})
static_variables[nvm_name.lower()] = {
"type": data_type_name,
"access": "READ-ONLY",
"init": init,
}
if nr_of_unused_signals > 0:
nvm_data["init"].append([0] * nr_of_unused_signals)
data_types[data_type_name]["elements"]["unused"] = f"{data_type_name}_Unused"
data_types[f"{data_type_name}_Unused"] = {
"type": "ARRAY",
"size": nr_of_unused_signals,
"element": project_nvm_definitions[nvm_name]["default_datatype"],
"element": self.zc_nvm.project_nvm_definitions[nvm_name]["default_datatype"],
}
return yaml_nvm_definitions, data_types
return nvm_dict, data_types, static_variables
def _get_ports_info(self):
"""Creates a dict containing port information.
@ -507,10 +509,12 @@ class CompositionYaml(ProblemLogger):
diagnostic_info = self._get_diagnostic_info()
if self.build_cfg.get_composition_config("includeDiagnostics"):
swcs[software_component_name]["diagnostics"] = diagnostic_info
nvm_info, nvm_data_types_tmp = self._get_nvm_info()
nvm_info, nvm_data_types_tmp, static_variables = self._get_nvm_info()
if self.build_cfg.get_composition_config("includeNvm"):
swcs[software_component_name]["nv-needs"] = nvm_info
nvm_data_types = nvm_data_types_tmp
if self.build_cfg.get_composition_config("includeStatic"):
swcs[software_component_name]["static"].update(static_variables)
else:
nvm_data_types = {}

View File

@ -0,0 +1,172 @@
# Copyright 2024 Volvo Car Corporation
# Licensed under Apache 2.0.
"""Unit test data for powertrain_build.nvm_def."""
nvm_vars_test = {
'sVcAcCtrl_t_CmprRunTiNVM': {
'VcAcCtrl': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice description of your variable here',
'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/'
'3_SystemInfo/36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAcCtrl_t_CmprRunTiNVM',
'offset': 0,
'type': 'UInt32',
'unit': '-',
'width': 1}},
'sVcAesHw_X_VntAdpnOffs': {
'VcAesVnt': {
'class': 'CVC_DISP_NVM',
'configs': ['Vc_Aes_Vnt_B_CodeGenVntGvnr '
'== 0'],
'description': 'Enter a nice '
'description of your '
'variable here',
'handle': 'VcAesVnt/VcAesVnt/Subsystem/VcAesVnt/VcAesVnt/1_Vnt/11_VntGvnr/'
'111_VntGvnrExe/1111_VntGvnrFct/11112_VntAdpn/sVcAesHw_X_VntAdpnOffs/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesHw_X_VntAdpnOffs',
'offset': 0,
'type': 'Float32',
'unit': '-',
'width': 1
}
},
'sVcAesMo_Ar_ArrayTest': {
'VcAesMoAdp': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice '
'description of your '
'variable here',
'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/'
'2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesMo_Ar_NvmThrAdpn',
'offset': 0,
'type': 'Float32',
'unit': '-',
'width': [4, 2]
}
},
'sVcAesMo_Ar_NvmThrAdpn': {
'VcAesMoAdp': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice '
'description of your '
'variable here',
'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/'
'2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesMo_Ar_NvmThrAdpn',
'offset': 0,
'type': 'Float32',
'unit': '-',
'width': 1
}
},
'sVcAesMo_rt_NvmMafLrngLd1Ne1': {
'VcAesMfl': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice '
'description of '
'your variable '
'here',
'handle': 'VcAesMfl/VcAesMfl/Subsystem/VcAesMfl/VcAesMfl/4_Nvm/41_Ld1Ne1/'
'sVcAesMo_rt_NvmMafLrngLd1Ne1/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesMo_rt_NvmMafLrngLd1Ne1',
'offset': 0,
'type': 'Bool',
'unit': '-',
'width': 1
}
},
'sVcAcCtrl_t_Test1': {
'VcAcCtrl': {
'class': 'CVC_DISP_NVM_P',
'configs': ['all'],
'description': 'Enter a nice description of your variable here',
'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/'
'36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAcCtrl_t_Test1',
'offset': 0,
'type': 'UInt32',
'unit': '-',
'width': 1
},
'VcAcCtrl2': {
'class': 'CVC_DISP_NVM_P',
'configs': ['all'],
'description': 'Enter a nice description of your variable here',
'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/'
'36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAcCtrl_t_Test1',
'offset': 0,
'type': 'UInt32',
'unit': '-',
'width': 1
}
}
}
nvm_configs_single = {
"fileName": "vcc_nvm_struct_single",
"baseNvmStructs": "nvm_structs_ref_single_signal.json"
}
nvm_configs = {
"fileName": "vcc_nvm_struct",
"baseNvmStructs": "nvm_structs_ref_empty.json"
}
nvm_configs_small = {
"fileName": "vcc_nvm_structs__small",
"baseNvmStructs": "nvm_structs_ref_small.json"
}
nvm_configs_empty_small = {
"fileName": "vcc_nvm_structs_empty_small",
"baseNvmStructs": "nvm_structs_ref_empty_small.json"
}
nvm_configs_signal_overwritten = {
"fileName": "vcc_nvm_structs_ref_used_positions",
"baseNvmStructs": "nvm_structs_ref_used_positions.json"
}
nvm_configs_critical = {
"fileName": "vcc_nvm_structs_critical",
"baseNvmStructs": "nvm_structs_ref_critical.json"
}
nvm_configs_critical_remove = {
"fileName": "vcc_nvm_struct_critical_remove",
"baseNvmStructs": "nvm_structs_ref_critical.json"
}
nvm_configs_wrong_type = {
"fileName": "vcc_nvm_structs_ref_used_positions",
"baseNvmStructs": "nvm_structs_ref_wrong_type.json"
}

View File

@ -0,0 +1,55 @@
# Copyright 2024 Volvo Car Corporation
# Licensed under Apache 2.0.
"""Unit test data for powertrain_build.nvm_def.ZCNVMDef."""
yaml_nvm_definitions = {
"NVM_LIST_8": {
"type": "type1",
"method": "DIRECT-CALL",
"runnables": ["Dummy"],
"attributes": {
"resistant-to-change": True,
"random-attribute": "Dummy",
},
},
"NVM_LIST_16": {
"type": "type2",
"method": "DIRECT-CALL",
"runnables": ["Dummy"],
"attributes": {
"resistant-to-change": True,
"random-attribute": "Dummy",
},
},
}
yaml_nvm_definitions_one_not_in_project = {
"NVM_LIST_8": {
"type": "type1",
"method": "DIRECT-CALL",
"runnables": ["Dummy"],
"attributes": {
"resistant-to-change": True,
"random-attribute": "Dummy",
},
},
"NVM_LIST_16": {
"type": "type2",
"method": "DIRECT-CALL",
"runnables": ["Dummy"],
"attributes": {
"resistant-to-change": True,
"random-attribute": "Dummy",
},
},
"NVM_LIST_NOT_IN_PROJECT": {
"type": "type1",
"method": "DIRECT-CALL",
"runnables": ["Dummy"],
"attributes": {
"resistant-to-change": True,
"random-attribute": "Dummy",
},
},
}

View File

@ -101,6 +101,14 @@ additional_data_types = {
},
}
additional_static = {
"prefix_nvm_list_8": {
"type": "dt_prefix_NVM_LIST_8",
"access": "READ-ONLY",
"init": [0, [0, 0], [[0, 0], [0, 0]], [0]],
},
}
expected_result = {
"SoftwareComponents": {
"testName_SC": {
@ -132,7 +140,10 @@ expected_result = {
},
},
},
"static": composition_yaml_setup.base_static,
"static": {
**composition_yaml_setup.base_static,
**additional_static,
},
"shared": composition_yaml_setup.base_shared,
"ports": {
"GlobSignNme": {"direction": "IN", "interface": "PIGlobSignNme"}

View File

@ -1,87 +0,0 @@
[
{
"signals": [
{
"x_size": 1,
"type": "UInt32",
"name": "sVcTest_t_UInt32",
"y_size": 1
}
],
"name": "NVM_LIST_32",
"default_datatype": "UInt32",
"instanceName": "nvm_list_32",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": false,
"allowed_datatypes": [
"Float32",
"UInt32",
"Int32"
]
},
{
"signals": [
{
"x_size": 1,
"type": "UInt32",
"name": "sVcTest_t_UInt32",
"y_size": 1
},
{
"x_size": 1,
"type": "Int16",
"name": "sVcTest_t_Int16",
"y_size": 1
},
{
"x_size": 1,
"type": "UInt8",
"name": "sVcTest_t_UInt8",
"y_size": 1
}
],
"name": "NVM_LIST_CRITICAL1",
"default_datatype": "UInt16",
"instanceName": "nvm_list_critical1",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": false,
"allowed_datatypes": ["NotApplicable"]
},
{
"signals": [
{
"x_size": 1,
"type": "Int16",
"name": "sVcTest_t_Int16",
"y_size": 1
}
],
"name": "NVM_LIST_16",
"default_datatype": "UInt16",
"instanceName": "nvm_list_16",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": false,
"allowed_datatypes": [
"UInt16",
"Int16"
]
},
{
"signals": [
],
"name": "NVM_LIST_8",
"default_datatype": "UInt8",
"instanceName": "nvm_list_8",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": false,
"allowed_datatypes": ["should_be_empty"]
}
]

View File

@ -1,109 +0,0 @@
[
{
"signals": [
{
"x_size": 1,
"type": "UInt8",
"name": "sVcDclOil_D_BadDcysMEM",
"y_size": 1
},
{
"x_size": 1,
"type": "UInt8",
"name": "sVcDclEem_D_MvBattChrReqCarModTrp",
"y_size": 1
},
{
"x_size": 5,
"type": "UInt8",
"name": "VcDclEem_D_LvBattChrReqDenial",
"y_size": 1
}
],
"name": "NVM_LIST_8",
"default_datatype": "UInt8",
"instanceName": "nvm_list_8",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": false,
"allowed_datatypes": [
"Bool",
"UInt8",
"Int8"
]
},
{
"signals": [],
"name": "NVM_LIST_16",
"default_datatype": "UInt16",
"instanceName": "nvm_list_16",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 240,
"persistent": false,
"allowed_datatypes": [
"UInt16",
"Int16"
]
},
{
"signals": [],
"name": "NVM_LIST_32",
"default_datatype": "UInt32",
"instanceName": "nvm_list_32",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 975,
"persistent": false,
"allowed_datatypes": [
"Float32",
"UInt32",
"Int32"
]
},
{
"signals": [],
"name": "NVM_LIST_8_PER",
"default_datatype": "UInt8",
"instanceName": "nvm_list_8_per",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": true,
"allowed_datatypes": [
"Bool",
"UInt8",
"Int8"
]
},
{
"signals": [],
"name": "NVM_LIST_16_PER",
"default_datatype": "UInt16",
"instanceName": "nvm_list_16_per",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 240,
"persistent": true,
"allowed_datatypes": [
"UInt16",
"Int16"
]
},
{
"signals": [],
"name": "NVM_LIST_32_PER",
"default_datatype": "UInt32",
"instanceName": "nvm_list_32_per",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 190,
"persistent": true,
"allowed_datatypes": [
"Float32",
"UInt32",
"Int32"
]
}
]

View File

@ -1,147 +0,0 @@
[
{
"signals": [
{
"x_size": 1,
"type": "UInt8",
"name": "sVcDclOil_D_BadDcysMEM",
"y_size": 1
},
{
"x_size": 1,
"type": "UInt8",
"name": "sVcDclEem_D_MvBattChrReqCarModTrp",
"y_size": 1
},
{
"x_size": 5,
"type": "UInt8",
"name": "VcDclEem_D_LvBattChrReqDenial",
"y_size": 1
},
{
"x_size": 1,
"type": "Bool",
"name": "sVcAesMo_rt_NvmMafLrngLd1Ne1",
"y_size": 1
}
],
"name": "NVM_LIST_8",
"default_datatype": "UInt8",
"instanceName": "nvm_list_8",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": false,
"allowed_datatypes": [
"Bool",
"UInt8",
"Int8"
]
},
{
"signals": [],
"name": "NVM_LIST_16",
"default_datatype": "UInt16",
"instanceName": "nvm_list_16",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 240,
"persistent": false,
"allowed_datatypes": [
"UInt16",
"Int16"
]
},
{
"signals": [
{
"name": "sVcAcCtrl_t_CmprRunTiNVM",
"type": "UInt32",
"x_size": 1,
"y_size": 1
},
{
"name": "sVcAesHw_X_VntAdpnOffs",
"type": "Float32",
"x_size": 1,
"y_size": 1
},
{
"name": "sVcAesMo_Ar_ArrayTest",
"type": "Float32",
"x_size": 4,
"y_size": 2
},
{
"name": "sVcAesMo_Ar_NvmThrAdpn",
"type": "Float32",
"x_size": 1,
"y_size": 1
}
],
"name": "NVM_LIST_32",
"default_datatype": "UInt32",
"instanceName": "nvm_list_32",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 975,
"persistent": false,
"allowed_datatypes": [
"Float32",
"UInt32",
"Int32"
]
},
{
"signals": [],
"name": "NVM_LIST_8_PER",
"default_datatype": "UInt8",
"instanceName": "nvm_list_8_per",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 56,
"persistent": true,
"allowed_datatypes": [
"Bool",
"UInt8",
"Int8"
]
},
{
"signals": [],
"name": "NVM_LIST_16_PER",
"default_datatype": "UInt16",
"instanceName": "nvm_list_16_per",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 240,
"persistent": true,
"allowed_datatypes": [
"UInt16",
"Int16"
]
},
{
"signals": [
{
"name": "sVcAcCtrl_t_Test1",
"type": "UInt32",
"x_size": 1,
"y_size": 1
}
],
"name": "NVM_LIST_32_PER",
"default_datatype": "UInt32",
"instanceName": "nvm_list_32_per",
"includeStart": "MemMap_SDA_START.h",
"includeStop": "MemMap_SDA_STOP.h",
"size": 190,
"persistent": true,
"allowed_datatypes": [
"Float32",
"UInt32",
"Int32"
]
}
]

View File

@ -11,7 +11,6 @@ from pathlib import Path
from powertrain_build import build_defs
from powertrain_build.lib import helper_functions
from powertrain_build.nvm_def import NVMDef
from powertrain_build.problem_logger import ProblemLogger
from powertrain_build.build_proj_config import BuildProjConfig
from powertrain_build.unit_configs import UnitConfigs
@ -223,8 +222,6 @@ class TestBuild(unittest.TestCase):
"""Check that NVM files are generated."""
unit_cfg = MagicMock(spec_set=UnitConfigs)
type(unit_cfg).base_types_headers = ''
tot_vars_nvm = unit_cfg.get_per_cfg_unit_cfg().get("nvm", {})
nvm_def = NVMDef(self.build_cfg, unit_cfg, tot_vars_nvm)
no_nvm_a2l = False
filepath = str(Path(SRC_DIR, 'output'))
files = [
@ -232,7 +229,7 @@ class TestBuild(unittest.TestCase):
filepath + '/vcc_nvm_struct.h',
filepath + '/vcc_nvm_struct.a2l']
remove(*files)
build.generate_nvm_def(nvm_def, no_nvm_a2l)
build.generate_nvm_def(self.build_cfg, unit_cfg, no_nvm_a2l)
self.build_cfg.get_src_code_dst_dir.assert_called()
unit_cfg.get_per_cfg_unit_cfg.assert_called()
exists(*files)

View File

@ -13,8 +13,9 @@ from unittest.mock import MagicMock, mock_open, patch, call
from pathlib import Path
from powertrain_build.lib import helper_functions
from powertrain_build.nvm_def import NVMDef
from powertrain_build.nvm_def import NVMDef, ZCNVMDef
from powertrain_build.unit_configs import UnitConfigs
from test_data.powertrain_build.test_nvm_def import nvm_def_setup, zc_nvm_def
SRC_DIR = Path(__file__).parent
@ -24,182 +25,6 @@ class TestNVMDef(unittest.TestCase):
Test case for testing the TestNVMDef class
"""
@classmethod
def setUpClass(cls):
"""Set-up common data structures for all tests in the test case
"""
cls.create_new = False
cls.unit_cfg = MagicMock(spec_set=UnitConfigs)
type(cls.unit_cfg).base_types_headers = '#include "tl_basetypes.h"\n'
cls.nvm_vars_test = {
'sVcAcCtrl_t_CmprRunTiNVM': {
'VcAcCtrl': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice description of your variable here',
'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/'
'3_SystemInfo/36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAcCtrl_t_CmprRunTiNVM',
'offset': 0,
'type': 'UInt32',
'unit': '-',
'width': 1}},
'sVcAesHw_X_VntAdpnOffs': {
'VcAesVnt': {
'class': 'CVC_DISP_NVM',
'configs': ['Vc_Aes_Vnt_B_CodeGenVntGvnr '
'== 0'],
'description': 'Enter a nice '
'description of your '
'variable here',
'handle': 'VcAesVnt/VcAesVnt/Subsystem/VcAesVnt/VcAesVnt/1_Vnt/11_VntGvnr/'
'111_VntGvnrExe/1111_VntGvnrFct/11112_VntAdpn/sVcAesHw_X_VntAdpnOffs/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesHw_X_VntAdpnOffs',
'offset': 0,
'type': 'Float32',
'unit': '-',
'width': 1
}
},
'sVcAesMo_Ar_ArrayTest': {
'VcAesMoAdp': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice '
'description of your '
'variable here',
'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/'
'2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesMo_Ar_NvmThrAdpn',
'offset': 0,
'type': 'Float32',
'unit': '-',
'width': [4, 2]
}
},
'sVcAesMo_Ar_NvmThrAdpn': {
'VcAesMoAdp': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice '
'description of your '
'variable here',
'handle': 'VcAesMoAdp/VcAesMoAdp/Subsystem/VcAesMoAdp/VcAesMoAdp/'
'2_ThrArAdpn/sVcAesMo_Ar_NvmThrAdpn/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesMo_Ar_NvmThrAdpn',
'offset': 0,
'type': 'Float32',
'unit': '-',
'width': 1
}
},
'sVcAesMo_rt_NvmMafLrngLd1Ne1': {
'VcAesMfl': {
'class': 'CVC_DISP_NVM',
'configs': ['all'],
'description': 'Enter a nice '
'description of '
'your variable '
'here',
'handle': 'VcAesMfl/VcAesMfl/Subsystem/VcAesMfl/VcAesMfl/4_Nvm/41_Ld1Ne1/'
'sVcAesMo_rt_NvmMafLrngLd1Ne1/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAesMo_rt_NvmMafLrngLd1Ne1',
'offset': 0,
'type': 'Bool',
'unit': '-',
'width': 1
}
},
'sVcAcCtrl_t_Test1': {
'VcAcCtrl': {
'class': 'CVC_DISP_NVM_P',
'configs': ['all'],
'description': 'Enter a nice description of your variable here',
'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/'
'36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAcCtrl_t_Test1',
'offset': 0,
'type': 'UInt32',
'unit': '-',
'width': 1
},
'VcAcCtrl2': {
'class': 'CVC_DISP_NVM_P',
'configs': ['all'],
'description': 'Enter a nice description of your variable here',
'handle': 'VcAcCtrl/VcAcCtrl/Subsystem/VcAcCtrl/CoolingManager/3_SystemInfo/'
'36_CompressorRunTime/sVcAcCtrl_t_CmprRunTiNVM/Unit Delay',
'lsb': 1,
'max': 'nan',
'min': 'nan',
'name': 'sVcAcCtrl_t_Test1',
'offset': 0,
'type': 'UInt32',
'unit': '-',
'width': 1
}
}
}
cls.nvm_configs_single = {
"fileName": "vcc_nvm_struct_single",
"baseNvmStructs": "nvm_structs_ref_single_signal.json"
}
cls.nvm_configs = {
"fileName": "vcc_nvm_struct",
"baseNvmStructs": "nvm_structs_ref_empty.json"
}
cls.nvm_configs_small = {
"fileName": "vcc_nvm_structs__small",
"baseNvmStructs": "nvm_structs_ref_small.json"
}
cls.nvm_configs_empty_small = {
"fileName": "vcc_nvm_structs_empty_small",
"baseNvmStructs": "nvm_structs_ref_empty_small.json"
}
cls.nvm_configs_signal_overwritten = {
"fileName": "vcc_nvm_structs_ref_used_positions",
"baseNvmStructs": "nvm_structs_ref_used_positions.json"
}
cls.nvm_configs_critical = {
"fileName": "vcc_nvm_structs_critical",
"baseNvmStructs": "nvm_structs_ref_critical.json"
}
cls.nvm_configs_critical_remove = {
"fileName": "vcc_nvm_struct_critical_remove",
"baseNvmStructs": "nvm_structs_ref_critical.json"
}
cls.nvm_configs_critical_duplicate = {
"fileName": "vcc_nvm_struct_critical_duplicate",
"baseNvmStructs": "nvm_structs_ref_critical_duplicate.json"
}
cls.nvm_configs_wrong_type = {
"fileName": "vcc_nvm_structs_ref_used_positions",
"baseNvmStructs": "nvm_structs_ref_wrong_type.json"
}
cls.nvm_configs_dcl = {
"fileName": "vcc_nvm_structs_ref_dcl",
"baseNvmStructs": "nvm_structs_ref_dcl.json"
}
def setUp(self):
"""Set-up common data structures for all tests in the test case
"""
@ -209,10 +34,13 @@ class TestNVMDef(unittest.TestCase):
projdir = Path(SRC_DIR, 'cnfg_files').resolve()
self.proj_cnfg.get_root_dir = MagicMock(return_value=projdir)
self.proj_cnfg.get_src_code_dst_dir = MagicMock(return_value=str(Path(SRC_DIR, 'output')))
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs)
self.proj_cnfg.get_code_generation_config = MagicMock(return_value=True)
self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='')
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.unit_cfg = MagicMock(spec_set=UnitConfigs)
type(self.unit_cfg).base_types_headers = '#include "tl_basetypes.h"\n'
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test)
self.create_new = False
self.small_nvm_struct = {
"sVcDummy_t_DummyNvm": {
@ -244,8 +72,8 @@ class TestNVMDef(unittest.TestCase):
project_config = MagicMock()
projdir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'cnfg_files'))
project_config.get_root_dir = MagicMock(return_value=projdir)
project_config.get_nvm_defs = MagicMock(return_value=self.nvm_configs_small)
nvm_def = NVMDef(project_config, self.unit_cfg, self.nvm_vars_test)
project_config.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_small)
nvm_def = NVMDef(project_config, self.unit_cfg, nvm_def_setup.nvm_vars_test)
nvm_structs_signals = nvm_def._get_signals_in_nvm_structs()
expected_signals_path = os.path.join(os.path.dirname(__file__),
'cnfg_files',
@ -262,7 +90,7 @@ class TestNVMDef(unittest.TestCase):
"""
no_nvm_a2l = False
self.nvm_def.generate_nvm_config_files(no_nvm_a2l)
h_file_name = Path(SRC_DIR, 'output', self.nvm_configs['fileName'] + '.h')
h_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs['fileName'] + '.h')
with h_file_name.open() as hfptr:
h_file = hfptr.read()
with Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref.h').open() as hfptr_ref:
@ -275,7 +103,7 @@ class TestNVMDef(unittest.TestCase):
"""
no_nvm_a2l = False
self.nvm_def.generate_nvm_config_files(no_nvm_a2l)
c_file_name = Path(SRC_DIR, 'output', self.nvm_configs['fileName'] + '.c')
c_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs['fileName'] + '.c')
with c_file_name.open() as cfptr:
c_file = cfptr.read()
with Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref.c').open() as cfptr_ref:
@ -287,7 +115,7 @@ class TestNVMDef(unittest.TestCase):
"""
no_nvm_a2l = False
self.nvm_def.generate_nvm_config_files(no_nvm_a2l)
a_file_name = Path(SRC_DIR, 'output', self.nvm_configs['fileName'] + '.a2l')
a_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs['fileName'] + '.a2l')
with a_file_name.open() as fptr:
a2l_file = fptr.read()
ref_file = Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref.a2l')
@ -431,9 +259,9 @@ class TestNVMDef(unittest.TestCase):
def test_gen_h_file_fail(self):
"""test for generating the h-file for NVM definitions
"""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_empty_small)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_empty_small)
NVMDef.init_logger(logging.getLogger())
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test)
with self.assertLogs(level='WARNING') as log:
no_nvm_a2l = False
self.nvm_def.generate_nvm_config_files(no_nvm_a2l)
@ -442,8 +270,8 @@ class TestNVMDef(unittest.TestCase):
def test_gen_h_file_signal_is_overwritten(self):
"""test that the NVM definitions is overwritten if signal is named position_*
"""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_signal_overwritten)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_signal_overwritten)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test)
nvm_list_32_pos = self.nvm_def._get_nvm_areas_index('NVM_LIST_32')
dummy_signal = {'name': 'dummy', 'type': 'Int32', 'x_size': 1, 'y_size': 1}
# find_empty_index should find next empty index to be 2 since that's
@ -458,7 +286,7 @@ class TestNVMDef(unittest.TestCase):
self.assertNotEqual(index_after_generation, index_before_generation)
self.assertEqual(index_after_generation, -1)
h_file_name = Path(SRC_DIR, 'output', self.nvm_configs_signal_overwritten['fileName'] + '.h')
h_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs_signal_overwritten['fileName'] + '.h')
with h_file_name.open() as hfptr:
h_file = hfptr.read()
with Path(SRC_DIR, 'reference_files', 'vcc_nvm_structs_ref_used_positions.h').open() as hfptr_ref:
@ -469,7 +297,7 @@ class TestNVMDef(unittest.TestCase):
def test_add_signal_with_nondefault_type_c(self):
"""Test that we can add different types of signals to critical area - c-file
"""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical)
nvm_vars_test = {
'sVcTest_t_UInt32': {
'VcTest': {
@ -532,7 +360,7 @@ class TestNVMDef(unittest.TestCase):
def test_add_signal_with_nondefault_type_h(self):
"""Test that we can add different types of signals to critical area - h-file
"""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical)
nvm_vars_test = {
'sVcTest_t_UInt32': {
'VcTest': {
@ -596,7 +424,7 @@ class TestNVMDef(unittest.TestCase):
"""Test that we can add different types of signals to critical area - a2l-file
"""
self.proj_cnfg.get_code_generation_config = MagicMock(return_value=False)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical)
nvm_vars_test = {
'sVcTest_t_UInt32': {
'VcTest': {
@ -665,7 +493,7 @@ class TestNVMDef(unittest.TestCase):
Note: Denso does not have any area like this at the time of writing this test
"""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical)
nvm_vars_test = {
'sVcTest_t_UInt32': {
'VcTest': {
@ -732,15 +560,15 @@ class TestNVMDef(unittest.TestCase):
def test_add_signal_with_wrong_type(self):
"""test that its not possible to add a signal of wrong type to a specific nwm area
"""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_wrong_type)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_wrong_type)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test)
NVMDef.init_logger(logging.getLogger())
no_nvm_a2l = False
self.assertRaises(NVMDef.WrongTypeException, self.nvm_def.generate_nvm_config_files, no_nvm_a2l)
def test_add_duplicate_signal_different_attributes(self):
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_single)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_single)
nvm_vars_test = {
'sVcAcCtrl_t_CmprRunTiNVM': {
'VcAcCtrl': {
@ -768,8 +596,8 @@ class TestNVMDef(unittest.TestCase):
self.assertEqual(nvm_def.get_nbr_problems()['critical'], 1)
def test_add_duplicate_signal_different_memory_area(self):
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_single)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, self.nvm_vars_test)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_single)
self.nvm_def = NVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test)
nvm_vars_test = {
'sVcAcCtrl_t_CmprRunTiNVM': {
'VcAcCtrl': {
@ -798,7 +626,7 @@ class TestNVMDef(unittest.TestCase):
def test_remove_signal_from_critical(self):
"""Test that a2l- and h-files are updated when removing a signal from the critical area."""
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=self.nvm_configs_critical_remove)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs_critical_remove)
nvm_vars_test = {
'sVcTest_t_UInt32': {
'VcTest': {
@ -835,7 +663,7 @@ class TestNVMDef(unittest.TestCase):
no_nvm_a2l = False
self.nvm_def.generate_nvm_config_files(no_nvm_a2l)
h_file_name = Path(SRC_DIR, 'output', self.nvm_configs_critical_remove['fileName'] + '.h')
h_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs_critical_remove['fileName'] + '.h')
with h_file_name.open() as h_ptr:
h_file = h_ptr.read()
with Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref_critical_remove.h').open() as h_ref_ptr:
@ -843,7 +671,7 @@ class TestNVMDef(unittest.TestCase):
self.maxDiff = None
self.assertEqual(h_ref_file, h_file)
a2l_file_name = Path(SRC_DIR, 'output', self.nvm_configs_critical_remove['fileName'] + '.a2l')
a2l_file_name = Path(SRC_DIR, 'output', nvm_def_setup.nvm_configs_critical_remove['fileName'] + '.a2l')
with a2l_file_name.open() as a2l_ptr:
a2l_file = a2l_ptr.read()
ref_file = Path(SRC_DIR, 'reference_files', 'vcc_nvm_struct_ref_critical_remove.a2l')
@ -853,3 +681,58 @@ class TestNVMDef(unittest.TestCase):
with ref_file.open() as a2l_ref_ptr:
a2l_ref_file = a2l_ref_ptr.read()
self.assertEqual(a2l_ref_file, a2l_file)
class TestZCNVMDef(unittest.TestCase):
"""Class for testing ZCNVMDef."""
def setUp(self):
self.proj_cnfg = MagicMock()
projdir = Path(SRC_DIR, 'cnfg_files').resolve()
self.proj_cnfg.get_root_dir = MagicMock(return_value=projdir)
self.proj_cnfg.get_nvm_defs = MagicMock(return_value=nvm_def_setup.nvm_configs)
self.proj_cnfg.get_scheduler_prefix = MagicMock(return_value='')
self.proj_cnfg.get_composition_config = MagicMock(return_value="Dummy_{NvName}")
self.unit_cfg = MagicMock(spec_set=UnitConfigs)
type(self.unit_cfg).base_types_headers = '#include "tl_basetypes.h"\n'
self.nvm_def = ZCNVMDef(self.proj_cnfg, self.unit_cfg, nvm_def_setup.nvm_vars_test)
def test_valid_nvm_definitions_setter(self):
"""Test setting property ZCNVMDef.valid_nvm_definitions."""
self.nvm_def.valid_nvm_definitions = zc_nvm_def.yaml_nvm_definitions
self.assertDictEqual(self.nvm_def.valid_nvm_definitions, zc_nvm_def.yaml_nvm_definitions)
def test_valid_nvm_definitions_setter_none(self):
"""Test setting property ZCNVMDef.valid_nvm_definitions with no nvms."""
self.nvm_def.valid_nvm_definitions = {}
self.assertDictEqual(self.nvm_def.valid_nvm_definitions, {})
def test_valid_nvm_definitions_etter_bad_project(self):
"""Test setting property ZCNVMDef.valid_nvm_definitions with NVM definition not in project."""
self.nvm_def.valid_nvm_definitions = zc_nvm_def.yaml_nvm_definitions_one_not_in_project
self.assertDictEqual(self.nvm_def.valid_nvm_definitions, zc_nvm_def.yaml_nvm_definitions)
@patch("builtins.open", new_callable=mock_open())
def test_append_nvm_rte_function_calls(self, mock_open_file):
"""Test ZCNVMDef._append_nvm_rte_function_calls."""
self.nvm_def.valid_nvm_definitions = zc_nvm_def.yaml_nvm_definitions
self.nvm_def._append_nvm_rte_function_calls()
expected = [
'#include "CVC_CODE_ASIL_D_START.h"\nvoid VcNvmInit(void) {\n',
" //Call this function in the SWC init runnable\n",
" Rte_Call_Dummy_NVM_LIST_8_SetRamBlockStatus(TRUE);\n", "}\n",
'#include "CVC_CODE_ASIL_D_END.h"\n',
"\n",
'#include "CVC_CODE_ASIL_D_START.h"\nvoid VcNvm(void) {\n',
" //Call this function in the SWC main runnable\n",
" UInt8 errorStatus = 0;\n",
" *Rte_Pim_NVM_LIST_8() = nvm_list_8;\n",
" *Rte_Pim_NVM_LIST_16() = nvm_list_16;\n",
" Rte_Call_Dummy_NVM_LIST_16_GetErrorStatus(&errorStatus);\n",
" if (errorStatus == 0) {\n",
" Rte_Call_Dummy_NVM_LIST_16_WriteBlock(Rte_Pim_NVM_LIST_16());\n",
" }\n",
"}\n",
'#include "CVC_CODE_ASIL_D_END.h"\n'
]
mock_open_file().__enter__().writelines.assert_called_once_with(expected)

View File

@ -248,6 +248,9 @@ class TestCompositionYaml(unittest.TestCase):
def test_composition_yaml_with_nvm(self):
"""Checking that the dict is generated correctly, with NVM."""
self.nvm_def.nvm_definitions = composition_yaml_with_nvm.project_nvm_definitions
self.nvm_def.project_nvm_definitions = {
f"prefix_{item['name']}": item for item in self.nvm_def.nvm_definitions
}
self.zc_spec["nv-needs"] = composition_yaml_with_nvm.yaml_nvm_definitions
with patch.object(
CompositionYaml,