| 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)) |
| ] |
| } |
| } |
| |
| } |