赞
踩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
在基于AUTOSAR平台开发的软件系统中,SWC的描述文件的格式是arxml。这个文件常由Vector的Developer导出或者MATLAB编译生成,但在开发过程中模块的接口文档一般是写在Excel表格中的,手动在工具中创建比较麻烦,所以如果能够由表格生成arxml再导入到开发工具或者集成工具中就比较方便了。
以下没有Excel表格读取的内容,仅分享arxml的生成,并且是SWC中常见的内容:SWC、runnable、SR接口和数据类型的创建。
以下功能是基于Python第三方库autosar (0.4.2)的基础上进行的封装,仅用了里面一部分功能,详细内容可查阅 https://autosar.readthedocs.io/en/latest/
由于库中的函数和一些方法不好理解,所以按照自己的方式进行了一层封装,只封装了常使用的一些功能。
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"
功能说明:
代码如下(示例):
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])
代码如下(示例):
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}")
代码如下(示例):
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}")
代码如下(示例):
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)
代码如下(示例):
def util_createImplementationArrayDataType(self, name, dataTypeRef, arraySize):
implTypes = self.ws.find(self.refs.get('datatypePackage'))
self.ws.setRole(implTypes.ref, 'DataType')
implementationTypeRef = implTypes.find(dataTypeRef)
if not implTypes.find(name):
try:
return implTypes.createImplementationArrayDataType(name, implementationTypeRef.ref, arraySize)
except ValueError as e:
LOG.exception(f"Exception: {e}, {name}, {dataTypeRef}")
代码如下(示例):
def util_createImplementationRecordDataType(self, name, itemList: [ElementInformation]):
implTypes = self.ws.find(self.refs.get('datatypePackage'))
self.ws.setRole(implTypes.ref, 'DataType')
if not implTypes.find(name):
try:
return implTypes.createImplementationRecordDataType(
name,
((item.name, item.dataType) for item in itemList)
)
except Exception as e:
LOG.exception(f"Exception: {e}, {name}, {itemList}")
ElementInformation类如下:
@dataclass
class ElementInformation:
name: str = ""
dataType: str = ""
initValue: int = None # None则初值为0。枚举的值,也存在这。
def __str__(self):
return str(self.__dict__)
__repr__ = __str__
arxml中没发现 enum 类型的定义方式,但可采用宏定义进行替代。
代码如下(示例):
def util_createEnumDataType(self, name, itemList: [ElementInformation]): """ 不支持Enum类型,但可采用 #define 的方式。即在基础类型加上comp method """ valueTable = [] maxValue = float("-inf") for item in itemList: # type: ElementInformation maxValue = max(maxValue, item.initValue) valueTable.append((item.initValue, item.initValue, item.name)) if maxValue < (2 ** 8): baseTypeRef = f'{self.refs.get("swBaseTypePackage")}/uint8' elif maxValue < (2 ** 16): baseTypeRef = f'{self.refs.get("swBaseTypePackage")}/uint16' elif maxValue < (2 ** 32): baseTypeRef = f'{self.refs.get("swBaseTypePackage")}/uint32' elif maxValue < (2 ** 64): baseTypeRef = f'{self.refs.get("swBaseTypePackage")}/uint64' else: raise ValueError(f"ERROR: too big maxValue: <{maxValue}>") return self.util_createImplementationDataType(name=name, baseTypeRef=baseTypeRef, valueTable=valueTable)
代码如下(示例):
def util_createImplementationDataTypePtr(self, name, baseTypeRef, swImplPolicy=None, category='DATA_REFERENCE',
targetCategory='VALUE', adminData=None):
implTypes = self.ws.find(self.refs.get('datatypePackage'))
self.ws.setRole(implTypes.ref, 'DataType')
if not implTypes.find(name):
try:
return implTypes.createImplementationDataTypePtr(name, baseTypeRef, swImplPolicy, category,
targetCategory, adminData)
except Exception as e:
LOG.exception(f"Exception: {e}, {name}, {baseTypeRef}")
代码如下(示例):
def common_type_create(self): """ Create common data type (BaseType, ImplementationType, ...), containing: dtRef_const_VOID, dtRef_VOID, boolean, float32, float64, sint8, sint16, sint32, uint8, uint16, uint32. """ # CompuMethod and DataConstraint are required. self.ws.setRole(self.refs.get('compuMethodPackage'), 'CompuMethod') self.ws.setRole(self.refs.get('physicalDataConstraintsPackage'), 'DataConstraint') # create SwBaseType self.util_createSwBaseType('dtRef_const_VOID', 1, encoding='VOID', nativeDeclaration='void') self.util_createSwBaseType('dtRef_VOID', 1, encoding='VOID', nativeDeclaration='void') self.util_createSwBaseType('boolean', 8, encoding='BOOLEAN', nativeDeclaration='boolean') self.util_createSwBaseType('float32', 32, encoding='IEEE754', nativeDeclaration='float32') self.util_createSwBaseType('float64', 64, encoding='IEEE754', nativeDeclaration='float64') self.util_createSwBaseType('sint8', 8, encoding='2C', nativeDeclaration='sint8') self.util_createSwBaseType('sint16', 16, encoding='2C', nativeDeclaration='sint16') self.util_createSwBaseType('sint32', 32, encoding='2C', nativeDeclaration='sint32') self.util_createSwBaseType('sint64', 64, encoding='2C', nativeDeclaration='sint64') self.util_createSwBaseType('uint8', 8, nativeDeclaration='uint8') self.util_createSwBaseType('uint16', 16, nativeDeclaration='uint16') self.util_createSwBaseType('uint32', 32, nativeDeclaration='uint32') self.util_createSwBaseType('uint64', 64, nativeDeclaration='uint64') # create ImplementationDataType self.util_createImplementationDataTypePtr('dtRef_const_VOID', f'{self.refs.get("swBaseTypePackage")}/dtRef_const_VOID', swImplPolicy='CONST') self.util_createImplementationDataTypePtr('dtRef_VOID', f'{self.refs.get("swBaseTypePackage")}/dtRef_VOID') self.util_createImplementationDataType('boolean', f'{self.refs.get("swBaseTypePackage")}/boolean', valueTable=['FALSE', 'TRUE'], typeEmitter='RTE') self.util_createImplementationDataType('float32', f'{self.refs.get("swBaseTypePackage")}/float32', typeEmitter='RTE') self.util_createImplementationDataType('float64', f'{self.refs.get("swBaseTypePackage")}/float64', typeEmitter='RTE') self.util_createImplementationDataType('sint8', f'{self.refs.get("swBaseTypePackage")}/sint8', lowerLimit=-128, upperLimit=127, typeEmitter='RTE') self.util_createImplementationDataType('sint16', f'{self.refs.get("swBaseTypePackage")}/sint16', lowerLimit=-32768, upperLimit=32767, typeEmitter='RTE') self.util_createImplementationDataType('sint32', f'{self.refs.get("swBaseTypePackage")}/sint32', lowerLimit=-2147483648, upperLimit=2147483647, typeEmitter='RTE') self.util_createImplementationDataType('sint64', f'{self.refs.get("swBaseTypePackage")}/sint64', lowerLimit=-9223372036854775808, upperLimit=9223372036854775807, typeEmitter='RTE') self.util_createImplementationDataType('uint8', f'{self.refs.get("swBaseTypePackage")}/uint8', lowerLimit=0, upperLimit=255, typeEmitter='RTE') self.util_createImplementationDataType('uint16', f'{self.refs.get("swBaseTypePackage")}/uint16', lowerLimit=0, upperLimit=65535, typeEmitter='RTE') self.util_createImplementationDataType('uint32', f'{self.refs.get("swBaseTypePackage")}/uint32', lowerLimit=0, upperLimit=4294967295, typeEmitter='RTE') self.util_createImplementationDataType('uint64', f'{self.refs.get("swBaseTypePackage")}/uint64', lowerLimit=0, upperLimit=18446744073709551615, typeEmitter='RTE')
代码如下(示例):
def util_createApplicationSoftwareComponent(self, swcName, behaviorName=None, implementationName=None,
multipleInstance=False, autoCreatePortAPIOptions=True):
pkg_swc = self.ws.find(self.refs.get('componentPackage'))
swc = pkg_swc.find(self.swc) # same as pkg_swc.map['elements'][self.swc]
if not swc: # None
swc = pkg_swc.createApplicationSoftwareComponent(swcName, behaviorName, implementationName,
multipleInstance, autoCreatePortAPIOptions)
return swc
swAddressMethod用于将代码放入指定的内存段中(MemMap定义的),目前autosar包中不支持。在MATLAB-2018版本前,可以为代码选择指定段。
代码如下(示例):
def common_swAddressMethod_create(self):
"""
Create common swAddressMethod according to self.refs.
NotImplementedError: SW-ADDR-METHOD-REF
"""
...
代码如下(示例):
def util_createSenderReceiverInterface(self, portName, eleList: [ElementInformation]): """ Create a S/R port, if dt not find, raise an exception. If existed, will not create. :param portName: (str) name of port :param eleList: name and dataType of port's element. """ pkg_dt = self.ws.find(self.refs.get('datatypePackage')) dataElements = [] for eleName, dt in ((item.name, item.dataType) for item in eleList): if pkg_dt.find(dt): dataElements.append(autosar.DataElement(eleName, f'{self.refs.get("datatypePackage")}/{dt}')) else: raise autosar.base.InvalidDataTypeRef(portName, str(dt), len(str(dt))) pkg_if = self.ws.find(self.refs.get('interfacePackage')) pkg_if.createSenderReceiverInterface(portName, dataElements)
对应Developer如下图:
代码如下(示例):
def util_createPort(self, isSend, portName, eleList: [ElementInformation]):
""" 在swc创建接口 """
swc = self.util_createApplicationSoftwareComponent(self.swc)
ref = f'{self.refs.get("interfacePackage")}/{portName}' # it can different with refName
port = swc.find(portName)
if not port:
if isSend:
port = swc.createProvidePort(portName, ref)
else:
port = swc.createRequirePort(portName, ref)
self.util_createPortInitValue(port, eleList)
else:
LOG.debug(f"Already exist Port: {portName}")
return port
对应Developer如下图:
代码如下(示例):
def util_runnablePortAccess(self, runnableName, portName, accessType):
runnable = self.util_createRunnable(runnableName)
swc = self.util_createApplicationSoftwareComponent(self.swc)
port = swc.find(portName)
portInterface = self.ws.find(port.portInterfaceRef, role='PortInterface')
for dataElement in portInterface.dataElements:
swc.behavior._createSendReceivePoint(port, dataElement, runnable) # accessType
util_createPortInitValue() 并没有创建Constant,然后接口去“Reference”,而是直接把值写到这里。
代码如下(示例):
def util_createPortInitValue(self, port: autosar.port, eleList: [ElementInformation]): """ 给swc中的接口创建初值 """ _dict = {} # {ele: (dataType, initValue)} for ele in eleList: _dict.update({ele.name: (ele.dataType, ele.initValue)}) # port 中的每个element建立初值 for comspec in port.comspec: # 查找接口的element是否存在于入参中。找不到则定为u8 dataType, initValue = _dict.get(comspec.name, ("uint8", 0)) if initValue is not None: # 如果指定初值。这里没有初值的check!! valueBuilder = autosar.builder.ValueBuilder() implTypes = self.ws.find(self.refs.get('datatypePackage')) comspec.initValue = valueBuilder.buildFromDataType(implTypes.find(dataType), initValue) else: # 否则初值为0 comspec.initValue = self.__util_buildZeroInit(dataType) def __util_buildZeroInit(self, dataTypeName): """ 建立初值的实体,swc中的接口的element创建初值使用。 """ def get_initValue(dataType): """ 获取初值为0的数值、列表、字典。 """ implTypes = self.ws.find(self.refs.get('datatypePackage')) # 如果传入参数是str,如 uint8,则查找其dataType实体 if isinstance(dataType, str): dataType = implTypes.find(dataTypeName) if not dataType: raise ValueError(f"Undefined data type: {dataType}") # 如果传入参数是dataType实体,则直接使用传参 elif isinstance(dataType, autosar.datatype.ImplementationDataType): dataType = dataType elif isinstance(dataType, autosar.datatype.ImplementationDataTypeElement): dataType = dataType # 如果传入参数未知类型,报错 else: raise ValueError(f"Undefined data type: {dataType}") # 根据dataType的类型,计算出对应初值的格式 if dataType.category == 'VALUE': return 0 elif dataType.category == 'ARRAY': return [get_initValue(dataType.subElements[0])] * int(dataType.arraySize) elif dataType.category == 'STRUCTURE': _dict = {} for sub in dataType.subElements: _dict.update({sub.name: get_initValue(sub)}) return _dict elif dataType.category == 'TYPE_REFERENCE': # 找到其参考的数据类型,计算出初值类型。 dataType = implTypes.find(dataType.variantProps[0].implementationTypeRef) return get_initValue(dataType) else: raise NotImplementedError(dataType.category) # 建立value valueBuilder = autosar.builder.ValueBuilder() # value = valueBuilder.buildFromDataType(dataType, get_initValue(dataType)) # 不好用 value = valueBuilder.build(dataTypeName, get_initValue(dataTypeName)) return value
一般情况下,初值的设置是0。如果有其他情况,可以参考__util_buildZeroInit()方法中的定义。对于不同的类型,初值的格式是不同的,即valueBuilder.build()的第二个参数是不同的:
对于数组类型和结构体类型,其参考类型或字段的类型如果不是一般类型,则需要层层嵌套。比如:
boolean类型属于"TEXTTABLE",其初值默认会是Textual,这会导致达芬奇工具报错,需要改为一般用的Numeric。
在autosar包中,将builder.py中创建为TextValue的分支屏蔽或删除,如下图位置:
runnable中的PortAccess是有两种的,autosar仅支持显式的,这里说明下如何添加隐式的。用不到隐式接口可忽略此节
修改behavior.py的内容
修改behavior_writer.py的内容,这个文件是最终写入arxml的文件。修改方法_writeRunnableXML(),代码示例如下:(代码太长,不对比了)
def _writeRunnableXML(self,runnable): ws=runnable.rootWS() assert(ws is not None) lines=['<RUNNABLE-ENTITY>', self.indent('<SHORT-NAME>%s</SHORT-NAME>'%runnable.name,1), ] if runnable.adminData is not None: lines.extend(self.indent(self.writeAdminDataXML(runnable.adminData),1)) if len(runnable.exclusiveAreaRefs)>0: lines.append(self.indent('<CAN-ENTER-EXCLUSIVE-AREA-REFS>',1)) for exclusiveAreaRef in runnable.exclusiveAreaRefs: exclusiveArea = ws.find(exclusiveAreaRef) if exclusiveArea is None: raise ValueError('invalid reference:' + exclusiveAreaRef) lines.append(self.indent('<CAN-ENTER-EXCLUSIVE-AREA-REF DEST="%s">%s</CAN-ENTER-EXCLUSIVE-AREA-REF>'%(exclusiveArea.tag(self.version),exclusiveArea.ref),2)) lines.append(self.indent('</CAN-ENTER-EXCLUSIVE-AREA-REFS>',1)) if self.version >= 4.0: if runnable.minStartInterval is not None: minStartInterval = self.format_float(float(runnable.minStartInterval)/1000.0) lines.append(self.indent('<MINIMUM-START-INTERVAL>{}</MINIMUM-START-INTERVAL>'.format(minStartInterval),1)) lines.append(self.indent('<CAN-BE-INVOKED-CONCURRENTLY>%s</CAN-BE-INVOKED-CONCURRENTLY>'%('true' if runnable.invokeConcurrently else 'false'),1)) if len(runnable.dataReceivePoints)>0: if self.version >= 4.0: dataReceivePoint_Read_List = [] dataReceivePoint_IRead_List = [] dataReceivePoint_DRead_List = [] for dataReceivePoint in runnable.dataReceivePoints: if dataReceivePoint.accessType == 0: # Read dataReceivePoint_Read_List.append(dataReceivePoint) elif dataReceivePoint.accessType == 1: # IRead dataReceivePoint_IRead_List.append(dataReceivePoint) elif dataReceivePoint.accessType == 2: # DRead dataReceivePoint_DRead_List.append(dataReceivePoint) else: raise Exception('Unexpected value(%s) of accessType(0-ExplicitByArgument, 1-Implicit, 2-ExplicitByValue): ' % dataReceivePoint.accessType) # Do not change sequence of if condition! if dataReceivePoint_IRead_List: lines.append(self.indent('<DATA-READ-ACCESSS>', 1)) for dataReceivePoint in dataReceivePoint_IRead_List: lines.extend(self.indent(self._writeDataReceivePointXML(ws, dataReceivePoint), 2)) lines.append(self.indent('</DATA-READ-ACCESSS>', 1)) if dataReceivePoint_Read_List: lines.append(self.indent('<DATA-RECEIVE-POINT-BY-ARGUMENTS>', 1)) for dataReceivePoint in dataReceivePoint_Read_List: lines.extend(self.indent(self._writeDataReceivePointXML(ws, dataReceivePoint), 2)) lines.append(self.indent('</DATA-RECEIVE-POINT-BY-ARGUMENTS>', 1)) if dataReceivePoint_DRead_List: lines.append(self.indent('<DATA-RECEIVE-POINT-BY-VALUES>', 1)) for dataReceivePoint in dataReceivePoint_DRead_List: lines.extend(self.indent(self._writeDataReceivePointXML(ws, dataReceivePoint), 2)) lines.append(self.indent('</DATA-RECEIVE-POINT-BY-VALUES>', 1)) # This is previous code. # lines.append(self.indent('<DATA-RECEIVE-POINT-BY-ARGUMENTS>',1)) # for dataReceivePoint in runnable.dataReceivePoints: # lines.extend(self.indent(self._writeDataReceivePointXML(ws, dataReceivePoint),2)) # lines.append(self.indent('</DATA-RECEIVE-POINT-BY-ARGUMENTS>',1)) else: lines.append(self.indent('<DATA-RECEIVE-POINTS>',1)) for dataReceivePoint in runnable.dataReceivePoints: lines.extend(self.indent(self._writeDataReceivePointXML(ws, dataReceivePoint),2)) lines.append(self.indent('</DATA-RECEIVE-POINTS>',1)) if len(runnable.dataSendPoints)>0: dataSendPoint_Write_List = [] dataSendPoint_IWrite_List = [] for dataSendPoint in runnable.dataSendPoints: if dataSendPoint.accessType == 0: # Write dataSendPoint_Write_List.append(dataSendPoint) elif dataSendPoint.accessType == 1: # IWrite dataSendPoint_IWrite_List.append(dataSendPoint) else: raise Exception('Unexpected value(%s) of accessType(0-Explicit, 1-Implicit): ' % dataSendPoint.accessType) if dataSendPoint_Write_List: lines.append(self.indent('<DATA-SEND-POINTS>', 1)) for dataSendPoint in dataSendPoint_Write_List: lines.append(self.indent('<%s>'%dataSendPoint.tag(self.version),2)) lines.append(self.indent('<SHORT-NAME>%s</SHORT-NAME>'%dataSendPoint.name,3)) lines.extend(self.indent(self._writeDataElementInstanceRefXML(ws, dataSendPoint.portRef, dataSendPoint.dataElemRef),3)) lines.append(self.indent('</%s>'%dataSendPoint.tag(self.version),2)) lines.append(self.indent('</DATA-SEND-POINTS>', 1)) if dataSendPoint_IWrite_List: lines.append(self.indent('<DATA-WRITE-ACCESSS>', 1)) for dataSendPoint in dataSendPoint_IWrite_List: lines.append(self.indent('<%s>' % dataSendPoint.tag(self.version), 2)) lines.append(self.indent('<SHORT-NAME>%s</SHORT-NAME>' % dataSendPoint.name, 3)) lines.extend(self.indent( self._writeDataElementInstanceRefXML(ws, dataSendPoint.portRef, dataSendPoint.dataElemRef), 3)) lines.append(self.indent('</%s>' % dataSendPoint.tag(self.version), 2)) lines.append(self.indent('</DATA-WRITE-ACCESSS>', 1)) # This is previous code. # lines.append(self.indent('<DATA-SEND-POINTS>',1)) # for dataSendPoint in runnable.dataSendPoints: # lines.append(self.indent('<%s>'%dataSendPoint.tag(self.version),2)) # lines.append(self.indent('<SHORT-NAME>%s</SHORT-NAME>'%dataSendPoint.name,3)) # lines.extend(self.indent(self._writeDataElementInstanceRefXML(ws, dataSendPoint.portRef, dataSendPoint.dataElemRef),3)) # lines.append(self.indent('</%s>'%dataSendPoint.tag(self.version),2)) # lines.append(self.indent('</DATA-SEND-POINTS>',1)) if (self.version >= 4.0) and (len(runnable.modeAccessPoints)>0): lines.append(self.indent('<MODE-ACCESS-POINTS>',1)) for modeAccessPoint in runnable.modeAccessPoints: lines.extend(self.indent(self._writeModeAccessPointXML(ws, modeAccessPoint),2)) lines.append(self.indent('</MODE-ACCESS-POINTS>',1)) if (self.version >= 4.0) and (len(runnable.modeSwitchPoints)>0): lines.append(self.indent('<MODE-SWITCH-POINTS>',1)) for modeSwitchPoint in runnable.modeSwitchPoints: lines.extend(self.indent(self._writeModePointXML(ws, modeSwitchPoint),2)) lines.append(self.indent('</MODE-SWITCH-POINTS>',1)) if (self.version >= 4.0) and (len(runnable.parameterAccessPoints)>0): lines.append(self.indent('<PARAMETER-ACCESSS>',1)) for parameterAccessPoint in runnable.parameterAccessPoints: lines.extend(self.indent(self._writeParameterAccessPointXML(ws, parameterAccessPoint),2)) lines.append(self.indent('</PARAMETER-ACCESSS>',1)) if len(runnable.serverCallPoints)>0: lines.append(self.indent('<SERVER-CALL-POINTS>',1)) for callPoint in runnable.serverCallPoints: lines.extend(self.indent(self._writeServerCallPointXML(ws, runnable, callPoint),2)) lines.append(self.indent('</SERVER-CALL-POINTS>',1)) lines.append(self.indent('<SYMBOL>%s</SYMBOL>'%runnable.symbol,1)) lines.append('</RUNNABLE-ENTITY>') return lines
def util_createRunnable(self, runnableName, TimerMs: int = 0):
# todo, 增加swAddrMethod - CODE. 指定代码段,matlab 2018之后版本需要。
swc = self.util_createApplicationSoftwareComponent(self.swc)
runnable = swc.behavior.find(runnableName)
if not runnable:
runnable = swc.behavior.createRunnable(runnableName)
if TimerMs == 0: # Init
swc.behavior.createInitEvent(runnableName)
else: # cyclic
swc.behavior.createTimerEvent(runnableName, TimerMs)
return runnable
有些时候,需要在接收到数据的时,立即执行这个runnable,Trigger就需要为“OnDataReception”。
代码如下(示例):
def util_createRunnable_DataReceived(self, runnableName, portName, eleName):
# todo, 增加swAddrMethod - CODE. 指定代码段,matlab 2018之后版本需要。
swc = self.util_createApplicationSoftwareComponent(self.swc)
runnable = swc.behavior.find(runnableName)
if not runnable:
runnable = swc.behavior.createRunnable(runnableName)
swc.behavior.createDataReceivedEvent(runnableName, f"{portName}/{eleName}")
self.util_runnablePortAccess(runnableName, portName, 0)
else:
LOG.debug(f"Already exist Runnable: {runnableName}")
return runnable
autosar这个包功能很强大,就是不咋更新了。我目前仅使用了一部分功能,如果有其他需求,建议查看一下源码,理解更新。
第一次发文章,格式和内容会有所欠缺,欢迎批评指正和探讨交流。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。