Generation

The Automation Interface provides generation API for different generation use cases:

  • Normal code generation, see Code Generation
    • Including external generation steps
  • SWC Templates and Contract Phase Headers generation, see Gneration Swct

Code Generation

The block generation encapsulates all settings and commands which are related to code generation of BSW modules:

The basic structure is the following:

generation {
    settings {
        // Settings like the selection of generators for execution are done here
        externalGenerationSteps {
            // Settings related to externalGenerationSteps can be done here
        }
    }
    // The execution of the generation or validation can be started here
}

Generation Settings

The class IGenerationSettingsApi encapsulates all settings which belong to a generation process.
E.g.

  • Select the generators to execute
  • Select the target type (Real, VTT)
  • Select the external generation steps
  • If the module supports multiple module configurations, select the configurations which shall be generated

The following chapters show samples for the standard use cases.

Generation with default Project Settings

The following snippet executes a validation with the default project settings.

Validate with default project settings
scriptTask("validate_with_default_settings"){
    code{
        generation{
            validate()
        }
    }
}

To execute a generation with the standard project settings the following snippet can be used. The validation is executed implicitly before the generation because of AUTOSAR requirements.

Generate with standard project settings
scriptTask("generate_with_default_settings"){
    code{
        generation{
            generate()
        }
    }
}

Generation with Report

IGenerationReportApi to configure generation report settings. After the generation has finished, the report output path is logged. The generated report is located in the project logs folder. Note: The report settings are not persisted and are only applied for the current execution.

The following snippet sets the report settings and executes a generation.

Generation of components with a result report
scriptTask("generate_components_with_report"){
    code{
        generation{
            settings {

                selectGeneratorsByDefRef("/MICROSAR/Aaa")
                selectGeneratorsByDefRef("/MICROSAR/Hhh")

                // Open the report closure to get access to the report settings
                report {
                      // If no settings set, the configurator settings get used
                      createHtmlReport true
                }
            }

            // After generation the output paths can be found in the console view
            generate()
        }
    }
}

setCreateHtmlReport(Boolean) specifies whether an HTML report is generated. The default is true.

Note: When HTML report generation is enabled, a JSON report file is generated * alongside it by default.

Generation of one Module

This sample selects one specific module and starts the generation. There are two ways to open a settings block:

  • settings
    • This keyword creates empty settings. E.g. no module is selected for execution.

Generate one module
scriptTask("generate_one_module"){
    code{
        generation{
            settings{ // uses an empty settings block
                selectGeneratorsByDefRef("/MICROSAR/Aaa")
            }
            generate()
        }
    }
}

  • settingsFromProject
    • Instead of using an empty generator selection, this keyword takes the generator selection from the project settings as template. This selection can optionally be refined by explicit selections. The generator project settings contain the latest generator selection of the generation dialog, that have been saved. Please note that the Target Type (VTT/REAL) is not saved and needs to be specified explicitly. The selection of a Target Type does not directly select or deselect generators within one settingsFromProject closure. So the API getSelectedGenerators () returns all selected generators, but this list may be further filtered according to the Target Type, before the generation is executed.

Generate modules from project settings
scriptTask("generate_one_module"){
    code{
        generation{
            settingsFromProject{ // loads the generator selection from project settings
                // further generators can be selected or deselected in here
            }
            generate()
        }
    }
}

Instead of selecting the generator directly by its DefRef, there is also the possibility to fetch the generator object and select this object for execution.

Generate one module
scriptTask("generate_one_module"){
    code{
        generation{
            settings{
            // To take the project settings as template use
            // settingsFromProject{
                def gens = generatorByDefRef ("/MICROSAR/Aaa")
                selectGenerators(gens)
            }
            generate()
        }
    }
}

Generation of multiple Modules

To select more than one generator the following snippet can be used.

Generate two modules
scriptTask("generate_two_modules"){
    code{
        generation{
            settings{
                selectGeneratorsByDefRef ("/MICROSAR/Aaa", "/MICROSAR/Bbb")
            }
            generate()
        }
    }
}

Generation of Multi Instance Modules

Some module definitions have a upper multiplicity greater than one. (E.g. [0:5] or [0:*]) This means it is allowed to create more than one module configuration from this module definition. If the related generator is started with the default API, all available module configurations are selected for generation. The following API can be used to generate only a subset of all related module configurations.

Generate one module with two configurations
scriptTask("generate_one_module_with_two_configs"){
    code{
        generation{
            settings{
                def gen = generatorByDefRef ("/MICROSAR/MultiInstModule")
                // clear default selection
                gen.deselectAllModuleInstances()
                // Select the module configurations to generate
                gen.selectModuleInstance(AsrPath.create("/ActiveEcuC/MultiInstModule1"))

                // Instead of the full qualified path, the module configuration short name can also be used
                gen.selectModuleInstance("MultiInstModule2")
            }
            generate()
        }
    }
}

Generation of Generation Steps

Besides the internal generators, which are covered by the topics above, there are also generation steps which can be executed with the following API. A new block externalGenerationSteps within the settings block encapsulates all settings related to external generation scripts.

Execute an external generation step
scriptTask("generate_ext_gen_step"){
    code{
        generation{
            settings{
                externalGenerationSteps{
                // To take the project settings as template use
                // externalGenerationStepsFromProject{}
                    selectStep("ExtGen1")
                    selectStep("ExtGen2")
                }
            }
            generate()
        }
    }
}

Retrieval of TargetType (REAL, VTT) of Generation Steps

You can query the EEnvironmentTargetType of the generation step. This will give you the information if the step can be executed in REAL, VTT or both modes.

Retrieval of the TargetType of a Generation Step
generation.settings.externalGenerationSteps{
    def step = stepByName("ExtGen1")
    def targetType = step.generationStep.targetType

    if(targetType.isRealAvailable()){
        // Real use case
    }else if(targetType.isVttAvailable()){
        // VTT use case
    }else{
        // None selected
    }
}

Set a user defined logger

It is possible to pass a specific logger to the generation settings. So all generation events (Phase startet, Module started...) are additionally logged to this logger.

Set a user defined logger
    generation{
        settings{
            setUserLogger(userLogger)
        }
        generate()
    }

Evaluate generation or validation results

Each validation and generation process has an overall result which states if the execution has been successfully or not. Additionally to the overall state, the state of one specific generator can also be of interest. To provide a possibility to access this information all methods for validate and generate return an IGenerationResultModel.

Evaluate the generation result
scriptTask("generate_with_default_settings"){
    code{
        generation{
           def result = generate()
           scriptLogger.info "Overall result : " + result.result
           scriptLogger.info "Duration       : " + result.formattedDuration

           // Access results of each generator or generation step
           result.generationResultRoot.allGeneratorAndStepElements.each {
              scriptLogger.info "Generator name : " + it.name
              scriptLogger.info "Result         : " + it.currentState
           }

        }
    }
}

Generation Task Types

There are three types of IScriptTaskType for the generation process:

  • Generation Step: DV_GENERATION_STEP
  • Generation Process Start: DV_ON_GENERATION_START
  • Generation Process End: DV_ON_GENERATION_END

The general description of the type is in chapter TaskTypeGenStepDescription. The following code samples show the usage of these task types:

Generation Step

A sample for the DV_GENERATION_STEP type:

Use a script task as generation step during generation
scriptTask("GenStepTask", DV_GENERATION_STEP){
    taskDescription "Task is executed as Generation Step"

    def myArg = newUserDefinedArgument(
                    "myArgument",
                    String,
                    "Defines a user argument for the GenerationStep")

    code{ phase, generationType, resultSink ->

        def myArgVal = myArg.value
        // The value myArgVal was passed from the generation step in the project settings editor

        scriptLogger.info "MyArg is: $myArgVal"
        scriptLogger.info "GenerationType is: $generationType"

        if(phase.calculation){
            // Execute code before / after calculation

            transaction {
               // Modify the Model in the calculation phase
            }
        }

        if(phase.validation){
            // Execute code before / after validation

        }

        if(phase.generation){
           // Execute code before / after generation

        }
    }
}

The Generation Step can also report validation results into the passed resultSink. See chapter CreateValidationResult for a sample how to create an validation-result and report it.

The generationType defines if the current generation is for the REAL or VTT platform.

Generation Process Start

A sample for the DV_ON_GENERATION_START type:

Hook into the GenerationProcess at the start with script task
scriptTask("GenStartTask", DV_ON_GENERATION_START){
    taskDescription "The task is automatically executed at generation start"

    code{ phasesToExecute, generators ->

        scriptLogger.info "Phases are: $phasesToExecute"
        scriptLogger.info "Generators to execute are: $generators"

        // Execute code before the generation will start
    }
}

Generation Process End

A sample for the DV_ON_GENERATION_END type:

Hook into the GenerationProcess at the end with script task
scriptTask("GenEndTask", DV_ON_GENERATION_END){
    taskDescription "The task is automatically executed at generation end"

    code{ generationResult, generators ->

        scriptLogger.info "Process result was: $generationResult"
        scriptLogger.info "Executed Generators: $generators"

        // Execute code after the generation process was finished
    }
}

Software Component Templates and Contract Phase Headers Generation

The Software Component Templates and Contract Phase Headers (Swct) generation automation API provides access to configure and start the Swct generation.

The block generation.swct encapsulates all settings and commands which are related to this use case.

The basic structure is the following:

generation.swct {
    settings {
        // Settings like the selection of components to generate
    }
    // The execution of the generation can be started here
    generate()
}

Swct Generation Settings

The class IGenerationSwctSettingsApi encapsulates all settings which belong to a Swct generation process.
Examples:

  • Select the software components to execute
  • Retrieve the available software components

The following chapters show samples for the standard use cases.

Generation with default Project Settings

To execute the Swct generation with the standard project settings the following snippet can be used:

SWC Templates and Contract Headers generation with standard project settings
scriptTask("generate_with_default_settings"){
    code{
        generation.swct{
            generate()
        }
    }
}

Generation of all Software Components

To execute the Swct generation for all available software components the following snippet can be used:

SWC Templates and Contract Headers generation of all components
scriptTask("generate_with_default_settings"){
    code{
        generation.swct{
            settings.selectAll()
            generate()
        }
    }
}

Generation of one Software Component

This sample selects one specific software component and starts the generation. There are two ways to open an settings block:

  • settings
    • This keyword creates empty settings. E.g. no component is selected for execution.
  • settingsFromProject
    • This keyword takes the project settings as template. E.g. component from the project settings are initially activated and can optionally be refined by explicit selections.

SWC Templates and Contract Headers generation of one selected component
scriptTask("generate_one_component"){
    code{
        generation.swct{
            settings{
                selectSoftwareComponent("MyApplType")
            }

            generate()
        }
    }
}

Instead of selecting the software component directly by its Name, there is also the possibility to fetch the software component object and select() this object for execution.

Swct generation get component and select component
scriptTask("generate_one_component"){ code{
    generation.swct{
        settings{
            def sw = softwareComponentByName("MyApplType")
            // Select the software component
            sw.select()

            // You could also retrieve information about the component
            def asrPath = sw.asrPath
            if(sw.selected){  /* Do something */ }
        }
        generate()
   }
}}

Generation of multiple Software Components

To select more than one Software Component the following snippet can be used.

Swct generation of multiple components
scriptTask("generate_one_component"){
    code{
        generation.swct{
            settings{

                // Select the tow software components
                selectSoftwareComponent("MyApplType","MySecondApplType")
            }

            generate()
        }
    }
}

Set a user defined logger

It is possible to pass a specific logger to the Swct generation settings. So all generation events (Phase startet, Module started...) are additionally logged to this logger.

Set a user defined logger
    generation.swct{
        settings{
            setUserLogger(userLogger)
        }
        generate()
    }

Evaluate generation results

The same API is used as for the normal generation, see chapter GenerationResult for details.