65c1d746a7
We don't transfer git history since it may contain proprietary data that we cannot have in an open sources version. Change-Id: I9586124c1720db69a76b9390e208e9f0ba3b86d4
225 lines
9.8 KiB
Python
225 lines
9.8 KiB
Python
# Copyright 2024 Volvo Car Corporation
|
|
# Licensed under Apache 2.0.
|
|
|
|
# -*- coding: utf-8 -*-
|
|
"""Module containing cvc classes for VCC - defines and includes for memory sections."""
|
|
|
|
import time
|
|
from pathlib import Path
|
|
from pybuild import build_defs
|
|
from pybuild.problem_logger import ProblemLogger
|
|
|
|
|
|
class MemorySection(ProblemLogger):
|
|
"""Handle headers for CVC_* definitions."""
|
|
|
|
calibration_definitions = [
|
|
'CVC_CAL',
|
|
'CVC_CAL_ASIL_A',
|
|
'CVC_CAL_ASIL_B',
|
|
'CVC_CAL_ASIL_C',
|
|
'CVC_CAL_ASIL_D',
|
|
'CVC_CAL_MERGEABLE_ASIL_A',
|
|
'CVC_CAL_MERGEABLE_ASIL_B',
|
|
'CVC_CAL_MERGEABLE_ASIL_C',
|
|
'CVC_CAL_MERGEABLE_ASIL_D'
|
|
]
|
|
measurable_definitions = [
|
|
'CVC_DISP',
|
|
'CVC_DISP_ASIL_A',
|
|
'CVC_DISP_ASIL_B',
|
|
'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.xcp_enabled = self.build_cfg.get_xcp_enabled()
|
|
self.use_volatile_globals = self.build_cfg.get_use_volatile_globals()
|
|
|
|
@staticmethod
|
|
def _get_mem_map_section(section):
|
|
return 'STOP' if section == 'END' else section
|
|
|
|
@staticmethod
|
|
def _get_header(section_file):
|
|
section_file_header_guard = section_file.split('.')[0].upper()
|
|
return [
|
|
f'#ifndef {section_file_header_guard}_H\n',
|
|
f'#define {section_file_header_guard}_H\n\n'
|
|
]
|
|
|
|
@staticmethod
|
|
def _get_footer(section_file):
|
|
section_file_header_guard = section_file.split('.')[0].upper()
|
|
return [f'\n#endif /* {section_file_header_guard}_H */\n']
|
|
|
|
def _get_cal(self, section):
|
|
cvc_undefines = [f'#undef {definition}\n' for definition in self.calibration_definitions]
|
|
if section == 'START':
|
|
volatile_string = 'volatile' if self.use_volatile_globals else ''
|
|
cvc_defines = [f'#define {definition} {volatile_string}\n' for definition in self.calibration_definitions]
|
|
else:
|
|
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
|
|
)
|
|
]
|
|
if self.ecu_supplier != 'HI' or not self.xcp_enabled:
|
|
memory_section_handling.append(self.mem_map_include)
|
|
return cvc_undefines, cvc_defines, memory_section_handling
|
|
|
|
def _get_disp(self, section):
|
|
cvc_undefines = [f'#undef {definition}\n' for definition in self.measurable_definitions]
|
|
if section == 'START':
|
|
volatile_string = 'volatile' if self.use_volatile_globals else ''
|
|
cvc_defines = [f'#define {definition} {volatile_string}\n' for definition in self.measurable_definitions]
|
|
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_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_include
|
|
]
|
|
return cvc_undefines, cvc_defines, memory_section_handling
|
|
|
|
def _get_const(self, section):
|
|
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_include
|
|
]
|
|
return cvc_undefines, cvc_defines, memory_section_handling
|
|
|
|
def _get_rest(self):
|
|
cvc_undefines = []
|
|
cvc_defines = []
|
|
memory_section_handling = [
|
|
self.mem_map_include
|
|
]
|
|
return cvc_undefines, cvc_defines, memory_section_handling
|
|
|
|
def _get_predecl(self):
|
|
cvc_undefines = []
|
|
cvc_defines = []
|
|
memory_section_handling = [
|
|
self.mem_map_include
|
|
]
|
|
return cvc_undefines, cvc_defines, memory_section_handling
|
|
|
|
def generate_cvc_header(self, section, section_file):
|
|
"""Generate CVC headers.
|
|
|
|
Args:
|
|
section (str): Name of the CVC section
|
|
section_file (str): Name of the header file
|
|
Returns:
|
|
lines_to_write (list(str)): Lines to write to given section file.
|
|
"""
|
|
header = self._get_header(section_file) if self.include_header_guards else []
|
|
footer = self._get_footer(section_file) if self.include_header_guards else []
|
|
if '_CAL_' in section_file:
|
|
cvc_undefines, cvc_defines, memory_section_handling = self._get_cal(section)
|
|
elif '_DISP_' in section_file:
|
|
cvc_undefines, cvc_defines, memory_section_handling = self._get_disp(section)
|
|
elif not section_file.startswith('PREDECL_'):
|
|
if section_file.startswith('CVC_CAL') or section_file.startswith('CVC_DISP'):
|
|
self.critical('Should not find CVC_CAL/DISP here. Check logic. File: %s.', section_file)
|
|
elif section_file.startswith('CVC_CODE'):
|
|
cvc_undefines, cvc_defines, memory_section_handling = self._get_code(section)
|
|
elif section_file.startswith('CVC_CONST'):
|
|
cvc_undefines, cvc_defines, memory_section_handling = self._get_const(section)
|
|
else:
|
|
cvc_undefines, cvc_defines, memory_section_handling = self._get_rest()
|
|
else:
|
|
cvc_undefines, cvc_defines, memory_section_handling = self._get_predecl()
|
|
|
|
return header + cvc_undefines + cvc_defines + memory_section_handling + footer
|
|
|
|
def generate_required_header_files(self):
|
|
"""Generate required header files to delivery folder.
|
|
|
|
Generate required header files such as memory protection files.
|
|
NOTE: Currently, only one ASIL level can be selected for an SWC.
|
|
"""
|
|
self.info('******************************************************')
|
|
self.info('Start generating required header files')
|
|
start_time = time.time()
|
|
src_dst_dir = self.build_cfg.get_src_code_dst_dir()
|
|
for section_dict in build_defs.PREDECL_EXTRA.values():
|
|
for section_file in section_dict.values():
|
|
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)
|
|
|
|
for asil_dict in build_defs.ASIL_LEVEL_MAP.values():
|
|
for type_dict in asil_dict.values():
|
|
for section_dict in type_dict.values():
|
|
for section, section_file in section_dict.items():
|
|
lines_to_write = self.generate_cvc_header(section, section_file)
|
|
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 section_dict in nvm_dict.values():
|
|
for section_file in section_dict.values():
|
|
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)
|
|
self.info('Finished generating required header files (in %4.2f s)', time.time() - start_time)
|