powertrain-build 1.13.1__py3-none-any.whl → 1.13.3.dev3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. powertrain_build/__init__.py +40 -40
  2. powertrain_build/__main__.py +6 -6
  3. powertrain_build/a2l.py +582 -582
  4. powertrain_build/a2l_merge.py +650 -650
  5. powertrain_build/a2l_templates.py +717 -717
  6. powertrain_build/build.py +985 -985
  7. powertrain_build/build_defs.py +309 -309
  8. powertrain_build/build_proj_config.py +690 -690
  9. powertrain_build/check_interface.py +575 -575
  10. powertrain_build/cli.py +141 -141
  11. powertrain_build/config.py +542 -542
  12. powertrain_build/core.py +395 -395
  13. powertrain_build/core_dummy.py +343 -343
  14. powertrain_build/create_conversion_table.py +73 -73
  15. powertrain_build/dids.py +916 -916
  16. powertrain_build/dummy.py +157 -157
  17. powertrain_build/dummy_spm.py +252 -252
  18. powertrain_build/environmentcheck.py +52 -52
  19. powertrain_build/ext_dbg.py +255 -255
  20. powertrain_build/ext_var.py +327 -327
  21. powertrain_build/feature_configs.py +301 -301
  22. powertrain_build/gen_allsysteminfo.py +227 -227
  23. powertrain_build/gen_label_split.py +449 -449
  24. powertrain_build/handcode_replacer.py +124 -124
  25. powertrain_build/html_report.py +133 -133
  26. powertrain_build/interface/__init__.py +4 -4
  27. powertrain_build/interface/application.py +511 -511
  28. powertrain_build/interface/base.py +500 -500
  29. powertrain_build/interface/csp_api.py +490 -490
  30. powertrain_build/interface/device_proxy.py +677 -677
  31. powertrain_build/interface/ems.py +67 -67
  32. powertrain_build/interface/export_global_vars.py +121 -121
  33. powertrain_build/interface/generate_adapters.py +132 -132
  34. powertrain_build/interface/generate_hi_interface.py +87 -87
  35. powertrain_build/interface/generate_service.py +69 -69
  36. powertrain_build/interface/generate_wrappers.py +147 -147
  37. powertrain_build/interface/generation_utils.py +142 -142
  38. powertrain_build/interface/hal.py +194 -194
  39. powertrain_build/interface/model_yaml_verification.py +348 -348
  40. powertrain_build/interface/service.py +296 -296
  41. powertrain_build/interface/simulink.py +249 -249
  42. powertrain_build/interface/update_call_sources.py +180 -180
  43. powertrain_build/interface/update_model_yaml.py +186 -186
  44. powertrain_build/interface/zone_controller.py +362 -362
  45. powertrain_build/lib/__init__.py +4 -4
  46. powertrain_build/lib/helper_functions.py +127 -127
  47. powertrain_build/lib/logger.py +55 -55
  48. powertrain_build/matlab_scripts/CodeGen/BuildAutomationPyBuild.m +78 -78
  49. powertrain_build/matlab_scripts/CodeGen/Generate_A2L.m +154 -154
  50. powertrain_build/matlab_scripts/CodeGen/generateTLUnit.m +239 -239
  51. powertrain_build/matlab_scripts/CodeGen/getAsilClassification.m +28 -28
  52. powertrain_build/matlab_scripts/CodeGen/modelConfiguredForTL.m +28 -28
  53. powertrain_build/matlab_scripts/CodeGen/moveDefOutports.m +88 -88
  54. powertrain_build/matlab_scripts/CodeGen/parseCalMeasData.m +410 -410
  55. powertrain_build/matlab_scripts/CodeGen/parseCoreIdentifiers.m +139 -139
  56. powertrain_build/matlab_scripts/CodeGen/parseDIDs.m +141 -141
  57. powertrain_build/matlab_scripts/CodeGen/parseInPorts.m +106 -106
  58. powertrain_build/matlab_scripts/CodeGen/parseIncludeConfigs.m +25 -25
  59. powertrain_build/matlab_scripts/CodeGen/parseModelInfo.m +38 -38
  60. powertrain_build/matlab_scripts/CodeGen/parseNVM.m +81 -81
  61. powertrain_build/matlab_scripts/CodeGen/parseOutPorts.m +120 -120
  62. powertrain_build/matlab_scripts/CodeGen/parsePreProcBlks.m +23 -23
  63. powertrain_build/matlab_scripts/CodeGen/struct2JSON.m +128 -128
  64. powertrain_build/matlab_scripts/CodeGen/updateCodeSwConfig.m +31 -31
  65. powertrain_build/matlab_scripts/Init_PyBuild.m +91 -91
  66. powertrain_build/matlab_scripts/__init__.py +2 -2
  67. powertrain_build/matlab_scripts/helperFunctions/Get_Full_Name.m +46 -46
  68. powertrain_build/matlab_scripts/helperFunctions/Get_SrcLines.m +12 -12
  69. powertrain_build/matlab_scripts/helperFunctions/Init_Models.m +78 -78
  70. powertrain_build/matlab_scripts/helperFunctions/Init_Projects.m +67 -67
  71. powertrain_build/matlab_scripts/helperFunctions/Read_Units.m +34 -34
  72. powertrain_build/matlab_scripts/helperFunctions/SetProjectTimeSamples.m +26 -26
  73. powertrain_build/matlab_scripts/helperFunctions/Strip_Suffix.m +16 -16
  74. powertrain_build/matlab_scripts/helperFunctions/followLink.m +118 -118
  75. powertrain_build/matlab_scripts/helperFunctions/getCodeSwitches.m +50 -50
  76. powertrain_build/matlab_scripts/helperFunctions/getConsumerBlocks.m +30 -30
  77. powertrain_build/matlab_scripts/helperFunctions/getDefBlock.m +39 -39
  78. powertrain_build/matlab_scripts/helperFunctions/getDefOutport.m +58 -58
  79. powertrain_build/matlab_scripts/helperFunctions/getDstBlocks.m +19 -19
  80. powertrain_build/matlab_scripts/helperFunctions/getDstLines.m +13 -13
  81. powertrain_build/matlab_scripts/helperFunctions/getInterfaceSignals.m +37 -37
  82. powertrain_build/matlab_scripts/helperFunctions/getName.m +37 -37
  83. powertrain_build/matlab_scripts/helperFunctions/getPath.m +6 -6
  84. powertrain_build/matlab_scripts/helperFunctions/getProperValue.m +21 -21
  85. powertrain_build/matlab_scripts/helperFunctions/getSrcBlocks.m +19 -19
  86. powertrain_build/matlab_scripts/helperFunctions/getSrcLines.m +13 -13
  87. powertrain_build/matlab_scripts/helperFunctions/loadLibraries.m +10 -10
  88. powertrain_build/matlab_scripts/helperFunctions/loadjson.m +6 -6
  89. powertrain_build/matlab_scripts/helperFunctions/modifyEnumStructField.m +21 -21
  90. powertrain_build/matlab_scripts/helperFunctions/removeConfigDuplicates.m +31 -31
  91. powertrain_build/matlab_scripts/helperFunctions/sortSystemByClass.m +26 -26
  92. powertrain_build/matlab_scripts/helperFunctions/tl_getfast.m +89 -89
  93. powertrain_build/matlab_scripts/helperFunctions/topLevelSystem.m +20 -20
  94. powertrain_build/matlab_scripts/helperFunctions/updateModels.m +131 -131
  95. powertrain_build/memory_section.py +224 -224
  96. powertrain_build/nvm_def.py +729 -729
  97. powertrain_build/problem_logger.py +86 -86
  98. powertrain_build/pt_matlab.py +430 -430
  99. powertrain_build/pt_win32.py +144 -144
  100. powertrain_build/replace_compu_tab_ref.py +105 -105
  101. powertrain_build/rte_dummy.py +254 -254
  102. powertrain_build/sched_funcs.py +209 -207
  103. powertrain_build/signal.py +7 -7
  104. powertrain_build/signal_if_html_rep.py +221 -221
  105. powertrain_build/signal_if_html_rep_all.py +302 -302
  106. powertrain_build/signal_incons_html_rep.py +180 -180
  107. powertrain_build/signal_incons_html_rep_all.py +366 -366
  108. powertrain_build/signal_incons_html_rep_base.py +168 -168
  109. powertrain_build/signal_inconsistency_check.py +641 -641
  110. powertrain_build/signal_interfaces.py +864 -864
  111. powertrain_build/templates/Index_SigCheck_All.html +22 -22
  112. powertrain_build/templates/Index_SigIf_All.html +19 -19
  113. powertrain_build/types.py +218 -218
  114. powertrain_build/unit_configs.py +419 -419
  115. powertrain_build/user_defined_types.py +660 -660
  116. powertrain_build/versioncheck.py +66 -66
  117. powertrain_build/wrapper.py +512 -512
  118. powertrain_build/xlrd_csv.py +87 -87
  119. powertrain_build/zone_controller/__init__.py +4 -4
  120. powertrain_build/zone_controller/calibration.py +176 -176
  121. powertrain_build/zone_controller/composition_yaml.py +880 -878
  122. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/METADATA +100 -100
  123. powertrain_build-1.13.3.dev3.dist-info/RECORD +130 -0
  124. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/WHEEL +1 -1
  125. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/LICENSE +202 -202
  126. powertrain_build-1.13.3.dev3.dist-info/pbr.json +1 -0
  127. powertrain_build-1.13.1.dist-info/RECORD +0 -130
  128. powertrain_build-1.13.1.dist-info/pbr.json +0 -1
  129. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/entry_points.txt +0 -0
  130. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/AUTHORS +0 -0
  131. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/NOTICE +0 -0
  132. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/top_level.txt +0 -0
@@ -1,327 +1,327 @@
1
- # Copyright 2024 Volvo Car Corporation
2
- # Licensed under Apache 2.0.
3
-
4
- # -*- coding: utf-8 -*-
5
- """Module containing classes for VCC - Supplier signal interface."""
6
-
7
- from powertrain_build import build_defs
8
- from powertrain_build.types import byte_size_string, get_bitmask
9
- from powertrain_build.a2l import A2l
10
- from powertrain_build.problem_logger import ProblemLogger
11
-
12
-
13
- class ExtVarBase(ProblemLogger):
14
- """Generate a2l- and c-files.
15
-
16
- These which declares all variables in the interface that the
17
- supplier platform writes to.
18
-
19
- This is needed due to legacy handling of the interfaces between units.
20
- Note that all variables sent from the VCC SPM to the platform should be declared in
21
- the function that produces the signal!
22
- """
23
-
24
- INPORT_INDEX = 0
25
- OUTPORT_INDEX = 1
26
-
27
- __data_type_size = {
28
- "Float32": "4",
29
- "UInt32": "4",
30
- "Int32": "4",
31
- "UInt16": "2",
32
- "Int16": "2",
33
- "UInt8": "1",
34
- "Int8": "1",
35
- "Bool": "1",
36
- }
37
-
38
- def __init__(self, variable_dict, prj_cfg, unit_cfg, user_defined_types, integrity_level=build_defs.ASIL_QM):
39
- """Constructor.
40
-
41
- Args:
42
- variable_dict (dict): dictionary with signal information.
43
- prj_cfg (BuildProjConfig): Build project class holding where files should be stored.
44
- user_defined_types (UserDefinedTypes): Class holding user defined data types.
45
- integrity_level (str): integrity level of the unit from 'A' to 'D' or 'QM'.
46
- """
47
- super().__init__()
48
- self.set_integrity_level(integrity_level)
49
- self._var_dict = variable_dict
50
- self._ext_vars = {}
51
- self._prj_cfg = prj_cfg
52
- self._unit_cfg = unit_cfg
53
- self._enumerations = user_defined_types.get_enumerations()
54
- self._common_header_files = user_defined_types.common_header_files
55
-
56
- def set_integrity_level(self, integrity_level):
57
- """Set integrity level of code generation.
58
-
59
- Args:
60
- integrity_level (str): integrity level of the unit from 'A' to 'D' or 'QM'
61
- """
62
- self._disp_start = integrity_level["CVC"]["DISP"]["START"]
63
- self._disp_end = integrity_level["CVC"]["DISP"]["END"]
64
- self._decl_start = integrity_level["PREDECL"]["DISP"]["START"]
65
- self._decl_end = integrity_level["PREDECL"]["DISP"]["END"]
66
-
67
- def _get_byte_size_string(self, data_type):
68
- """Get byte size of a data type as string.
69
- Enumeration byte sizes are derived from the underlying data type.
70
-
71
- Args:
72
- data_type (str): Data type.
73
- Returns:
74
- byte_size_string(powertrain_build.types.byte_size_string): Return result of
75
- powertrain_build.types.byte_size_string.
76
- """
77
- if data_type in self._enumerations:
78
- return byte_size_string(self._enumerations[data_type]["underlying_data_type"])
79
- return byte_size_string(data_type)
80
-
81
- def _get_bitmask(self, data_type):
82
- """Get bitmask of a data type.
83
- Enumeration bitmasks are derived from the underlying data type.
84
-
85
- Args:
86
- data_type (str): Data type.
87
- Returns:
88
- get_bitmask(powertrain_build.types.get_bitmask): Return result of powertrain_build.types.get_bitmask.
89
- """
90
- if data_type in self._enumerations:
91
- return get_bitmask(self._enumerations[data_type]["underlying_data_type"])
92
- return get_bitmask(data_type)
93
-
94
- def _restruct_input_data(self):
95
- """Restructure all the input variables per data-type.
96
-
97
- This will be used for declaring the variables and generating the
98
- A2L-file
99
- """
100
- external_inports = {}
101
- external_outports = {}
102
- for external_port_type in self.EXTERNAL_INPORT_TYPES:
103
- if external_port_type in self._var_dict:
104
- for var, data in self._var_dict[external_port_type].items():
105
- data_type_size = self._get_byte_size_string(data[self.TYPE_NAME])
106
- external_inports.setdefault(data_type_size, {})[var] = data
107
- for external_port_type in self.EXTERNAL_OUTPORT_TYPES:
108
- if external_port_type in self._var_dict:
109
- for var, data in self._var_dict[external_port_type].items():
110
- data_type_size = self._get_byte_size_string(data[self.TYPE_NAME])
111
- external_outports.setdefault(data_type_size, {})[var] = data
112
- self._ext_vars = external_inports, external_outports
113
-
114
- def _a2l_dict(self):
115
- """Return a dict defining all parameters for a2l-generation."""
116
- res = {"vars": {}, "function": "VcExtVar"}
117
- for inp in self.EXTERNAL_INPORT_TYPES:
118
- if inp in self._var_dict:
119
- for var, data in self._var_dict[inp].items():
120
- if data[self.TYPE_NAME] in self._enumerations:
121
- data_type = self._enumerations[data[self.TYPE_NAME]]["underlying_data_type"]
122
- else:
123
- data_type = data[self.TYPE_NAME]
124
-
125
- resv = res["vars"]
126
- resv.setdefault(var, {})["a2l_data"] = self.get_a2l_format(data)
127
- resv[var]["array"] = []
128
- resv[var]["function"] = ["VcEc"]
129
- resv[var]["var"] = {"cvc_type": "CVC_DISP", "type": data_type, "var": var}
130
- return res
131
-
132
- def _get_array_declaration(self, var, width):
133
- """Get array declaration string from width information.
134
-
135
- Args:
136
- var (str): Variable name.
137
- width (int or list): Width information.
138
- Returns:
139
- array (str): Array declaration string.
140
- """
141
- array = ""
142
- widths = [width] if not isinstance(width, list) else width
143
- if len(widths) != 1 or widths[0] != 1:
144
- for w in widths:
145
- if w > 1:
146
- if not isinstance(w, int):
147
- self.critical(f'{var} widths must be integers. Got "{type(w)}"')
148
- array += f'[{w}]'
149
- elif w < 0:
150
- self.critical(f'{var} widths can not be negative. Got "{w}"')
151
- return array
152
-
153
- def _generate_c_file(self, path):
154
- """Generate the c-file defining all the supplier input signals."""
155
- header = path.with_suffix(".h").name
156
- var_set = set()
157
- with path.open("w") as fh_c:
158
- fh_c.write(f'#include "{header}"\n')
159
- fh_c.write(f'#include "{self._disp_start}"\n\n')
160
- for data_type_s, ext_vars in self._ext_vars[self.INPORT_INDEX].items():
161
- fh_c.write(f"/* Variables of size {data_type_s} bytes */\n\n")
162
- for var in sorted(ext_vars.keys()):
163
- data = ext_vars[var]
164
- if var not in var_set:
165
- array = self._get_array_declaration(var, data.get("width", 1))
166
- if array:
167
- init_value = data["init"] if data["init"] != 0 else "{0}"
168
- else:
169
- init_value = data["init"]
170
- fh_c.write(f"CVC_DISP {data[self.TYPE_NAME]} {var}{array} = {init_value};\n")
171
- var_set.add(var)
172
- fh_c.write("\n")
173
- fh_c.write(f'\n#include "{self._disp_end}"\n')
174
- self.info("Generated %s", path.name)
175
-
176
- def _generate_h_file(self, path):
177
- """Generate header file externally declaring interface signals."""
178
- filename = path.stem
179
- guard = f"{filename.upper()}_H"
180
- var_set = set()
181
- with path.open("w") as fh_c:
182
- fh_c.write(f"#ifndef {guard}\n")
183
- fh_c.write(f"#define {guard}\n")
184
- fh_c.write("#define CVC_DISP\n")
185
- fh_c.write(self._unit_cfg.base_types_headers)
186
-
187
- for common_header_file in self._common_header_files:
188
- fh_c.write(f'#include "{common_header_file}"\n')
189
- fh_c.write("\n")
190
-
191
- fh_c.write(f'#include "{self._decl_start}"\n')
192
- fh_c.write("/* VCC Inports */\n")
193
- for data_type_s, ext_vars in self._ext_vars[self.INPORT_INDEX].items():
194
- fh_c.write(f"/* Variables of size {data_type_s} bytes */\n\n")
195
- for var in sorted(ext_vars.keys()):
196
- if var not in var_set:
197
- data = ext_vars[var]
198
- array = self._get_array_declaration(var, data.get("width", 1))
199
- fh_c.write(f"extern CVC_DISP {data[self.TYPE_NAME]} {var}{array};\n")
200
- var_set.add(var)
201
- fh_c.write("\n")
202
-
203
- fh_c.write("/* VCC Outports */\n")
204
- for data_type_s, ext_vars in self._ext_vars[self.OUTPORT_INDEX].items():
205
- fh_c.write(f"/* Variables of size {data_type_s} bytes */\n\n")
206
- for var in sorted(ext_vars.keys()):
207
- if var not in var_set:
208
- data = ext_vars[var]
209
- array = self._get_array_declaration(var, data.get("width", 1))
210
- fh_c.write(f"extern CVC_DISP {data[self.TYPE_NAME]} {var}{array};\n")
211
- var_set.add(var)
212
- fh_c.write("\n")
213
- fh_c.write(f'#include "{self._decl_end}"\n')
214
- fh_c.write("#endif\n")
215
- self.info("Generated %s", path.name)
216
-
217
- def generate_files(self, path):
218
- """Generate the c- and a2l-file for defining all the supplier input variables."""
219
- self._restruct_input_data()
220
- if not self._ext_vars[0] and not self._ext_vars[1]:
221
- self.info(f"Skipping {path.name} as there were no corresponding vars.")
222
- return
223
- self._generate_c_file(path.with_suffix(".c"))
224
- self._generate_h_file(path.with_suffix(".h"))
225
- a2l_dict = self._a2l_dict()
226
- a2l = A2l(a2l_dict, self._prj_cfg)
227
- a2l.gen_a2l(path.with_suffix(".a2l"))
228
-
229
-
230
- class ExtVarCsv(ExtVarBase):
231
- """Handles variable dicts from CSV files.
232
-
233
- Variable dict shall have the following format and is generated by the
234
- :doc:`CsvSignalInterfaces <signal_interfaces>` class::
235
-
236
- {
237
- 'CAN-Input': {
238
- 'signal1': {
239
- 'IOType': 'd',
240
- 'description': 'Some description',
241
- 'init': 0,
242
- 'max': 1,
243
- 'min': 0,
244
- 'type': 'UInt8',
245
- 'unit': '-'
246
- },
247
- 'signal2': {
248
- ...
249
- }
250
- },
251
- 'CAN-Output': {
252
- 'signal3': {
253
- ...
254
- }
255
- },
256
- 'xxx-Input': ...,
257
- 'xxx-Output': ...
258
- }
259
- """
260
-
261
- EXTERNAL_INPORT_TYPES = ["EMS-Input", "CAN-Input", "Private CAN-Input", "LIN-Input"]
262
- EXTERNAL_OUTPORT_TYPES = ["EMS-Output", "CAN-Output", "Private CAN-Output", "LIN-Output"]
263
- TYPE_NAME = "type"
264
-
265
- def get_a2l_format(self, data):
266
- """Get a2l format.
267
-
268
- Args:
269
- data (dict): Data dictionary.
270
- Returns:
271
- dict: A2l format dictionary.
272
- """
273
- return {
274
- "bitmask": self._get_bitmask(data[self.TYPE_NAME]),
275
- "description": data["description"],
276
- "lsb": "2^0",
277
- "max": data["max"],
278
- "min": data["min"],
279
- "offset": "0",
280
- "unit": data["unit"],
281
- "x_axis": None,
282
- "y_axis": None,
283
- }
284
-
285
-
286
- class ExtVarYaml(ExtVarBase):
287
- """Handles variable dicts from Yaml files.
288
-
289
- Variable dict shall have the following format and is generated by the
290
- :doc:`YamlSignalInterfaces <signal_interfaces>` class::
291
-
292
- {
293
- 'input': {
294
- 'sVcIhfa_D_WhlMotSysFrntLimnIndcn': {},
295
- 'sVcIhfa_D_WhlMotSysFrntModSts': {},
296
- 'sVcIhfa_I_WhlMotSysFrntIdc': {},
297
- 'sVcIhfa_U_UDcDcActHiSide1': {},
298
- 'sVcIhfa_U_WhlMotSysFrntUdc': {}
299
- },
300
- 'output': {},
301
- 'status': {},
302
- }
303
- """
304
-
305
- EXTERNAL_INPORT_TYPES = ["input", "status"]
306
- EXTERNAL_OUTPORT_TYPES = ["output"]
307
- TYPE_NAME = "variable_type"
308
-
309
- def get_a2l_format(self, data):
310
- """Get a2l format.
311
-
312
- Args:
313
- data (dict): Data dictionary.
314
- Returns:
315
- dict: A2l format dictionary.
316
- """
317
- return {
318
- "bitmask": self._get_bitmask(data[self.TYPE_NAME]),
319
- "description": data["description"],
320
- "lsb": "2^0",
321
- "max": data["range"]["max"],
322
- "min": data["range"]["min"],
323
- "offset": "0",
324
- "unit": data["unit"],
325
- "x_axis": None,
326
- "y_axis": None,
327
- }
1
+ # Copyright 2024 Volvo Car Corporation
2
+ # Licensed under Apache 2.0.
3
+
4
+ # -*- coding: utf-8 -*-
5
+ """Module containing classes for VCC - Supplier signal interface."""
6
+
7
+ from powertrain_build import build_defs
8
+ from powertrain_build.types import byte_size_string, get_bitmask
9
+ from powertrain_build.a2l import A2l
10
+ from powertrain_build.problem_logger import ProblemLogger
11
+
12
+
13
+ class ExtVarBase(ProblemLogger):
14
+ """Generate a2l- and c-files.
15
+
16
+ These which declares all variables in the interface that the
17
+ supplier platform writes to.
18
+
19
+ This is needed due to legacy handling of the interfaces between units.
20
+ Note that all variables sent from the VCC SPM to the platform should be declared in
21
+ the function that produces the signal!
22
+ """
23
+
24
+ INPORT_INDEX = 0
25
+ OUTPORT_INDEX = 1
26
+
27
+ __data_type_size = {
28
+ "Float32": "4",
29
+ "UInt32": "4",
30
+ "Int32": "4",
31
+ "UInt16": "2",
32
+ "Int16": "2",
33
+ "UInt8": "1",
34
+ "Int8": "1",
35
+ "Bool": "1",
36
+ }
37
+
38
+ def __init__(self, variable_dict, prj_cfg, unit_cfg, user_defined_types, integrity_level=build_defs.ASIL_QM):
39
+ """Constructor.
40
+
41
+ Args:
42
+ variable_dict (dict): dictionary with signal information.
43
+ prj_cfg (BuildProjConfig): Build project class holding where files should be stored.
44
+ user_defined_types (UserDefinedTypes): Class holding user defined data types.
45
+ integrity_level (str): integrity level of the unit from 'A' to 'D' or 'QM'.
46
+ """
47
+ super().__init__()
48
+ self.set_integrity_level(integrity_level)
49
+ self._var_dict = variable_dict
50
+ self._ext_vars = {}
51
+ self._prj_cfg = prj_cfg
52
+ self._unit_cfg = unit_cfg
53
+ self._enumerations = user_defined_types.get_enumerations()
54
+ self._common_header_files = user_defined_types.common_header_files
55
+
56
+ def set_integrity_level(self, integrity_level):
57
+ """Set integrity level of code generation.
58
+
59
+ Args:
60
+ integrity_level (str): integrity level of the unit from 'A' to 'D' or 'QM'
61
+ """
62
+ self._disp_start = integrity_level["CVC"]["DISP"]["START"]
63
+ self._disp_end = integrity_level["CVC"]["DISP"]["END"]
64
+ self._decl_start = integrity_level["PREDECL"]["DISP"]["START"]
65
+ self._decl_end = integrity_level["PREDECL"]["DISP"]["END"]
66
+
67
+ def _get_byte_size_string(self, data_type):
68
+ """Get byte size of a data type as string.
69
+ Enumeration byte sizes are derived from the underlying data type.
70
+
71
+ Args:
72
+ data_type (str): Data type.
73
+ Returns:
74
+ byte_size_string(powertrain_build.types.byte_size_string): Return result of
75
+ powertrain_build.types.byte_size_string.
76
+ """
77
+ if data_type in self._enumerations:
78
+ return byte_size_string(self._enumerations[data_type]["underlying_data_type"])
79
+ return byte_size_string(data_type)
80
+
81
+ def _get_bitmask(self, data_type):
82
+ """Get bitmask of a data type.
83
+ Enumeration bitmasks are derived from the underlying data type.
84
+
85
+ Args:
86
+ data_type (str): Data type.
87
+ Returns:
88
+ get_bitmask(powertrain_build.types.get_bitmask): Return result of powertrain_build.types.get_bitmask.
89
+ """
90
+ if data_type in self._enumerations:
91
+ return get_bitmask(self._enumerations[data_type]["underlying_data_type"])
92
+ return get_bitmask(data_type)
93
+
94
+ def _restruct_input_data(self):
95
+ """Restructure all the input variables per data-type.
96
+
97
+ This will be used for declaring the variables and generating the
98
+ A2L-file
99
+ """
100
+ external_inports = {}
101
+ external_outports = {}
102
+ for external_port_type in self.EXTERNAL_INPORT_TYPES:
103
+ if external_port_type in self._var_dict:
104
+ for var, data in self._var_dict[external_port_type].items():
105
+ data_type_size = self._get_byte_size_string(data[self.TYPE_NAME])
106
+ external_inports.setdefault(data_type_size, {})[var] = data
107
+ for external_port_type in self.EXTERNAL_OUTPORT_TYPES:
108
+ if external_port_type in self._var_dict:
109
+ for var, data in self._var_dict[external_port_type].items():
110
+ data_type_size = self._get_byte_size_string(data[self.TYPE_NAME])
111
+ external_outports.setdefault(data_type_size, {})[var] = data
112
+ self._ext_vars = external_inports, external_outports
113
+
114
+ def _a2l_dict(self):
115
+ """Return a dict defining all parameters for a2l-generation."""
116
+ res = {"vars": {}, "function": "VcExtVar"}
117
+ for inp in self.EXTERNAL_INPORT_TYPES:
118
+ if inp in self._var_dict:
119
+ for var, data in self._var_dict[inp].items():
120
+ if data[self.TYPE_NAME] in self._enumerations:
121
+ data_type = self._enumerations[data[self.TYPE_NAME]]["underlying_data_type"]
122
+ else:
123
+ data_type = data[self.TYPE_NAME]
124
+
125
+ resv = res["vars"]
126
+ resv.setdefault(var, {})["a2l_data"] = self.get_a2l_format(data)
127
+ resv[var]["array"] = []
128
+ resv[var]["function"] = ["VcEc"]
129
+ resv[var]["var"] = {"cvc_type": "CVC_DISP", "type": data_type, "var": var}
130
+ return res
131
+
132
+ def _get_array_declaration(self, var, width):
133
+ """Get array declaration string from width information.
134
+
135
+ Args:
136
+ var (str): Variable name.
137
+ width (int or list): Width information.
138
+ Returns:
139
+ array (str): Array declaration string.
140
+ """
141
+ array = ""
142
+ widths = [width] if not isinstance(width, list) else width
143
+ if len(widths) != 1 or widths[0] != 1:
144
+ for w in widths:
145
+ if w > 1:
146
+ if not isinstance(w, int):
147
+ self.critical(f'{var} widths must be integers. Got "{type(w)}"')
148
+ array += f'[{w}]'
149
+ elif w < 0:
150
+ self.critical(f'{var} widths can not be negative. Got "{w}"')
151
+ return array
152
+
153
+ def _generate_c_file(self, path):
154
+ """Generate the c-file defining all the supplier input signals."""
155
+ header = path.with_suffix(".h").name
156
+ var_set = set()
157
+ with path.open("w") as fh_c:
158
+ fh_c.write(f'#include "{header}"\n')
159
+ fh_c.write(f'#include "{self._disp_start}"\n\n')
160
+ for data_type_s, ext_vars in self._ext_vars[self.INPORT_INDEX].items():
161
+ fh_c.write(f"/* Variables of size {data_type_s} bytes */\n\n")
162
+ for var in sorted(ext_vars.keys()):
163
+ data = ext_vars[var]
164
+ if var not in var_set:
165
+ array = self._get_array_declaration(var, data.get("width", 1))
166
+ if array:
167
+ init_value = data["init"] if data["init"] != 0 else "{0}"
168
+ else:
169
+ init_value = data["init"]
170
+ fh_c.write(f"CVC_DISP {data[self.TYPE_NAME]} {var}{array} = {init_value};\n")
171
+ var_set.add(var)
172
+ fh_c.write("\n")
173
+ fh_c.write(f'\n#include "{self._disp_end}"\n')
174
+ self.info("Generated %s", path.name)
175
+
176
+ def _generate_h_file(self, path):
177
+ """Generate header file externally declaring interface signals."""
178
+ filename = path.stem
179
+ guard = f"{filename.upper()}_H"
180
+ var_set = set()
181
+ with path.open("w") as fh_c:
182
+ fh_c.write(f"#ifndef {guard}\n")
183
+ fh_c.write(f"#define {guard}\n")
184
+ fh_c.write("#define CVC_DISP\n")
185
+ fh_c.write(self._unit_cfg.base_types_headers)
186
+
187
+ for common_header_file in self._common_header_files:
188
+ fh_c.write(f'#include "{common_header_file}"\n')
189
+ fh_c.write("\n")
190
+
191
+ fh_c.write(f'#include "{self._decl_start}"\n')
192
+ fh_c.write("/* VCC Inports */\n")
193
+ for data_type_s, ext_vars in self._ext_vars[self.INPORT_INDEX].items():
194
+ fh_c.write(f"/* Variables of size {data_type_s} bytes */\n\n")
195
+ for var in sorted(ext_vars.keys()):
196
+ if var not in var_set:
197
+ data = ext_vars[var]
198
+ array = self._get_array_declaration(var, data.get("width", 1))
199
+ fh_c.write(f"extern CVC_DISP {data[self.TYPE_NAME]} {var}{array};\n")
200
+ var_set.add(var)
201
+ fh_c.write("\n")
202
+
203
+ fh_c.write("/* VCC Outports */\n")
204
+ for data_type_s, ext_vars in self._ext_vars[self.OUTPORT_INDEX].items():
205
+ fh_c.write(f"/* Variables of size {data_type_s} bytes */\n\n")
206
+ for var in sorted(ext_vars.keys()):
207
+ if var not in var_set:
208
+ data = ext_vars[var]
209
+ array = self._get_array_declaration(var, data.get("width", 1))
210
+ fh_c.write(f"extern CVC_DISP {data[self.TYPE_NAME]} {var}{array};\n")
211
+ var_set.add(var)
212
+ fh_c.write("\n")
213
+ fh_c.write(f'#include "{self._decl_end}"\n')
214
+ fh_c.write("#endif\n")
215
+ self.info("Generated %s", path.name)
216
+
217
+ def generate_files(self, path):
218
+ """Generate the c- and a2l-file for defining all the supplier input variables."""
219
+ self._restruct_input_data()
220
+ if not self._ext_vars[0] and not self._ext_vars[1]:
221
+ self.info(f"Skipping {path.name} as there were no corresponding vars.")
222
+ return
223
+ self._generate_c_file(path.with_suffix(".c"))
224
+ self._generate_h_file(path.with_suffix(".h"))
225
+ a2l_dict = self._a2l_dict()
226
+ a2l = A2l(a2l_dict, self._prj_cfg)
227
+ a2l.gen_a2l(path.with_suffix(".a2l"))
228
+
229
+
230
+ class ExtVarCsv(ExtVarBase):
231
+ """Handles variable dicts from CSV files.
232
+
233
+ Variable dict shall have the following format and is generated by the
234
+ :doc:`CsvSignalInterfaces <signal_interfaces>` class::
235
+
236
+ {
237
+ 'CAN-Input': {
238
+ 'signal1': {
239
+ 'IOType': 'd',
240
+ 'description': 'Some description',
241
+ 'init': 0,
242
+ 'max': 1,
243
+ 'min': 0,
244
+ 'type': 'UInt8',
245
+ 'unit': '-'
246
+ },
247
+ 'signal2': {
248
+ ...
249
+ }
250
+ },
251
+ 'CAN-Output': {
252
+ 'signal3': {
253
+ ...
254
+ }
255
+ },
256
+ 'xxx-Input': ...,
257
+ 'xxx-Output': ...
258
+ }
259
+ """
260
+
261
+ EXTERNAL_INPORT_TYPES = ["EMS-Input", "CAN-Input", "Private CAN-Input", "LIN-Input"]
262
+ EXTERNAL_OUTPORT_TYPES = ["EMS-Output", "CAN-Output", "Private CAN-Output", "LIN-Output"]
263
+ TYPE_NAME = "type"
264
+
265
+ def get_a2l_format(self, data):
266
+ """Get a2l format.
267
+
268
+ Args:
269
+ data (dict): Data dictionary.
270
+ Returns:
271
+ dict: A2l format dictionary.
272
+ """
273
+ return {
274
+ "bitmask": self._get_bitmask(data[self.TYPE_NAME]),
275
+ "description": data["description"],
276
+ "lsb": "2^0",
277
+ "max": data["max"],
278
+ "min": data["min"],
279
+ "offset": "0",
280
+ "unit": data["unit"],
281
+ "x_axis": None,
282
+ "y_axis": None,
283
+ }
284
+
285
+
286
+ class ExtVarYaml(ExtVarBase):
287
+ """Handles variable dicts from Yaml files.
288
+
289
+ Variable dict shall have the following format and is generated by the
290
+ :doc:`YamlSignalInterfaces <signal_interfaces>` class::
291
+
292
+ {
293
+ 'input': {
294
+ 'sVcIhfa_D_WhlMotSysFrntLimnIndcn': {},
295
+ 'sVcIhfa_D_WhlMotSysFrntModSts': {},
296
+ 'sVcIhfa_I_WhlMotSysFrntIdc': {},
297
+ 'sVcIhfa_U_UDcDcActHiSide1': {},
298
+ 'sVcIhfa_U_WhlMotSysFrntUdc': {}
299
+ },
300
+ 'output': {},
301
+ 'status': {},
302
+ }
303
+ """
304
+
305
+ EXTERNAL_INPORT_TYPES = ["input", "status"]
306
+ EXTERNAL_OUTPORT_TYPES = ["output"]
307
+ TYPE_NAME = "variable_type"
308
+
309
+ def get_a2l_format(self, data):
310
+ """Get a2l format.
311
+
312
+ Args:
313
+ data (dict): Data dictionary.
314
+ Returns:
315
+ dict: A2l format dictionary.
316
+ """
317
+ return {
318
+ "bitmask": self._get_bitmask(data[self.TYPE_NAME]),
319
+ "description": data["description"],
320
+ "lsb": "2^0",
321
+ "max": data["range"]["max"],
322
+ "min": data["range"]["min"],
323
+ "offset": "0",
324
+ "unit": data["unit"],
325
+ "x_axis": None,
326
+ "y_axis": None,
327
+ }