
We don't transfer git history since it may contain proprietary data that we cannot have in an open sources version. Change-Id: I9586124c1720db69a76b9390e208e9f0ba3b86d4
160 lines
6.6 KiB
Python
160 lines
6.6 KiB
Python
# Copyright 2024 Volvo Car Corporation
|
|
# Licensed under Apache 2.0.
|
|
|
|
"""Module for generation of c- and a2l-file with dummy signal declarations."""
|
|
|
|
import pybuild.build_defs as bd
|
|
|
|
from pybuild.types import byte_size_string, get_bitmask
|
|
from pybuild.a2l import A2l
|
|
from pybuild.problem_logger import ProblemLogger
|
|
|
|
|
|
class DummyVar(ProblemLogger):
|
|
"""Generate c- and a2l-files which declares all missing variables in the interfaces.
|
|
|
|
TODO: Please remove this file! Only used while testing.
|
|
"""
|
|
|
|
def __init__(self, unit_cfg, ext_dict, res_dict, prj_cfg, user_defined_types):
|
|
"""Initialize instance of class."""
|
|
super().__init__()
|
|
self._unit_cfg = unit_cfg
|
|
self._unit_vars = unit_cfg.get_per_cfg_unit_cfg()
|
|
self._ext_dict = ext_dict
|
|
self._res_dict = res_dict
|
|
self._ext_vars = {}
|
|
self._int_vars = {}
|
|
self._prj_cfg = prj_cfg
|
|
self._enumerations = user_defined_types.get_enumerations()
|
|
self._common_header_files = user_defined_types.common_header_files
|
|
|
|
def _get_byte_size_string(self, data_type):
|
|
"""Get byte size of a data type as string.
|
|
Enumeration byte sizes are derived from the underlying data type.
|
|
|
|
Args:
|
|
data_type (str): Data type.
|
|
Returns:
|
|
byte_size_string(pybuild.types.byte_size_string): Return result of pybuild.types.byte_size_string.
|
|
"""
|
|
if data_type in self._enumerations:
|
|
return byte_size_string(self._enumerations[data_type]['underlying_data_type'])
|
|
return byte_size_string(data_type)
|
|
|
|
def _restruct_input_data(self):
|
|
"""Restructure all the input variables per data-type.
|
|
|
|
This will be used for declaring the variables and generating the
|
|
A2L-file
|
|
"""
|
|
ext_out = {var: data for ioclass, vardict in self._ext_dict.items()
|
|
if ioclass.endswith('-Output') for var, data in vardict.items()}
|
|
ext_ = {}
|
|
for var in self._res_dict['sigs']['ext']['missing']:
|
|
self.debug('ext: %s', var)
|
|
if var in ext_out:
|
|
data = ext_out[var]
|
|
self.debug('ext_data: %s', data)
|
|
ext_[var] = data
|
|
int_ = {}
|
|
for unit in self._res_dict['sigs']['int']:
|
|
for var in self._res_dict['sigs']['int'][unit]['missing']:
|
|
if var not in ext_ and var in self._unit_vars['inports']:
|
|
data = self._unit_vars['inports'][var][unit]
|
|
int_[var] = data
|
|
for var, data in int_.items():
|
|
data_type_size = self._get_byte_size_string(data['type'])
|
|
self._int_vars.setdefault(data_type_size, {})[var] = data
|
|
for var, data in ext_.items():
|
|
data_type_size = self._get_byte_size_string(data['type'])
|
|
self._ext_vars.setdefault(data_type_size, {})[var] = data
|
|
|
|
def _a2l_dict(self):
|
|
"""Return a dict defining all parameters for a2l-generation."""
|
|
res = {
|
|
'vars': {},
|
|
'function': 'VcDummy'
|
|
}
|
|
for inp in [self._ext_vars]:
|
|
for sizes in inp.values():
|
|
for var, data in sizes.items():
|
|
if data['type'] in self._enumerations:
|
|
data_type = self._enumerations[data['type']]['underlying_data_type']
|
|
else:
|
|
data_type = data['type']
|
|
|
|
resv = res['vars']
|
|
resv.setdefault(var, {})['a2l_data'] = {
|
|
'bitmask': get_bitmask(data_type),
|
|
'description': data.get('description', ''),
|
|
'lsb': '2^0',
|
|
'max': data.get('max'),
|
|
'min': data.get('min'),
|
|
'offset': '0',
|
|
'unit': data['unit'],
|
|
'x_axis': None,
|
|
'y_axis': None
|
|
}
|
|
resv[var]['array'] = []
|
|
resv[var]['function'] = ['VcEc']
|
|
resv[var]['var'] = {
|
|
'cvc_type': 'CVC_DISP',
|
|
'type': data_type,
|
|
'var': var
|
|
}
|
|
return res
|
|
|
|
@classmethod
|
|
def _generate_var_defs(cls, fh_c, vars, enums, comment):
|
|
"""Generate the variable definitions."""
|
|
fh_c.write(f'\n{comment}\n\n')
|
|
for varsize in sorted(vars.keys(), reverse=True):
|
|
fh_c.write(f'/* Variables of size {varsize} bytes */\n\n')
|
|
var_defs = vars[varsize]
|
|
for var in sorted(var_defs.keys()):
|
|
data = var_defs[var]
|
|
if data['type'] in enums:
|
|
if enums[data['type']]['default_value'] is not None:
|
|
init_value = enums[data['type']]['default_value']
|
|
else:
|
|
cls.warning('Initializing enumeration %s to "zero".', data['type'])
|
|
init_value = [k for k, v in enums[data['type']]['members'].items() if v == 0][0]
|
|
fh_c.write(f"{data['type']} {var} = {init_value};\n")
|
|
else:
|
|
fh_c.write(f"{data['type']} {var} = {0};\n")
|
|
fh_c.write('\n')
|
|
|
|
@classmethod
|
|
def _generate_var_initialization(cls, fh_c, vars, comment):
|
|
"""Generate the variable initializations."""
|
|
fh_c.write(f'\n{comment}\n\n')
|
|
fh_c.write('\nvoid RESTART_VcDummy(void)\n{\n')
|
|
for varsize in sorted(vars.keys(), reverse=True):
|
|
var_defs = vars[varsize]
|
|
for var in sorted(var_defs.keys()):
|
|
fh_c.write(f" {var} = {0};\n")
|
|
fh_c.write('}\n')
|
|
|
|
def _generate_c_file(self, filename):
|
|
"""Generate the c-file defining all missing input variables."""
|
|
general_includes = ''
|
|
general_includes += self._unit_cfg.base_types_headers
|
|
for common_header_file in self._common_header_files:
|
|
general_includes += f'#include "{common_header_file}"\n'
|
|
general_includes += '\n'
|
|
|
|
with open(filename, 'w', encoding="utf-8") as fh_c:
|
|
fh_c.write(general_includes)
|
|
fh_c.write(f'#include "{bd.CVC_DISP_START}"\n\n')
|
|
self._generate_var_defs(fh_c, self._ext_vars, self._enumerations, '/** Missing external signals **/')
|
|
fh_c.write(f'\n#include "{bd.CVC_DISP_END}"\n')
|
|
self.info('Generated %s', filename)
|
|
|
|
def generate_file(self, filename):
|
|
"""Generate the files for defining all missing input variables."""
|
|
self._restruct_input_data()
|
|
self._generate_c_file(filename + '.c')
|
|
a2l_dict = self._a2l_dict()
|
|
A2l(a2l_dict, self._prj_cfg).gen_a2l(filename + '.a2l')
|