Merge "Add option for generating RTE dummy files"
This commit is contained in:
commit
55f9545791
@ -34,6 +34,7 @@ from powertrain_build.memory_section import MemorySection
|
||||
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.rte_dummy import RteDummy
|
||||
from powertrain_build.sched_funcs import SchedFuncs
|
||||
from powertrain_build.signal_if_html_rep import SigIfHtmlReport
|
||||
from powertrain_build.signal_incons_html_rep import SigConsHtmlReport
|
||||
@ -669,6 +670,11 @@ def add_args(parser):
|
||||
action="store_true",
|
||||
help="Generate core dummy code to enable integration with old supplier code",
|
||||
)
|
||||
powertrain_build_parser.add_argument(
|
||||
"--rte-dummy",
|
||||
action="store_true",
|
||||
help="Generate RTE dummy code to enable e.g. Silver testing",
|
||||
)
|
||||
powertrain_build_parser.add_argument(
|
||||
"--debug", action="store_true", help="Activate the debug log"
|
||||
)
|
||||
@ -708,6 +714,7 @@ def build(
|
||||
project_config,
|
||||
interface=False,
|
||||
core_dummy=False,
|
||||
rte_dummy=False,
|
||||
no_abort=False,
|
||||
no_nvm_a2l=False,
|
||||
debug=False,
|
||||
@ -724,6 +731,7 @@ def build(
|
||||
project_config (str): Project configuration file.
|
||||
interface (bool): Generate interface report. Default=False.
|
||||
core_dummy (bool): Generate core dummy code. Default=False.
|
||||
rte_dummy (bool): Generate RTE dummy code. Default=False.
|
||||
no_abort (bool): Do not abort due to errors. Default=False.
|
||||
no_nvm_a2l (bool): Do not generate A2L for NVM structs. Default=False.
|
||||
debug (bool): Activate the debug log. Default=False.
|
||||
@ -921,9 +929,15 @@ def build(
|
||||
LOG.info("Generating DID files")
|
||||
zc_dids.generate_did_files()
|
||||
LOG.info("******************************************************")
|
||||
LOG.info("Start generating NVMDefinitions")
|
||||
LOG.info("Generating NVM definitions")
|
||||
zc_nvm.generate_nvm_rte_files()
|
||||
|
||||
if rte_dummy:
|
||||
LOG.info("******************************************************")
|
||||
LOG.info("Generating RTE dummy files")
|
||||
zc_rte = RteDummy(build_cfg, zc_nvm)
|
||||
zc_rte.generate_rte_dummy()
|
||||
|
||||
if code_generation_config["generateCalibrationInterfaceFiles"]:
|
||||
LOG.info("******************************************************")
|
||||
LOG.info("Generating calibration interface files")
|
||||
|
132
powertrain_build/rte_dummy.py
Normal file
132
powertrain_build/rte_dummy.py
Normal file
@ -0,0 +1,132 @@
|
||||
# Copyright 2024 Volvo Car Corporation
|
||||
# Licensed under Apache 2.0.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Module containing classes for generating RTE dummy code.
|
||||
|
||||
These files are needed for building test SW,
|
||||
where the RTE is not available.
|
||||
For example, when running Silver tests.
|
||||
"""
|
||||
|
||||
from powertrain_build.problem_logger import ProblemLogger
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class RteDummy(ProblemLogger):
|
||||
"""A class for RTE dummy file generation."""
|
||||
|
||||
def __init__(self, build_cfg, nvm_def):
|
||||
"""Init.
|
||||
|
||||
Args:
|
||||
build_cfg (BuildProjConfig): Object with build configuration settings.
|
||||
nvm_def (ZCNVMDef): Object with NVM definition information.
|
||||
"""
|
||||
super().__init__()
|
||||
self.build_cfg = build_cfg
|
||||
self.nvm_def = nvm_def
|
||||
self.header_file_name = "Rte_Type"
|
||||
self.source_file_name = "Rte_Dummy"
|
||||
nvm_port_pattern = self.build_cfg.get_composition_config("nvmPortPattern")
|
||||
if nvm_port_pattern is None:
|
||||
nvm_port_pattern = "{NvName}"
|
||||
self.nvm_port_pattern = nvm_port_pattern
|
||||
|
||||
def _get_header_header(self):
|
||||
"""Get header for the RTE dummy header."""
|
||||
return (
|
||||
"/*\n"
|
||||
" * This file is generated by the Powertrain Build System.\n"
|
||||
" * It defines RTE dummy types.\n"
|
||||
" * Do not modify this file manually.\n"
|
||||
" */\n"
|
||||
f"#ifndef {self.header_file_name.upper()}_H\n"
|
||||
f"#define {self.header_file_name.upper()}_H\n\n"
|
||||
'#include "tl_basetypes.h"\n\n'
|
||||
"#define FALSE 0U\n"
|
||||
"#define TRUE 1U\n\n"
|
||||
)
|
||||
|
||||
def _get_header_footer(self):
|
||||
"""Get footer for the RTE dummy header."""
|
||||
return f"\n#endif /* {self.header_file_name.upper()}_H */\n"
|
||||
|
||||
def _get_source_header(self):
|
||||
"""Get header for the RTE dummy source."""
|
||||
return (
|
||||
"/*\n"
|
||||
" * This file is generated by the Powertrain Build System.\n"
|
||||
" * It defines RTE dummy functions.\n"
|
||||
" * Do not modify this file manually.\n"
|
||||
" */\n"
|
||||
f'#include "{self.header_file_name}.h"\n\n'
|
||||
)
|
||||
|
||||
def _get_nvm_header_dummy(self):
|
||||
"""Get NVM dummy header code."""
|
||||
struct_defines = []
|
||||
function_declarations = []
|
||||
prefix = self.build_cfg.get_scheduler_prefix()
|
||||
|
||||
for memory_area in self.nvm_def._nvm_memory_areas:
|
||||
nvm_name = f"{prefix}{memory_area}"
|
||||
function_prefix = f"Rte_Call_{self.nvm_port_pattern.format(NvName=nvm_name)}"
|
||||
function_declarations.append(f"dt_{nvm_name} *Rte_Pim_{nvm_name}(void);")
|
||||
function_declarations.append(f"void {function_prefix}_SetRamBlockStatus(UInt8 status);")
|
||||
function_declarations.append(f"void {function_prefix}_GetErrorStatus(UInt8 *status);")
|
||||
function_declarations.append(f"void {function_prefix}_WriteBlock(dt_{nvm_name} *block);")
|
||||
|
||||
if self.build_cfg.get_code_generation_config("useRteNvmStructs"):
|
||||
struct_defines.append("typedef struct\n{")
|
||||
memory_area_index = self.nvm_def._get_nvm_areas_index(memory_area)
|
||||
nr_of_unused_signals = self.nvm_def.nvm_definitions[memory_area_index]["size"]
|
||||
signals = self.nvm_def.nvm_definitions[memory_area_index]["signals"]
|
||||
for signal in signals:
|
||||
signal_string = ""
|
||||
nr_of_unused_signals -= signal["x_size"] * signal["y_size"]
|
||||
signal_string += f' {signal["type"]} {self.nvm_def.struct_member_prefix}{signal["name"]}'
|
||||
size = max(signal["x_size"], 1) * max(signal["y_size"], 1)
|
||||
if size > 1:
|
||||
if signal["x_size"] > 1:
|
||||
signal_string += f'[{signal["x_size"]}]'
|
||||
if signal["y_size"] > 1:
|
||||
signal_string += f'[{signal["y_size"]}]'
|
||||
signal_string += ";"
|
||||
struct_defines.append(signal_string)
|
||||
if nr_of_unused_signals > 0:
|
||||
struct_defines.append(
|
||||
f' {self.nvm_def.nvm_definitions[memory_area_index]["default_datatype"]} '
|
||||
f'unused[{nr_of_unused_signals}];'
|
||||
)
|
||||
struct_defines.append(f"}} dt_{nvm_name};\n")
|
||||
|
||||
return "\n".join(struct_defines + function_declarations)
|
||||
|
||||
def _generate_nvm_source_dummy(self):
|
||||
"""Generate NVM source dummy code."""
|
||||
lines_to_write = []
|
||||
prefix = self.build_cfg.get_scheduler_prefix()
|
||||
for memory_area in self.nvm_def._nvm_memory_areas:
|
||||
nvm_name = f"{prefix}{memory_area}"
|
||||
function_prefix = f"Rte_Call_{self.nvm_port_pattern.format(NvName=nvm_name)}"
|
||||
lines_to_write.append(f"dt_{nvm_name} *Rte_Pim_{nvm_name}(void) {{ return (dt_{nvm_name} *)0; }}")
|
||||
lines_to_write.append(f"void {function_prefix}_SetRamBlockStatus(UInt8 status) {{}}")
|
||||
lines_to_write.append(f"void {function_prefix}_GetErrorStatus(UInt8 *status) {{}}")
|
||||
lines_to_write.append(f"void {function_prefix}_WriteBlock(dt_{nvm_name} *block) {{}}")
|
||||
lines_to_write.append("")
|
||||
return "\n".join(lines_to_write)
|
||||
|
||||
def generate_rte_dummy(self):
|
||||
"""Generate RTE dummy files."""
|
||||
src_code_dest_dir = self.build_cfg.get_src_code_dst_dir()
|
||||
header_file = Path(src_code_dest_dir, self.header_file_name + ".h")
|
||||
source_file = Path(src_code_dest_dir, self.source_file_name + ".c")
|
||||
with header_file.open(mode="w", encoding="utf-8") as header_fh:
|
||||
header_fh.write(self._get_header_header())
|
||||
header_fh.write(self._get_nvm_header_dummy())
|
||||
header_fh.write(self._get_header_footer())
|
||||
with source_file.open(mode="w", encoding="utf-8") as source_fh:
|
||||
source_fh.write(self._get_source_header())
|
||||
source_fh.write(self._generate_nvm_source_dummy())
|
@ -56,6 +56,7 @@ class PyBuildWrapper(pt_matlab.Matlab):
|
||||
self.project_config = self._set_project_configuration(args)
|
||||
self.generate_system_info = getattr(args, "generate_system_info", False)
|
||||
self.core_dummy = getattr(args, "core_dummy", True)
|
||||
self.rte_dummy = getattr(args, "rte_dummy", False)
|
||||
self.debug = getattr(args, "debug", True)
|
||||
self.no_abort = getattr(args, "no_abort", True)
|
||||
self.no_nvm_a2l = getattr(args, "no_nvm_a2l", False)
|
||||
@ -374,6 +375,7 @@ class PyBuildWrapper(pt_matlab.Matlab):
|
||||
self.project_config,
|
||||
interface=self.interface,
|
||||
core_dummy=self.core_dummy,
|
||||
rte_dummy=self.rte_dummy,
|
||||
no_abort=self.no_abort,
|
||||
no_nvm_a2l=self.no_nvm_a2l,
|
||||
debug=self.debug,
|
||||
|
122
tests/powertrain_build/test_rte_dummy.py
Normal file
122
tests/powertrain_build/test_rte_dummy.py
Normal file
@ -0,0 +1,122 @@
|
||||
# Copyright 2024 Volvo Car Corporation
|
||||
# Licensed under Apache 2.0.
|
||||
|
||||
"""Unit test script for powertrain_build.rte_dummy."""
|
||||
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch, mock_open
|
||||
|
||||
from powertrain_build.rte_dummy import RteDummy
|
||||
|
||||
|
||||
def mock_get_nvm_areas_index(memory_area):
|
||||
"""Return the index of the given memory area."""
|
||||
return {"NVM_LIST_8": 0, "NVM_LIST_16": 1}[memory_area]
|
||||
|
||||
|
||||
class TestRteDummy(unittest.TestCase):
|
||||
"""Class for testing powertrain_build.rte_dummy."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set-up mocks and common variables and data structures for all tests in the test case."""
|
||||
self.build_cfg = MagicMock()
|
||||
self.build_cfg.get_scheduler_prefix.return_value = "DUMMY_"
|
||||
self.build_cfg.get_composition_config.return_value = "PS_DUMMY_SwcNv_{NvName}"
|
||||
self.nvm_def = MagicMock()
|
||||
self.nvm_def._get_nvm_areas_index.side_effect = mock_get_nvm_areas_index
|
||||
self.nvm_def.struct_member_prefix = "e_"
|
||||
self.nvm_def._nvm_memory_areas = ("NVM_LIST_8", "NVM_LIST_16")
|
||||
self.nvm_def.nvm_definitions = [
|
||||
{
|
||||
"name": "NVM_LIST_8",
|
||||
"allowed_datatypes": ["Bool", "UInt8", "Int8"],
|
||||
"size": 2,
|
||||
"instanceName": "nvm_list_8",
|
||||
"default_datatype": "UInt8",
|
||||
"includeStop": "",
|
||||
"includeStart": "",
|
||||
"persistent": False,
|
||||
"signals": [
|
||||
{"name": "dummy", "type": "UInt8", "x_size": 1, "y_size": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "NVM_LIST_16",
|
||||
"allowed_datatypes": ["UInt16", "Int16"],
|
||||
"size": 2,
|
||||
"instanceName": "nvm_list_16",
|
||||
"default_datatype": "UInt16",
|
||||
"includeStop": "",
|
||||
"includeStart": "",
|
||||
"persistent": False,
|
||||
"signals": [
|
||||
{"name": "dummy2", "type": "UInt16", "x_size": 1, "y_size": 1}
|
||||
]
|
||||
}
|
||||
]
|
||||
self.rte_dummy = RteDummy(self.build_cfg, self.nvm_def)
|
||||
|
||||
def test_generate_rte_dummy(self):
|
||||
"""Test RteDummy.generate_rte_dummy()."""
|
||||
result = []
|
||||
m_open = mock_open()
|
||||
m_open.return_value.write = result.append
|
||||
with patch.object(Path, "open", m_open, create=True):
|
||||
self.rte_dummy.generate_rte_dummy()
|
||||
expected = [
|
||||
( # header header
|
||||
"/*\n"
|
||||
" * This file is generated by the Powertrain Build System.\n"
|
||||
" * It defines RTE dummy types.\n"
|
||||
" * Do not modify this file manually.\n"
|
||||
" */\n"
|
||||
"#ifndef RTE_TYPE_H\n"
|
||||
"#define RTE_TYPE_H\n\n"
|
||||
"#include \"tl_basetypes.h\"\n\n"
|
||||
"#define FALSE 0U\n"
|
||||
"#define TRUE 1U\n\n"
|
||||
),
|
||||
( # header content
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" UInt8 e_dummy;\n"
|
||||
" UInt8 unused[1];\n"
|
||||
"} dt_DUMMY_NVM_LIST_8;\n\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" UInt16 e_dummy2;\n"
|
||||
" UInt16 unused[1];\n"
|
||||
"} dt_DUMMY_NVM_LIST_16;\n\n"
|
||||
"dt_DUMMY_NVM_LIST_8 *Rte_Pim_DUMMY_NVM_LIST_8(void);\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_8_SetRamBlockStatus(UInt8 status);\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_8_GetErrorStatus(UInt8 *status);\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_8_WriteBlock(dt_DUMMY_NVM_LIST_8 *block);\n"
|
||||
"dt_DUMMY_NVM_LIST_16 *Rte_Pim_DUMMY_NVM_LIST_16(void);\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_16_SetRamBlockStatus(UInt8 status);\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_16_GetErrorStatus(UInt8 *status);\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_16_WriteBlock(dt_DUMMY_NVM_LIST_16 *block);"
|
||||
),
|
||||
( # header footer
|
||||
"\n#endif /* RTE_TYPE_H */\n"
|
||||
),
|
||||
( # source header
|
||||
"/*\n"
|
||||
" * This file is generated by the Powertrain Build System.\n"
|
||||
" * It defines RTE dummy functions.\n"
|
||||
" * Do not modify this file manually.\n"
|
||||
" */\n"
|
||||
"#include \"Rte_Type.h\"\n\n"
|
||||
),
|
||||
( # source content
|
||||
"dt_DUMMY_NVM_LIST_8 *Rte_Pim_DUMMY_NVM_LIST_8(void) { return (dt_DUMMY_NVM_LIST_8 *)0; }\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_8_SetRamBlockStatus(UInt8 status) {}\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_8_GetErrorStatus(UInt8 *status) {}\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_8_WriteBlock(dt_DUMMY_NVM_LIST_8 *block) {}\n"
|
||||
"dt_DUMMY_NVM_LIST_16 *Rte_Pim_DUMMY_NVM_LIST_16(void) { return (dt_DUMMY_NVM_LIST_16 *)0; }\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_16_SetRamBlockStatus(UInt8 status) {}\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_16_GetErrorStatus(UInt8 *status) {}\n"
|
||||
"void Rte_Call_PS_DUMMY_SwcNv_DUMMY_NVM_LIST_16_WriteBlock(dt_DUMMY_NVM_LIST_16 *block) {}\n"
|
||||
)
|
||||
]
|
||||
self.assertListEqual(result, expected)
|
Loading…
x
Reference in New Issue
Block a user