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 CanGeneral for example as type-safe implementation in contrast to the generic AUTOSAR class MIContainer in 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:

Read with BswmdModel objects starting with a module DefRef (no type declaration)
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:

Read with BswmdModel objects starting with a module class (strong typing)
// 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:

Read with BswmdModel objects with closure argument
// 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:

Read with BswmdModel object for an MDF model object
// 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:

Read with BswmdModel objects with the untyped model (DefRefAPI)
// 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.

Write with BswmdModel required/optional objects
// 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()
    }}

Write with BswmdModel multiple objects
// 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()
}}

Write with BswmdModel - Duplicate a container
// 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()
    }
}

Write with BswmdModel - Delete elements
// 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.

Read system description starting with an AUTOSAR path in closure
// 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:

Read system description starting with an AUTOSAR path in property style
// 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>OrCreate
  • createAndAdd()
  • 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:

Changing a simple property of an MIVariableDataPrototype
transaction{
    // The asrPath points to an MIVariableDataPrototype
    mdfModel(asrPath) { dataPrototype ->
        dataPrototype.category = "NewCategory"
    }
}

Creating non-existing member by navigating into its content with OrCreate()
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
    }
}

Creating new members of child lists with createAndAdd() by type
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"
    }
}

Updating existing members of child lists with byNameOrCreate() by type
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
    }
}