blob: 4e1acab0391823db0503b17b0543225a57a67cd0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 Dortmund University of Applied Sciences and Arts and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dortmund University of Applied Sciences and Arts - initial API and implementation
*******************************************************************************/
package org.eclipse.app4mc.cdgen;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.amalthea.model.Label;
import org.eclipse.app4mc.amalthea.model.MappingModel;
import org.eclipse.app4mc.amalthea.model.PeriodicStimulus;
import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
import org.eclipse.app4mc.amalthea.model.SchedulerAllocation;
import org.eclipse.app4mc.amalthea.model.Stimulus;
import org.eclipse.app4mc.amalthea.model.Task;
import org.eclipse.app4mc.amalthea.model.Time;
import org.eclipse.app4mc.amalthea.model.TimeUnit;
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.app4mc.amalthea.model.util.SoftwareUtil;
import org.eclipse.app4mc.amalthea.model.util.TimeUtil;
import org.eclipse.app4mc.cdgen.utils.fileUtil;
import org.eclipse.emf.common.util.EList;
/**
* Implementation of Main function in which scheduling is done. Specific to RMS
* Scheduler
*
*
*/
public class MainRMSFileCreation {
final private Amalthea model;
/**
* MainRMSFileCreation Constructor
*
* @param Model
* @param srcPath
* @param configFlag
* @throws IOException
*/
public MainRMSFileCreation(final Amalthea Model, final String srcPath, final int configFlag) throws IOException {
this.model = Model;
System.out.println("Main File Creation Begins");
fileCreate(this.model, srcPath, configFlag);
System.out.println("Main File Creation Ends");
}
/**
* MainRMSFileCreation - File Creation
*
* @param model
* @param srcPath
* @param configFlag
* @throws IOException
*/
private static void fileCreate(final Amalthea model, final String srcPath, final int configFlag)
throws IOException {
final EList<SchedulerAllocation> CoreNo = model.getMappingModel().getSchedulerAllocation();
int k = 0;
for (final SchedulerAllocation c : CoreNo) {
final ProcessingUnit pu = c.getResponsibility().get(0);
final Set<Task> tasks = DeploymentUtil.getTasksMappedToCore(pu, model);
final String fname = srcPath + File.separator + "main" + k + ".c";
final File f2 = new File(srcPath);
final File f1 = new File(fname);
f2.mkdirs();
try {
f1.createNewFile();
}
catch (final IOException e) {
e.printStackTrace();
}
final File fn = f1;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
try {
fileUtil.fileMainHeader(f1);
mainFileHeader(f1);
if ((0x0100 == (0x0F00 & configFlag)) & (0x3000 == (0xF000 & configFlag))) {
if (0x0001 == (0x0001 & configFlag)) {
headerIncludesMainRMS(f1, k, true);
mainTaskStimuli(model, f1, tasks);
mainTaskPriority(f1, tasks);
mainFucntionRMS(model, f1, tasks, true);
// SharedLabelDeclarationHead(f1, model);
}
else {
headerIncludesMainRMS(f1, k, false);
mainTaskStimuli(model, f1, tasks);
mainTaskPriority(f1, tasks);
mainFucntionRMS(model, f1, tasks, false);
// SharedLabelDeclarationHead(f1, model);
}
}
else {
headerIncludesMainFreeRTOS(f1, k);
mainTaskStimuli(model, f1, tasks);
mainTaskPriority(f1, tasks);
mainFucntionFreeRTOS(model, f1, tasks);
}
}
finally {
try {
fw.close();
}
catch (final IOException e) {
e.printStackTrace();
}
}
k++;
}
}
/**
* Main function in Main file of RMS specific scheduler
*
* @param model
* @param file
* @param tasks
* @param btfEnable
*/
private static void mainFucntionRMS(final Amalthea model, final File file, final Set<Task> tasks, final boolean btfEnable) {
try {
final File fn = file;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("int main(void) \n{\n");
if (btfEnable == true) {
fw.write("\tinit_btf_mem_section();\n");
fw.write("\tinit_task_trace_buffer();\n");
fw.write("\tint ts = get_time_scale_factor();\n");
}
else {
fw.write("\toutbuf_init();\n");
}
final List<Label> SharedLabelList = LabelFileCreation.SharedLabelFinder(model);
final List<Label> SharedLabelListSortCore = new ArrayList<Label>();
if (SharedLabelList.size() == 0) {
System.out.println("Shared Label size 0");
}
else {
final HashMap<Label, HashMap<Task, ProcessingUnit>> sharedLabelTaskMap = LabelFileCreation
.LabelTaskMap(model, SharedLabelList);
for (final Label share : SharedLabelList) {
final HashMap<Task, ProcessingUnit> TaskMap = sharedLabelTaskMap.get(share);
final Collection<ProcessingUnit> puList = TaskMap.values();
final List<ProcessingUnit> puListUnique = puList.stream().distinct().collect(Collectors.toList());
if (puListUnique.size() > 1) {
SharedLabelListSortCore.add(share);
}
}
}
final HashMap<Label, String> SharedLabelTypeMap = new HashMap<Label, String>();
for (final Label share : SharedLabelListSortCore) {
SharedLabelTypeMap.put(share, share.getSize().toString());
}
final List<String> SharedTypeMapList = new ArrayList<>(
SharedLabelTypeMap.values().stream().distinct().collect(Collectors.toList()));
final List<Label> SharedLabelMapList = new ArrayList<Label>(SharedLabelTypeMap.keySet());
for (int k = 0; k < SharedTypeMapList.size(); k++) {
final List<Label> SharedLabel = new ArrayList<Label>();
final String sh = SharedTypeMapList.get(k);
for (final Label s : SharedLabelMapList) {
final String ShTy = SharedLabelTypeMap.get(s);
if (sh.equals(ShTy)) {
SharedLabel.add(s);
}
}
int SharedLabelCounter = SharedLabel.size();
if (SharedLabelCounter != 0) {
fw.write("\tshared_label_" + sh.toString().replace(" ", "") + "_init();\n");
}
SharedLabelCounter = 0;
}
if (btfEnable == true) {
final List<Task> localTaskPriority = new ArrayList<Task>();
localTaskPriority.addAll(tasks);
@SuppressWarnings("resource")
final HashMap<Task, Long> periodMap = new HashMap<Task, Long>();
for (final Task task : tasks) {
final long period = fileUtil.getRecurrence(task).getValue().longValue();
periodMap.put(task, period);
}
final Map<Task, Long> periodMapSorted = fileUtil.sortByValue(periodMap);
for (int i = (periodMapSorted.size()), k = 0; i > 0; i--, k++) {
final Task task = (Task) periodMapSorted.keySet().toArray()[k];
final MappingModel mappingModel = model.getMappingModel();
ProcessingUnit pu = null;
if (mappingModel != null) {
pu = DeploymentUtil.getAssignedCoreForProcess(task, model).iterator().next();
Time taskTime = RuntimeUtil.getExecutionTimeForProcess(task, pu, null, TimeType.WCET);
taskTime = TimeUtil.convertToTimeUnit(taskTime, TimeUnit.MS);
final BigInteger sleepTime = taskTime.getValue();
final BigInteger b2 = new BigInteger("1000");
final int comparevalue = sleepTime.compareTo(b2);
if (comparevalue < 0) {
fw.write("\tAmaltheaTask AmalTk_" + task.getName() + " = createAmaltheaTask( v" + task.getName()
+ ", cIN_" + task.getName() + ", cOUT_" + task.getName() + ",\n\t\t\t "
+ task.getStimuli().get(0).getName() + "*ts, " + task.getStimuli().get(0).getName()
+ "*ts, 1*ts, "+ pu.getName()+"_ID, 0, 0, 0);\n");
}
else {
fw.write("\tAmaltheaTask AmalTk_" + task.getName() + " = createAmaltheaTask( v" + task.getName()
+ ", cIN_" + task.getName() + ", cOUT_" + task.getName() + ",\n\t\t\t "
+ task.getStimuli().get(0).getName() + "*ts, " + task.getStimuli().get(0).getName() + "*ts, "
+ sleepTime + "*ts, "+ pu.getName()+"_ID, 0, 0, 0);\n");
}
}
}
}
else {
for (final Task task : tasks) {
final MappingModel mappingModel = model.getMappingModel();
ProcessingUnit pu = null;
if (mappingModel != null) {
pu = DeploymentUtil.getAssignedCoreForProcess(task, model).iterator().next();
Time taskTime = RuntimeUtil.getExecutionTimeForProcess(task, pu, null, TimeType.WCET);
taskTime = TimeUtil.convertToTimeUnit(taskTime, TimeUnit.MS);
final BigInteger sleepTime = taskTime.getValue();
final BigInteger b2 = new BigInteger("1000");
final int comparevalue = sleepTime.compareTo(b2);
if (comparevalue < 0) {
fw.write("\tAmaltheaTask AmalTk_" + task.getName() + " = createAmaltheaTask( v" + task.getName()
+ ", cIN_" + task.getName() + ", cOUT_" + task.getName() + ", "
+ task.getStimuli().get(0).getName() + ", " + task.getStimuli().get(0).getName()
+ ", 1);\n");
}
else {
fw.write("\tAmaltheaTask AmalTk_" + task.getName() + " = createAmaltheaTask( v" + task.getName()
+ ", cIN_" + task.getName() + ", cOUT_" + task.getName() + ", "
+ task.getStimuli().get(0).getName() + ", " + task.getStimuli().get(0).getName() + ", "
+ sleepTime + ");\n");
}
}
}
}
if (btfEnable == true) {
final List<Task> localTaskPriority = new ArrayList<Task>();
localTaskPriority.addAll(tasks);
@SuppressWarnings("resource")
final HashMap<Task, Long> periodMap = new HashMap<Task, Long>();
for (final Task task : tasks) {
final long period = fileUtil.getRecurrence(task).getValue().longValue();
periodMap.put(task, period);
}
final Map<Task, Long> periodMapSorted = fileUtil.sortByValue(periodMap);
for (int i = (periodMapSorted.size()), k = 0; i > 0; i--, k++) {
final Task task = (Task) periodMapSorted.keySet().toArray()[k];
final Set<Label> taskLabel = SoftwareUtil.getAccessedLabelSet(task, null);
final List<Label> taskLabelList = new ArrayList<>(taskLabel);
final HashMap<Label, String> LabelTypeMap = new HashMap<Label, String>();
for (final Label tl : taskLabelList) {
LabelTypeMap.put(tl, tl.getSize().toString());
}
final List<String> TypeList = new ArrayList<>(
LabelTypeMap.values().stream().distinct().collect(Collectors.toList()));
final List<Label> LabelList = new ArrayList<>(
LabelTypeMap.keySet().stream().distinct().collect(Collectors.toList()));
fw.write("\tcreateRTOSTask( &AmalTk_" + task.getName() + ", main" + task.getName() + ", "
+ TypeList.size() + ",");
final List<Label> dataTypeList = new ArrayList<Label>();
int j = 0;
for (final String tl : TypeList) {
fw.write(fileUtil.datatypeSize(tl) + ", ");
for (final Label La : LabelList) {
if (LabelTypeMap.get(La).contains(tl) && (SharedLabelListSortCore.contains(La))) {
dataTypeList.add(La);
}
}
fw.write("" + dataTypeList.size() + "");
j++;
if (j < TypeList.size()) {
fw.write(", ");
}
}
fw.write(");\n");
}
}
else {
for (final Task task : tasks) {
final Set<Label> taskLabel = SoftwareUtil.getAccessedLabelSet(task, null);
final List<Label> taskLabelList = new ArrayList<>(taskLabel);
final HashMap<Label, String> LabelTypeMap = new HashMap<Label, String>();
for (final Label tl : taskLabelList) {
LabelTypeMap.put(tl, tl.getSize().toString());
}
final List<String> TypeList = new ArrayList<>(
LabelTypeMap.values().stream().distinct().collect(Collectors.toList()));
final List<Label> LabelList = new ArrayList<>(
LabelTypeMap.keySet().stream().distinct().collect(Collectors.toList()));
fw.write("\tcreateRTOSTask( &AmalTk_" + task.getName() + ", main" + task.getName() + ", "
+ TypeList.size() + ",");
final List<Label> dataTypeList = new ArrayList<Label>();
int k = 0;
for (final String tl : TypeList) {
fw.write(fileUtil.datatypeSize(tl) + ", ");
for (final Label La : LabelList) {
if (LabelTypeMap.get(La).contains(tl) && (SharedLabelListSortCore.contains(La))) {
dataTypeList.add(La);
}
}
fw.write("" + dataTypeList.size() + "");
k++;
if (k < TypeList.size()) {
fw.write(", ");
}
}
fw.write(");\n");
}
}
fw.write("\tvTaskStartScheduler();\n");
fw.write("\t" + "return EXIT_SUCCESS;\n");
fw.write("}\n\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
/**
* Main function in Main file of RMS specific scheduler
*
* @param model
* @param file
* @param tasks
*/
private static void mainFucntionFreeRTOS(final Amalthea model, final File file, final Set<Task> tasks) {
try {
final File fn = file;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("int main(void) \n{\n");
fw.write("\toutbuf_init();\n");
final List<Label> SharedLabelList = LabelFileCreation.SharedLabelFinder(model);
final List<Label> SharedLabelListSortCore = new ArrayList<Label>();
if (SharedLabelList.size() == 0) {
System.out.println("Shared Label size 0");
}
else {
// System.out.println("Shared Label size
// "+SharedLabelList.size());
final HashMap<Label, HashMap<Task, ProcessingUnit>> sharedLabelTaskMap = LabelFileCreation
.LabelTaskMap(model, SharedLabelList);
for (final Label share : SharedLabelList) {
final HashMap<Task, ProcessingUnit> TaskMap = sharedLabelTaskMap.get(share);
final Collection<ProcessingUnit> puList = TaskMap.values();
final List<ProcessingUnit> puListUnique = puList.stream().distinct().collect(Collectors.toList());
if (puListUnique.size() > 1) {
SharedLabelListSortCore.add(share);
}
}
}
final HashMap<Label, String> SharedLabelTypeMap = new HashMap<Label, String>();
for (final Label share : SharedLabelListSortCore) {
SharedLabelTypeMap.put(share, share.getSize().toString());
}
final List<String> SharedTypeMapList = new ArrayList<>(
SharedLabelTypeMap.values().stream().distinct().collect(Collectors.toList()));
final List<Label> SharedLabelMapList = new ArrayList<Label>(SharedLabelTypeMap.keySet());
for (int k = 0; k < SharedTypeMapList.size(); k++) {
final List<Label> SharedLabel = new ArrayList<Label>();
final String sh = SharedTypeMapList.get(k);
for (final Label s : SharedLabelMapList) {
final String ShTy = SharedLabelTypeMap.get(s);
if (sh.equals(ShTy)) {
SharedLabel.add(s);
}
}
int SharedLabelCounter = SharedLabel.size();
if (SharedLabelCounter != 0) {
fw.write("\tshared_label_" + sh.toString().replace(" ", "") + "_init();\n");
// fw.write("void shared_label_"+sh.toString().replace(" ",
// "")+"_init_core();\n");
}
SharedLabelCounter = 0;
}
for (final Task task : tasks) {
fw.write("\txTaskCreate( v" + task.getName() + " , \"" + task.getName()
+ "\", configMINIMAL_STACK_SIZE, &v" + task.getName() + ", main" + task.getName()
+ ", NULL);\n");
}
fw.write("\tvTaskStartScheduler();\n");
fw.write("\t" + "return EXIT_SUCCESS;\n");
fw.write("}\n\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
/**
* Title Card of MainRMSFileCreation
*
* @param file
*/
private static void mainFileHeader(final File file) {
try {
final File fn = file;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("*Title : C File for Tasks Call\n");
fw.write("*Description : Main file in which scheduling is done \n");
fw.write("******************************************************************\n");
fw.write("******************************************************************\n");
fw.write("******************************************************************/\n\n\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
/**
* MainRMSFileCreation Header inclusion
*
* @param file
* @param k - Core-id
* @param btfEnable
*/
private static void headerIncludesMainRMS(final File file, final int k, final boolean btfEnable) {
try {
final File fn = file;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("/* Standard includes. */\n");
fw.write("#include <stdio.h>\n");
fw.write("#include <stdlib.h>\n");
fw.write("#include <string.h>\n");
fw.write("#include <e_lib.h>\n\n");
fw.write("/* Scheduler includes. */\n");
fw.write("#include \"FreeRTOS.h\"\n");
fw.write("#include \"task.h\"\n");
fw.write("#include \"queue.h\"\n");
fw.write("#include \"AmaltheaConverter.h\"\n");
fw.write("#include \"debugFlags.h\"\n");
fw.write("#include \"ParallellaUtils.h\"\n");
fw.write("#include \"taskDef" + k + ".h\"\n");
fw.write("#include \"shared_comms.h\"\n\n");
fw.write("#include \"label" + k + ".h\"\n");
if (btfEnable == true) {
fw.write("#include \"RTFParallellaConfig.h\"\n");
}
// fw.write("#include \"c2c.h\"\n\n");
// fw.write("#define READ_PRECISION_US 1000\n\n\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
/**
* Assign Priority to task in RMS
*
* @param file
* @param tasks
*/
private static void mainTaskPriority(final File file, final Set<Task> tasks) {
try {
final File fn = file;
final List<Task> localTaskPriority = new ArrayList<Task>();
localTaskPriority.addAll(tasks);
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("/* TaskPriorities. */\n");
final HashMap<Task, Long> periodMap = new HashMap<Task, Long>();
for (final Task task : tasks) {
final long period = fileUtil.getRecurrence(task).getValue().longValue();
periodMap.put(task, period);
}
final Map<Task, Long> periodMapSorted = fileUtil.sortByValue(periodMap);
// System.out.println("periodMapSorted Size "+
// periodMapSorted.size());
// for (int i=0;i<(periodMapSorted.size());i++) {
for (int i = (periodMapSorted.size()), k = 0; i > 0; i--, k++) {
final Task task = (Task) periodMapSorted.keySet().toArray()[k];
fw.write("\t#define main" + task.getName() + "\t( tskIDLE_PRIORITY +" + (i) + " )\n");
}
fw.write("\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
/**
* MainRMSFileCreation Header inclusion
*
* @param file
*/
private static void headerIncludesMainFreeRTOS(final File file, final int k) {
try {
final File fn = file;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("/* Standard includes. */\n");
fw.write("#include <stdio.h>\n");
fw.write("#include <stdlib.h>\n");
fw.write("#include <string.h>\n");
fw.write("#include <e_lib.h>\n\n");
fw.write("/* Scheduler includes. */\n");
fw.write("#include \"FreeRTOS.h\"\n");
fw.write("#include \"task.h\"\n");
fw.write("#include \"queue.h\"\n");
fw.write("#include \"AmaltheaConverter.h\"\n");
fw.write("#include \"debugFlags.h\"\n");
fw.write("#include \"ParallellaUtils.h\"\n");
fw.write("#include \"taskDef" + k + ".h\"\n");
fw.write("#include \"shared_comms.h\"\n\n");
fw.write("#include \"label" + k + ".h\"\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
/**
* Macro for Stimuli in the model
*
* @param model
* @param file
* @param tasks
*/
private static void mainTaskStimuli(final Amalthea model, final File f1, final Set<Task> tasks) {
try {
final File fn = f1;
@SuppressWarnings("resource")
final FileWriter fw = new FileWriter(fn, true);
fw.write("/* TaskStimuli. */\n");
final EList<Stimulus> Stimuli = model.getStimuliModel().getStimuli();
for (final Stimulus s : Stimuli) {
if (s instanceof PeriodicStimulus) {
fw.write("\t#define " + s.getName() + "\t" + ((PeriodicStimulus) s).getRecurrence().getValue()
+ " \n");
}
}
fw.write("\n");
fw.close();
}
catch (final IOException ioe) {
System.err.println("IOException: " + ioe.getMessage());
}
}
}