added first implementation of AMALTHEA to Inchron model transformation
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/AbstractAmaltheaInchronTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/AbstractAmaltheaInchronTransformer.xtend
new file mode 100644
index 0000000..1740ae4
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/AbstractAmaltheaInchronTransformer.xtend
@@ -0,0 +1,64 @@
+package templates
+
+import com.inchron.realtime.root.RootFactory
+import com.inchron.realtime.root.model.Model
+import com.inchron.realtime.root.model.ModelFactory
+import com.inchron.realtime.root.model.memory.MemoryFactory
+import com.inchron.realtime.root.model.stimulation.StimulationFactory
+import org.eclipse.app4mc.amalthea.model.Amalthea
+import org.eclipse.app4mc.amalthea.model.AmaltheaFactory
+import org.eclipse.app4mc.transformation.extensions.base.templates.AbstractTransformer
+import org.eclipse.emf.ecore.EObject
+
+class AbstractAmaltheaInchronTransformer extends AbstractTransformer{
+
+ public var Model inchronModel;
+
+ public var Amalthea amaltheaModel
+
+ /*- Factory initiaization */
+ public val inchronRootFactory = RootFactory.eINSTANCE
+
+ public val inchronModelFactory = ModelFactory.eINSTANCE
+
+ public val inchronmemoryFactory = MemoryFactory.eINSTANCE
+
+ public val inchronStimulationFactory = StimulationFactory.eINSTANCE
+
+
+ public val amaltheaFactory = AmaltheaFactory.eINSTANCE
+
+ public def OSTransformer getOSTransformerInstance(){
+ return customObjsStore.getInstance(OSTransformer)
+ }
+
+ public def HWTransformer getHWTransformerInstance(){
+ return customObjsStore.getInstance(HWTransformer)
+ }
+
+ public def SWTransformer getSWTransformerInstance(){
+ return customObjsStore.getInstance(SWTransformer)
+ }
+
+
+ public def StimuliTransformer getStimuliTransformerInstance(){
+ return customObjsStore.getInstance(StimuliTransformer)
+ }
+
+ public def static <T> T getParentContainer(EObject eObject, Class<T> cl)
+ {
+ var EObject result = null;
+ if (eObject != null)
+ {
+ for (var EObject parent = eObject.eContainer(); parent != null; parent = parent.eContainer())
+ {
+
+ if(cl.isAssignableFrom(parent.getClass())){
+ return parent as T;
+ }
+
+ }
+ }
+ return result as T;
+ }
+}
\ No newline at end of file
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/AmaltheaTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/AmaltheaTransformer.xtend
new file mode 100644
index 0000000..79d202d
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/AmaltheaTransformer.xtend
@@ -0,0 +1,141 @@
+package templates
+
+import com.google.inject.Inject
+import com.inchron.realtime.root.RootFactory
+import com.inchron.realtime.root.model.Model
+import com.inchron.realtime.root.model.ModelFactory
+import java.io.File
+import org.apache.log4j.ConsoleAppender
+import org.apache.log4j.PatternLayout
+import org.eclipse.app4mc.amalthea.model.Amalthea
+import org.eclipse.app4mc.transformation.extensions.base.templates.Model2ModelRootTransformer
+import org.eclipse.emf.common.util.URI
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.resource.ResourceSet
+import templates.utils.AmltCacheModel
+
+class AmaltheaTransformer extends Model2ModelRootTransformer{
+
+ /*- Factory initiaization */
+ val inchronRootFactory = RootFactory.eINSTANCE
+
+ val inchronModelFactory = ModelFactory.eINSTANCE
+
+ /*- Transformer classes initiaization */
+ @Inject extension SWTransformer swTransformer
+
+ @Inject extension HWTransformer hwTransformer
+
+ @Inject extension OSTransformer osTransformer
+
+ @Inject extension StimuliTransformer stimuliTransformer
+
+ /**
+ * This method performs the transformation of AMALTHEA model to INCHRON model and saves the transformed model in the output directory.
+ */
+ override m2mTransformation(ResourceSet inputResourceSet, ResourceSet outputResourceSet) {
+
+ /*- Associating CacheModel to the transformation.
+ * Note: This is a cummulative cache of all the elements from various input AMALTHEA model files.
+ */
+ var AmltCacheModel cacheModel = new AmltCacheModel
+
+ customObjsStore.injectMembers(AmltCacheModel, cacheModel)
+
+ var int fileIndex = 1
+
+ for (resource : inputResourceSet.resources) {
+ for (content : resource.contents) {
+
+ logger.info("Processing file : " + resource.URI)
+
+ /*- Building INCHRON model from AMALTHEA input model */
+ val inchronRoot = transform(content as Amalthea)
+
+ val out_uri = URI.createFileURI(
+ getProperty("m2m_output_folder") + File.separator + fileIndex++ + ".root")
+
+ val out_resource = outputResourceSet.createResource(out_uri)
+
+ /*-Attaching a resource to the INCHRON model element */
+ out_resource.contents.add(inchronRoot)
+
+ }
+ }
+
+ /*- Saving all the root INCHRON model files*/
+ for (resource : outputResourceSet.resources) {
+
+ resource.save(null)
+
+ logger.info("Transformed model file generated at : " + resource.URI)
+ }
+
+ logger.info("*********************** Completed : Model to Model transformation **************************")
+ }
+
+
+ /**
+ * This method is used to transform AMALTHEA model to INCHRON model
+ */
+ def create inchronRootFactory.createRoot transform(Amalthea amalthea){
+
+ /*-Step 1: Injecting all the required transformation objects into the CustomObjsStore. Advantage with this approach is, it provides flexibility to access these elements across various transformers */
+
+ customObjsStore.injectMembers(SWTransformer , swTransformer)
+
+ customObjsStore.injectMembers(HWTransformer , hwTransformer)
+
+ customObjsStore.injectMembers(OSTransformer , osTransformer)
+
+ customObjsStore.injectMembers(StimuliTransformer , stimuliTransformer)
+
+ /* Step 2: Building INCHRON model by invoking various transformers */
+ model = createInchronModel(amalthea)
+
+
+
+ }
+
+ /**
+ * This method creates the object of INCHRON Model element, and fills it by invoking various transformations
+ */
+ def create inchronModelFactory.createModel createInchronModel(Amalthea amalthea) {
+
+ setRequiredAttributes(amalthea, it)
+
+ hwTransformer.transfromHWModel(amalthea.hwModel,it)
+
+ }
+
+ /**
+ * Each transformation object should be set with the required attributes.
+ * At present the required attributes are : amaltheaModel and inchronModel elements. In future this list can grow
+ */
+ protected def EObject setRequiredAttributes(Amalthea amalthea, Model inchronModel) {
+
+ swTransformer.amaltheaModel=amalthea
+ swTransformer.inchronModel=inchronModel
+
+ hwTransformer.amaltheaModel=amalthea
+ hwTransformer.inchronModel=inchronModel
+
+ osTransformer.amaltheaModel=amalthea
+ osTransformer.inchronModel=inchronModel
+
+ stimuliTransformer.amaltheaModel=amalthea
+ stimuliTransformer.inchronModel=inchronModel
+
+ }
+
+ /**
+ * Overriding the logger creation method and attaching "ConsoleAppender" to it.
+ */
+ override protected getLogger() {
+ var logger=super.getLogger()
+ return logger
+
+ }
+
+
+}
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/CustomHWTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/CustomHWTransformer.xtend
new file mode 100644
index 0000000..91683df
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/CustomHWTransformer.xtend
@@ -0,0 +1,40 @@
+package templates
+
+import com.inchron.realtime.root.model.Model
+import org.eclipse.app4mc.amalthea.model.Frequency
+import org.eclipse.app4mc.amalthea.model.FrequencyDomain
+import org.eclipse.app4mc.amalthea.model.HWModel
+import org.eclipse.app4mc.amalthea.model.HwStructure
+import org.eclipse.app4mc.amalthea.model.Memory
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit
+
+public class CustomHWTransformer extends HWTransformer{
+
+protected var Model inchronModel;
+
+ public override transfromHWModel(HWModel amltHWModel, Model inchronModel){
+ super.transfromHWModel(amltHWModel,inchronModel)
+ }
+
+
+ public override create inchronModelFactory.createCpu createCpu(HwStructure amltMicrocontroller){
+ super.createCpu(amltMicrocontroller)
+ }
+
+ override create inchronModelFactory.createClock createClock(FrequencyDomain amltQuartz){
+ super.createClock(amltQuartz)
+ }
+
+ override create inchronModelFactory.createFrequency createFrequency(Frequency amltFrequency){
+ super.createFrequency(amltFrequency)
+ }
+
+ override create inchronModelFactory.createCpuCore createCpuCore(ProcessingUnit core){
+
+ super.createCpuCore(core)
+ }
+
+ override create inchronmemoryFactory.createMemory createMemory(Memory amltMemory){
+ super.createMemory(amltMemory)
+ }
+}
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/HWTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/HWTransformer.xtend
new file mode 100644
index 0000000..59576da
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/HWTransformer.xtend
@@ -0,0 +1,215 @@
+package templates
+
+import com.inchron.realtime.root.model.FrequencyUnit
+import com.inchron.realtime.root.model.GenericSystem
+import com.inchron.realtime.root.model.Model
+import com.inchron.realtime.root.model.memory.MemoryType
+import java.util.ArrayList
+import java.util.List
+import org.eclipse.app4mc.amalthea.model.Cache
+import org.eclipse.app4mc.amalthea.model.Frequency
+import org.eclipse.app4mc.amalthea.model.FrequencyDomain
+import org.eclipse.app4mc.amalthea.model.HWModel
+import org.eclipse.app4mc.amalthea.model.HwStructure
+import org.eclipse.app4mc.amalthea.model.Memory
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit
+import org.eclipse.app4mc.amalthea.model.StructureType
+import templates.utils.AmltCacheModel
+
+/**
+ * This class is responsible for the transformation of AMALTHEA Hardware Model into corresponding INCHRON mdoel elements and accordingly invoke other transformations
+ */
+public class HWTransformer extends AbstractAmaltheaInchronTransformer {
+
+
+
+ public def transfromHWModel(HWModel amltHWModel, Model inchronModel) {
+
+ this.inchronModel=inchronModel
+
+ val AmltCacheModel cacheModel=customObjsStore.getInstance(AmltCacheModel)
+
+ /*- Transformation of FrequencyDomain elements to Clock elements in Inchron */
+
+ amltHWModel?.domains.filter[it instanceof FrequencyDomain].forEach [ amltQuartz |
+
+ val inchronClock = createClock(amltQuartz as FrequencyDomain)
+ inchronModel.clocks.add(inchronClock)
+ ]
+
+ /*- Transformation of each Memory element of SYSTEM to Memory element in Inchron*/
+
+ amltHWModel?.structures.filter[it.structureType==StructureType.SYSTEM]?.forEach[st|
+ st?.modules.filter[it instanceof Memory].forEach[amltMem|
+ val inchronMemory = createMemory(amltMem as Memory)
+ inchronModel.memories.add(inchronMemory)
+ ]
+ ]
+
+ /*- Collecting all Amalthea ECU elements */
+
+ val amltECUs=new ArrayList
+
+ amltHWModel?.structures.filter[it.structureType==StructureType.SYSTEM]?.forEach[it?.structures.filter[it.structureType==StructureType.ECU].forEach[
+ ecu|
+ amltECUs.add(ecu)
+ ]]
+
+ /*- Conversion of Amalthea ECU and its sub-elements into corresponding Inchron elements */
+
+ for (amaltheaEcu : amltECUs) {
+
+ amaltheaEcu?.modules.forEach [ amltMem |
+
+ /*- Transformation of each Memory element of ECU to Memory element in Inchron*/
+
+ if(amltMem instanceof Memory){
+ val inchronMemory = createMemory(amltMem)
+ inchronModel.memories.add(inchronMemory)
+
+ }
+ ]
+
+ val List<GenericSystem> allGenericSystems=new ArrayList<GenericSystem>
+
+ /*- Transformation of each Structure of type MicroController to correspnding Inchron element*/
+
+ for (amaltheaMicroController : amaltheaEcu?.structures.filter[it.structureType==StructureType.MICROCONTROLLER]) {
+
+ /*- Each MicroController is created as GenericSystem element in Inchron and corresponding data of sub-elements is transformed accordingly. */
+
+ val genericSystem = OSTransformerInstance.createGenericSystem(amaltheaMicroController)
+
+ /*-Building Inchron CPU element */
+ val inchronCpu = createCpu(amaltheaMicroController);
+
+ /*-Adding Inchron CPU and GenericSystem elements to Inchron Model */
+
+ inchronModel.cpus.add(inchronCpu)
+
+ inchronModel.systems.add(genericSystem)
+
+ /*- Transformation of each Memory element of MicroController to Memory element in Inchron*/
+
+ amaltheaMicroController?.modules.filter[it instanceof Memory].forEach [ amltMem |
+ val inchronMemory = createMemory(amltMem as Memory)
+ inchronCpu.memories.add(inchronMemory)
+ ]
+
+ /*-Adding Amalthea microController and Inchron GenericSystem into the Cache map. */
+ cacheModel.cacheMappingAmltMicroController_GenericSystem(amaltheaMicroController, genericSystem)
+
+ /*-Collecting all Inchron GenericSystems, so as to process them later */
+ allGenericSystems.add(genericSystem)
+ }
+
+ for (genericSystem : allGenericSystems) {
+
+ /*-======================================Process each Inchron GenericSystem and populate the data ======================================*/
+
+ OSTransformerInstance.fillGenericSystem(genericSystem, amaltheaModel, inchronModel)
+
+ }
+ }
+
+ /*-Adding Stimulation scenarios to Inchron Model */
+ inchronModel.stimulationScenarios.add(stimuliTransformerInstance.createstimulationScenario(amaltheaModel))
+ }
+
+/**
+ * Creating a Inchron CPU element from AMALTHEA HwStructure of type MicroController
+ */
+ public def create inchronModelFactory.createCpu createCpu(HwStructure amltMicrocontroller) {
+
+ it.name = amltMicrocontroller.name
+
+ /*Transformation of Amalthea ProcessingUnit to CpuCore element in Inchron */
+
+ for (amltCore : amltMicrocontroller?.modules.filter[it instanceof ProcessingUnit]) {
+
+ val inchronCpuCore = createCpuCore(amltCore as ProcessingUnit)
+
+ /*- Transformation of each Memory element of ProcessingUnit to Memory element of type CACHE in Inchron*/
+
+ (amltCore as ProcessingUnit)?.caches.forEach [ amltMem |
+ val inchronMemory = createMemory_CacheType(amltMem)
+ inchronMemory.type = MemoryType.CACHE
+ it.memories.add(inchronMemory)
+ ]
+
+ inchronCpuCore.cpu = it
+
+ it.cores.add(inchronCpuCore)
+
+ /*-Transformation of FrequencyDomain of the ProcessingUnit in Amalthea */
+ val amltQuartz = amltCore?.frequencyDomain
+
+ if (amltQuartz != null) {
+ val inchronClock = createClock(amltQuartz)
+
+ //TODO:Clarify if this is correct ? as the CpuCore Clock into is set to the CPU level in Inchron
+ it.clock = (inchronClock) //TODO: Error : In this case, CPU will only hold the Clock of last CpuCore
+ }
+
+ }
+
+ }
+
+/**
+ * Creating Inchron Clock element for FrequencyDomain element of Amalthea
+ */
+ def create inchronModelFactory.createClock createClock(FrequencyDomain amltQuartz) {
+
+ it.name = amltQuartz.name
+ it.frequency = createFrequency(amltQuartz.defaultValue)
+ }
+
+/**
+ * Creating Inchron Frequency element for the corresponding Frequency element of Amalthea
+ */
+ def create inchronModelFactory.createFrequency createFrequency(Frequency amltFrequency) {
+
+ it.unit = FrequencyUnit.getByName(amltFrequency?.unit.getName)
+ it.value = amltFrequency?.value.floatValue
+ }
+
+/**
+ * Creating Inchron CpuCore from ProcessingUnit element of Amalthea
+ */
+ def create inchronModelFactory.createCpuCore createCpuCore(ProcessingUnit core) {
+
+ it.name = core.name
+
+ }
+
+/**
+ * Creating Inchron Memory element from Memory element of Amalthea.
+ * In this method, corresponding FrequencyDomain of the Amalthea element is accordingly converted to Inchron Clock element
+ */
+ def create inchronmemoryFactory.createMemory createMemory(Memory amltMemory) {
+
+ it.name = amltMemory.name
+
+ if (amltMemory.frequencyDomain != null) {
+ it.clock = createClock(amltMemory.frequencyDomain)
+ it.prescaler = amltMemory?.frequencyDomain?.defaultValue?.value
+
+ }
+
+ }
+
+ /** Creating Inchron Memory element from Memory element of Amalthea.
+ * In this method, corresponding FrequencyDomain of the Amalthea element is accordingly converted to Inchron Clock element
+ */
+ def create inchronmemoryFactory.createMemory createMemory_CacheType(Cache amltMemory) {
+
+ it.name = amltMemory.name
+
+ if (amltMemory.frequencyDomain != null) {
+ it.clock = createClock(amltMemory.frequencyDomain)
+ it.prescaler = amltMemory?.frequencyDomain?.defaultValue?.value
+
+ }
+
+ }
+}
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/OSTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/OSTransformer.xtend
new file mode 100644
index 0000000..c184cd7
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/OSTransformer.xtend
@@ -0,0 +1,436 @@
+package templates
+
+import com.inchron.realtime.root.model.GenericSystem
+import com.inchron.realtime.root.model.Model
+import com.inchron.realtime.root.model.SchedulerStrategy
+import org.eclipse.app4mc.amalthea.model.Amalthea
+import org.eclipse.app4mc.amalthea.model.FixedPriorityPreemptive
+import org.eclipse.app4mc.amalthea.model.HwStructure
+import org.eclipse.app4mc.amalthea.model.MappingModel
+import org.eclipse.app4mc.amalthea.model.OSEK
+import org.eclipse.app4mc.amalthea.model.SchedulerAssociation
+import org.eclipse.app4mc.amalthea.model.Semaphore
+import org.eclipse.app4mc.amalthea.model.StructureType
+import org.eclipse.app4mc.amalthea.model.TaskScheduler
+import templates.utils.AmltCacheModel
+
+/**
+ * This class is responsible for the transformation of AMALTHEA OS Model into corresponding INCHRON mdoel elements and accordingly invoke other transformations
+ */
+public class OSTransformer extends AbstractAmaltheaInchronTransformer {
+
+ /**
+ * Creating Inchron GenericSystem from HwStructure of type MicroController in Amalthea
+ */
+ def create inchronModelFactory.createGenericSystem createGenericSystem(HwStructure microController) {
+ it.name = "System_" + microController.name
+ }
+
+ /**
+ * Populating Inchron GenericSystem contents based on the Amalthea model data
+ */
+ public def void fillGenericSystem(GenericSystem genericSystem, Amalthea amalthea, Model inchronModel) {
+
+ val AmltCacheModel cacheModel=customObjsStore.getInstance(AmltCacheModel)
+
+ /*-Creating RtosConfig element and associating it to the GenericSystem */
+
+ var inchronRtosConfig = inchronModelFactory.createRtosConfig
+
+ genericSystem.rtosConfig = inchronRtosConfig
+
+ /*-Fetching contents of Amalthea OS model */
+ if (amalthea.osModel != null) {
+
+ /*-Fetching all Amalthea Semaphore elements and creating corresponding Inchron elements */
+
+ for (Semaphore amltSemaphore : amalthea.osModel.semaphores) {
+
+ val inchronSemaphore = createSemaphore(amltSemaphore)
+
+ /*-Caching Inchron Semaphore object */
+
+ cacheModel.cacheInchronSemaphore(inchronSemaphore)
+
+ /*- Adding Semaphore to RtosConfig object*/
+
+ genericSystem.rtosConfig.semaphores.add(inchronSemaphore)
+ }
+ }
+
+ /*-Fetching Amalthea Tasks objects from SwModel and invoking the StimuliTransformer to build corresponding Inchron objects */
+
+ if(amalthea.swModel!=null){
+
+ stimuliTransformerInstance.createInchronActivationConnections(amalthea.swModel.tasks ,inchronModel )
+
+ }
+
+
+ // heuristic for Inchron
+
+ /*-Creating Dummy Inchron Scheduler */
+
+ val dummyISRScheduler = inchronModelFactory.createScheduler
+
+ /*-Adding Dummy scheduler to RtosConfig element of Inchron */
+
+ genericSystem.rtosConfig.schedulables.add(dummyISRScheduler)
+
+ val MappingModel amltMappingModel = amalthea.mappingModel
+
+ if (amltMappingModel != null) {
+
+ /*-Building cache for TaskScheduler <---> and SchedulerAssociation's */
+
+ cacheModel.buildTaskSchedulerAndSchedulerAssociationMap(amltMappingModel)
+
+ /*-Building cache for TaskScheduler <---> and TaskAllocation's */
+
+ cacheModel.buildTaskSchedulerAndTaskAllocationMap(amltMappingModel)
+
+ /*- Collecting all the root TaskScheduler's */
+
+ val rootTaskSchedulers = amltMappingModel?.schedulerAllocation?.map [ amltSchedulerAllocation |
+
+ if (amltSchedulerAllocation.scheduler instanceof TaskScheduler) {
+ return (amltSchedulerAllocation.scheduler as TaskScheduler).rootScheduler
+ }
+
+ ].toSet.filter[it != null]
+
+ /*-Case 1: Fetching all the Amalthea SchedulerAllocation objects from Amalthea */
+
+ amltMappingModel?.schedulerAllocation?.forEach [ amltSchAllocation |
+
+ /*- Considering only if the associated scheduler is TaskScheduler */
+
+ if (amltSchAllocation.scheduler instanceof TaskScheduler) {
+
+ /*- getting Root scheduler */
+ var rootScheduler = getRootScheduler(amltSchAllocation.scheduler as TaskScheduler)
+
+ /*- gettting the ProcessingUnit from the responsibility of SchedulerAllocation*/
+
+ if (amltSchAllocation?.responsibility.size > 0) {
+
+ /*- Based on the Amalthea model, eContainer of ProcessingUnit is HwStructure of type MicroController */
+
+ var amltMicroController = amltSchAllocation?.responsibility?.get(0)?.eContainer
+
+ if ((amltMicroController != null) && (amltMicroController instanceof HwStructure) && (amltMicroController as HwStructure).structureType==StructureType.MICROCONTROLLER ){
+
+ /*- Based on the extend behaviour, if create method is invoked - with the same parameters again and again -> it does caching and returns back the already created object from cache */
+
+ var inchronCpu = HWTransformerInstance.createCpu(amltMicroController as HwStructure)
+
+ if (inchronCpu != null) {
+
+ if(inchronCpu.eContainer==null){
+ inchronModel.cpus.add(inchronCpu)
+ }
+
+ }
+
+ /*-Adding the root scheduler to dummy ISR Scheduler */
+
+ dummyISRScheduler.schedulables.add(OSTransformerInstance.createRootScheduler(rootScheduler))
+ }
+
+ } else {
+ logger.info(amltSchAllocation + " " + amltSchAllocation.scheduler)
+ }
+
+ }
+ ]
+
+ /*-Case 2: Fetching all the Amalthea ISRAllocation objects from Amalthea */
+
+ amltMappingModel?.isrAllocation?.forEach [ amltISRAllocation |
+
+ var amltISR = amltISRAllocation.isr
+
+ /*-Fetching InterruptController from ISRAllocation element */
+
+ var amltInterruptController = amltISRAllocation.controller
+
+ if (amltInterruptController != null) {
+
+ var AmltCacheModel amltCacheModel = customObjsStore.getInstance(AmltCacheModel)
+
+ //TODO: Clarify this .. why to get SchedulerAllocation again when ISRAllocation is already present
+ var amltSchedulerAllocation = amltCacheModel.taskScheduler_SchedulerAllocationMap.get(
+ amltInterruptController)
+
+ if (amltSchedulerAllocation != null) {
+
+ if (amltSchedulerAllocation.executingPU != null) {
+
+ /*-get executing Core from SchedulerAllocation */
+ var amltExecutingCore = amltSchedulerAllocation.executingPU
+
+ if(amltExecutingCore!=null){
+ val amltMicroController= amltExecutingCore.eContainer
+
+ // RootISRScheduler should be unique for each MicroController
+ val inchronRootISRScheduler = OSTransformerInstance.createRootISRScheduler(
+ amltMicroController as HwStructure)
+
+ /*-creating inchron Cpu element from the MicroController element in Amalthea model*/
+ var inchronCpu = HWTransformerInstance.createCpu(
+ amltExecutingCore.eContainer as HwStructure)
+
+ /*-Below check is made, if Inchron CPU object is already associated to Inchron model !! If not associating it explicitly */
+ if(inchronCpu.eContainer==null){
+ inchronModel.cpus.add(inchronCpu)
+ }
+
+ // TODO: clarify if Inchron root ISRScheduler can be added in HyperVisorConfig - vmSchedulers list
+ dummyISRScheduler.schedulables.add(inchronRootISRScheduler)
+
+ var inchronCpuCore = HWTransformerInstance.createCpuCore(
+ amltExecutingCore)
+
+ /*-Below check is made, if Inchron CpuCore object is already associated to Inchron Cpu !! If not associating it explicitly */
+
+ if(inchronCpuCore.eContainer==null){
+ inchronCpu.cores.add(inchronCpuCore)
+ }
+
+ /*- Creating a Process from ISR */
+ var inchronProcess = SWTransformerInstance.createProcess(amltISR)
+
+ // setting the priority from amlt ISRAllocation
+ inchronProcess.priority = amltISRAllocation.priority
+
+ /*-Associating CpuCore to Process */
+ inchronProcess.cpuCores.add(inchronCpuCore)
+
+ // adding all the amlt ISR's as Processes to root ISR scheduler
+ inchronRootISRScheduler.schedulables.add(inchronProcess)
+ }
+
+ }
+
+ }
+ }
+ ]
+
+ }
+
+
+
+ }
+
+
+/**
+ * This method is used to create a Inchron Semaphore object from Amalthea Semaphore
+ */
+ public def create inchronModelFactory.createSemaphore createSemaphore(Semaphore amltSemaphore) {
+ it.initialValue = amltSemaphore.initialValue;
+ it.maxValue = amltSemaphore.maxValue;
+ it.name = amltSemaphore.name;
+ }
+
+ /**
+ * This method is used to return the root TaskScheduler object
+ */
+ def TaskScheduler getRootScheduler(TaskScheduler sch) {
+
+ if (sch.parentScheduler == null) {
+ return sch
+ }
+ return getRootScheduler(sch.parentScheduler)
+ }
+
+/**
+ * This method is used to create a Root ISR Scheduler object from Amalthea HwStructure (of type MicroController)
+ */
+ public def create inchronModelFactory.createScheduler createRootISRScheduler(HwStructure amltMicroController) {
+ it.name = "Root-ISR" + "_" + amltMicroController.name
+ }
+
+/**
+ * This method is used to create Inchron Root Scheduler object from Amalthea TaskScheduler
+ * <br>
+ * Additional things performed in this method are :
+ * <br>1. creation of child Schedulers for corresponding childAssociations to Amalthea Scheduler
+ * <br>2. Processing through TaskAllocations of a Amalthea scheduler and creating Inchron Process element
+ * <br>3. Processing through SchedulerAssociations of a Amalthea scheduler and creating Inchron CpuCore elements.. and associating them to the the Scheduler object
+ *
+ */
+
+ public def create inchronModelFactory.createScheduler createRootScheduler(TaskScheduler amltTaskScheduler) {
+
+ it.name = amltTaskScheduler.name
+
+ var amltSchedulingAlgorithm = amltTaskScheduler.schedulingAlgorithm
+
+ if (amltSchedulingAlgorithm instanceof FixedPriorityPreemptive) {
+ it.strategy = SchedulerStrategy.FIXED_PRIORITY
+ }
+ if (amltSchedulingAlgorithm instanceof OSEK) {
+ it.strategy = SchedulerStrategy.OSEK
+ }
+
+ /* ============ building Inchron child Scheduler elements ======================== */
+
+ amltTaskScheduler.childAssociations.forEach [ amltChildSchedulerAssociation |
+
+ if (amltChildSchedulerAssociation.child instanceof TaskScheduler) {
+ var amltSchedulingParameters = amltChildSchedulerAssociation.schedulingParameters
+
+ var amltSubSchedulerPrio = 0
+
+ if (amltSchedulingParameters != null) {
+ amltSubSchedulerPrio = amltSchedulingParameters.priority
+ }
+ schedulables.add(
+ createScheduler(amltChildSchedulerAssociation.child as TaskScheduler, amltSubSchedulerPrio))
+
+ }
+
+ ]
+
+ /* ============ building Inchron Process elements and associating to the Scheduler object ======================== */
+
+ var AmltCacheModel amltCacheModel = customObjsStore.getInstance(AmltCacheModel)
+
+ //fetching all TaskAllocations associated to a specific TaskScheduler
+ var taskAllocations = amltCacheModel.taskScheduler_TaskAllocationMap.get(amltTaskScheduler)
+
+ if (taskAllocations != null) {
+ taskAllocations.forEach [ amltTaskAllocation |
+
+ var process = SWTransformerInstance.createProcess(amltTaskAllocation.task)
+ // adding a created process inside the schedulables list of inchron scheduler
+ it.schedulables.add(process)
+
+ if (amltTaskAllocation?.schedulingParameters != null) {
+ process.priority = amltTaskAllocation?.schedulingParameters?.priority
+
+ }
+ ]
+ }
+ /* ============ building Inchron CpuCore elements and associating to the Scheduler object ======================== */
+
+ var amltSchedulerAllocation = amltCacheModel.getTaskScheduler_SchedulerAllocationMap.get(amltTaskScheduler)
+
+ if (amltSchedulerAllocation != null) {
+
+ amltSchedulerAllocation.responsibility.forEach [ amltcore |
+ // associating CpuCore to HyperVisorSystemSchedulable
+ it.cpuCores.add(HWTransformerInstance.createCpuCore(amltcore))
+ ]
+ }
+
+ }
+
+ @Deprecated
+ public def create inchronModelFactory.createScheduler createSubScheduler(
+ SchedulerAssociation amltSchedulerAssociation) {
+
+ // TODO: create virtual system (use ARSystem instead of OSEK System), create coreMappings, schedulingParameters
+ var amltChildScheduler = amltSchedulerAssociation.child
+
+ // get the appropriate SchedulerAssociation to identify on which Core this scheduler is mapped
+ var AmltCacheModel cacheModel = customObjsStore.getInstance(AmltCacheModel)
+
+ var amltChildSchedulerAllocation = cacheModel.getTaskScheduler_SchedulerAllocationMap.get(amltChildScheduler)
+
+ if (amltChildSchedulerAllocation != null) {
+
+ name = amltChildSchedulerAllocation.scheduler?.name
+
+ amltChildSchedulerAllocation.responsibility.forEach [ amltcore |
+ // associating CpuCore to HyperVisorSystemSchedulable
+ it.cpuCores.add(HWTransformerInstance.createCpuCore(amltcore))
+ ]
+ }
+
+ }
+
+/**
+ * This method is used to create Inchron Scheduler object from Amalthea TaskScheduler
+ * <br>
+ * Additional things performed in this method are :
+ * <br>1. creation of child Schedulers for corresponding childAssociations to Amalthea Scheduler
+ * <br>2. Processing through TaskAllocations of a Amalthea scheduler and creating Inchron Process element
+ * <br>3. Processing through SchedulerAssociations of a Amalthea scheduler and creating Inchron CpuCore elements.. and associating them to the the Scheduler object
+ *
+ */
+ public def create inchronModelFactory.createScheduler createScheduler(TaskScheduler amltTaskScheduler,
+ int priority) {
+ it.name = amltTaskScheduler.name
+
+ it.priority = priority
+
+ var amltSchedulingAlgorithm = amltTaskScheduler.schedulingAlgorithm
+
+ //TODO: Mostly the same for the root -- point for harmonization?
+
+ if (amltSchedulingAlgorithm instanceof FixedPriorityPreemptive) {
+ it.strategy = SchedulerStrategy.FIXED_PRIORITY
+ }
+ if (amltSchedulingAlgorithm instanceof OSEK) {
+ it.strategy = SchedulerStrategy.OSEK
+ }
+
+ /* ============ building Inchron child Scheduler elements ======================== */
+
+ // TODO: add if conditions for all the sub classes of TaskSchedulingAlgorithm
+ amltTaskScheduler.childAssociations.forEach [ amltChildAssociation |
+
+ if (amltChildAssociation.child instanceof TaskScheduler) {
+ var amltSchedulingParameters = amltChildAssociation.schedulingParameters
+
+ var amltSubSchedulerPrio = 0
+
+ if (amltSchedulingParameters != null) {
+ amltSubSchedulerPrio = amltSchedulingParameters.priority
+ }
+ it.schedulables.add(createScheduler(amltChildAssociation.child as TaskScheduler, amltSubSchedulerPrio))
+
+ }
+
+ ]
+
+
+ /* ============ building Inchron Process elements and associating to the Scheduler object ======================== */
+
+
+ var AmltCacheModel amltCacheModel = customObjsStore.getInstance(AmltCacheModel)
+
+ // fetching all TaskAllocations associated to a specific TaskScheduler
+ var taskAllocations = amltCacheModel.taskScheduler_TaskAllocationMap.get(amltTaskScheduler)
+
+ if (taskAllocations != null) {
+ taskAllocations.forEach [ amltTaskAllocation |
+
+ var process = SWTransformerInstance.createProcess(amltTaskAllocation.task)
+ // adding a created process inside the schedulables list of inchron scheduler
+ it.schedulables.add(process)
+
+ if (amltTaskAllocation?.schedulingParameters != null) {
+ process.priority = amltTaskAllocation?.schedulingParameters?.priority
+
+ }
+ ]
+ }
+
+ /* ============ building Inchron CpuCore elements and associating to the Scheduler object ======================== */
+
+ var amltChildSchedulerAllocation = amltCacheModel.getTaskScheduler_SchedulerAllocationMap.get(amltTaskScheduler)
+
+ if (amltChildSchedulerAllocation != null) {
+
+ name = amltChildSchedulerAllocation.scheduler?.name
+
+ amltChildSchedulerAllocation.responsibility.forEach [ amltcore |
+ // associating CpuCore to HyperVisorSystemSchedulable
+ it.cpuCores.add(HWTransformerInstance.createCpuCore(amltcore))
+ ]
+ }
+ }
+
+}
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/SWTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/SWTransformer.xtend
new file mode 100644
index 0000000..fcaf471
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/SWTransformer.xtend
@@ -0,0 +1,537 @@
+package templates
+
+import com.inchron.realtime.root.model.CallSequenceItem
+import com.inchron.realtime.root.model.GenericSystem
+import com.inchron.realtime.root.model.SemaphoreAccessType
+import com.inchron.realtime.root.model.TimeDistributionType
+import com.inchron.realtime.root.model.TimeUnit
+import java.util.ArrayList
+import java.util.List
+import java.util.Set
+import org.eclipse.app4mc.amalthea.model.Amalthea
+import org.eclipse.app4mc.amalthea.model.AsynchronousServerCall
+import org.eclipse.app4mc.amalthea.model.CallGraph
+import org.eclipse.app4mc.amalthea.model.CallSequence
+import org.eclipse.app4mc.amalthea.model.ChannelReceive
+import org.eclipse.app4mc.amalthea.model.ChannelSend
+import org.eclipse.app4mc.amalthea.model.CustomEventTrigger
+import org.eclipse.app4mc.amalthea.model.ExecutionNeed
+import org.eclipse.app4mc.amalthea.model.Group
+import org.eclipse.app4mc.amalthea.model.HwFeature
+import org.eclipse.app4mc.amalthea.model.ISR
+import org.eclipse.app4mc.amalthea.model.InterProcessTrigger
+import org.eclipse.app4mc.amalthea.model.LabelAccess
+import org.eclipse.app4mc.amalthea.model.ModeLabelAccess
+import org.eclipse.app4mc.amalthea.model.ModeSwitch
+import org.eclipse.app4mc.amalthea.model.Need
+import org.eclipse.app4mc.amalthea.model.NeedConstant
+import org.eclipse.app4mc.amalthea.model.NeedDeviation
+import org.eclipse.app4mc.amalthea.model.Preemption
+import org.eclipse.app4mc.amalthea.model.ProbabilitySwitch
+import org.eclipse.app4mc.amalthea.model.Process
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit
+import org.eclipse.app4mc.amalthea.model.Runnable
+import org.eclipse.app4mc.amalthea.model.RunnableCall
+import org.eclipse.app4mc.amalthea.model.RunnableModeSwitch
+import org.eclipse.app4mc.amalthea.model.RunnableProbabilitySwitch
+import org.eclipse.app4mc.amalthea.model.SemaphoreAccess
+import org.eclipse.app4mc.amalthea.model.SemaphoreAccessEnum
+import org.eclipse.app4mc.amalthea.model.SenderReceiverRead
+import org.eclipse.app4mc.amalthea.model.SenderReceiverWrite
+import org.eclipse.app4mc.amalthea.model.SynchronousServerCall
+import org.eclipse.app4mc.amalthea.model.Task
+import org.eclipse.app4mc.amalthea.model.TaskRunnableCall
+import org.eclipse.app4mc.amalthea.model.Time
+import org.eclipse.app4mc.amalthea.model.util.DeploymentUtil
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType
+import org.eclipse.emf.common.util.EMap
+import org.eclipse.emf.ecore.util.EcoreUtil
+import templates.utils.AmltCacheModel
+
+/**
+ * This class is responsible to convert Amalthea SW Model eleemnts to corresponding Inchron elements and invoke other transformation classes
+ */
+public class SWTransformer extends AbstractAmaltheaInchronTransformer {
+
+ /**
+ * Creating a Inchron Process element from Amalthea ISR element
+ */
+ def create inchronModelFactory.createProcess createProcess(ISR amltISR){
+ it.isr = true
+ it.name=amltISR.name
+ /*-Building a cache of Stimuli name and the "List of Process" elements to which it is associated to */
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+ amltISR.stimuli.forEach[stimuli |
+ amltCache.cacheAmltStimuliInchronProcessMap(stimuli.getName, it)
+ ]
+
+ }
+
+
+ /**
+ * Creating a Inchron Process element from Amalthea Task element
+ */
+ def create inchronModelFactory.createProcess createProcess(Task amltTask){
+ it.isr = false
+ it.name=amltTask.name
+
+ //TODO: schedule between runnables for co-operative
+ if(amltTask.preemption == Preemption.NON_PREEMPTIVE || amltTask.preemption == Preemption.COOPERATIVE){
+ it.preemptable=false
+ }else{
+ it.preemptable=true
+ }
+
+ if(amltTask.callGraph !=null){
+ /*-building a inchron CallGraph element from amalthea CallGraph */
+ it.callGraph=createCallGraph(amltTask.callGraph)
+ }
+
+ /*-Building a cache of Stimuli name and the "List of Process" elements to which it is associated to */
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+ amltTask.stimuli.forEach[stimuli |
+ amltCache.cacheAmltStimuliInchronProcessMap(stimuli.getName, it)
+ ]
+
+ }
+
+ /**
+ * This method is used to create a Inchron CallGraph element from Amalthea CallGraph element
+ */
+ def create inchronModelFactory.createCallGraph createCallGraph(CallGraph amltCallGraph){
+
+ amltCallGraph.graphEntries.forEach[amltGraphEntry|
+
+ if(amltGraphEntry instanceof CallSequence){
+
+ it.graphEntries.add(createCallSequence(amltGraphEntry as CallSequence))
+
+ }else if(amltGraphEntry instanceof ModeSwitch){
+ it.graphEntries.add(createModeSwitch(amltGraphEntry as ModeSwitch))
+
+ }else if(amltGraphEntry instanceof ProbabilitySwitch){
+ it.graphEntries.add(createProbabilitySwitch(amltGraphEntry as ProbabilitySwitch))
+
+ }
+ ]
+
+ }
+
+ /**
+ * This method is used to create inchron CallSequence object from Amalthea CallSequence element.
+ *
+ * Below are the CallSequence items are currently supported:
+ * <br>1.TaskRunnableCall
+ * <br>2.InterProcessTrigger
+ *
+ */
+ def create inchronModelFactory.createCallSequence createCallSequence(CallSequence amltCallSequence){
+ it.name=amltCallSequence.name
+ amltCallSequence?.calls.forEach[amltCallsequenceItem|
+
+ //todo: handle other CallSequenceItem's
+
+ if(amltCallsequenceItem instanceof TaskRunnableCall){
+
+ it.calls.add(createFunctionCall(amltCallsequenceItem as TaskRunnableCall))
+ }
+
+ if (amltCallsequenceItem instanceof InterProcessTrigger) {
+ it.calls.add(createActivationItem(amltCallsequenceItem as InterProcessTrigger))
+ }
+ ]
+ }
+
+ /**
+ * This method is used to create inchron InterProcessTrigger element from Amalthea ActivationItem element
+ */
+ def create inchronModelFactory.createActivationItem createActivationItem(InterProcessTrigger trigger) {
+
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+
+ val tasks = amltCache.interProcessTriggerRelationsMap.get(trigger.stimulus.name);
+
+ val inchronConnection=amltCache.inchronConnectionElementsMap.get(trigger.stimulus.name)
+
+ it.connection =inchronConnection
+
+ if(tasks !=null){
+ for ( task : tasks) {
+ val inchronActivateProcess=createActivateProcess(trigger, task as Task)
+ inchronConnection.activations.add(inchronActivateProcess)
+ }
+
+ }else{
+ //Note: This is the case where Stimulus is not InterProcessStimulus or there are no Process elements to which this stimulus is triggering
+ }
+
+ }
+
+ /**
+ * This method is used to create inchron ActivateProcess element from Amalthea InterProcessTrigger
+ */
+ def create inchronModelFactory.createActivateProcess createActivateProcess(InterProcessTrigger trigger, Task amltTask) {
+
+ it.target = createProcess(amltTask);
+ it.offset = trigger.counter.offset as int
+ it.period = trigger.counter.prescaler as int
+ }
+
+
+ def create inchronModelFactory.createModeSwitch createModeSwitch(ModeSwitch amltModeSwitch){
+ //TODO: need to enhance it in near future
+ }
+
+ def create inchronModelFactory.createProbabilitySwitch createProbabilitySwitch(ProbabilitySwitch amltProbabilitySwitch){
+ //TODO: need to enhance it in near future
+ }
+
+ /**
+ * This method is used to create inchron FunctionCall element from RunnableCall element
+ */
+ def create inchronModelFactory.createFunctionCall createFunctionCall(RunnableCall amltRunnableCall){
+
+ var amltProcess=amltRunnableCall.getParentContainer(Process)
+
+ var inchronComponent=createComponent(amltProcess)
+
+
+ val inchronGenericSystem= getInchronGenericSystem(amltProcess)
+
+ if(inchronGenericSystem !=null){
+ inchronGenericSystem.components.add(inchronComponent)
+
+ }
+
+ var inchronFunction=createFunction(amltProcess, amltRunnableCall.runnable)
+
+ inchronComponent.functions.add(inchronFunction)
+
+ it.function=inchronFunction
+ }
+
+
+ /**
+ * This method is used to create inchron FunctionCall element from TaskRunnableCall element
+ */
+ def create inchronModelFactory.createFunctionCall createFunctionCall(TaskRunnableCall amltTaskRunnableCall){
+
+ var amltProcess=amltTaskRunnableCall.getParentContainer(Process)
+
+ var inchronComponent=createComponent(amltProcess)
+
+ val inchronGenericSystem= getInchronGenericSystem(amltProcess)
+
+ if(inchronGenericSystem !=null){
+ inchronGenericSystem.components.add(inchronComponent)
+
+ }
+
+ var inchronFunction=createFunction(amltProcess, amltTaskRunnableCall.runnable)
+
+ it.function=inchronFunction
+
+ inchronComponent.functions.add(inchronFunction)
+
+ it.offset=amltTaskRunnableCall?.counter?.offset.intValue
+
+ it.period=amltTaskRunnableCall?.counter?.prescaler.intValue
+ }
+
+ /**
+ * This method is used to fetch the inchron GenericSystem object for a specific Amalthea Process element
+ */
+ def GenericSystem getInchronGenericSystem(Process amltProcess) {
+
+ val Set<ProcessingUnit> cores=DeploymentUtil.getAssignedCoreForProcess(amltProcess as Process, EcoreUtil.getRootContainer(amltProcess) as Amalthea)
+
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+
+ //TODO: write validaiton to assure that only 1 core is present
+
+ //TODO: currently taking 1st core
+
+ if(cores.size>0){
+ //TODO: clarify if this approach is OK !!
+ val amltCore=cores.get(0)
+
+ val amltMicroController=amltCore.eContainer
+
+ val inchronGenericSystem=amltCache.mappingAmltMicroController_GenericSystem.get(amltMicroController)
+
+ return inchronGenericSystem
+ }
+ }
+
+
+ def create inchronModelFactory.createComponent createComponent(Process amltProcess){
+
+ it.name=amltProcess.name
+ }
+
+ def create inchronModelFactory.createFunction createFunction(Process amltProcess, Runnable amltRunnable){
+
+ it.name=amltRunnable.name
+
+ it.callGraph=inchronModelFactory.createCallGraph
+
+ val inchronCallSequence=inchronModelFactory.createCallSequence
+
+ it.callGraph.graphEntries.add(inchronCallSequence)
+
+ amltRunnable?.runnableItems.forEach[amltRunnableItem|
+
+ if(amltRunnableItem instanceof AsynchronousServerCall){
+
+ }
+ else if(amltRunnableItem instanceof ChannelReceive){
+
+ }
+ else if(amltRunnableItem instanceof ChannelSend){
+
+ }
+ else if(amltRunnableItem instanceof CustomEventTrigger){
+
+ }
+ else if(amltRunnableItem instanceof Group){
+
+ }
+ else if(amltRunnableItem instanceof LabelAccess){
+
+ }
+ else if(amltRunnableItem instanceof ModeLabelAccess){
+
+ }
+ else if(amltRunnableItem instanceof RunnableCall){
+
+ inchronCallSequence.calls.add(createFunctionCall( amltRunnableItem))
+
+
+ }else if(amltRunnableItem instanceof ExecutionNeed){//Earlier it was RunnableInstructions
+
+ inchronCallSequence.calls.add(createResourceConsumption(amltProcess, amltRunnableItem))
+ }
+ else if(amltRunnableItem instanceof RunnableModeSwitch){
+
+ }
+ else if(amltRunnableItem instanceof RunnableProbabilitySwitch){
+
+ }
+ else if(amltRunnableItem instanceof SemaphoreAccess){
+ inchronCallSequence.calls.addAll(semaphoreInterruptCreation(amltRunnableItem))
+ }
+
+ else if(amltRunnableItem instanceof SenderReceiverRead){
+
+ }
+ else if(amltRunnableItem instanceof SenderReceiverWrite){
+
+ }
+ else if(amltRunnableItem instanceof SynchronousServerCall){
+
+ }
+ ]
+ }
+
+ def create inchronModelFactory.createSemaphoreAccess createSemaphoreAccess(SemaphoreAccess amltAccess) {
+
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+
+ val amltSemaphoreName=amltAccess?.semaphore?.name
+
+ //TODO CREATE THIS THE RIGHT WAY!
+ var inchronSemaphore = amltCache.getInchronSemaphoreCacheElement(amltSemaphoreName)// = createSemaphore(amltSemaphore);
+ //SemaphoreAccessType.;
+ //amltAccess.access;
+
+ switch (amltAccess.access) {
+ case SemaphoreAccessEnum.RELEASE: {
+ it.type = SemaphoreAccessType.RELEASE
+ }
+ case SemaphoreAccessEnum.EXCLUSIVE: {
+ it.type = SemaphoreAccessType.EXCLUSIVE
+ }
+ case SemaphoreAccessEnum.REQUEST : {
+ it.type = SemaphoreAccessType.REQUEST
+ }
+ }
+ it.semaphore = inchronSemaphore;
+
+
+ }
+
+ def List<CallSequenceItem> semaphoreInterruptCreation(SemaphoreAccess amltAccess){
+
+ val List<CallSequenceItem> items=new ArrayList
+
+ switch (amltAccess.access) {
+
+ case SemaphoreAccessEnum.RELEASE: {
+
+ items.add(createSemaphoreAccess(amltAccess))
+
+ items.add(createResumeAllInterrupts(amltAccess))
+
+ }
+ case SemaphoreAccessEnum.EXCLUSIVE: {
+ //TODO:check semantics
+ items.add(createSuspendAllInterrupts(amltAccess))
+ items.add(createSemaphoreAccess(amltAccess))
+
+ }
+ case SemaphoreAccessEnum.REQUEST : {
+
+ items.add(createSuspendAllInterrupts(amltAccess))
+ items.add(createSemaphoreAccess(amltAccess))
+
+
+ }
+ }
+ return items
+ }
+
+ /*
+ * LL: SemaphoreAccess object should be mandatorily supplied here, as Xtend caches the elements based on input parameters
+ */
+ def create inchronModelFactory.createSuspendAllInterrupts createSuspendAllInterrupts(SemaphoreAccess amltAccess) {
+ it.offset=0
+ it.period=0
+ }
+
+ /*
+ * LL: SemaphoreAccess object should be mandatorily supplied here, as Xtend caches the elements based on input parameters
+ */
+ def create inchronModelFactory.createResumeAllInterrupts createResumeAllInterrupts(SemaphoreAccess amltAccess) {
+ it.offset=0
+ it.period=0
+ }
+
+
+ def create inchronModelFactory.createResourceConsumption createResourceConsumption(Process amltProcess, ExecutionNeed amltRunnableInstructions){
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+
+
+ if(amltProcess instanceof Task){
+
+
+ var listOfTaskAllocations=amltCache.tasks_TaskAllocationMap.get(amltProcess as Task)
+
+ listOfTaskAllocations?.forEach[amltTaskAllocation|
+ var amltScheduler=amltTaskAllocation.scheduler
+
+ var amltSchedulerAllocation=amltCache.taskScheduler_schedulerAllocationMap.get(amltScheduler)
+
+ //TODO: What if affinity is not set and core should be derived from SchedulerMapping?
+ var List cores1=amltTaskAllocation.affinity
+
+ var List cores2 =(amltSchedulerAllocation.responsibility)
+
+ //to obtain only common Core objects across both lists
+ cores1.retainAll(cores2)
+
+ //TODO: write assumptions about core mapping of tasks (if it is 1 to 1 mapping ?)
+
+ if(cores1.size==1){
+ var timeDistribution=inchronModelFactory.createTimeDistribution
+ //TODO: uniform as a starting point --- more complex distributions need to be simulated
+ timeDistribution.type = TimeDistributionType.UNIFORM
+ timeDistribution.bcet = getRuntimeForRunnableInstruction(amltRunnableInstructions, TimeType.BCET, cores1.get(0) as ProcessingUnit);
+ timeDistribution.wcet = getRuntimeForRunnableInstruction(amltRunnableInstructions, TimeType.WCET, cores1.get(0) as ProcessingUnit);
+ timeDistribution.mean = getRuntimeForRunnableInstruction(amltRunnableInstructions, TimeType.ACET, cores1.get(0) as ProcessingUnit);
+ it.timeDistribution = timeDistribution
+
+ }
+ ]
+ }
+ }
+
+
+
+ //TODO: Check if some of this methods can be part of AMALTHEA
+ //TODO: set getInstructionCountForInstruction to public in APP4MC UTILS
+ def com.inchron.realtime.root.model.Time getRuntimeForRunnableInstruction(ExecutionNeed amltRunnableInstructions, TimeType timeType, ProcessingUnit core) {
+ //TODO: handle extended instructions
+ var amltInstructions = getInstructionCountForInstruction(amltRunnableInstructions.^default, timeType);
+ val hwFeatureFromExecutionNeed = getHwFeatureFromExecutionNeed(amltRunnableInstructions,core)
+ var amltTime = RuntimeUtil.getExecutionTimeForExecutionNeedValueCount(amltInstructions, core, hwFeatureFromExecutionNeed,null);
+ return getInchronTimeValue(amltTime);
+
+ }
+
+ def HwFeature getHwFeatureFromExecutionNeed(ExecutionNeed executionNeed, ProcessingUnit processingUnit){
+
+ val EMap<String, Need> defaultMap = executionNeed.^default
+
+ if(defaultMap.size>0){
+ val processingUnitDefinition = processingUnit.definition
+ if(processingUnitDefinition!=null){
+ for(feature: processingUnitDefinition?.features){
+ //TODO:At present supporting only HwFeatureCategory with name "Instructions"
+ if(feature.containingCategory?.name.equals("Instructions")){
+ return feature
+ }
+ }
+ }
+ }
+
+ return null
+ }
+
+ def Long getInstructionCountForInstruction(EMap<String, Need> defaultMap, TimeType execTimeType) {
+
+
+ for(need: defaultMap.values){
+ if(need instanceof NeedDeviation) {
+ var NeedDeviation instDeviation = need as NeedDeviation ;
+ switch(execTimeType) {
+ case ACET: {
+ return RuntimeUtil.getMean(instDeviation.getDeviation().getDistribution(), instDeviation.getDeviation().getLowerBound().getValue(), instDeviation.getDeviation().getUpperBound().getValue())
+ }
+ case BCET: {
+ return instDeviation.getDeviation().getLowerBound().getValue()
+ }
+ case WCET: {
+ return instDeviation.getDeviation().getUpperBound().getValue();
+ }
+ default:
+ return RuntimeUtil.getMean(instDeviation.getDeviation().getDistribution(), instDeviation.getDeviation().getLowerBound().getValue(), instDeviation.getDeviation().getUpperBound().getValue())
+
+
+ }
+ } else if(need instanceof NeedConstant) {
+ return (need as NeedConstant).getValue();
+ }
+
+ }
+
+
+ return 0L;
+ }
+
+ def com.inchron.realtime.root.model.Time getInchronTimeValue(Time amltTime) {
+ var result = inchronModelFactory.createTime
+
+ result.value = amltTime.value.longValue;
+ switch (amltTime.unit.getName) {
+ case "s": {
+ result.unit = TimeUnit.S
+ }
+ case "ms": {
+ result.unit = TimeUnit.MS
+ }
+ case "us": {
+ result.unit = TimeUnit.US
+ }
+ case "ns": {
+ result.unit = TimeUnit.NS
+ }
+ case "ps": {
+ result.unit = TimeUnit.PS
+ }
+ }
+ return result;
+ }
+
+
+}
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/StimuliTransformer.xtend b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/StimuliTransformer.xtend
new file mode 100644
index 0000000..9dc84d7
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/StimuliTransformer.xtend
@@ -0,0 +1,140 @@
+package templates
+
+import com.inchron.realtime.root.model.Model
+import com.inchron.realtime.root.model.ModelFactory
+import com.inchron.realtime.root.model.TimeUnit
+import java.util.List
+import java.util.Map
+import org.eclipse.app4mc.amalthea.model.Amalthea
+import org.eclipse.app4mc.amalthea.model.InterProcessStimulus
+import org.eclipse.app4mc.amalthea.model.PeriodicStimulus
+import org.eclipse.app4mc.amalthea.model.Stimulus
+import org.eclipse.app4mc.amalthea.model.Task
+import org.eclipse.app4mc.amalthea.model.Time
+import org.eclipse.emf.common.util.EList
+import templates.utils.AmltCacheModel
+
+public class StimuliTransformer extends AbstractAmaltheaInchronTransformer {
+
+ /**
+ * This method is used to perform following:
+ *
+ * <br>1.Build a cache of "InterProcess Stimuli name" and "List of Tasks" which are triggered by it
+ * <br>2.Create ActivationConnection for each InterProcessStimulus
+ */
+ public def void createInchronActivationConnections(EList<Task> amltTasks,Model inchronModel){
+
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+
+ for (process : amltTasks) {
+ process.stimuli.forEach[stimuli | {
+ if(stimuli instanceof InterProcessStimulus){
+ amltCache.cacheInterProcessTriggerRelations(stimuli.name, process)
+ }
+
+ }]
+ }
+
+ /*-For each InterProcessStimulus, create corresponding ActivationConnection in Inchron and store this info in the cache */
+
+ amltCache.interProcessTriggerRelationsMap.keySet.forEach[stimuliName|{
+
+ val inchronConnection=ModelFactory.eINSTANCE.createActivationConnection
+
+ inchronConnection.name=stimuliName
+
+ /*-Adding ActivationConnect object to Inchron Model */
+ inchronModel.connections.add(inchronConnection)
+
+ /*-Adding ActivationConnect object to Cache */
+ amltCache.cacheInchronConnection(stimuliName,inchronConnection)
+
+
+ }]
+
+ }
+ /**
+ * This method is used to create SimulationScenario based on Periodic Stimulus objects present in Amalthea model
+ */
+ public def create inchronStimulationFactory.createStimulationScenario createstimulationScenario(Amalthea amaltheaModel) {
+ val AmltCacheModel amltCache=customObjsStore.getInstance(AmltCacheModel)
+
+ val Map<String, List<com.inchron.realtime.root.model.Process>> stimuliCache = amltCache.amltStimuliInchronProcessElementsMap;
+
+ for (Stimulus stimuli : amaltheaModel?.stimuliModel?.stimuli) {
+
+ if (stimuli instanceof PeriodicStimulus) {
+
+ val inchronProcessList = stimuliCache.get(stimuli.name)
+
+ if (inchronProcessList != null) {
+
+ for (com.inchron.realtime.root.model.Process inchronProcess : inchronProcessList) {
+
+ it.generators.add(createRandomStimuliGenerator(stimuli, inchronProcess))
+ }
+
+ }
+ }
+
+ }
+ }
+
+ /**
+ * This method is used to create RandomStimuliGenerator object, based on the Amalthea PeriodicStimulus object and Inchron Process object
+ */
+ public def create inchronStimulationFactory.createRandomStimuliGenerator createRandomStimuliGenerator(PeriodicStimulus amltStimuli, com.inchron.realtime.root.model.Process inchronProcess) {
+ if (amltStimuli?.minDistance != null)
+ it.minInterArrivalTime = getInchronTimeValue(amltStimuli?.minDistance)
+ it.period = getInchronTimeValue(amltStimuli.recurrence)
+ it.startOffset = getInchronTimeValue(amltStimuli?.offset)
+ //it.clock; //need the clock
+ it.relative = false; //only for sporadics
+ it.iterations = -1 //right?
+ //it.startOffsetVariation; //don't know
+ it.target = inchronProcess;
+ //it.variation
+
+
+ //jitter
+ if (amltStimuli?.jitter != null) {
+ var timeDistribution=inchronModelFactory.createTimeDistribution
+ if (amltStimuli?.jitter?.lowerBound != null) {
+ timeDistribution.bcet = getInchronTimeValue(amltStimuli?.jitter?.lowerBound)
+ }
+ if (amltStimuli?.jitter?.upperBound != null) {
+ timeDistribution.wcet = getInchronTimeValue(amltStimuli?.jitter?.upperBound)
+ }
+
+ //TODO: handle more complex distributions
+ it.variation = timeDistribution
+ }
+
+
+ }
+
+ def com.inchron.realtime.root.model.Time getInchronTimeValue(Time amltTime) {
+ var result = inchronModelFactory.createTime
+
+ result.value = amltTime.value.longValue;
+ switch (amltTime.unit.getName) {
+ case "s": {
+ result.unit = TimeUnit.S
+ }
+ case "ms": {
+ result.unit = TimeUnit.MS
+ }
+ case "us": {
+ result.unit = TimeUnit.US
+ }
+ case "ns": {
+ result.unit = TimeUnit.NS
+ }
+ case "ps": {
+ result.unit = TimeUnit.PS
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/utils/AmltCacheModel.java b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/utils/AmltCacheModel.java
new file mode 100644
index 0000000..6b41dc7
--- /dev/null
+++ b/eclipse-tools/model-transformation/examples/amalthea-to-inchron-transformation/org.eclipse.app4mc.transform.to.inchron.m2m/src/templates/utils/AmltCacheModel.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * * Copyright (c) 2018 Robert Bosch GmbH.
+ * * All rights reserved. This program and the accompanying materials
+ * * are made available under the terms of the Eclipse Public License v1.0
+ * * which accompanies this distribution, and is available at
+ * * http://www.eclipse.org/legal/epl-v10.html
+ * *
+ * * Contributors:
+ * * Robert Bosch GmbH - initial API and implementation
+ *******************************************************************************/
+package templates.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.app4mc.amalthea.model.HwStructure;
+import org.eclipse.app4mc.amalthea.model.InterruptController;
+import org.eclipse.app4mc.amalthea.model.MappingModel;
+import org.eclipse.app4mc.amalthea.model.Process;
+import org.eclipse.app4mc.amalthea.model.Scheduler;
+import org.eclipse.app4mc.amalthea.model.SchedulerAllocation;
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.TaskAllocation;
+import org.eclipse.app4mc.amalthea.model.TaskScheduler;
+import org.eclipse.emf.common.util.EList;
+
+import com.inchron.realtime.root.model.ActivationConnection;
+import com.inchron.realtime.root.model.GenericSystem;
+import com.inchron.realtime.root.model.Semaphore;
+
+
+public class AmltCacheModel {
+
+ private Map<HwStructure, GenericSystem> mappingAmltMicroController_GenericSystem = new HashMap<>();
+
+ private Map<Scheduler, SchedulerAllocation> taskScheduler_schedulerAllocationMap=new HashMap<Scheduler, SchedulerAllocation>();
+
+ private Map<Task, List<TaskAllocation>> tasks_TaskAllocationMap=new HashMap<Task, List<TaskAllocation>>();
+
+// private Map<ISR, SchedulerAllocation> isr_schedulerAllocationMap=new HashMap<ISR, SchedulerAllocation>();
+
+ private Map<TaskScheduler, List<TaskAllocation>> taskScheduler_taskAllocationMap=new HashMap<TaskScheduler, List<TaskAllocation>>();
+
+ private Map<String, Semaphore> inchronSemaphoresMap=new HashMap<>();
+
+ private Map<String, List<org.eclipse.app4mc.amalthea.model.Process>> amltInterProcessStimuli_processActivationsMap=new HashMap<>();
+
+ private Map<String, ActivationConnection> inchronConnectionElementsMap=new HashMap<>();
+
+ private Map<String, List<com.inchron.realtime.root.model.Process>> amltStimuliInchronProcessMap=new HashMap<>();
+
+ public Map<HwStructure, GenericSystem> getMappingAmltMicroController_GenericSystem() {
+ return mappingAmltMicroController_GenericSystem;
+ }
+
+
+ public void cacheMappingAmltMicroController_GenericSystem(HwStructure hwStructure, GenericSystem genericSystem){
+ mappingAmltMicroController_GenericSystem.put(hwStructure, genericSystem);
+ }
+
+ public void cacheAmltStimuliInchronProcessMap(String amltStimuliName, com.inchron.realtime.root.model.Process inchronProcess){
+ if(amltStimuliName !=null){
+ List<com.inchron.realtime.root.model.Process> processList = amltStimuliInchronProcessMap.get(amltStimuliName);
+
+ if(processList==null){
+ processList=new ArrayList<>();
+ amltStimuliInchronProcessMap.put(amltStimuliName, processList);
+ }
+ processList.add(inchronProcess);
+ }
+ }
+
+ public Map<String, List<com.inchron.realtime.root.model.Process>> getAmltStimuliInchronProcessElementsMap(){
+
+ return amltStimuliInchronProcessMap;
+ }
+
+
+ public void cacheInchronConnection(String name, ActivationConnection connection){
+ if(name !=null){
+ inchronConnectionElementsMap.put(name, connection);
+ }
+ }
+
+ public Map<String, ActivationConnection> getInchronConnectionElementsMap(){
+ return inchronConnectionElementsMap;
+ }
+
+
+ public void cacheInterProcessTriggerRelations(String stimuliName, Process amltProcess){
+
+ if(stimuliName!=null){
+ List<Process> processList = amltInterProcessStimuli_processActivationsMap.get(stimuliName);
+
+ if(processList==null){
+ processList=new ArrayList<>();
+ amltInterProcessStimuli_processActivationsMap.put(stimuliName, processList);
+ }
+ processList.add(amltProcess);
+ }
+
+ }
+
+ public Map<String, List<Process>> getInterProcessTriggerRelationsMap(){
+ return amltInterProcessStimuli_processActivationsMap;
+ }
+
+
+
+ public void cacheInchronSemaphore(com.inchron.realtime.root.model.Semaphore inchronSemaphore){
+
+ if(inchronSemaphore.getName()!=null){
+ inchronSemaphoresMap.put(inchronSemaphore.getName(), inchronSemaphore);
+ }
+ }
+
+ public com.inchron.realtime.root.model.Semaphore getInchronSemaphoreCacheElement(String semaphoreName){
+ return inchronSemaphoresMap.get(semaphoreName);
+ }
+
+ public Map<Scheduler, SchedulerAllocation> getTaskScheduler_schedulerAllocationMap() {
+ return taskScheduler_schedulerAllocationMap;
+ }
+
+
+ public Map<Task, List<TaskAllocation>> getTasks_TaskAllocationMap() {
+ return tasks_TaskAllocationMap;
+ }
+
+
+ public Map<TaskScheduler, List<TaskAllocation>> getTaskScheduler_taskAllocationMap() {
+ return taskScheduler_taskAllocationMap;
+ }
+
+
+ public void buildProcesses_SchedulerAllocationMap(MappingModel mappingModel){
+
+ EList<SchedulerAllocation> schedulerAllocations = mappingModel.getSchedulerAllocation();
+
+ for (SchedulerAllocation schedulerAllocation : schedulerAllocations) {
+
+
+ taskScheduler_schedulerAllocationMap.put(schedulerAllocation.getScheduler(), schedulerAllocation);
+ }
+
+ }
+
+
+ public void buildTaskSchedulerAndSchedulerAssociationMap(MappingModel mappingModel){
+
+ EList<SchedulerAllocation> schedulerAllocations = mappingModel.getSchedulerAllocation();
+
+ for (SchedulerAllocation schedulerAllocation : schedulerAllocations) {
+
+
+ Scheduler scheduler = schedulerAllocation.getScheduler();
+ if(scheduler instanceof TaskScheduler){
+ taskScheduler_schedulerAllocationMap.put(scheduler, schedulerAllocation);
+
+ }else if(scheduler instanceof InterruptController){
+// isr_schedulerAllocationMap.put(((InterruptController)scheduler).getISR, schedulerAllocation);
+ }
+ }
+
+ }
+
+ public Map<Scheduler, SchedulerAllocation> getTaskScheduler_SchedulerAllocationMap() {
+ return taskScheduler_schedulerAllocationMap;
+ }
+
+ public Map<TaskScheduler, List<TaskAllocation>> getTaskScheduler_TaskAllocationMap() {
+ return taskScheduler_taskAllocationMap;
+ }
+
+ public void buildTaskSchedulerAndTaskAllocationMap(MappingModel mappingModel){
+
+ EList<TaskAllocation> taskAllocations = mappingModel.getTaskAllocation();
+
+ for (TaskAllocation taskAllocation : taskAllocations) {
+
+ List<TaskAllocation> listOfTaskAllocations;
+
+ if(taskScheduler_taskAllocationMap.containsKey(taskAllocation.getScheduler())){
+ listOfTaskAllocations=taskScheduler_taskAllocationMap.get(taskAllocation.getScheduler());
+ }else{
+ listOfTaskAllocations=new ArrayList<TaskAllocation>();
+ taskScheduler_taskAllocationMap.put(taskAllocation.getScheduler(),listOfTaskAllocations);
+ }
+
+ listOfTaskAllocations.add(taskAllocation);
+
+
+
+ //populating map tasks_TaskAllocationMap
+
+ List<TaskAllocation> listOftask_TaskAllocations;
+
+ if(tasks_TaskAllocationMap.containsKey(taskAllocation.getTask())){
+ listOftask_TaskAllocations=tasks_TaskAllocationMap.get(taskAllocation.getTask());
+ }else{
+ listOftask_TaskAllocations=new ArrayList<TaskAllocation>();
+ tasks_TaskAllocationMap.put(taskAllocation.getTask(),listOftask_TaskAllocations);
+ }
+
+ listOftask_TaskAllocations.add(taskAllocation);
+
+
+ }
+
+ }
+
+}