找回密码
 会员注册
查看: 30|回复: 0

汽车架构解析:python解析Autosar架构的ARXML

[复制链接]

4

主题

0

回帖

13

积分

新手上路

积分
13
发表于 2024-9-12 16:52:16 | 显示全部楼层 |阅读模式
文章目录前言一、Container-I-PDU概念引入二、以文本形式读取ARXML文件三、解析Frame的基本参数四、解析Frame中的PDU五、解析PDU中的Signals六、解析Signal中的初始值和长度七、解析Signal中的起始位置八、解析Signal中的枚举值或公式九、解析ARXML总结前言Autosar架构下arxml文件作为通用数据库文件,在数据传输和存储中起到关键作用。行业上其实有一些arxml的工具可以将arxml转换成dbc,再将dbc转换成自己想要的数据,但是拿到的数据是不完整的,arxml有一些数据dbc是没有的,也根据缺少的数据直接到ARXML拿,不用硬解ARXML。想要解析ARXML的最好的方法就是对原始数据进行处理。网上有一些python的库推荐,如xml.etree.ElementTree等,我试用了下,arxml的层级关系太多了感觉处理起来不太自由。于是我决定用python的正则表达式来解析,因为知道了所需数据存放的结构体,就可以通过正则表达式快速定位获取数据,而且可以自由的获取arxml的任意数据片段,按照自己的规则解析。正则表达式相关学习点这里一、Container-I-PDU概念引入1、下图为autosar的协议栈,可以看出具备多种类型的PDU:Dcm-I-PDU、General-Purpose-PDU、General-Purpose-I-PDU、I-Signal-I-PDU、Multiplexed-I-PDU、NM-PDU、N-PDU、User-Defined-PDU、User-Defined-I-PDU、XCP-PDU、J1939-Dcm-I-PDU和Secured-I-PDU。2、而Container-I-PDU是一种在AUTOSAR中使用的数据单元,用于封装其他类型的PDU(ProtocolDataUnit)。它是一种容器,可以包含不同类型的PDU作为其成员。Container-I-PDU的主要目的是将多个PDU组合成一个逻辑单元进行传输。通过将多个PDU打包到一个Container-I-PDU中,可以减少通信开销,并提高通信效率。3、虽然有Container-I-PDU的概念,但是不代表I-PDU就一定需要通过Container-I-PDU去传输,因此也有两种传输方式。1)通过Container-I-PDU打包传输:如果是通过Container-I-PDU打包发出则需要先找到Container-I-PDU,再找到I-PDU,最后才能找到Signal。2)不通过Container-I-PDU打包传输:如果是直接通过I-PDU发出,则直接找到I-PDU,再找到Signal。二、以文本形式读取ARXML文件importrefile_path=r'C:\Users\Desktop\Demo.arxml'#============读取Arxml文件============withopen(file_path,'r')asfile:#读取文件内容arxml_data=file.read()123456三、解析Frame的基本参数1、下面是arxml的片段其中就包括了CAN报文的名称DMS_ADCANFD_FrP01,寻址模式STANDARD,通讯协议CAN-FD,以及报文ID554;2、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的../报文名称来获得报文名称;匹配片段中的帧类型来获得帧类型;匹配片段中的报文类型来获得报文类型;匹配片段中的报文ID来获得报文ID; FrTrDMS_ADCANFD_FrP01 /ECUSystem/DMS/DMSC/DMSCCfg/DMSCCfg/ADCANFD/FramePort_Out /VectorAutosarExplorerGeneratedObjects/ECU_INSTANCES/OtherNodes/Connector_OtherNodes_64e0f3f0db5999fe/framePort_ac33e765d8d23aa9 /Communication/Frame/DMS_ADCANFD_FrP01 /VehicleTopology/ADCANFD/PhCnADCANFD/PduTrDMS_ADCANFD_050ms_Container01 STANDARD CAN-FD 554123456789101112131415163、正则表达式处理数据python代码:#找出所有frame的数据片段CANFrameNode_pattern=r'(.*?)'CANFrameNodes_List=re.findall(CANFrameNode_pattern,arxml_data,re.DOTALL)#使用re.DOTALL标志使.匹配任意字符,包括换行符#设置CANFrame的匹配规则:报文名称:(.*?),寻址模式:,报文类型CAN/CANFD:,报文标识ID:CANFrame_pattern=r'(.*?).*?(.*?).*?(.*?).*?(.*?)'#开始匹配上述参数forCANFrameNodesinCANFrameNodes_List:CANFrames_match=re.findall(CANFrame_pattern,CANFrameNodes,re.DOTALL)#使用re.DOTALL标志使.匹配任意字符,包括换行符ifCANFrames_match:forCANFrameinCANFrames_match:CAN_FrameData_dict={"FrameName":"","AdressingMode":'',"Frametype":"","CanId":"","signals":[]}CAN_FrameData_dict["FrameName"]=CANFrame[0].split("/")[-1]CAN_FrameData_dict["AdressingMode"]=CANFrame[1]CAN_FrameData_dict["Frametype"]=CANFrame[2]CAN_FrameData_dict["CanId"]=CANFrame[3]CAN_matrix.append(CAN_FrameData_dict)print(CAN_matrix)12345678910111213141516171819打印结果:#打印结果只列举一个[{'FrameName':'DMS_ADCANFD_FrP01','AdressingMode':'STANDARD','Frametype':'CAN-FD','CanId':'554','signals':[]}]12四、解析Frame中的PDU1、这里举例解析Frame中的Container-I-PDU和Signal-I-PDU,这里强调必须注意是否存在Container-I-PDU,因为匹配的方法不太一样。2、下面是arxml的片段其中就包括了CAN报文的名称DMS_ADCANFD_FrP01,PDU名称PduTrDMS_ADCANFD_050ms_Container01;3、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的../报文名称来获得报文名称;匹配片段中的 ../PDU名称来获取PDU名称; FrTrDMS_ADCANFD_FrP01 /ECUSystem/DMS/DMSC/DMSCCfg/DMSCCfg/ADCANFD/FramePort_Out /VectorAutosarExplorerGeneratedObjects/ECU_INSTANCES/OtherNodes/Connector_OtherNodes_64e0f3f0db5999fe/framePort_ac33e765d8d23aa9 /Communication/Frame/DMS_ADCANFD_FrP01 /VehicleTopology/ADCANFD/PhCnADCANFD/PduTrDMS_ADCANFD_050ms_Container01 STANDARD CAN-FD 554123456789101112131415164、正则表达式处理数据python代码:这里的参数不和上述的《三、解析Frame的基本参数》一起匹配的原因是Frame中的Container-I-PDU的数量可能不唯一,用贪婪匹配可以匹配多个结果。#设置PDU的匹配规则:报文名称:,PDU名称: PDUS_pattern=r'(.*?)| (.*?)'Frame_Pdus_Data=[]Pdus_data=[]#匹配FrameName和PDUforCANFrameNodeinCANFrameNodes_List:Frame_Pdus_dict={"FrameName":"","pduname":""}PDUS_match=re.findall(PDUS_pattern,CANFrameNode,re.DOTALL)Framepdu=[match[0].split("/")[-1]ormatch[1].split("/")[-1]formatchinPDUS_matchifmatch[0]ormatch[1]]Frame_Pdus_dict["FrameName"]=Framepdu[0]Frame_Pdus_dict["pduname"]=Framepdu[1:]Frame_Pdus_Data.append(Frame_Pdus_dict)print(Frame_Pdus_Data)123456789101112131415打印结果:#打印结果只列举一个[{'FrameName':'DMS_ADCANFD_FrP01','pduname':['PduTrDMS_ADCANFD_050ms_Container01']}]125、下面是arxml的片段其中就包括了PDU的名称CCP_ADCANFD_020ms_Container11,Container-I-PDU中的I-PDUPduTrCCP_020ms_PDU00_AD,PduTrCCP_020ms_PDU02_AD,NewPduTriggering_a1955a2b08c2a3bb;6、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的PDU名称来获得报文名称;匹配片段中的../IPDU名称来获取PDU名称,I-PDU可能存在多个;CCP_ADCANFD_020ms_Container1164/VehicleTopology/ADCANFD/PhCnADCANFD/PduTrCCP_020ms_PDU00_AD/VehicleTopology/ADCANFD/PhCnADCANFD/PduTrCCP_020ms_PDU02_AD/VehicleTopology/ADCANFD/PhCnADCANFD/NewPduTriggering_a1955a2b08c2a3bb0DEFAULT-TRIGGERACCEPT-CONFIGURED01234567891011121314python代码匹配CONTAINER-I-PDU中的PDU#============找出CONTAINER-I-PDU中的PDU===========Container_PDUS_pattern=r'(.*?)'#匹配具体参数获得I-PDU参数Container_PDUS_match=re.findall(Container_PDUS_pattern,arxml_data,re.DOTALL)#使用re.DOTALL标志使.匹配任意字符,包括换行符ISignal_PDUS_pattern=r'(.*?)|(.*?)'Container_PDUS=[]forContainer_PDUinContainer_PDUS_match:ISignal_PDUS=[]ISignal_PDUS_match=re.findall(ISignal_PDUS_pattern,Container_PDU,re.DOTALL)forISignal_PDUinISignal_PDUS_match:a=[PDU.split("/")[-1]forPDUinISignal_PDUifPDU!=""]ISignal_PDUS.extend([PDU.split("/")[-1]forPDUinISignal_PDUifPDU!=""])Container_PDUS.append(ISignal_PDUS)123456789101112131415将Container-I-PDU中的iI-PDU成员整合到Frame中#填充CONTAINER-I-PDU数据到字典forFrame_PdusinFrame_Pdus_Data:forpdnameinFrame_Pdus['pduname']:forContainer_PDUinContainer_PDUS:ifany(elementinpdnameforelementinContainer_PDU)isTrue:forCpinContainer_PDUduData_dict={"FrameName":"","pduname":""}PduData_dict["FrameName"]=Frame_Pdus["FrameName"]PduData_dict["pduname"]=CpPdus_data.append(PduData_dict)print(Pdus_data)1234567891011打印结果:#这里只举例一个结果[{'FrameName':'CCP_ADCANFD_FrP02','pduname':'CCP_ADCANFD_020ms_Container11'},{'FrameName':'CCP_ADCANFD_FrP02','pduname':'PduTrCCP_020ms_PDU00_AD'},{'FrameName':'CCP_ADCANFD_FrP02','pduname':'PduTrCCP_020ms_PDU02_AD'},{'FrameName':'CCP_ADCANFD_FrP02','pduname':'NewPduTriggering_a1955a2b08c2a3bb'}]127、拓展:假设有其他PDU,但是又不经过Container-I-PDU打包传输怎么办?直接在Frame中匹配到N-PDU或者I-Signal-PDUd等等,这种情况也很常见,大家在匹配PDU部分的时候一定要特别注意不要在Frame中匹配Container-I-PDU;NmPDU_ADCANFD_DMS8isDMS_NM_BSMtoRMS_mtx/Communication/ISignal/isDMS_NM_BSMtoRMS MOST-SIGNIFICANT-BYTE-FIRST16TRIGGEREDfalse255123456789101112131415python代码:NM_PDUS_Pattern=r'.*?(.*?).*?'NM_PDUs=re.findall(N_PDUS_pattern,arxml_data,re.DOTALL)12打印结果#这里只举例一个结果NmPDU_ADCANFD_DMS12可以直接查找有Frame中的PDU,而且PDU里面直接有signal参数,后面会正式一起匹配Signal的参数。五、解析PDU中的Signals1、匹配Signal名称的mapping关系,因为PDU中的Signal名称只是MappingSignalname,真正的名称在其他arxml片段,我也不知道autosar为什么需要这么设计,还是按照他的规则办事吧。2、下面是arxml的片段其中就包括了PDU中Signal的名称ISTrisDMSAdoWrnngDspCmd_0,以及真实用到的RealSignal名称isDMSAdoWrnngDspCmd;3、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的PDU中Signal名称来获得PDU中MappingSignalname名称;匹配片段中的../RealSignal名称来获取RealSignalname名称;ISTrisDMSAdoWrnngDspCmd_0/ECUSystem/DMS/DMSC/DMSCCfg/DMSCCfg/ADCANFD/SignalPort_Out/VectorAutosarExplorerGeneratedObjects/ECU_INSTANCES/OtherNodes/Connector_OtherNodes_64e0f3f0db5999fe/SP_b097681ed4394b359291806d796936a3_Rx/Communication/ISignal/isDMSAdoWrnngDspCmd123456789python代码#因为PDU中的部分Signal名称有Mapping关系,所以需要拿到Realsignalname名称signalTrig_pattern=r'(.*?)'signalTrig_match=re.findall(signalTrig_pattern,arxml_data,re.DOTALL)signalTrig_str=""#存在的片段,才具有Mapping属性,仅有一个forsignalTriginsignalTrig_match:if''insignalTrig:signalTrig_str=signalTrig#匹配signalname的Mapping关系signalRealName_pattern=r'(.*?)|(.*?)'signalRealName_match=re.findall(signalRealName_pattern,signalTrig_str,re.DOTALL)signalsname_map=[]fornuminrange(0,len(signalRealName_match),2):signalname_dict={"MappingName":"","RealName":""}signalRealName=signalRealName_match[num:num+2]signalname_dict["MappingName"]=signalRealName[0][0]signalname_dict["RealName"]=signalRealName[1][1].split("/")[-1]signalsname_map.append(signalname_dict)print(signalsname_map)12345678910111213141516171819202122打印结果#这里只举例一个结果[{'MappingName':'ISTrisDMSAdoWrnngDspCmd_0','RealName':'isDMSAdoWrnngDspCmd'}]12匹配完Signal名称的Mapping关系之后,需要开始匹配PDU中的MappingSignalname名称,并且替换MappingSignalname为RealSignalname,因为只能通过真实的RealSignalname才能找到Signal的相关参数。4、下面是arxml的片段其中就包括了PDU的名称PduTrDMS_050ms_PDU00,以及MappingSignalname名称ISTrisDMSAdoWrnngDspCmd_0;5、我们查找报文相关的参数就可以通过查找 数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的PDU名称来获得PDU名称;匹配片段中的../MappingSignalname名称来获取MappingSignalname名称; PduTrDMS_050ms_PDU00/ECUSystem/DMS/DMSC/DMSCCfg/DMSCCfg/ADCANFD/IPduPort_Out/VectorAutosarExplorerGeneratedObjects/ECU_INSTANCES/OtherNodes/Connector_OtherNodes_64e0f3f0db5999fe/PP_01fa4447d4724b9298c6e01a29830d3a_Rx/Communication/Pdu/DMS_050ms_PDU00/VehicleTopology/ADCANFD/PhCnADCANFD/ISTrisDMSAdoWrnngDspCmd_0123456789101112136、匹配完MappingSignalName之后,顺便替换成RealSignalName;python代码#============匹配PDU中的Signal信息==============PDUSignals_pattern=r' (.*?)'PDUSignals_match=re.findall(PDUSignals_pattern,arxml_data,re.DOTALL)#使用re.DOTALL标志使.匹配任意字符,包括换行符#============匹配PDUName和signalsname=============signals_pattern=r'(.*?)|(.*?)'PDUSignals_data=[]forPDUSignalsinPDUSignals_matchDU_signals=[]PDU_signals_dict={'pduname':'','signals':[]}#开始查找signal的信息signals_match=re.findall(signals_pattern,PDUSignals,re.DOTALL)#使用re.DOTALL标志使.匹配任意字符,包括换行符forcntr,signal_matchinenumerate(signals_match):signalsdata_dict={"signalname":"","signaldata":[]}ifcntr==0DU_signals_dict['pduname']=signal_match[0]else:signal_name=signal_match[1].split("/")[-1]forsignalname_mapinsignalsname_map:#开始替换signal的名称ifsignal_nameinsignalname_map["MappingName"]:signalsdata_dict["signalname"]=signalname_map["RealName"]PDU_signals.append(signalsdata_dict)PDU_signals_dict['signals']=PDU_signalsPDUSignals_data.append(PDU_signals_dict)print(PDUSignals_data)12345678910111213141516171819202122232425262728打印结果#这里只举例一个结果[{'pduname':'PduTrDMS_050ms_PDU00','signals':[{'signalname':'isDMSAdoWrnngDspCmd','signaldata':[]}]12六、解析Signal中的初始值和长度1、下面是arxml的片段其中就包括了SignalNameisDMSAdoWrnngDspCmd,初始值InitValue2,和长度Length2;2、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的SignalName名称来获得SignalName;匹配片段中的初始值来获取Signal的初始值InitValue;匹配片段中的长度来获取Signal的长度Length;isDMSAdoWrnngDspCmdOVERRIDE22/DataType/DataTypeSemantics/SwBaseTypes/UINT2/DataType/DataTypeSemantics/DMSAdoWrnngDspCmd/Signal/DMSAdoWrnngDspCmd12345678910111213141516171819python代码有些信号是不存在初始值的,解析的时候要注意#匹配或者中的文本iSignals_pattern=r'(.*?)'iSignals_match=re.findall(iSignals_pattern,arxml_data,re.DOTALL)#匹配signal的初始值和长度的数据iSignalsPara_pattern=r'(.*?)|(.*?)|(.*?)'iSignalsPara_data=[]foriSignalsiniSignals_match:signal_dict={'signalname':'','initvalue':None,'length':0}iSignal_match=re.findall(iSignalsPara_pattern,iSignals,re.DOTALL)iflen(iSignal_match)==3:signal_dict['signalname']=iSignal_match[0][0]signal_dict['initvalue']=iSignal_match[1][1]signal_dict['length']=iSignal_match[2][2]#iSignal_match长度为2,说明没有匹配到initvalueeliflen(iSignal_match)==2:signal_dict['signalname']=iSignal_match[0][0]signal_dict['length']=iSignal_match[1][2]iSignalsPara_data.append(signal_dict)print(iSignalsPara_data)1234567891011121314151617181920212223242526打印结果#这里只举例一个结果[{'signalname':'isDMSAdoWrnngDspCmd','initvalue':'2','length':'2'}]12七、解析Signal中的起始位置1、下面是arxml的片段其中就包括了SignalNameisDMSAdoWrnngDspCmd_mtx,初始值StartPosition63;2、我们查找报文相关的参数就可以通过查找片段数据来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的SignalName名称来获得SignalName;匹配片段中的起始位来获取Signal的起始位StartPosition;isDMSAdoWrnngDspCmd_mtx/Communication/ISignal/isDMSAdoWrnngDspCmd MOST-SIGNIFICANT-BYTE-FIRST6312345678python代码#匹配中的内容,signal的START-POSITION在其中signal2PDUs_pattern=r'(.*?)'signal2PDUs_match=re.findall(signal2PDUs_pattern,arxml_data,re.DOTALL)#匹配signal的真实名称和signal的startpositionstartPosition_pattern=r'(.*?)|(.*?)'iSignalSPos_data=[]forsignal2PDUinsignal2PDUs_match:#开始匹配signalSPos_match=re.findall(startPosition_pattern,signal2PDU,re.DOTALL)#每个signal有2个参数,signal名称,startpositionfornuminrange(0,len(signalSPos_match),2):signalSPos_dict={'signalname':'','startposition':0}signalPara=signalSPos_match[num:num+2]try:signalname=signalPara[0][0].split("/")[-1]if"PDU"notinsignalname.upper():#处理signalName,因为signal是路径加名称../signalNamesignalSPos_dict['signalname']=signalPara[0][0].split("/")[-1]signalSPos_dict['startposition']=signalPara[1][1]iSignalSPos_data.append(signalSPos_dict)exceptIndexError:print("无法找到参数")print(iSignalSPos_data)1234567891011121314151617181920212223242526打印结果#这里只举例一个结果[{'signalname':'isDMSAdoWrnngDspCmd','startposition':'63'}]12八、解析Signal中的枚举值或公式1、每个信号都有Internal-To-phys,有些类型是TEXTTABLE,有些是LINEAR;TEXTTABLEINEAR:因此匹配方法有两种情况情况一:TEXTTABLE类型2、下面是arxml的片段其中就包括了SignalNameDMSAdoWrnngDspCmd,Internal-To-phys类型TEXTTABLE,值的范围0-0,枚举值DMSAdoWrnngDspCmd_0_Unavailable/DMSAdoWrnngDspCmd_1_Off/DMSAdoWrnngDspCmd_2_On/DMSAdoWrnngDspCmd_3_laststatus;3、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的SignalName名称来获得SignalName;匹配片段中的LIMIT值区域来获得Signal值得区域范围;匹配片段中的枚举值来获取Signal的枚举值;DMSAdoWrnngDspCmdTEXTTABLE00DMSAdoWrnngDspCmd_0_Unavailable11DMSAdoWrnngDspCmd_1_Off22DMSAdoWrnngDspCmd_2_On33DMSAdoWrnngDspCmd_3_laststatus123456789101112131415161718192021222324252627282930313233343536情况二:LINEAR类型4、下面是arxml的片段其中就包括了SignalNameVehSpdAvg,Internal-To-phys类型LINEAR,值的范围0-32767,Offset分子0,Factor分子0.015625,Offset和Factor分母1,最终需要组合成(0-32767)0.015625*raw)/1;5、我们查找报文相关的参数就可以通过查找数据片段来获取arxml中的数据片段,再进行更详细的匹配获取其余数据。匹配片段中的SignalName名称来获得SignalName;匹配片段中的Signal值区域来获得Signal值得区域范围;匹配片段中的Offset分子Factor分子来获取分子;匹配片段中的分母来获得分母;VehSpdAvgLINEAR03276700.0156251123456789101112131415161718192021python代码#匹配或者中的文本compuMethod_pattern=r'(.*?)'compuMethod_match=re.findall(compuMethod_pattern,arxml_data,re.DOTALL)#匹配信号名和对应的值,有枚举值或者线性值compuMethodPara_pattern=r'(.*?)|(.*?)|(.*?)'#匹配TEXTTABLE中的枚举值,每个中有一个枚举值和枚举文本compuScale_pattern=r'(.*?)'#匹配中的枚举值和枚举文本compuScaleEnum_pattern=r'(.*?).*?(.*?)'#匹配值的范围compuScaleLimit_pattern=r'(.*?).*?(.*?)'#匹配值的计算公式compuScaleFormula_pattern=r'(.*?)'compuMethodPara_data=[]forcompuMethodincompuMethod_match:enumrate=[]compuMethodPara_dic={'signalname':'','category':'','TEXTTABLE':[],'formula':''}#匹配信号名和对应的值,有枚举值或者线性值compuMethodPara_match=re.findall(compuMethodPara_pattern,compuMethod,re.DOTALL)iflen(compuMethodPara_match)==3:#signalnamecompuMethodPara_dic['signalname']=compuMethodPara_match[0][0]#值的类型,是TEXTTABLE或者LINEARcategory=compuMethodPara_match[1][1]compuMethodPara_dic['category']=category#compuScales含有多个枚举的值和文本compuScales_text=compuMethodPara_match[2][2]#signal有枚举值ifcategory=="TEXTTABLE":compuScales=re.findall(compuScale_pattern,compuScales_text,re.DOTALL)forcompuScaleincompuScales:#查找枚举值和枚举文本compuScalePara=re.findall(compuScaleEnum_pattern,compuScale,re.DOTALL)#字典形式存放枚举值和枚举文本try:enumrate_dict={compuScalePara[0][0]:compuScalePara[0][1]}enumrate.append(enumrate_dict)exceptIndexError:print(compuScalePara)compuMethodPara_dic['TEXTTABLE']=enumrate#信号有factor和offsetelifcategory=="LINEAR"imit=re.findall(compuScaleLimit_pattern,compuMethod,re.DOTALL)formula=re.findall(compuScaleFormula_pattern,compuMethod,re.DOTALL)iflen(Limit)==1andlen(formula)==3imit_str='('+Limit[0][0]+'-'+Limit[0][1]+'):'formula_str='('+'phys=raw'+'*'+formula[1]+'+'+formula[0]+')'+'/'+formula[2]compuMethodPara_dic['formula']=Limit_str+formula_strcompuMethodPara_data.append(compuMethodPara_dic)print(compuMethodPara_data)1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465打印结果[{'signalname':'DMSAdoWrnngDspCmd','category':'TEXTTABLE','TEXTTABLE':[{'0':'DMSAdoWrnngDspCmd_0_Unavailable'},{'1':'DMSAdoWrnngDspCmd_1_Off'},{'2':'DMSAdoWrnngDspCmd_2_On'},{'3':'DMSAdoWrnngDspCmd_3_laststatus'}],'formula':''},{'signalname':'VehSpdAvg','category':'LINEAR','TEXTTABLE':[],'formula'0-32767)phys=raw*0.015625+0)/1'}]1九、解析ARXML总结1、注意这不是完整版的ARXML解析代码,只是提供一种方法给大家参考,还有大量的参数需要大家去学习解读autosar规范,本人也是利用下班时间自己学习,如果有什么问题请大家指出。2、另外正则表达式并不是行业内推荐的方法,大家在操作前可以先看看Python的库matrix,我更建议使用matrix将ARXML转换成DBC,然后缺少哪些数据再去ARXML拿,拿完之后再匹配到DBC矩阵中去。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 01:50 , Processed in 0.448275 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表