diff --git a/.vscode/settings.json b/.vscode/settings.json index 0051eac..3fc34b4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ "bdist", "Bswm", "Bswmd", + "CORTEXM", "datamodel", "ebmodel", "Ecuc", @@ -17,6 +18,7 @@ "Microkernel", "nsmap", "openpyxl", + "OSDEFAULTAPPMODE", "ostask", "preemptable", "prefs", diff --git a/README.md b/README.md index 4f1ae24..094e8a2 100644 --- a/README.md +++ b/README.md @@ -206,4 +206,9 @@ PrefSystemImporter --base-path c:/EB/ACG-8_8_8_WIN32X86/workspace/simple_demo_rt 1. Solve the case issue of read_optional_value enables attribute. 2. Support to read IMPORT_INFO for OsResource. -3. Add the test cases for OsXdmParser. \ No newline at end of file +3. Add the test cases for OsXdmParser. + +**Version 1.1.8** + +1. Support to read NvM configuration from EB tresos Xdm file +2. Export the NvM Configuration to excel file. \ No newline at end of file diff --git a/setup.py b/setup.py index 664ee04..9fe5f39 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='py_eb_model', - version='1.1.7', + version='1.1.8', license='proprietary', description="The parser for EB XDM file", long_description=long_description, diff --git a/src/eb_model/cli/pref_system_importer_cli.py b/src/eb_model/cli/pref_system_importer_cli.py index 386b078..4392706 100644 --- a/src/eb_model/cli/pref_system_importer_cli.py +++ b/src/eb_model/cli/pref_system_importer_cli.py @@ -9,23 +9,31 @@ from ..parser import PerfXdmParser from ..models import PreferenceModel + def main(): version = pkg_resources.require("py_eb_model")[0].version ap = argparse.ArgumentParser() - ap.add_argument("-v", "--verbose", required= False, help = "print debug information.", action = "store_true") - ap.add_argument("--file-list", required=False, help = "generate the file list (Default)", action = "store_true") - ap.add_argument("--ab-project", required=False, help = "generate the AUTOSAR builder project", action = "store_true") - ap.add_argument("--base-path", required=True, help="base Path for EB tresos") - ap.add_argument("--env", required=False, help="specify the environment variable", nargs='+') - ap.add_argument("--project", required=False, help="specify the project name") - ap.add_argument("INPUTS", nargs='+', help = "The path of perf_imp_xxx.xdm.") - ap.add_argument("OUTPUT", help = "The path of output file.") + ap.description = "PrefSystemImporter ver: %s" % version + ap.add_argument("-v", "--verbose", required=False, + help="print debug information.", action="store_true") + ap.add_argument("--file-list", required=False, + help="generate the file list (Default)", action="store_true") + ap.add_argument("--ab-project", required=False, + help="generate the AUTOSAR builder project", action="store_true") + ap.add_argument("--base-path", required=True, + help="base Path for EB tresos") + ap.add_argument("--env", required=False, + help="specify the environment variable", nargs='+') + ap.add_argument("--project", required=False, + help="specify the project name") + ap.add_argument("INPUTS", nargs='+', help="The path of perf_imp_xxx.xdm.") + ap.add_argument("OUTPUT", help="The path of output file.") args = ap.parse_args() logger = logging.getLogger() - + formatter = logging.Formatter('[%(levelname)s] : %(message)s') stdout_handler = logging.StreamHandler(sys.stderr) @@ -48,7 +56,7 @@ def main(): stdout_handler.setLevel(logging.DEBUG) else: stdout_handler.setLevel(logging.INFO) - + if args.verbose: logger.addHandler(file_handler) logger.addHandler(stdout_handler) @@ -68,7 +76,8 @@ def main(): parser = PerfXdmParser() for file in args.INPUTS: if args.base_path is not None: - file_name = os.path.realpath(os.path.join(args.base_path, file)) + file_name = os.path.realpath( + os.path.join(args.base_path, file)) else: file_name = file parser.parse_preference_xdm(file_name, doc) @@ -80,7 +89,7 @@ def main(): m = re.match(r'(\w+)=([:\/\\\.\w]+)', env) if m: params["env_var:%s" % m.group(1)] = m.group(2) - #params['tresos_output_base_dir'] = args.TRESOS_OUTPUT_BASE_DIR + # params['tresos_output_base_dir'] = args.TRESOS_OUTPUT_BASE_DIR if format == "file_list": writer = TextPreferenceModelWriter() @@ -88,7 +97,7 @@ def main(): elif format == "ab_project": writer = ABProjectWriter() writer.writer_import_files(args.OUTPUT, doc.getSystemDescriptionImporter(), params) - + except Exception as e: logger.error(e) raise e diff --git a/src/eb_model/models/importer_xdm.py b/src/eb_model/models/importer_xdm.py index 5b0e23d..bded0f4 100644 --- a/src/eb_model/models/importer_xdm.py +++ b/src/eb_model/models/importer_xdm.py @@ -36,12 +36,14 @@ def getParsedInputFiles(self, params={}) -> List[str]: if m and m.group(1) in params: old_input_file = input_file input_file = params[m.group(1)] + m.group(2) - self.logger.info("Replace Environment Variable Path: %s => %s" % (old_input_file, os.path.realpath(input_file))) + # self.logger.info("Replace Environment Variable Path: %s => %s" % (old_input_file, os.path.realpath(input_file))) + self.logger.info("Replace Environment Variable Path: %s => %s" % (old_input_file, input_file)) if params['base_path'] is not None: if params['wildcard']: m = re.match(r'(.+)\\(\*\.\w+)', input_file) if m: for file_name in self.parseWildcard(os.path.realpath(os.path.join(params['base_path'], input_file))): + # self.logger.info("Add the file <%s>." % file_name) file_list.append(file_name) else: file_list.append(os.path.realpath(os.path.join(params['base_path'], input_file))) diff --git a/src/eb_model/models/nvm_xdm.py b/src/eb_model/models/nvm_xdm.py index da25c98..aca204e 100644 --- a/src/eb_model/models/nvm_xdm.py +++ b/src/eb_model/models/nvm_xdm.py @@ -2,18 +2,254 @@ from ..models.abstract import EcucParamConfContainerDef, Module, EcucRefType -class NvM(Module): - def __init__(self, parent): - super().__init__(parent, "NvM") +class NvMTargetBlockReference(EcucParamConfContainerDef): + def __init__(self, parent, name): + super().__init__(parent, name) - self.NvMBlockDescriptors = [] # type: List[NvMBlockDescriptor] - def getNvMBlockDescriptorList(self): - return self.NvMBlockDescriptors +class NvMEaRef(NvMTargetBlockReference): + def __init__(self, parent, name): + super().__init__(parent, name) + + self.NvMNameOfEaBlock: EcucRefType = None - def addNvMBlockDescriptor(self, value): + def getNvMNameOfEaBlock(self) -> EcucRefType: + return self.NvMNameOfEaBlock + + def setNvMNameOfEaBlock(self, value: EcucRefType): if value is not None: - self.NvMBlockDescriptors.append(value) + self.NvMNameOfEaBlock = value + return self + + +class NvMFeeRef(NvMTargetBlockReference): + def __init__(self, parent, name): + super().__init__(parent, name) + + self.NvMNameOfFeeBlock: EcucRefType = None + + def getNvMNameOfFeeBlock(self) -> EcucRefType: + return self.NvMNameOfFeeBlock + + def setNvMNameOfFeeBlock(self, value: EcucRefType): + if value is not None: + self.NvMNameOfFeeBlock = value + return self + + +class NvMCommon(EcucParamConfContainerDef): + def __init__(self, parent, name): + super().__init__(parent, name) + + self.NvMApiConfigClass: str = None + self.NvMBswMMultiBlockJobStatusInformation: bool = None + self.NvMCompiledConfigId: int = None + self.NvMCrcNumOfBytes: int = None + self.NvMCsmRetryCounter: int = None + self.NvMDatasetSelectionBits: int = None + self.NvMDevErrorDetect: bool = None + self.NvMDynamicConfiguration: bool = None + self.NvMJobPrioritization: bool = None + self.NvMMainFunctionPeriod: float = None + self.NvMMultiBlockCallback: str = None + self.NvMPollingMode: bool = None + self.NvMRepeatMirrorOperations: int = None + self.NvMSetRamBlockStatusApi: bool = None + self.NvMSizeImmediateJobQueue: int = None + self.NvMSizeStandardJobQueue: int = None + self.NvMVersionInfoApi: bool = None + self.NvMBufferAlignmentValue: str = None + self.NvMEcucPartitionRefs: List[EcucRefType] = [] + self.NvMMasterEcucPartitionRef: EcucRefType = None + + def getNvMApiConfigClass(self) -> str: + return self.NvMApiConfigClass + + def setNvMApiConfigClass(self, value: str): + if value is not None: + self.NvMApiConfigClass = value + return self + + def getNvMBswMMultiBlockJobStatusInformation(self) -> bool: + return self.NvMBswMMultiBlockJobStatusInformation + + def setNvMBswMMultiBlockJobStatusInformation(self, value: bool): + if value is not None: + self.NvMBswMMultiBlockJobStatusInformation = value + return self + + def getNvMCompiledConfigId(self) -> int: + return self.NvMCompiledConfigId + + def setNvMCompiledConfigId(self, value: int): + if value is not None: + self.NvMCompiledConfigId = value + return self + + def getNvMCrcNumOfBytes(self) -> int: + return self.NvMCrcNumOfBytes + + def setNvMCrcNumOfBytes(self, value: int): + if value is not None: + self.NvMCrcNumOfBytes = value + return self + + def getNvMCsmRetryCounter(self) -> int: + return self.NvMCsmRetryCounter + + def setNvMCsmRetryCounter(self, value: int): + if value is not None: + self.NvMCsmRetryCounter = value + return self + + def getNvMDatasetSelectionBits(self) -> int: + return self.NvMDatasetSelectionBits + + def setNvMDatasetSelectionBits(self, value: int): + if value is not None: + self.NvMDatasetSelectionBits = value + return self + + def getNvMDevErrorDetect(self) -> bool: + return self.NvMDevErrorDetect + + def setNvMDevErrorDetect(self, value: bool): + if value is not None: + self.NvMDevErrorDetect = value + return self + + def getNvMDynamicConfiguration(self) -> bool: + return self.NvMDynamicConfiguration + + def setNvMDynamicConfiguration(self, value: bool): + if value is not None: + self.NvMDynamicConfiguration = value + return self + + def getNvMJobPrioritization(self) -> bool: + return self.NvMJobPrioritization + + def setNvMJobPrioritization(self, value: bool): + if value is not None: + self.NvMJobPrioritization = value + return self + + def getNvMMainFunctionPeriod(self) -> float: + return self.NvMMainFunctionPeriod + + def setNvMMainFunctionPeriod(self, value: float): + if value is not None: + self.NvMMainFunctionPeriod = value + return self + + def getNvMMultiBlockCallback(self) -> str: + return self.NvMMultiBlockCallback + + def setNvMMultiBlockCallback(self, value: str): + if value is not None: + self.NvMMultiBlockCallback = value + return self + + def getNvMPollingMode(self) -> bool: + return self.NvMPollingMode + + def setNvMPollingMode(self, value: bool): + if value is not None: + self.NvMPollingMode = value + return self + + def getNvMRepeatMirrorOperations(self) -> int: + return self.NvMRepeatMirrorOperations + + def setNvMRepeatMirrorOperations(self, value: int): + if value is not None: + self.NvMRepeatMirrorOperations = value + return self + + def getNvMSetRamBlockStatusApi(self) -> bool: + return self.NvMSetRamBlockStatusApi + + def setNvMSetRamBlockStatusApi(self, value: bool): + if value is not None: + self.NvMSetRamBlockStatusApi = value + return self + + def getNvMSizeImmediateJobQueue(self) -> int: + return self.NvMSizeImmediateJobQueue + + def setNvMSizeImmediateJobQueue(self, value: int): + if value is not None: + self.NvMSizeImmediateJobQueue = value + return self + + def getNvMSizeStandardJobQueue(self) -> int: + return self.NvMSizeStandardJobQueue + + def setNvMSizeStandardJobQueue(self, value: int): + if value is not None: + self.NvMSizeStandardJobQueue = value + return self + + def getNvMVersionInfoApi(self) -> bool: + return self.NvMVersionInfoApi + + def setNvMVersionInfoApi(self, value: bool): + if value is not None: + self.NvMVersionInfoApi = value + return self + + def getNvMBufferAlignmentValue(self) -> str: + return self.NvMBufferAlignmentValue + + def setNvMBufferAlignmentValue(self, value: str): + if value is not None: + self.NvMBufferAlignmentValue = value + return self + + def getNvMEcucPartitionRefList(self) -> List[EcucRefType]: + return self.NvMEcucPartitionRefs + + def addNvMEcucPartitionRef(self, value: EcucRefType): + if value is not None: + self.NvMEcucPartitionRefs.append(value) + return self + + def getNvMMasterEcucPartitionRef(self) -> EcucRefType: + return self.NvMMasterEcucPartitionRef + + def setNvMMasterEcucPartitionRef(self, value: EcucRefType): + if value is not None: + self.NvMMasterEcucPartitionRef = value + return self + + +class NvMSingleBlockCallback(EcucParamConfContainerDef): + def __init__(self, parent, name): + super().__init__(parent, name) + + self.NvMSingleBlockCallbackFnc: str = None + + def getNvMSingleBlockCallbackFnc(self) -> str: + return self.NvMSingleBlockCallbackFnc + + def setNvMSingleBlockCallbackFnc(self, value: str): + if value is not None: + self.NvMSingleBlockCallbackFnc = value + return self + + +class NvMInitBlockCallback(EcucParamConfContainerDef): + def __init__(self, parent, name): + super().__init__(parent, name) + + self.NvMInitBlockCallbackFnc: str = None + + def getNvMInitBlockCallbackFnc(self) -> str: + return self.NvMInitBlockCallbackFnc + + def setNvMInitBlockCallbackFnc(self, value: str): + if value is not None: + self.NvMInitBlockCallbackFnc = value return self @@ -23,11 +259,11 @@ def __init__(self, parent, name): self.nvMBlockCrcType = None # type: str # optional self.nvMBlockHeaderInclude = None # type: int # optional - self.nvMBlockJobPriority = None # type: str # required + self.nvMBlockJobPriority: int = None self.nvMBlockManagementType = None # type: str # required self.nvMBlockUseAutoValidation = None # required self.nvMBlockUseCompression = None # required - self.nvMBlockUseCrc = None # required + self.nvMBlockUseCrc: bool = False self.nvMBlockUseCRCCompMechanism = None # required self.NvMBlockUsePort = None # required self.nvMBlockUseSetRamBlockStatus = None # required @@ -44,7 +280,7 @@ def __init__(self, parent, name): self.nvMNvramDeviceId = None # required self.nvMRamBlockDataAddress = None # optional self.nvMReadRamBlockFromNvCallback = None # optional - self.nvMResistantToChangedSw = None # required + self.nvMResistantToChangedSw: bool = False self.nvMRomBlockDataAddress = None # optional self.nvMRomBlockNum = None # required self.nvMSelectBlockForFirstInitAll = None # optional @@ -56,7 +292,15 @@ def __init__(self, parent, name): self.nvMWriteVerification = None # required self.nvMWriteVerificationDataSize = None # required self.nvMBlockCipheringRef = None # optional - self.nvMBlockEcucPartitionRef = None # type: EcucRefType # required + self.nvMBlockEcucPartitionRef: EcucRefType = None + + self.nvMInitBlockCallback: NvMInitBlockCallback = None + self.nvMSingleBlockCallback: NvMSingleBlockCallback = None + self.nvMTargetBlockReference: NvMTargetBlockReference = None + + # EB extended + self.nvMProvideRteJobFinishedPort: bool = False + self.nvMProvideRteServicePort: bool = False def getNvMBlockCrcType(self): return self.nvMBlockCrcType @@ -345,3 +589,68 @@ def setNvMBlockEcucPartitionRef(self, value: EcucRefType): if value is not None: self.nvMBlockEcucPartitionRef = value return self + + def getNvMInitBlockCallback(self) -> NvMInitBlockCallback: + return self.nvMInitBlockCallback + + def setNvMInitBlockCallback(self, value: NvMInitBlockCallback): + if value is not None: + self.nvMInitBlockCallback = value + return self + + def getNvMSingleBlockCallback(self) -> NvMSingleBlockCallback: + return self.nvMSingleBlockCallback + + def setNvMSingleBlockCallback(self, value: NvMSingleBlockCallback): + if value is not None: + self.nvMSingleBlockCallback = value + return self + + def getNvMTargetBlockReference(self) -> NvMTargetBlockReference: + return self.nvMTargetBlockReference + + def setNvMTargetBlockReference(self, value: NvMTargetBlockReference): + if value is not None: + self.nvMTargetBlockReference = value + return self + + def getNvMProvideRteJobFinishedPort(self) -> bool: + return self.nvMProvideRteJobFinishedPort + + def setNvMProvideRteJobFinishedPort(self, value: bool): + if value is not None: + self.nvMProvideRteJobFinishedPort = value + return self + + def getNvMProvideRteServicePort(self) -> bool: + return self.nvMProvideRteServicePort + + def setNvMProvideRteServicePort(self, value: bool): + if value is not None: + self.nvMProvideRteServicePort = value + return self + + +class NvM(Module): + def __init__(self, parent): + super().__init__(parent, "NvM") + + # type: List[NvMBlockDescriptor] + self.NvMBlockDescriptors = [] + self.NvMCommon: NvMCommon = None + + def getNvMCommon(self) -> NvMCommon: + return self.NvMCommon + + def setNvMCommon(self, value: NvMCommon): + if value is not None: + self.NvMCommon = value + return self + + def getNvMBlockDescriptorList(self) -> List[NvMBlockDescriptor]: + return self.NvMBlockDescriptors + + def addNvMBlockDescriptor(self, value: NvMBlockDescriptor): + if value is not None: + self.NvMBlockDescriptors.append(value) + return self diff --git a/src/eb_model/parser/nvm_xdm_parser.py b/src/eb_model/parser/nvm_xdm_parser.py index 685a367..ec86aa9 100644 --- a/src/eb_model/parser/nvm_xdm_parser.py +++ b/src/eb_model/parser/nvm_xdm_parser.py @@ -1,6 +1,6 @@ import xml.etree.ElementTree as ET -from ..models.nvm_xdm import NvM, NvMBlockDescriptor +from ..models.nvm_xdm import NvM, NvMBlockDescriptor, NvMCommon, NvMEaRef, NvMFeeRef, NvMInitBlockCallback, NvMSingleBlockCallback from ..models.eb_doc import EBModel from ..parser.eb_parser import AbstractEbModelParser @@ -23,22 +23,99 @@ def parse(self, element: ET.Element, doc: EBModel): self.nvm = nvm + self.read_nvm_common(element, nvm) self.read_nvm_block_descriptors(element, nvm) + def read_nvm_common(self, element: ET.Element, nvm: NvM): + ctr_tag = self.find_ctr_tag(element, "NvMCommon") + if ctr_tag is not None: + nvm_common = NvMCommon(nvm, "NvMCommon") + nvm_common.setNvMApiConfigClass(self.read_value(ctr_tag, "NvMApiConfigClass")) + nvm_common.setNvMBswMMultiBlockJobStatusInformation(self.read_value(ctr_tag, "NvMBswMMultiBlockJobStatusInformation")) + nvm_common.setNvMCompiledConfigId(self.read_value(ctr_tag, "NvMCompiledConfigId")) + nvm_common.setNvMCrcNumOfBytes(self.read_value(ctr_tag, "NvMCrcNumOfBytes")) + nvm_common.setNvMCsmRetryCounter(self.read_optional_value(ctr_tag, "NvMCsmRetryCounter")) + nvm_common.setNvMDatasetSelectionBits(self.read_value(ctr_tag, "NvMDatasetSelectionBits")) + nvm_common.setNvMDevErrorDetect(self.read_value(ctr_tag, "NvMDevErrorDetect")) + nvm_common.setNvMDynamicConfiguration(self.read_value(ctr_tag, "NvMDynamicConfiguration")) + nvm_common.setNvMJobPrioritization(self.read_value(ctr_tag, "NvMJobPrioritization")) + nvm_common.setNvMMainFunctionPeriod(self.read_value(ctr_tag, "NvMMainFunctionPeriod")) + nvm_common.setNvMMultiBlockCallback(self.read_optional_value(ctr_tag, "NvMMultiBlockCallback")) + nvm_common.setNvMPollingMode(self.read_value(ctr_tag, "NvMPollingMode")) + nvm_common.setNvMRepeatMirrorOperations(self.read_value(ctr_tag, "NvMRepeatMirrorOperations")) + nvm_common.setNvMSetRamBlockStatusApi(self.read_value(ctr_tag, "NvMSetRamBlockStatusApi")) + nvm_common.setNvMSizeImmediateJobQueue(self.read_optional_value(ctr_tag, "NvMSizeImmediateJobQueue")) + nvm_common.setNvMSizeStandardJobQueue(self.read_value(ctr_tag, "NvMSizeStandardJobQueue")) + nvm_common.setNvMVersionInfoApi(self.read_value(ctr_tag, "NvMVersionInfoApi")) + nvm_common.setNvMBufferAlignmentValue(self.read_value(ctr_tag, "NvMBufferAlignmentValue")) + for ref in self.read_ref_value_list(ctr_tag, "NvMEcucPartitionRef"): + nvm_common.addNvMEcucPartitionRef(ref) + nvm_common.setNvMMasterEcucPartitionRef(self.read_ref_value(ctr_tag, "NvMMasterEcucPartitionRef")) + + nvm.setNvMCommon(nvm_common) + + def read_nvm_init_block_callback(self, element: ET.Element, nvm_block: NvMBlockDescriptor): + ctr_tag = self.find_ctr_tag(element, "NvMInitBlockCallback") + if ctr_tag is not None: + init_block_callback = NvMInitBlockCallback(nvm_block, "NvMInitBlockCallback") + init_block_callback.setNvMInitBlockCallbackFnc(self.read_value(ctr_tag, "NvMInitBlockCallbackFnc")) + nvm_block.setNvMInitBlockCallback(init_block_callback) + + def read_nvm_single_block_callback(self, element: ET.Element, nvm_block: NvMBlockDescriptor): + ctr_tag = self.find_ctr_tag(element, "NvMSingleBlockCallback") + if ctr_tag is not None: + single_block_callback = NvMSingleBlockCallback(nvm_block, "NvMSingleBlockCallback") + single_block_callback.setNvMSingleBlockCallbackFnc(self.read_value(ctr_tag, "NvMSingleBlockCallbackFnc")) + nvm_block.setNvMSingleBlockCallback(single_block_callback) + + def read_nvm_block_target_block_reference(self, element: ET.Element, nvm_block: NvMBlockDescriptor): + block_ref = self.read_choice_value(element, "NvMTargetBlockReference") + if block_ref == "NvMEaRef": + ctr_tag = self.find_ctr_tag(element, "NvMEaRef") + if ctr_tag is not None: + ref = NvMEaRef(nvm_block, block_ref) + ref.setNvMNameOfEaBlock(self.read_ref_value(element, "NvMNameOfEaBlock")) + nvm_block.setNvMTargetBlockReference(ref) + elif block_ref == "NvMFeeRef": + ctr_tag = self.find_ctr_tag(element, "NvMFeeRef") + if ctr_tag is not None: + ref = NvMFeeRef(nvm_block, block_ref) + ref.setNvMNameOfFeeBlock(self.read_ref_value(element, "NvMNameOfFeeBlock")) + nvm_block.setNvMTargetBlockReference(ref) + else: + raise ValueError("Invalid block reference type <%s>" % block_ref) + def read_nvm_block_descriptors(self, element: ET.Element, nvm: NvM): for ctr_tag in self.find_ctr_tag_list(element, "NvMBlockDescriptor"): nvm_block = NvMBlockDescriptor(nvm, ctr_tag.attrib["name"]) - nvm_block.setNvMBlockCrcType(self.read_optional_value(ctr_tag, "NvMBlockCrcType")) \ - .setNvMBlockEcucPartitionRef(self.read_ref_value(ctr_tag, "NvMBlockEcucPartitionRef")) \ - .setNvMNvramBlockIdentifier(self.read_value(ctr_tag, "NvMNvramBlockIdentifier")) \ - .setNvMRamBlockDataAddress(self.read_optional_value(ctr_tag, "NvMRamBlockDataAddress")) \ - .setNvMRomBlockDataAddress(self.read_optional_value(ctr_tag, "NvMRomBlockDataAddress")) \ - .setNvMRomBlockNum(self.read_value(ctr_tag, "NvMRomBlockNum")) \ - .setNvMBlockManagementType(self.read_value(ctr_tag, "NvMBlockManagementType")) \ - .setNvMNvBlockLength(self.read_value(ctr_tag, "NvMNvBlockLength")) \ - .setNvMNvBlockNum(self.read_value(ctr_tag, "NvMNvBlockNum")) \ - .setNvMSelectBlockForReadAll(self.read_value(ctr_tag, "NvMSelectBlockForReadAll")) \ - .setNvMSelectBlockForWriteAll(self.read_value(ctr_tag, "NvMSelectBlockForWriteAll")) + nvm_block.setNvMBlockCrcType(self.read_optional_value(ctr_tag, "NvMBlockCrcType")) + nvm_block.setNvMBlockEcucPartitionRef(self.read_ref_value(ctr_tag, "NvMBlockEcucPartitionRef")) + nvm_block.setNvMNvramBlockIdentifier(self.read_value(ctr_tag, "NvMNvramBlockIdentifier")) + nvm_block.setNvMRamBlockDataAddress(self.read_optional_value(ctr_tag, "NvMRamBlockDataAddress")) + nvm_block.setNvMRomBlockDataAddress(self.read_optional_value(ctr_tag, "NvMRomBlockDataAddress")) + nvm_block.setNvMBlockJobPriority(self.read_value(ctr_tag, "NvMBlockJobPriority")) + nvm_block.setNvMResistantToChangedSw(self.read_value(ctr_tag, "NvMResistantToChangedSw")) + nvm_block.setNvMBlockCrcType(self.read_value(ctr_tag, "NvMBlockCrcType")) + nvm_block.setNvMBlockUseCrc(self.read_value(ctr_tag, "NvMBlockUseCrc")) + nvm_block.setNvMRomBlockNum(self.read_value(ctr_tag, "NvMRomBlockNum")) + nvm_block.setNvMBlockManagementType(self.read_value(ctr_tag, "NvMBlockManagementType")) + nvm_block.setNvMNvBlockLength(self.read_value(ctr_tag, "NvMNvBlockLength")) + nvm_block.setNvMNvBlockNum(self.read_value(ctr_tag, "NvMNvBlockNum")) + nvm_block.setNvMSelectBlockForReadAll(self.read_value(ctr_tag, "NvMSelectBlockForReadAll")) + nvm_block.setNvMSelectBlockForWriteAll(self.read_value(ctr_tag, "NvMSelectBlockForWriteAll")) + + nvm_block.setNvMProvideRteJobFinishedPort(self.read_value(ctr_tag, "NvMProvideRteJobFinishedPort")) + nvm_block.setNvMProvideRteServicePort(self.read_value(ctr_tag, "NvMProvideRteServicePort")) + + nvm_block.setNvMReadRamBlockFromNvCallback(self.read_optional_value(ctr_tag, "NvMReadRamBlockFromNvCallback")) + nvm_block.setNvMWriteRamBlockToNvCallback(self.read_optional_value(ctr_tag, "NvMWriteRamBlockToNvCallback")) + nvm_block.setNvMBlockUseSyncMechanism(self.read_value(ctr_tag, "NvMBlockUseSyncMechanism")) + + self.read_nvm_init_block_callback(ctr_tag, nvm_block) + self.read_nvm_single_block_callback(ctr_tag, nvm_block) + + nvm_block.setNvMNvBlockBaseNumber(self.read_value(ctr_tag, "NvMNvBlockBaseNumber")) + self.read_nvm_block_target_block_reference(ctr_tag, nvm_block) nvm.addNvMBlockDescriptor(nvm_block) diff --git a/src/eb_model/parser/os_xdm_parser.py b/src/eb_model/parser/os_xdm_parser.py index 41a34a9..8c3816f 100644 --- a/src/eb_model/parser/os_xdm_parser.py +++ b/src/eb_model/parser/os_xdm_parser.py @@ -45,11 +45,11 @@ def read_os_task_autostart(self, element: ET.Element, os_task: OsTask): def read_os_tasks(self, element: ET.Element, os: Os): for ctr_tag in self.find_ctr_tag_list(element, "OsTask"): os_task = OsTask(os, ctr_tag.attrib["name"]) - os_task.setOsTaskPriority(int(self.read_value(ctr_tag, "OsTaskPriority"))) \ - .setOsTaskActivation(self.read_value(ctr_tag, "OsTaskActivation")) \ - .setOsTaskSchedule(self.read_value(ctr_tag, "OsTaskSchedule")) \ - .setOsTaskType(self.read_optional_value(ctr_tag, "OsTaskType")) \ - .setOsStacksize(int(self.read_optional_value(ctr_tag, "OsStacksize", 0))) + os_task.setOsTaskPriority(int(self.read_value(ctr_tag, "OsTaskPriority"))) + os_task.setOsTaskActivation(self.read_value(ctr_tag, "OsTaskActivation")) + os_task.setOsTaskSchedule(self.read_value(ctr_tag, "OsTaskSchedule")) + os_task.setOsTaskType(self.read_optional_value(ctr_tag, "OsTaskType")) + os_task.setOsStacksize(int(self.read_value(ctr_tag, "OsStacksize"))) for resource_ref in self.read_ref_value_list(ctr_tag, "OsTaskResourceRef"): os_task.addOsTaskResourceRef(resource_ref) @@ -62,10 +62,10 @@ def read_os_tasks(self, element: ET.Element, os: Os): def read_os_isrs(self, element: ET.Element, os: Os): for ctr_tag in self.find_ctr_tag_list(element, "OsIsr"): os_isr = OsIsr(os, ctr_tag.attrib["name"]) - os_isr.setOsIsrCategory(self.read_value(ctr_tag, "OsIsrCategory")) \ - .setOsIsrPeriod(self.read_optional_value(ctr_tag, "OsIsrPeriod", 0.0)) \ - .setOsStacksize(int(self.read_value(ctr_tag, "OsStacksize"))) \ - .setOsIsrPriority(self.read_optional_value(ctr_tag, "OsIsrPriority")) + os_isr.setOsIsrCategory(self.read_value(ctr_tag, "OsIsrCategory")) + os_isr.setOsIsrPeriod(self.read_optional_value(ctr_tag, "OsIsrPeriod", 0.0)) + os_isr.setOsStacksize(int(self.read_value(ctr_tag, "OsStacksize"))) + os_isr.setOsIsrPriority(self.read_optional_value(ctr_tag, "OsIsrPriority")) # Infineon Aurix Tricore os_isr.setOsIsrPriority(self.read_optional_value(ctr_tag, "OsTricoreIrqLevel")) diff --git a/src/eb_model/reporter/excel_reporter/abstract.py b/src/eb_model/reporter/excel_reporter/abstract.py index cd84c28..c2dda34 100644 --- a/src/eb_model/reporter/excel_reporter/abstract.py +++ b/src/eb_model/reporter/excel_reporter/abstract.py @@ -41,11 +41,17 @@ def write_cell(self, sheet: Worksheet, row: int, column: int, value, format=None cell.number_format = format['number_format'] return cell + def write_cell_center(self, sheet: Worksheet, row: int, column: int, value) -> Cell: + self.write_cell(sheet, row, column, value, format={"alignment": Alignment(horizontal="center")}) + + def write_bool_cell(self, sheet: Worksheet, row: int, column: int, value) -> Cell: + self.write_cell_center(sheet, row, column, self.format_boolean(value)) + def format_boolean(self, value: bool) -> str: if value is True: return "Y" else: - return "N" + return "" def save(self, name: str): self.wb.save(name) diff --git a/src/eb_model/reporter/excel_reporter/nvm_xdm.py b/src/eb_model/reporter/excel_reporter/nvm_xdm.py index 33b050c..5ce399d 100644 --- a/src/eb_model/reporter/excel_reporter/nvm_xdm.py +++ b/src/eb_model/reporter/excel_reporter/nvm_xdm.py @@ -1,30 +1,91 @@ from ...models.eb_doc import EBModel +from ...models.nvm_xdm import NvMEaRef, NvMFeeRef from ...reporter.excel_reporter.abstract import ExcelReporter +from openpyxl.styles.alignment import Alignment class NvMXdmXlsWriter(ExcelReporter): def __init__(self) -> None: super().__init__() + def write_nvm_general(self, doc: EBModel): + sheet = self.wb.create_sheet("General", 0) + + title_row = ["Key", "Value"] + self.write_title_row(sheet, title_row) + + nvm_common = doc.getNvM().getNvMCommon() + + if nvm_common is None: + self.logger.error("NvMCommon is Invalid and General updating is skipped.") + return + + row = 2 + self.write_cell(sheet, row, 1, "NvMCompiledConfigId") + self.write_cell_center(sheet, row, 2, nvm_common.getNvMCompiledConfigId()) + row += 1 + self.write_cell(sheet, row, 1, "NvMDatasetSelectionBits") + self.write_cell_center(sheet, row, 2, nvm_common.getNvMDatasetSelectionBits()) + row += 1 + self.write_cell(sheet, row, 1, "NvMMaxNumOfReadRetries") + self.write_cell_center(sheet, row, 2, "3") + row += 1 + self.write_cell(sheet, row, 1, "NvMMaxNumOfWriteRetries") + self.write_cell_center(sheet, row, 2, "3") + row += 1 + + self.auto_width(sheet) + def write_nvm_block_descriptors(self, doc: EBModel): - sheet = self.wb.create_sheet("NvMBlock", 0) + sheet = self.wb.create_sheet("Block List", 2) title_row = [ "BlockId", "Name", "NvMBlockEcucPartitionRef", "NvMRamBlockDataAddress", "NvMRomBlockDataAddress", - "NvMBlockManagementType", "NvMNvBlockLength", "NvMNvBlockNum", "NvMSelectBlockForReadAll", "NvMSelectBlockForWriteAll"] + "NvMBlockJobPriority", "NvMResistantToChangedSw", "NvMBlockManagementType", "NvMNvBlockLength", "NvMBlockCrcType", + "NvMNvBlockNum", "NvMSelectBlockForReadAll", "NvMSelectBlockForWriteAll", "NvMProvideRteJobFinishedPort", "NvMProvideRteServicePort", + "NvMInitBlockCallbackFnc", "NvMSingleBlockCallbackFnc", "NvMReadRamBlockFromNvCallback", "NvMWriteRamBlockToNvCallback", "NvMBlockUseSyncMechanism", # noqa E501 + "NvMNvBlockBaseNumber", "NvMFeeRef"] self.write_title_row(sheet, title_row) row = 2 for nvm_block in doc.getNvM().getNvMBlockDescriptorList(): - self.write_cell(sheet, row, 1, nvm_block.getNvMNvramBlockIdentifier()) + self.write_cell_center(sheet, row, 1, nvm_block.getNvMNvramBlockIdentifier()) self.write_cell(sheet, row, 2, nvm_block.getName()) - self.write_cell(sheet, row, 3, nvm_block.getNvMBlockEcucPartitionRef()) + if nvm_block.getNvMBlockEcucPartitionRef() is not None: + self.write_cell_center(sheet, row, 3, nvm_block.getNvMBlockEcucPartitionRef().getShortName()) self.write_cell(sheet, row, 4, nvm_block.getNvMRamBlockDataAddress()) self.write_cell(sheet, row, 5, nvm_block.getNvMRomBlockDataAddress()) - self.write_cell(sheet, row, 6, nvm_block.getNvMBlockManagementType()) - self.write_cell(sheet, row, 7, nvm_block.getNvMNvBlockLength()) - self.write_cell(sheet, row, 8, nvm_block.getNvMNvBlockNum()) + self.write_cell_center(sheet, row, 6, nvm_block.getNvMBlockJobPriority()) + self.write_bool_cell(sheet, row, 7, nvm_block.getNvMResistantToChangedSw()) + self.write_cell_center(sheet, row, 8, nvm_block.getNvMBlockManagementType()) + self.write_cell_center(sheet, row, 9, nvm_block.getNvMNvBlockLength()) + if nvm_block.getNvMBlockUseCrc(): + self.write_cell_center(sheet, row, 10, nvm_block.getNvMBlockCrcType()) + + self.write_cell(sheet, row, 11, nvm_block.getNvMNvBlockNum()) + self.write_bool_cell(sheet, row, 12, nvm_block.getNvMSelectBlockForReadAll()) + self.write_bool_cell(sheet, row, 13, nvm_block.getNvMSelectBlockForWriteAll()) + self.write_bool_cell(sheet, row, 14, nvm_block.getNvMProvideRteJobFinishedPort()) + self.write_bool_cell(sheet, row, 15, nvm_block.getNvMProvideRteServicePort()) + + if nvm_block.getNvMInitBlockCallback() is not None: + self.write_cell(sheet, row, 16, nvm_block.getNvMInitBlockCallback().getNvMInitBlockCallbackFnc()) + if nvm_block.getNvMSingleBlockCallback() is not None: + self.write_cell(sheet, row, 17, nvm_block.getNvMSingleBlockCallback().getNvMSingleBlockCallbackFnc()) + if nvm_block.getNvMReadRamBlockFromNvCallback() is not None: + self.write_cell(sheet, row, 18, nvm_block.getNvMReadRamBlockFromNvCallback()) + if nvm_block.getNvMWriteRamBlockToNvCallback() is not None: + self.write_cell(sheet, row, 19, nvm_block.getNvMWriteRamBlockToNvCallback()) + self.write_bool_cell(sheet, row, 20, nvm_block.getNvMBlockUseSyncMechanism()) + + self.write_cell_center(sheet, row, 21, nvm_block.getNvMNvBlockBaseNumber()) + block_reference = nvm_block.getNvMTargetBlockReference() + if block_reference is not None: + if isinstance(block_reference, NvMFeeRef): + self.write_cell(sheet, row, 22, block_reference.getNvMNameOfFeeBlock().getShortName()) + else: + raise NotImplementedError("Unsupported Target block reference.") row += 1 @@ -32,9 +93,38 @@ def write_nvm_block_descriptors(self, doc: EBModel): self.auto_width(sheet) + def write_nvm_bsw_distribution(self, doc: EBModel): + sheet = self.wb.create_sheet("BSW Distribution", 1) + + title_row = ["NvMEcucPartitionRef", "Master"] + self.write_title_row(sheet, title_row) + + nvm_common = doc.getNvM().getNvMCommon() + + if nvm_common is None: + self.logger.error("NvMCommon is Invalid and BSW Distribution updating is skipped.") + return + + master_partition_ref = nvm_common.getNvMMasterEcucPartitionRef() + + row = 2 + for ref_link in nvm_common.getNvMEcucPartitionRefList(): + self.write_cell(sheet, row, 1, ref_link.getShortName()) + if ref_link.getShortName() == master_partition_ref.getShortName(): + self.write_cell(sheet, row, 2, "Y", format={"alignment": Alignment(horizontal="center")}) + else: + self.write_cell(sheet, row, 2, "N", format={"alignment": Alignment(horizontal="center")}) + row += 1 + + self.logger.debug("Write NvM EcucPartition <%s>" % ref_link.getShortName()) + + self.auto_width(sheet) + def write(self, filename, doc: EBModel, options): self.logger.info("Writing <%s>" % filename) + self.write_nvm_general(doc) + self.write_nvm_bsw_distribution(doc) self.write_nvm_block_descriptors(doc) self.save(filename) diff --git a/src/eb_model/tests/parser/test_nvm_xdm_parser.py b/src/eb_model/tests/parser/test_nvm_xdm_parser.py new file mode 100644 index 0000000..935a4b5 --- /dev/null +++ b/src/eb_model/tests/parser/test_nvm_xdm_parser.py @@ -0,0 +1,259 @@ +from eb_model.parser.nvm_xdm_parser import NvMXdmParser +from eb_model.models.eb_doc import EBModel + +import xml.etree.ElementTree as ET +import pytest + + +class TestNvmXdmParser: + def test_read_nvm_block_descriptors(self): + + # Create a mock XML element for testing + xml_content = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @DEF + @CALC + + + + + + + + + + @DEF + @CALC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """ + element = ET.fromstring(xml_content) + + model = EBModel.getInstance() + nvm = model.getNvM() + + # Create parser instance + parser = NvMXdmParser() + parser.nsmap = { + '': "http://www.tresos.de/_projects/DataModel2/18/root.xsd", + 'a': "http://www.tresos.de/_projects/DataModel2/18/attribute.xsd", + 'v': "http://www.tresos.de/_projects/DataModel2/06/schema.xsd", + 'd': "http://www.tresos.de/_projects/DataModel2/06/data.xsd" + } + + # Call the method + parser.read_nvm_block_descriptors(element, nvm) + + # Assertions + blocks = nvm.getNvMBlockDescriptorList() + assert len(blocks) == 1 + + # Validate first block + block1 = blocks[0] + assert block1.getName() == "NvmBlock_TestData" + assert block1.getNvMBlockCrcType() == "NVM_CRC16" + assert block1.getNvMBlockEcucPartitionRef().getShortName() == "OsApplication_C0" + assert block1.getNvMNvramBlockIdentifier() == 9 + assert block1.getNvMRamBlockDataAddress() == "&Ram_TestData" + assert block1.getNvMRomBlockDataAddress() == "&Rom_TestData" + assert block1.getNvMRomBlockNum() == 1 + assert block1.getNvMBlockManagementType() == "NVM_BLOCK_NATIVE" + assert block1.getNvMNvBlockLength() == 64 + assert block1.getNvMNvBlockNum() == 1 + assert block1.getNvMSelectBlockForReadAll() is True + assert block1.getNvMSelectBlockForWriteAll() is True + + \ No newline at end of file diff --git a/src/eb_model/tests/parser/test_os_xdm_parser.py b/src/eb_model/tests/parser/test_os_xdm_parser.py index e6d38f3..a0e436c 100644 --- a/src/eb_model/tests/parser/test_os_xdm_parser.py +++ b/src/eb_model/tests/parser/test_os_xdm_parser.py @@ -76,6 +76,252 @@ def test_read_os_resources(self): assert resource2.getOsResourceProperty() == "INTERNAL" assert len(resource2.getOsResourceAccessingApplicationRefs()) == 0 + def test_read_os_tasks(self): + # Create a mock XML element for testing + xml_content = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """ + element = ET.fromstring(xml_content) + + # Mock Os object + model = EBModel.getInstance() + os = model.getOs() + + # Create parser instance + parser = OsXdmParser() + parser.nsmap = { + '': "http://www.tresos.de/_projects/DataModel2/18/root.xsd", + 'a': "http://www.tresos.de/_projects/DataModel2/18/attribute.xsd", + 'v': "http://www.tresos.de/_projects/DataModel2/06/schema.xsd", + 'd': "http://www.tresos.de/_projects/DataModel2/06/data.xsd" + } + + # Call the method + parser.read_os_tasks(element, os) + + # Assertions + tasks = os.getOsTaskList() + assert len(tasks) == 3 + + task1 = tasks[0] + assert task1.getName() == "Idle_Task_C0" + assert task1.getOsTaskPriority() == 1 + assert task1.getOsTaskActivation() == 1 + assert task1.getOsTaskSchedule() == "FULL" + assert task1.getOsTaskType() is None + assert task1.getOsStacksize() == 800 + assert len(task1.getOsTaskResourceRefList()) == 0 + assert task1.getOsTaskAutostart() is not None + assert task1.getOsTaskAutostart().getOsTaskAppModeRefList() is not None + + task2 = tasks[1] + assert task2.getName() == "Task1" + assert task2.getOsTaskPriority() == 250 + assert task2.getOsTaskActivation() == 1 + assert task2.getOsTaskSchedule() == "FULL" + assert task2.getOsTaskType() == "BASIC" + assert task2.getOsStacksize() == 1024 + assert len(task2.getOsTaskResourceRefList()) == 2 + assert task2.getOsTaskResourceRefList()[0].getValue() == "/Os/Os/Res_Core0" + assert task2.getOsTaskResourceRefList()[1].getValue() == "/Os/Os/Res_Core1" + autostart = task2.getOsTaskAutostart() + assert autostart is not None + assert len(autostart.getOsTaskAppModeRefList()) == 1 + assert autostart.getOsTaskAppModeRefList()[0].getValue() == "/Os/Os/OSDEFAULTAPPMODE" + + task3 = tasks[2] + assert task3.getName() == "Task2" + assert task3.getOsTaskPriority() == 3 + assert task3.getOsTaskActivation() == 2 + assert task3.getOsTaskSchedule() == "NON" + assert task3.getOsTaskType() is None + assert task3.getOsStacksize() == 2048 + assert len(task3.getOsTaskResourceRefList()) == 0 + assert task3.getOsTaskAutostart() is None + ''' def test_read_os_applications(self): # Create a mock XML element for testing diff --git a/src/eb_model/writer/text_writer.py b/src/eb_model/writer/text_writer.py index fc214fc..2049401 100644 --- a/src/eb_model/writer/text_writer.py +++ b/src/eb_model/writer/text_writer.py @@ -1,8 +1,8 @@ import logging from typing import List - from ..models.eb_doc import SystemDescriptionImporter + class TextWriter: def __init__(self): self.logger = logging.getLogger() @@ -12,11 +12,13 @@ def write(self, filename: str, lines: List[str]): for line in lines: f_out.write("%s\n" % line) + class TextPreferenceModelWriter(TextWriter): def __init__(self): super().__init__() - def writer_import_files(self, filename: str, importer: SystemDescriptionImporter, params = {'base_path': None, 'wildcard': None, "tresos_output_base_dir": None}): + def writer_import_files(self, filename: str, importer: SystemDescriptionImporter, + params={'base_path': None, 'wildcard': None, "tresos_output_base_dir": None}): self.logger.info("Generate import files list <%s>" % filename) lines = [] for file in sorted(importer.getParsedInputFiles(params)):