在我现在的代码基础上改
# -*- coding: utf-8 -*-
# Copyright (c) 2013, Eduard Broecker
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that
# the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this list of conditions and the
# following disclaimer.
# Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
# following disclaimer in the documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# this script exports arxml-files from a canmatrix-object
# arxml-files are the can-matrix-definitions and a lot more in AUTOSAR-Context
# currently Support for Autosar 3.2 and 4.0-4.3 is planned
# AUTOSAR 4.2.2 is partial support -> 2024/05/20
import copy
import decimal
import logging
import re
import typing
from builtins import *
import lxml.etree
import io
from arxml_base import *
# for typing only
_Element = lxml.etree._Element
option = {}
# option = {
# "gatewayArPackegeName" : "RouteGateway",
# "gatewayName" : "FLZCU",
# "ecuInstanceName" : "FLZCU"
# }
class gatewayDoc(Arxmldoc):
def __init__(self, opt: dict | None = None):
super().__init__()
# instance-level options
self.ecuInstance = None
self.option: dict = {} if opt is None else dict(opt)
# internal caches / holders
self.gatewayElements: _Element | None = None
self.ecuInstancePath: str | None = None
self.FibexElements: _Element | None = None
self.GwFibexElementTable: list[str] = []
self.GwGatewayTable: dict[str, _Element] = {}
self.GwiPduMappingTable: dict[str, _Element] = {}
self.GwiSignalMappingTable: dict[str, _Element] = {}
# 添加 IPDUGroup 包引用
self.ipdu_group_package: _Element | None = None
self.ipdu_group_elements: _Element | None = None
def init(self, **options) -> None:
# initialize parent and merge options
super().init(**options)
# merge provided options into instance option dict
self.option.update(options)
# ensure defaults
self.option.setdefault("gatewayArPackegeName", "RouteGateway")
self.option.setdefault("gatewayName", "FLZCU")
self.option.setdefault("ecuInstanceName", "FLZCU")
# create System package and FIBEX elements
ar_package = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(ar_package)
arxml_create_sub_element(ar_package, "SHORT-NAME", "System")
elements = arxml_create_sub_element(ar_package, "ELEMENTS")
system = arxml_create_sub_element(elements, "SYSTEM")
arxml_UpdateElemUUID(system)
arxml_create_sub_element(system, "SHORT-NAME", "System")
arxml_create_sub_element(system, "CATEGORY", "SYSTEM_EXTRACT")
self.FibexElements = arxml_create_sub_element(system, "FIBEX-ELEMENTS")
# add ECU-INSTANCE fibex element
fibexElemCond = arxml_create_sub_element(self.FibexElements, "FIBEX-ELEMENT-REF-CONDITIONAL")
fibexElemRef = arxml_create_sub_element(fibexElemCond, "FIBEX-ELEMENT-REF")
fibexElemRef.set("DEST", "ECU-INSTANCE")
self.ecuInstancePath = "/ECU/" + self.option["ecuInstanceName"]
fibexElemRef.text = self.ecuInstancePath
# add gateway package
ar_package = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(ar_package)
arxml_create_sub_element(ar_package, "SHORT-NAME", self.option["gatewayArPackegeName"])
self.gatewayElements = arxml_create_sub_element(ar_package, "ELEMENTS")
# 创建 IPDUGroup 包(只创建一次)
self.ipdu_group_package = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(self.ipdu_group_package)
arxml_create_sub_element(self.ipdu_group_package, "SHORT-NAME", "IPDUGroup")
self.ipdu_group_elements = arxml_create_sub_element(self.ipdu_group_package, "ELEMENTS")
return
def addEcuInstance(self, **options) -> None:
"""
创建完整的 ECU package 和 ECU-INSTANCE,包含所有必要的元素和属性
Args:
options: 可选参数,用于覆盖默认设置
"""
# 更新选项
self.option.update(options)
# 创建 ECU package
ar_package = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(ar_package)
arxml_create_sub_element(ar_package, "SHORT-NAME", "ECU")
# 创建 ELEMENTS
elements = arxml_create_sub_element(ar_package, "ELEMENTS")
# 创建 ECU-INSTANCE
ecuInstance = arxml_create_sub_element(elements, "ECU-INSTANCE")
arxml_UpdateElemUUID(ecuInstance)
arxml_create_sub_element(ecuInstance, "SHORT-NAME", self.option["ecuInstanceName"])
# 添加 CATEGORY
arxml_create_sub_element(ecuInstance, "CATEGORY", "WIRED")
# 添加 ASSOCIATED-COM-I-PDU-GROUP-REFS (空容器,可以在后续添加引用)
associated_refs = arxml_create_sub_element(ecuInstance, "ASSOCIATED-COM-I-PDU-GROUP-REFS")
# 添加 CONNECTORS (空容器,可以在后续添加连接器)
connectors = arxml_create_sub_element(ecuInstance, "CONNECTORS")
# 保存 ECU instance 以便后续使用
self.ecuInstance = ecuInstance
self.ecuPackage = ar_package
return
def add_ecu_connector(self, connector_name, controller_ref, frame_ports=None, pdu_ports=None):
"""
为ECU-INSTANCE添加通信连接器
Args:
connector_name: 连接器名称,例如"CN_TestCAN1"
controller_ref: 控制器引用路径,例如"/ECU/MyECU/CT_TestCAN1"
frame_ports: 帧端口列表,每个元素是字典,包含name和direction
pdu_ports: PDU端口列表,每个元素是字典,包含name和direction
"""
if not hasattr(self, 'ecuInstance') or self.ecuInstance is None:
arxml_Abort("ECU-INSTANCE not found")
return
# 获取或创建CONNECTORS元素
connectors = self.ecuInstance.find("CONNECTORS")
if connectors is None:
connectors = arxml_create_sub_element(self.ecuInstance, "CONNECTORS")
# 创建CAN-COMMUNICATION-CONNECTOR
can_connector = arxml_create_sub_element(connectors, "CAN-COMMUNICATION-CONNECTOR")
arxml_create_sub_element(can_connector, "SHORT-NAME", connector_name)
# 添加COMM-CONTROLLER-REF
controller_ref_elem = arxml_create_sub_element(can_connector, "COMM-CONTROLLER-REF", controller_ref)
controller_ref_elem.set("DEST", "CAN-COMMUNICATION-CONTROLLER")
# 添加ECU-COMM-PORT-INSTANCES
ecu_comm_ports = arxml_create_sub_element(can_connector, "ECU-COMM-PORT-INSTANCES")
# 添加帧端口
if frame_ports:
for port in frame_ports:
frame_port = arxml_create_sub_element(ecu_comm_ports, "FRAME-PORT")
arxml_create_sub_element(frame_port, "SHORT-NAME", port['name'])
arxml_create_sub_element(frame_port, "COMMUNICATION-DIRECTION", port['direction'])
# 添加PDU端口
if pdu_ports:
for port in pdu_ports:
pdu_port = arxml_create_sub_element(ecu_comm_ports, "I-PDU-PORT")
arxml_create_sub_element(pdu_port, "SHORT-NAME", port['name'])
arxml_create_sub_element(pdu_port, "COMMUNICATION-DIRECTION", port['direction'])
def add_associated_pdu_group_ref(self, pdu_group_ref):
"""
为ECU-INSTANCE添加关联的PDU组引用
Args:
pdu_group_ref: PDU组引用路径,例如"/IPDUGroup/MyECU_oTestCAN1_Tx"
"""
if not hasattr(self, 'ecuInstance') or self.ecuInstance is None:
arxml_Abort("ECU-INSTANCE not found")
return
# 获取或创建ASSOCIATED-COM-I-PDU-GROUP-REFS元素
associated_refs = self.ecuInstance.find("ASSOCIATED-COM-I-PDU-GROUP-REFS")
if associated_refs is None:
associated_refs = arxml_create_sub_element(self.ecuInstance, "ASSOCIATED-COM-I-PDU-GROUP-REFS")
# 添加引用
group_ref = arxml_create_sub_element(associated_refs, "ASSOCIATED-COM-I-PDU-GROUP-REF", pdu_group_ref)
group_ref.set("DEST", "I-SIGNAL-I-PDU-GROUP")
def addGwFibexElement(self, name: str) -> None:
if self.FibexElements is None:
arxml_Abort("FibexElements is None")
return
if name in self.GwFibexElementTable:
# arxml_info(name + "is in GwFibexElementTable already")
return
fibexElemCond = arxml_create_sub_element(self.FibexElements, "FIBEX-ELEMENT-REF-CONDITIONAL")
fibexElemRef = arxml_create_sub_element(fibexElemCond, "FIBEX-ELEMENT-REF")
fibexElemRef.set("DEST", "GATEWAY")
pack = self.option.get("gatewayArPackegeName", "RouteGateway")
fibexElemRef.text = f"/{pack}/{name}"
self.GwFibexElementTable.append(name)
def addGwIPduRoutingPath(self, name: str) -> _Element | None:
if self.gatewayElements is None:
arxml_Abort("gatewayElements is None")
return None
if name in self.GwiPduMappingTable:
iPduMappings = self.GwiPduMappingTable[name]
else:
if name in self.GwGatewayTable:
gateway = self.GwGatewayTable[name]
else:
gateway = arxml_create_sub_element(self.gatewayElements, 'GATEWAY')
arxml_UpdateElemUUID(gateway)
arxml_create_sub_element(gateway, 'SHORT-NAME', name)
ecuRef = arxml_create_sub_element(gateway, 'ECU-REF', self.ecuInstancePath)
ecuRef.set("DEST","ECU-INSTANCE")
self.GwGatewayTable[name] = gateway
iPduMappings = arxml_create_sub_element(gateway, 'I-PDU-MAPPINGS')
self.GwiPduMappingTable[name] = iPduMappings
return iPduMappings
def addGwISignaloutingPath(self, name: str) -> _Element | None:
if self.gatewayElements is None:
arxml_Abort("gatewayElements is None")
return None
if name in self.GwiSignalMappingTable:
ISignalMappings = self.GwiSignalMappingTable[name]
else:
if name in self.GwGatewayTable:
gateway = self.GwGatewayTable[name]
else:
gateway = arxml_create_sub_element(self.gatewayElements, 'GATEWAY')
arxml_UpdateElemUUID(gateway)
arxml_create_sub_element(gateway, 'SHORT-NAME', name)
ecuRef = arxml_create_sub_element(gateway, 'ECU-REF', self.ecuInstancePath)
ecuRef.set("DEST","ECU-INSTANCE")
self.GwGatewayTable[name] = gateway
ISignalMappings = arxml_create_sub_element(gateway, 'SIGNAL-MAPPINGS')
self.GwiSignalMappingTable[name] = ISignalMappings
return ISignalMappings
def AddPduMapping(self, RoutingPathName: str, srcPduRefText: str, tagPduRefText: str) -> None:
self.addGwFibexElement(RoutingPathName)
iPduMappings = self.addGwIPduRoutingPath(RoutingPathName)
if iPduMappings is None:
arxml_Abort("iPduMappings is None")
return
mapping = arxml_create_sub_element(iPduMappings, "I-PDU-MAPPING")
srcIpduRef = arxml_create_sub_element(mapping, "SOURCE-I-PDU-REF", srcPduRefText)
srcIpduRef.set("DEST", "PDU-TRIGGERING")
tagIpdu = arxml_create_sub_element(mapping, "TARGET-I-PDU")
tagIpduRef = arxml_create_sub_element(tagIpdu, "TARGET-I-PDU-REF", tagPduRefText)
tagIpduRef.set("DEST", "PDU-TRIGGERING")
def AddSignalMapping(self, RoutingPathName: str, srcSignalRefText: str, tagSignalRefText: str) -> None:
self.addGwFibexElement(RoutingPathName)
ISignalMappings = self.addGwISignaloutingPath(RoutingPathName)
if ISignalMappings is None:
arxml_Abort("ISignalMappings is None")
return
mapping = arxml_create_sub_element(ISignalMappings, "I-SIGNAL-MAPPING")
srcISignalRef = arxml_create_sub_element(mapping, "SOURCE-SIGNAL-REF", srcSignalRefText)
srcISignalRef.set("DEST", "I-SIGNAL-TRIGGERING")
tagISignalRef = arxml_create_sub_element(mapping, "TARGET-SIGNAL-REF", tagSignalRefText)
tagISignalRef.set("DEST", "I-SIGNAL-TRIGGERING")
def AddClusterStructure(self, cluster_name="TestCAN1", channel_name="CHNL"):
"""
创建 Cluster 基础结构,并返回 CAN-PHYSICAL-CHANNEL 元素
"""
# 1. 创建 Cluster AR-PACKAGE
ar_package_cluster = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(ar_package_cluster)
arxml_create_sub_element(ar_package_cluster, "SHORT-NAME", "Cluster")
# 2. ELEMENTS
cluster_elements = arxml_create_sub_element(ar_package_cluster, "ELEMENTS")
# 3. CAN-CLUSTER
can_cluster = arxml_create_sub_element(cluster_elements, "CAN-CLUSTER")
arxml_UpdateElemUUID(can_cluster)
arxml_create_sub_element(can_cluster, "SHORT-NAME", cluster_name)
# 4. CAN-CLUSTER-VARIANTS -> CAN-CLUSTER-CONDITIONAL
cluster_variants = arxml_create_sub_element(can_cluster, "CAN-CLUSTER-VARIANTS")
cluster_conditional = arxml_create_sub_element(cluster_variants, "CAN-CLUSTER-CONDITIONAL")
arxml_create_sub_element(cluster_conditional, "BAUDRATE", "500000")
# 5. PHYSICAL-CHANNELS -> CAN-PHYSICAL-CHANNEL
physical_channels = arxml_create_sub_element(cluster_conditional, "PHYSICAL-CHANNELS")
physical_channel = arxml_create_sub_element(physical_channels, "CAN-PHYSICAL-CHANNEL")
arxml_UpdateElemUUID(physical_channel)
arxml_create_sub_element(physical_channel, "SHORT-NAME", channel_name)
arxml_create_sub_element(cluster_conditional, "PROTOCOL-NAME", "CAN")
arxml_create_sub_element(cluster_conditional, "CAN-FD-BAUDRATE", "500000")
return physical_channel
def create_ipdu_group_package(self, group_name: str, communication_direction: str, pdu_refs: list[str]) -> _Element:
"""
在 IPDUGroup 包中创建 I-SIGNAL-I-PDU-GROUP 元素
Args:
group_name: I-PDU组的名称,例如"FLZCU_oEEA_5_1_Message_List_EP_CANFD_V1_0_20250825_Rx"
communication_direction: 通信方向,例如"IN"或"OUT"
pdu_refs: I-SIGNAL-I-PDU引用路径列表
Returns:
创建的I-SIGNAL-I-PDU-GROUP元素
"""
if self.ipdu_group_elements is None:
arxml_Abort("IPDUGroup elements not initialized")
return None
# 创建I-SIGNAL-I-PDU-GROUP
ipdu_group = arxml_create_sub_element(self.ipdu_group_elements, "I-SIGNAL-I-PDU-GROUP")
arxml_UpdateElemUUID(ipdu_group)
arxml_create_sub_element(ipdu_group, "SHORT-NAME", group_name)
arxml_create_sub_element(ipdu_group, "COMMUNICATION-DIRECTION", communication_direction)
# 创建I-SIGNAL-I-PDUS容器
ipdus = arxml_create_sub_element(ipdu_group, "I-SIGNAL-I-PDUS")
# 为每个PDU引用创建引用元素
for pdu_ref in pdu_refs:
ref_conditional = arxml_create_sub_element(ipdus, "I-SIGNAL-I-PDU-REF-CONDITIONAL")
ref_elem = arxml_create_sub_element(ref_conditional, "I-SIGNAL-I-PDU-REF", pdu_ref)
ref_elem.set("DEST", "I-SIGNAL-I-PDU")
return ipdu_group
def create_can_frame_package(self, frame_name: str, frame_length: int, pdu_mappings: list[dict]) -> _Element:
"""
创建CanFrame包和CAN-FRAME元素
Args:
frame_name: CAN帧名称,例如"TestCan1_Msg_001_Tx_oTestCAN1"
frame_length: 帧长度,例如64
pdu_mappings: PDU映射列表,每个映射包含:
- name: 映射名称
- pdu_ref: PDU引用路径
- start_position: 起始位置
- byte_order: 字节顺序,默认为"MOST-SIGNIFICANT-BYTE-LAST"
Returns:
创建的AR-PACKAGE元素
"""
# 创建CanFrame包
ar_package = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(ar_package)
arxml_create_sub_element(ar_package, "SHORT-NAME", "CanFrame")
# 创建ELEMENTS
elements = arxml_create_sub_element(ar_package, "ELEMENTS")
# 创建CAN-FRAME
can_frame = arxml_create_sub_element(elements, "CAN-FRAME")
arxml_UpdateElemUUID(can_frame)
arxml_create_sub_element(can_frame, "SHORT-NAME", frame_name)
arxml_create_sub_element(can_frame, "FRAME-LENGTH", str(frame_length))
# 创建PDU-TO-FRAME-MAPPINGS容器
pdu_mappings_container = arxml_create_sub_element(can_frame, "PDU-TO-FRAME-MAPPINGS")
# 为每个PDU映射创建映射元素
for mapping in pdu_mappings:
pdu_mapping = arxml_create_sub_element(pdu_mappings_container, "PDU-TO-FRAME-MAPPING")
arxml_create_sub_element(pdu_mapping, "SHORT-NAME", mapping.get("name", ""))
# 设置字节顺序,默认为"MOST-SIGNIFICANT-BYTE-LAST"
byte_order = mapping.get("byte_order", "MOST-SIGNIFICANT-BYTE-LAST")
arxml_create_sub_element(pdu_mapping, "PACKING-BYTE-ORDER", byte_order)
# 创建PDU引用
pdu_ref = arxml_create_sub_element(pdu_mapping, "PDU-REF", mapping.get("pdu_ref", ""))
pdu_ref.set("DEST", "I-SIGNAL-I-PDU")
# 设置起始位置
arxml_create_sub_element(pdu_mapping, "START-POSITION", str(mapping.get("start_position", 0)))
return ar_package
def create_pdu_package(self, pdu_name: str, pdu_length: int, timing_spec: dict = None) -> _Element:
"""
创建PDU包和I-SIGNAL-I-PDU元素
Args:
pdu_name: PDU名称,例如"TestCan1_Msg_001_Tx_oTestCAN1"
pdu_length: PDU长度,例如64
timing_spec: 时序规范字典,包含:
- min_delay: 最小延迟,默认为0
- time_offset: 时间偏移,默认为0
- time_period: 时间周期,默认为0.01
Returns:
创建的AR-PACKAGE元素
"""
# 创建PDU包
ar_package = arxml_create_sub_element(self.top_level_packages, "AR-PACKAGE")
arxml_UpdateElemUUID(ar_package)
arxml_create_sub_element(ar_package, "SHORT-NAME", "PDU")
# 创建ELEMENTS
elements = arxml_create_sub_element(ar_package, "ELEMENTS")
# 创建I-SIGNAL-I-PDU
isignal_ipdu = arxml_create_sub_element(elements, "I-SIGNAL-I-PDU")
arxml_UpdateElemUUID(isignal_ipdu)
arxml_create_sub_element(isignal_ipdu, "SHORT-NAME", pdu_name)
arxml_create_sub_element(isignal_ipdu, "LENGTH", str(pdu_length))
# 创建I-PDU-TIMING-SPECIFICATIONS容器
timing_specs = arxml_create_sub_element(isignal_ipdu, "I-PDU-TIMING-SPECIFICATIONS")
# 创建I-PDU-TIMING
ipdu_timing = arxml_create_sub_element(timing_specs, "I-PDU-TIMING")
# 设置默认时序规范
if timing_spec is None:
timing_spec = {
"min_delay": 0,
"time_offset": 0,
"time_period": 0.01
}
arxml_create_sub_element(ipdu_timing, "MINIMUM-DELAY", str(timing_spec.get("min_delay", 0)))
# 创建TRANSMISSION-MODE-DECLARATION
transmission_mode = arxml_create_sub_element(ipdu_timing, "TRANSMISSION-MODE-DECLARATION")
# 创建FALSE和TRUE两种传输模式的时序
for mode in ["FALSE", "TRUE"]:
mode_timing = arxml_create_sub_element(
transmission_mode,
f"TRANSMISSION-MODE-{mode}-TIMING"
)
cyclic_timing = arxml_create_sub_element(mode_timing, "CYCLIC-TIMING")
time_offset = arxml_create_sub_element(cyclic_timing, "TIME-OFFSET")
arxml_create_sub_element(time_offset, "VALUE", str(timing_spec.get("time_offset", 0)))
time_period = arxml_create_sub_element(cyclic_timing, "TIME-PERIOD")
arxml_create_sub_element(time_period, "VALUE", str(timing_spec.get("time_period", 0.01)))
# 添加未使用位模式
arxml_create_sub_element(isignal_ipdu, "UNUSED-BIT-PATTERN", "0")
return ar_package
def AddPduTriggeringUnderPhysicalChannel(self, physical_channel_elem: _Element, pdu_short_name: str, ipdu_port_path: str, ipdu_ref_path: str) -> _Element:
"""
在给定的 CAN-PHYSICAL-CHANNEL 下创建 PDU-TRIGGERINGS -> PDU-TRIGGERING 节点并返回它。
参数:
- physical_channel_elem: CAN-PHYSICAL-CHANNEL 元素
- pdu_short_name: e.g. "PT_TestCan1_Msg_001_Tx"
- ipdu_port_path: e.g. "/ECU/MyECU/CN_TestCAN1/PP_TestCan1_Msg_001_Tx_Tx"
- ipdu_ref_path: e.g. "/PDU/TestCan1_Msg_001_Tx_oTestCAN1"
"""
pdu_triggerings_container = arxml_get_or_create_sub_element(physical_channel_elem, "PDU-TRIGGERINGS")
pdu_trig = arxml_create_sub_element(pdu_triggerings_container, "PDU-TRIGGERING")
arxml_create_sub_element(pdu_trig, "SHORT-NAME", pdu_short_name)
ipdu_port_refs = arxml_create_sub_element(pdu_trig, "I-PDU-PORT-REFS")
ipdu_port_ref = arxml_create_sub_element(ipdu_port_refs, "I-PDU-PORT-REF", ipdu_port_path)
ipdu_port_ref.set("DEST", "I-PDU-PORT")
ipdu_ref = arxml_create_sub_element(pdu_trig, "I-PDU-REF", ipdu_ref_path)
ipdu_ref.set("DEST", "I-SIGNAL-I-PDU")
return pdu_trig
def AddCanFrameTriggeringUnderPhysicalChannel(
self,
physical_channel_elem: _Element,
frame_triggering_short_name: str,
frame_port_path: str,
can_frame_ref_path: str,
pdu_triggering_ref_paths: list,
identifier: int = 0,
addressing_mode: str = "STANDARD",
rx_behavior: str = "ANY",
tx_behavior: str = "CAN-FD"
) -> _Element:
"""
在给定的 CAN-PHYSICAL-CHANNEL 元素下创建 FRAME-TRIGGERINGS -> CAN-FRAME-TRIGGERING 节点,
返回新创建的 CAN-FRAME-TRIGGERING 元素。
参数:
- physical_channel_elem: 已创建的 CAN-PHYSICAL-CHANNEL 元素
- frame_triggering_short_name: e.g. "FT_TestCan1_Msg_001_Tx"
- frame_port_path: 完整 path 文本, e.g. "/ECU/MyECU/CN_TestCAN1/FP_TestCan1_Msg_001_Tx_Tx"
- can_frame_ref_path: e.g. "/CanFrame/TestCan1_Msg_001_Tx_oTestCAN1"
- pdu_triggering_ref_paths: list of full PDU-TRIGGERING 路径,例如 ["/Cluster/TestCAN1/CHNL/PT_TestCan1_Msg_001_Tx"]
- identifier/addressing_mode/rx_behavior/tx_behavior: 可选属性
"""
# 确保 FRAME-TRIGGERINGS 容器存在(若已存在就复用)
frame_triggerings = arxml_get_or_create_sub_element(physical_channel_elem, "FRAME-TRIGGERINGS")
# 创建 CAN-FRAME-TRIGGERING
frame_trig = arxml_create_sub_element(frame_triggerings, "CAN-FRAME-TRIGGERING")
arxml_create_sub_element(frame_trig, "SHORT-NAME", frame_triggering_short_name)
# FRAME-PORT-REFS
frame_port_refs = arxml_create_sub_element(frame_trig, "FRAME-PORT-REFS")
frame_port_ref = arxml_create_sub_element(frame_port_refs, "FRAME-PORT-REF", frame_port_path)
frame_port_ref.set("DEST", "FRAME-PORT")
# FRAME-REF
frame_ref = arxml_create_sub_element(frame_trig, "FRAME-REF", can_frame_ref_path)
frame_ref.set("DEST", "CAN-FRAME")
# PDU-TRIGGERINGS -> 多个 PDU-TRIGGERING-REF-CONDITIONAL / PDU-TRIGGERING-REF
pdu_triggerings = arxml_create_sub_element(frame_trig, "PDU-TRIGGERINGS")
for pdu_ref in pdu_triggering_ref_paths:
pdu_ref_cond = arxml_create_sub_element(pdu_triggerings, "PDU-TRIGGERING-REF-CONDITIONAL")
pdu_ref_elem = arxml_create_sub_element(pdu_ref_cond, "PDU-TRIGGERING-REF", pdu_ref)
pdu_ref_elem.set("DEST", "PDU-TRIGGERING")
# 其它属性
arxml_create_sub_element(frame_trig, "CAN-ADDRESSING-MODE", addressing_mode)
arxml_create_sub_element(frame_trig, "CAN-FRAME-RX-BEHAVIOR", rx_behavior)
arxml_create_sub_element(frame_trig, "CAN-FRAME-TX-BEHAVIOR", tx_behavior)
arxml_create_sub_element(frame_trig, "IDENTIFIER", str(identifier))
return frame_trig
# if __name__ == "__main__":
# now = GetTimeStr()
# opts = {
# "gatewayArPackegeName": "RouteGateway",
# "gatewayName": "GEN_GW",
# "ecuInstanceName": "GEN_GW",
# }
# arxml = gatewayDoc(opt=opts)
# arxml.init()
# arxml.AddPduMapping("GEN_GW","/Cluster/ICM_ADAS/CHNL/PT_ADAS_IPC12", "/Cluster/ICM_AUX/CHNL/PT_AUX_BCM_RC5")
# arxml.save("gatewayOutput.arxml")
if __name__ == "__main__":
# 从 JSON 文件读取路由信息
with open('TestInputFile/routing_info1.json', 'r') as f:
routing_info = json.load(f)
now = GetTimeStr()
opts = {
"gatewayArPackegeName": "RouteGateway",
"gatewayName": "FLZCU",
"ecuInstanceName": "FLZCU",
}
# 1. 初始化 gatewayDoc
arxml = gatewayDoc(opt=opts)
arxml.init()
# 收集所有网络(Cluster)信息
clusters = {}
for route in routing_info:
# 假设每个路由项都有一个 cluster_name 字段
cluster_name = route.get("cluster_name", "TestCAN1")
if cluster_name not in clusters:
# 创建 Cluster 结构
physical_channel = arxml.AddClusterStructure(
cluster_name=cluster_name,
channel_name=f"CHNL_{cluster_name}"
)
clusters[cluster_name] = physical_channel
# 处理每个路由项
for route in routing_info:
routing_type = route.get("routing_type", "Message")
cluster_name = route.get("cluster_name", "TestCAN1")
physical_channel = clusters[cluster_name]
# 添加 Gateway PDU Mapping 或 Signal Mapping
if routing_type == "Message":
arxml.AddPduMapping(
route.get("routing_path_name", "GEN_GW"),
route.get("rx_pdu_trigger", ""),
route.get("tx_pdu_trigger", "")
)
elif routing_type == "Signal":
# 如果有信号映射,可以在这里添加
pass
# 添加 CAN-FRAME-TRIGGERING
frame_triggering = route.get("frame_triggering", {})
if frame_triggering:
arxml.AddCanFrameTriggeringUnderPhysicalChannel(
physical_channel_elem=physical_channel,
frame_triggering_short_name=frame_triggering.get("short_name", ""),
frame_port_path=frame_triggering.get("frame_port_path", ""),
can_frame_ref_path=frame_triggering.get("can_frame_ref_path", ""),
pdu_triggering_ref_paths=frame_triggering.get("pdu_triggering_ref_paths", []),
identifier=frame_triggering.get("identifier", 0)
)
# 添加 PDU-TRIGGERING
pdu_triggering = route.get("pdu_triggering", {})
if pdu_triggering:
arxml.AddPduTriggeringUnderPhysicalChannel(
physical_channel_elem=physical_channel,
pdu_short_name=pdu_triggering.get("short_name", ""),
ipdu_port_path=pdu_triggering.get("ipdu_port_path", ""),
ipdu_ref_path=pdu_triggering.get("ipdu_ref_path", "")
)
# 创建 IPDUGroup 包
ipdu_group = route.get("ipdu_group", {})
if ipdu_group:
arxml.create_ipdu_group_package(
group_name=ipdu_group.get("group_name", ""),
communication_direction=ipdu_group.get("communication_direction", "OUT"),
pdu_refs=ipdu_group.get("pdu_refs", [])
)
# 创建 CanFrame 包
can_frame = route.get("can_frame", {})
if can_frame:
arxml.create_can_frame_package(
frame_name=can_frame.get("frame_name", ""),
frame_length=can_frame.get("frame_length", 64),
pdu_mappings=can_frame.get("pdu_mappings", [])
)
# 创建 PDU 包
pdu_info = route.get("pdu", {})
if pdu_info:
arxml.create_pdu_package(
pdu_name=pdu_info.get("pdu_name", ""),
pdu_length=pdu_info.get("pdu_length", 64)
)
# 创建 ECU package
arxml.addEcuInstance()
# 添加关联的 PDU 组引用
for route in routing_info:
ipdu_group = route.get("ipdu_group", {})
if ipdu_group:
arxml.add_associated_pdu_group_ref(f"/IPDUGroup/{ipdu_group.get('group_name', '')}")
# 添加 ECU 连接器
for cluster_name in clusters:
arxml.add_ecu_connector(
connector_name=f"CN_{cluster_name}",
controller_ref=f"/ECU/{opts['ecuInstanceName']}/CT_{cluster_name}",
frame_ports=[{
"name": f"FP_{cluster_name}_Tx",
"direction": "OUT"
}],
pdu_ports=[{
"name": f"PP_{cluster_name}_Tx",
"direction": "OUT"
}]
)
# 保存 ARXML 文件
arxml.save("TestOutputFile/gatewayOutput1.arxml")
print("ARXML 文件已生成:TestOutputFile/gatewayOutput1.arxml")
最新发布