Getting Started
The model API basically provides two different approaches:
-
The MDF model is the low level AUTOSAR model. It stores all data read from AUTOSAR XML files. Its structure is based on the AUTOSAR MetaModel which can be found for example on the AUTOSAR website. In MDFModelRaw you find detailed information about this model.
-
The BswmdModel is a model which wraps the MDF model to provide convenient and type-safe access to the Ecuc data. It contains, definition based classes for module configurations, containers, parameters and references. The class
CanGeneralfor example as type-safe implementation in contrast to the generic AUTOSAR classMIContainerin MDF.
It is strongly recommended to use the BswmdModel model to deal with Ecuc data because it simplifies scripting a lot.
Read the ActiveEcuc
This section provides some typical examples as a brief introduction for reading the Ecuc by means of the BswmdModel. See chapter BswmdModelRead for more details.
The following example specifies no types for the local variables. It therefore requires no import statements. A drawback on the other hand is that the type is only known at runtime and you have no type support in the IDE:
scriptTask("TaskName"){
code {
// Gets the module DefRef searching all definitions of this SIP
def moduleDefRef = bswDefRef.EcuC
// Creates all BswmdModel instances with this definition. A List<EcuC> in this case.
def ecucModules = bswmdModel(moduleDefRef)
// Gets the EcucGeneral container of the first found module instance
def ecuc = ecucModules.single
def ecucGeneral = ecuc.ecucGeneral
// Gets an (enum) parameter of this container
def cpuType = ecucGeneral.CPUType
}
}
In contrast to the listing above the next one implements the same behavior but specifies all types:
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.CPUType
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.ECPUType
scriptTask("TaskName"){
code {
// Gets the ecuc module configuration
EcuC ecuc = bswmdModel(EcuC).single
// Gets the EcucGeneral container
EcucGeneral ecucGeneral = ecuc.ecucGeneral
// Gets an enum parameter of this container
CPUType cpuType = ecucGeneral.CPUType
if (cpuType.value == ECPUType.CPU32Bit) {
"Do something ..."
}
}
}
The bswmdModel() API takes an optional closure argument which is being called for each created BswmdModel object. This
object is used as parameter of the closure:
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.ECPUType
scriptTask("TaskName"){
code {
// Executes the closure with all instances of this definition
bswmdModel(EcuC) {
// The related BswmdModel instance is parameter of this closure
ecuc ->
if (ecuc.ecucGeneral.CPUType.value == ECPUType.CPU32Bit) {
"Do something ..."
}
}
}
}
Additionally, to the DefRef, an already available MDF model object can be specified to create the related BswmdModel object for it:
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.cputype.ECPUType
scriptTask("TaskName"){
code {
// Gets the MDF model instance of the Ecuc General container
def container = mdfModel(EcucGeneral.DefRef).single
// Executes the closure with this MDF object instance
bswmdModel(container, EcucGeneral.DefRef) {
// The related BswmdModel instance is parameter of this closure
ecucGeneral ->
if (ecucGeneral.CPUType.value == ECPUType.CPU32Bit) {
"Do something ..."
}
}
}
}
For a generic access to Ecu configuration structure (e.g. to use the script with different BSW packages and different
platforms/derivatives) the untyped model in combination with BswDefRefs can be used. See chapter BswDefRefs
and BswmdUntypedModel for more details:
// Required imports
import com.vector.cfg.gen.core.bswmdmodel.GIContainer
import com.vector.cfg.gen.core.bswmdmodel.GIParameter
scriptTask("TaskName"){
code {
GIContainer ecucGen = bswmdModel(bswDefRef.EcucGeneral).single
GIParameter<Boolean> ecuCSafeBswChecks = ecucGen.getParameter(bswDefRef.EcuCSafeBswChecks)
if (ecuCSafeBswChecks.valueMdf.booleanValue()) {
"Do something ..."
}
}
}
Write the ActiveEcuc
This section provides some typical examples as a brief introduction for writing the Ecuc by means of the BswmdModel. See chapter BswmdModelWrite for more details.
For the most cases the entry point for writing the ActiveEcuc is a (existing) module configuration object which can be
retrieved with the bswmdModel() API. Because the model is in read-only state by default, every call to an API which
creates or deletes elements has to be executed in a transaction() block.
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcuC ecuc = bswmdModel(EcuC).single
//Gets the EcucGeneral container or create one if it is missing
EcucGeneral ecucGeneral = ecuc.ecucGeneralOrCreate
// Gets an boolean parameter of this container or create one if it is missing
def ecuCSafeBswChecks = ecucGeneral.ecuCSafeBswChecksOrCreate
// Sets the parameter value to true
ecuCSafeBswChecks.value = true
}
saveProject()
}}
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecuchardware.ecuccoredefinition.EcucCoreDefinition
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcuC ecuc = bswmdModel(EcuC).single
//Gets the EcucCoreDefinition list (creates ecucHardware if it is missing)
def ecucCoreDefinitions = ecuc.ecucHardwareOrCreate.ecucCoreDefinition
//Adds two EcucCores
EcucCoreDefinition core0 = ecucCoreDefinitions.createAndAdd("EcucCore0")
EcucCoreDefinition core1 = ecucCoreDefinitions.createAndAdd("EcucCore1")
if(ecucCoreDefinitions.exists("EcucCore0")) {
//Sets EcucCoreId to 0
ecucCoreDefinitions.byName("EcucCore0").ecucCoreId.setValue(0)
}
//Creates a new EcucCore by method 'byNameOrCreate'
EcucCoreDefinition core2 = ecucCoreDefinitions.byNameOrCreate("EcucCore2")
}
saveProject()
}}
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.EcuC
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcuC ecuc = bswmdModel(EcuC).single
//Duplicates container 'EcucGeneral' and all its children
EcucGeneral ecucGeneral_Dup = ecuc.ecucGeneral.duplicate()
}
saveProject()
}
}
// Required imports
import com.vector.cfg.automation.model.ecuc.microsar.ecuc.ecucgeneral.EcucGeneral
scriptTask("TaskName"){
code {
transaction {
// Gets the first found ecuc module instance
EcucGeneral ecucGeneral = bswmdModel(EcucGeneral).single
//Deletes 'ecucGeneral' from model
ecucGeneral.moRemove()
//Checks if the container 'ecucGeneral' was removed from repository
if(ecucGeneral.moIsRemoved()) {
"Do something ..."
}
}
saveProject()
}
}
Read the SystemDescription
This section contains only one example for reading the SystemDescription by means of the MDF model. See chapter mdfModel for more details.
// Required imports
import com.vector.cfg.model.mdf.ar4x.swcomponenttemplate.datatype.dataprototypes.*
import com.vector.cfg.model.mdf.ar4x.commonstructure.datadefproperties.*
scriptTask("mdfModel", DV_PROJECT){
code {
// Create a type-safe AUTOSAR path
def asrPath =
AsrPath.create("/PortInterfaces/PiSignal_Dummy/DeSignal_Dummy", MIVariableDataPrototype)
// Enter the MDF model tree starting at the object with this path
mdfModel(asrPath) { MIVariableDataPrototype prototype ->
// Traverse down to the swDataDefProps
prototype.swDataDefProps.with { MISwDataDefProps swDataDefPropsParam ->
// swDataDefPropsVariant is a List<MISwDataDefPropsConditional>
// Execute the following for ALL elements of this List
swDataDefPropsParam.swDataDefPropsVariant.each {
MISwDataDefPropsConditional swDataDefPropsCondParam ->
// Resolve the dataConstr reference (type MIDataConstr)
def target = swDataDefPropsCondParam.dataConstr.refTarget
// Get the swCalibrationAccess enum value
def access = swDataDefPropsCondParam.swCalibrationAccess
assert access == MISwCalibrationAccessEnum.NOT_ACCESSIBLE
}
}
}
}
}
The same sample as above, but in property access style instead of closures:
// Create a type-safe AUTOSAR path
def asrPath =
AsrPath.create("/PortInterfaces/PiSignal_Dummy/DeSignal_Dummy", MIVariableDataPrototype)
def prototype = mdfModel(asrPath)
def swDataDefPropsParam = prototype.swDataDefProps
// Execute the following for ALL swDataDefPropsVariant
swDataDefPropsParam.swDataDefPropsVariant.each{ swDataDefPropsCondParam ->
// Resolve the dataConstr reference (type MIDataConstr)
def target = swDataDefPropsCondParam.dataConstr.refTarget
// Get the swCalibrationAccess enum value
def access = swDataDefPropsCondParam.swCalibrationAccess
assert access == MISwCalibrationAccessEnum.NOT_ACCESSIBLE
}
Write the SystemDescription
Writing the system description looks quite similar to the reading, but you have to use methods like (see chapter mdfWrite for more details):
get<Element>OrCreate()or<element>OrCreatecreateAndAdd()byNameOrCreate()
You have to open a transaction before you can modify the MDF model, see chapter transactions for details.
The following samples show the different types of write API:
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) { dataPrototype ->
dataPrototype.category = "NewCategory"
}
}
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
int count = 0
assert adminData == null
withAdminData().orCreate.with {
count++
}
assert count == 1
assert adminData != null
}
}
transaction{
// The asrPath points to an MIVariableDataPrototype
mdfModel(asrPath) {
assert adminData.sdg.empty
adminData.with {
withSdg().create{
it.gid = "NewGidValue"
}
}
assert adminData.sdg.first.gid == "NewGidValue"
}
}
transaction{
// The path points to an MISenderReceiverInterface
mdfModel(asrPath) { MISenderReceiverInterface sendRecIf ->
def dataElementRelation = sendRecIf.withDataElement()
def dataElement = dataElementRelation.byNameOrCreate("MyDataElement")
dataElement.name = "NewName"
def dataElement2 = dataElementRelation.byNameOrCreate("NewName")
assert dataElement == dataElement2
}
}