【Python】生成SWC arxml

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在基于AUTOSAR平台开发的软件系统中,SWC的描述文件的格式是arxml。这个文件常由Vector的Developer导出或者MATLAB编译生成,但在开发过程中模块的接口文档一般是写在Excel表格中的,手动在工具中创建比较麻烦,所以如果能够由表格生成arxml再导入到开发工具或者集成工具中就比较方便了。
以下没有Excel表格读取的内容,仅分享arxml的生成,并且是SWC中常见的内容:SWC、runnable、SR接口和数据类型的创建。

一、第三方库autosar

以下功能是基于Python第三方库autosar (0.4.2)的基础上进行的封装,仅用了里面一部分功能,详细内容可查阅 https://autosar.readthedocs.io/en/latest/

二、代码分享

由于库中的函数和一些方法不好理解,所以按照自己的方式进行了一层封装,只封装了常使用的一些功能。

1. Swc类初始化

Swc是自定义的一个类,一些功能都写在这个类的方法中。
代码如下(示例):

class Swc(object):
    def __init__(self, swc, file):
        self.swc = swc
        pkg_swc = swc
        pkg = pkg_swc + '_pkg'
        self.refs = {
   
            # Package Paths
            'componentPackage': f'/{
     pkg}/{
     pkg_swc}_swc',
            'datatypePackage': f'/{
     pkg}/{
     pkg_swc}_dt',  # /ImplementationDataTypes
            'interfacePackage': f'/{
     pkg}/{
     pkg_swc}_if',  # "PortInterfaces", #
            # Qualified Names
            # 'internalBehaviorName': f'/{pkg}/{pkg_swc}_swc/ib/{pkg_swc}',
            # 'implementationName': f'/{pkg}/{pkg_swc}_swc/{pkg_swc}_imp',
            # Additional Packages
            'applicationDataTypePackage': f'/{
     pkg}/{
     pkg_swc}_dt/ApplDataTypes',
            'swBaseTypePackage': f'/{
     pkg}/{
     pkg_swc}_dt/SwBaseTypes',
            'dataTypeMappingSetPackage': f'/{
     pkg}/{
     pkg_swc}_dt/DataTypeMappings',
            'constantSpecificationPackages': f'/{
     pkg}/{
     pkg_swc}_dt/Ground',
            'physicalDataConstraintsPackage': f'/{
     pkg}/{
     pkg_swc}_dt/ApplDataTypes/DataConstrs',
            'systemConstantPackage': '',
            'swAddressMethodPackage': f'/{
     pkg}/{
     pkg_swc}_dt/SwAddrMethods',
            'modeDeclarationGroupPackage': '',
            'compuMethodPackage': f'/{
     pkg}/{
     pkg_swc}_dt/CompuMethod',
            'unitPackage': f'/{
     pkg}/{
     pkg_swc}_dt',
            'swRecordLayoutPackage': f'/{
     pkg}/{
     pkg_swc}_dt/ApplDataTypes/RecordLayouts',
            'internalDataConstraintsPackage': 'AUTOSAR_Platform/DataConstrs'
        }
        self.ws = autosar.workspace("4.2.2")
        if file:
            self.ws.loadXML(file)
        self.ws.version = "4.2.2"
  • swc:swc的名称。(如果容易混淆,可以改成其他名字。)
  • file:arxml文件路径。autosar也是可以读取arxml文件的,可以在此基础上修改。如果从零创建,可以传入None。

功能说明:

  • self.refs:这个是package的路径,后续创建的内容会放到这里面。MATLAB生成的arxml也是可以设置这个路径的,如下:
    在这里插入图片描述
  • self.ws = autosar.workspace(“4.2.2”):后续的处理都是在workspace的基础上进行的,传入的数字是arxml版本,4.0以后的都可以。(这个workspace是可以创建一个Developer工程的,没用到就没咋研究。)
  • self.ws.loadXML:是用于读取arxml。
  • self.ws.version = “4.2.2”:读取后需要设置一下arxml版本,否则后续处理会出现exception。(好像4.0以后SWC的arxml没事区别,设置一个即可。)

2. 创建package

代码如下(示例):

    def common_pkg_create(self):
        """
        Create common package according to self.refs.
        If package already exist, it will not be created controlling by autosar.workspace. See createPackage.
        """
        for ref in self.refs.values():
            if ref:
                refList = autosar.base.splitRef(ref)
                pkg = self.ws.createPackage(refList[0])  # 创建一级目录
                if len(refList) > 1:
                    self.create_sub_pkg_by_ref(pkg, '/'.join(refList[1::]))  # 创建子目录

    def create_sub_pkg_by_ref(self, pkg, ref):
        """
        Create subPackage for pkg according to ref.
        """
        refList = autosar.base.splitRef(ref)
        f = pkg.find(refList[0])  # 查找是否已经存在package (refList[0])
        if len(refList) > 1:  # 存在深层次路径,则需要迭代创建
            if f:
                self.create_sub_pkg_by_ref(f, '/'.join(refList[1::]))
            else:  # 如果不存在pkg,则创建
                temp = pkg.createSubPackage(refList[0])
                self.create_sub_pkg_by_ref(temp, '/'.join(refList[1::]))
        else:
            if not f:
                pkg.createSubPackage(refList[0])

3. 创建数据类型

3.1 BaseType

代码如下(示例):

    def util_createSwBaseType(self, name, size=None, encoding=None, nativeDeclaration=None, category='FIXED_LENGTH',
                              adminData=None):
        baseTypes = self.ws.find(self.refs.get('swBaseTypePackage'))
        self.ws.setRole(self.refs.get('swBaseTypePackage'), 'DataType')
        try:
            baseTypes.createSwBaseType(name, size, encoding, nativeDeclaration, category, adminData)
        except ValueError:
            LOG.debug(f"Already exist SwBaseType: {
     name}")
  • self.ws.find:可以findpackage,但需要注意传入ref的绝对路径(因为会常用这个路径,所以定义了一个refs字典)。
  • self.ws.setRole:需要将swBaseTypePackage设置为DataType角色,一些内部的处理用的这个“Role”。也可在创建package时设置,设置一次即可。
  • baseTypes.createSwBaseType:创建BaseType的函数。(后面会有例子)

3.2 ImplementationDataType

代码如下(示例):

    def util_createImplementationDataType(self, name, baseTypeRef, lowerLimit=None, upperLimit=None, valueTable=None,
                                          bitmask=None, offset=None, scaling=None, unit=None, forceFloat=False,
                                          dataConstraint='', swCalibrationAccess='', typeEmitter=None,
                                          lowerLimitType=None, upperLimitType=None, category='VALUE', adminData=None):
        implTypes = self.ws.find(self.refs.get('datatypePackage'))
        self.ws.setRole(implTypes.ref, 'DataType')
        try:
            implTypes.createImplementationDataType(name, baseTypeRef, lowerLimit, upperLimit, valueTable, bitmask,
                                                   offset, scaling, unit, forceFloat, dataConstraint,
                                                   swCalibrationAccess, typeEmitter, lowerLimitType, upperLimitType,
                                                   category, adminData)
        except ValueError:
            LOG.debug(f"Already exist ImplementationDataType: {
     name}")
  • 这个创建Implementation类型,不同的类型(结构体,数组,枚举等)需要传入的参数不同。在此基础上又进行了一次封装。
3.2.1 一般类型

代码如下(示例):

    def util_createDataType(self, name, baseType):
        implTypes = self.ws.find(self.refs.get('datatypePackage'))
        self.ws.setRole(implTypes.ref, 'DataType')
        if not implTypes.find(name):
            baseTypeRef = f'{
     self.refs.get("swBaseTypePackage")}/{
     baseType}'
            return self.util_createImplementationDataType(name=name, baseTypeRef=baseTypeRef)
  • 用于生成如uint8、sint8、float32的一般类型。
  • 需要传入baseTypeRef,这个用的是创建的BaseType,其ref在swBaseTypePackage路径下。(在某packa
<think>好的,用户想用Python解析SWC.arxml文件以获取Autosar组件的端口和接口信息。首先,我需要回忆一下AUTOSAR的ARXML文件结构,这类文件通常是基于XML的,所以使用Python的XML库来处理应该没问题。 用户提供的引用中提到了使用xml.etree.ElementTree库来解析ARXML文件,这是一个常用的方法。首先需要导入相应的库,比如ET和os。然后通过ET.parse加载文件,获取根节点。接下来需要遍历节点,找到相关的组件信息。 根据AUTOSAR的标准,端口和接口信息可能存储在特定的标签下,比如SHORT-NAME、PORT或者INTERFACE。可能需要先找到SWC组件的定义部分,然后在其子节点中查找端口信息。每个端口可能会有对应的接口引用,需要进一步解析接口的具体内容,比如数据类型和方法。 需要注意的是,不同的ARXML文件结构可能有所不同,用户需要根据实际文件调整标签名称。另外,命名空间的问题也很重要,AUTOSAR文件通常有命名空间前缀,比如{http://autosar.org/schema/r4.0},所以在查找标签时要包含命名空间。 用户可能还需要处理接口类型,比如SENDER-RECEIVER-INTERFACE或CLIENT-SERVER-INTERFACE,这些不同类型的接口可能有不同的结构,需要分别处理。例如,SENDER-RECEIVER接口可能包含DATA-ELEMENT,而CLIENT-SERVER接口可能有OPERATION。 最后,生成相关问题时,要考虑用户可能遇到的后续步骤,比如如何处理命名空间,提取数据类型,或者优化解析方法。同时,用户可能需要了解如何将这些信息导出为表格,或者验证提取的数据是否正确。</think>按照AUTOSAR标准解析SWC.arxml文件,可通过以下步骤提取组件接口信息: ### 一、ARXML结构分析 AUTOSAR组件接口信息通常存储在以下路径: $$AR-PACKAGE → ELEMENTS → APPLICATION-SW-COMPONENT-TYPE → PORTS → ※PORT※$$ 接口类型包括: - SENDER-RECEIVER-INTERFACE(发送接收接口) - CLIENT-SERVER-INTERFACE(客户端服务端接口)[^3] ### 二、Python解析实现 ```python import xml.etree.ElementTree as ET def parse_swc_ports(arxml_path): tree = ET.parse(arxml_path) root = tree.getroot() # 声明AUTOSAR命名空间 ns = {'ns': 'http://autosar.org/schema/r4.0'} interface_table = [] # 查找所有SWC组件 for swc in root.findall('.//ns:APPLICATION-SW-COMPONENT-TYPE', ns): swc_name = swc.find('ns:SHORT-NAME', ns).text # 提取端口信息 for port in swc.findall('.//ns:PORTS/ns:P-PORT-PROTOTYPE', ns): port_info = { 'component': swc_name, 'port_name': port.find('ns:SHORT-NAME', ns).text, 'interface_ref': port.find('.//ns:PROVIDED-INTERFACE-TREF', ns).text, 'direction': '提供' if 'PROVIDED' in port.tag else '需求' } # 获取接口详细信息 interface = root.find(f".//*[@UUID='{port_info['interface_ref'].split('/')[-1]}']", ns) if interface is not None: port_info['interface_type'] = interface.tag.split('}')[-1] port_info['data_elements'] = [elem.text for elem in interface.findall('.//ns:DATA-ELEMENT-PROTOTYPE/ns:SHORT-NAME', ns)] interface_table.append(port_info) return interface_table ``` ### 三、关键解析点说明 1. **命名空间处理**:必须声明`ns`命名空间才能正确访问节点[^1] 2. **XPath查询**: - `//ns:APPLICATION-SW-COMPONENT-TYPE` 定位SWC组件 - `.//ns:PORTS/ns:P-PORT-PROTOTYPE` 获取所有端口 3. **接口关联**:通过`UUID`实现接口引用跳转[^2] 4. **数据类型解析**:对`SENDER-RECEIVER-INTERFACE`会提取`DATA-ELEMENT-PROTOTYPE` ### 四、执行与输出 ```python if __name__ == "__main__": result = parse_swc_ports("SWC.arxml") for item in result: print(f"组件:{item['component']}") print(f"端口:{item['port_name']} ({item['direction']})") print(f"接口类型:{item.get('interface_type','N/A')}") print(f"数据元素:{item.get('data_elements',[])}\n") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kook 1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值