+/* $Id: RtemsModuleVisitor.java 114 2010-07-05 07:47:02Z haidw $ */
+package dol.visitor.rtems;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.mapping.ComputationBinding;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.mapping.Schedule;
+import dol.datamodel.mapping.ScheduleEntry;
+import dol.datamodel.mapping.SchedulingPolicy;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.main.UserInterface;
+import dol.parser.xml.archischema.ArchiXmlParser;
+import dol.parser.xml.mapschema.MapXmlParser;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class RtemsModuleVisitor extends PNVisitor {
+
+ /**
+ * Constructor.
+ *
+ * @param dir path of this file
+ */
+ public RtemsModuleVisitor(String dir, HashMap<Port, Integer> portMap) {
+ _dir = dir;
+ _portMap = portMap;
+ }
+
+ /**
+ * Visit process network.
+ *
+ * @param x process network that needs to be rendered
+ */
+ public void visitComponent(ProcessNetwork x) {
+ try {
+ _ui = UserInterface.getInstance();
+ String filename = _dir + _delimiter + "main.c";
+ OutputStream file = new FileOutputStream(filename);
+ _mainPS = new CodePrintStream(file);
+
+ Vector<Process> pList = x.getProcessList();
+ Vector<String> processList = new Vector<String>();
+ for (Process p : x.getProcessList()) {
+ String basename = p.getBasename();
+ if (!processList.contains(basename)) {
+ processList.add(basename);
+ }
+ }
+
+ Architecture arch = null;
+ Mapping mapping = null;
+
+ //create header section
+ if (_ui.getRtemsBSP().equals("pc386")) {
+ _mainPS.println("#include <bsp.h>");
+ _mainPS.println("#include <stdlib.h>");
+ _mainPS.println("#include <stdio.h>");
+ _mainPS.println("#include <inttypes.h>");
+ _mainPS.println();
+ _mainPS.println("rtems_task Init(rtems_task_argument argument);");
+ _mainPS.println();
+ _mainPS.println("#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER");
+ _mainPS.println("#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER");
+ _mainPS.println("#define CONFIGURE_RTEMS_INIT_TASKS_TABLE");
+ _mainPS.println("#define CONFIGURE_MAXIMUM_TASKS "
+ + (x.getProcessList().size() + 2));
+ _mainPS.println("#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES "
+ + x.getChannelList().size());
+ _mainPS.println("#define CONFIGURE_INIT");
+ _mainPS.println("#include <rtems/confdefs.h>");
+ _mainPS.println();
+ } else if (_ui.getRtemsBSP().equals("mparm")) {
+ _mainPS.println("#define TEST_INIT");
+ _mainPS.println("#include <bsp.h>");
+ _mainPS.println("#include <stdlib.h>");
+ _mainPS.println("#include <stdio.h>");
+ _mainPS.println();
+ _mainPS.println("#define RTEMS_TRACE_MAIN_APP");
+ _mainPS.println("#include \"system.h\"");
+ _mainPS.println("#include \"appsupport.h\"");
+ _mainPS.println("#include \"scratch_queue.h\"");
+ _mainPS.println();
+ }
+
+ _mainPS.println("#include \"dol.h\"");
+ _mainPS.println("#include \"rtems_process_wrapper.h\"");
+ _mainPS.println();
+
+ if (_ui.getRtemsBSP().equals("pc386")) {
+ _mainPS.println("rtems_task CleanupTask(rtems_task_argument arg);");
+ _mainPS.println("rtems_id queue_id["
+ + x.getChannelList().size() + "];");
+ _mainPS.println();
+ } else if (_ui.getRtemsBSP().equals("mparm")) {
+ //if no mapping is provided, map each process to a new
+ //processor
+ //shaper
+ _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+ _mainPS.println("#include \"traffic_shaping.h\"");
+ //_mainPS.println("#define shaper_PROCESSOR "
+ // + (pList.size()+1));
+ _mainPS.println("#endif // shaper");
+ _mainPS.println();
+
+ if (_ui.getMappingFileName() == null) {
+
+ int i = 0;
+ for (Process p : pList) {
+ _mainPS.println("#define " + p.getName()
+ + "_PROCESSOR " + ++i); //count from 1
+ }
+ _mainPS.println();
+
+ _mainPS.print("unsigned int number_of_processes["
+ + pList.size() + "] = { ");
+ for (i = 0; i < pList.size(); i++) {
+ _mainPS.print("1, ");
+ }
+ _mainPS.println("};");
+ _mainPS.println();
+
+ } else { //map processes according to mapping file
+ ArchiXmlParser archParser = new ArchiXmlParser();
+ arch = archParser.doParse(_ui.getPlatformFileName());
+ MapXmlParser mappingParser = new MapXmlParser(x, arch);
+ mapping = mappingParser.doParse(_ui.getMappingFileName());
+ int numOfUsedProcessors = mapping.getProcessorList().size();
+ int numOfProcessors = arch.getProcessorList().size();
+ int processesPerProcessor[] = new int[numOfProcessors];
+
+ // need to check processors used start from 0 and
+ //continuous
+ for (Process p : pList) {
+ for (ComputationBinding b : mapping.getCompBindList()){
+ int processorIndex = Integer.valueOf(
+ b.getProcessor().getName().
+ replaceAll(".*_", ""));
+ if (b.getProcess().getName().
+ equals(p.getName())) {
+ processesPerProcessor[processorIndex]++;
+ //processor indices start at 1 in MPARM
+ _mainPS.println("#define " + p.getName()
+ + "_PROCESSOR "
+ + (processorIndex + 1));
+ }
+ }
+ }
+
+
+ for (int i=0; i < numOfUsedProcessors; i++) {
+ if (processesPerProcessor[i] < 1)
+ throw new Exception("No process is mapped to "
+ + "PROCESSOR[" + i + "]. For the MPARM "
+ + "platform, processors should be used "
+ + "starting from 0 until N (in the "
+ + "generated code, from 1 to N + 1), and "
+ + "every processor between 0 and N "
+ + "should have at least one process "
+ + "mapped on it!");
+ }
+
+ _mainPS.println();
+ /*
+ _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+ _mainPS.println("#define shaper_PROCESSOR "
+ + (numOfUsedProcessors+1));
+ _mainPS.println("#endif // shaper");
+ _mainPS.println();
+ */
+ _mainPS.print("unsigned int number_of_processes[]"
+ + " = { ");
+ for (int i = 0; i < numOfUsedProcessors; i++) {
+ _mainPS.print(processesPerProcessor[i] + ", ");
+ }
+ _mainPS.println("};");
+ _mainPS.println();
+ }
+
+ _mainPS.println("unsigned int active_processes;");
+ _mainPS.println("inline void processor_init() "
+ + "{active_processes"
+ + " = number_of_processes[get_id() - 1];}");
+ _mainPS.println();
+
+ for (Process p : pList) {
+ _mainPS.println("void " + "rtems_" + p.getName()
+ + "_init(rtems_task_argument arg);");
+ }
+ _mainPS.println();
+ }
+
+ for (String pName : x.getProcessBasenames()) {
+ _mainPS.println("extern rtems_task " + pName
+ + "_task(rtems_task_argument argument);");
+ }
+ _mainPS.println();
+
+ //declare processes and channels
+ for (Process process : x.getProcessList()) {
+ _mainPS.println("RtemsProcessWrapper *" + process.getName()
+ + "_wrapper;");
+ }
+ _mainPS.println();
+
+ _mainPS.println("#ifdef PRINTF_TO_DEBUG");
+ _mainPS.println("#undef printf");
+ _mainPS.println("#define printf(...) \\");
+ _mainPS.println(" do { \\");
+ _mainPS.println(" char _buffer[128]; \\");
+ _mainPS.println(" sprintf(_buffer, __VA_ARGS__); \\");
+ _mainPS.println(" SHOW_DEBUG((int)_buffer); \\");
+ _mainPS.println(" } while (0)");
+ _mainPS.println("#endif");
+ _mainPS.println();
+ _mainPS.println("#ifdef WORKLOAD_EXTRACT");
+ _mainPS.println("void callback(int code, int* arg, int size) "
+ + "{");
+ _mainPS.println(" long unsigned int time = get_cycle1();");
+ _mainPS.println(" Thread_Control *x = "
+ + "(Thread_Control*)arg;");
+ _mainPS.println(" SHOW_DEBUG(\"log callback\");");
+ _mainPS.println(" SHOW_DEBUG_INT((int)time);");
+ _mainPS.println(" SHOW_DEBUG_INT(x->Object.id);");
+ _mainPS.println("}");
+ _mainPS.println("#endif");
+ _mainPS.println();
+ _mainPS.println("rtems_id timer_sem_id;");
+ _mainPS.println();
+ //RTEMS init task
+ _mainPS.println("/**");
+ _mainPS.println(" *");
+ _mainPS.println(" */");
+ _mainPS.println("rtems_task Init(rtems_task_argument arg) {");
+
+ if (_ui.getRtemsBSP().equals("mparm")) {
+ // //////////////////// mparm /////////////////////////
+ int processCount = 0;
+
+ _mainPS.println(" rtems_id task_id;");
+ _mainPS.println(" rtems_status_code status;");
+ _mainPS.println();
+ _mainPS.println(" status = rtems_semaphore_create(rtems_build_name('c','s','e','m'), 1, RTEMS_BINARY_SEMAPHORE |RTEMS_NO_PRIORITY_CEILING |RTEMS_LOCAL |RTEMS_PRIORITY, 0,&timer_sem_id);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] Could not create semaphore (status %d).\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+
+
+ _mainPS.println();
+
+ _mainPS.println(" scratch_queue_autoinit_system();");
+ _mainPS.println();
+
+ _mainPS.println("#ifdef WORKLOAD_EXTRACT");
+ _mainPS.println(" rtems_monitor_register_callback"
+ + "(callback);");
+ for (Channel c : x.getChannelList()) {
+ _mainPS.println(" SHOW_DEBUG(\"log "
+ + "create_channel\");");
+ _mainPS.println(" SHOW_DEBUG(\"log " + c.getName()
+ + "\");");
+ _mainPS.println(" SHOW_DEBUG_INT((int)"
+ + (c.getSize() * c.getTokenSize()) + ");");
+ }
+ _mainPS.println("#endif");
+
+ //shaper process
+ _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+ _mainPS.println(" if ((get_id()-1) == shaper_PROCESSOR) "
+ + "{");
+ _mainPS.println(" rtems_name name = rtems_build_name"
+ +"('s', 's', '0', ' ');");
+ _mainPS.println();
+
+ // create pre task
+ _mainPS.println(" //one more init to prevent the"
+ + "blocking instatiation of scrach queue");
+ _mainPS.println(" status = rtems_task_create(");
+ _mainPS.println(" name,");
+ _mainPS.println(" 1,");
+ _mainPS.println(" RTEMS_MINIMUM_STACK_SIZE,");
+ _mainPS.println(" RTEMS_DEFAULT_MODES,");
+ _mainPS.println(" RTEMS_LOCAL,");
+ _mainPS.println(" &task_id, -1);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not create init shaper"
+ + "(status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println();
+
+ // start pre init
+ _mainPS.println(" status = rtems_task_start(task_id, "
+ + "shaping_init, arg);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not start init shaping"
+ + " (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println(" }");
+ _mainPS.println("#endif // QUEUE_BUFF_SHAPER");
+ _mainPS.println();
+
+ for (Process process : x.getProcessList()) {
+ _mainPS.println(" if (get_id() == "
+ + process.getName() + "_PROCESSOR) {");
+ _mainPS.println(" processor_init();");
+ _mainPS.println(" rtems_name name = "
+ + "rtems_build_name"
+ + "('p', 'i', 0x" + ++processCount
+ + ", ' ');");
+ _mainPS.println();
+
+ // create pre task
+ _mainPS.println(" //one more init to prevent the"
+ + "blocking instatiation of scrach queue");
+ _mainPS.println(" status = rtems_task_create(");
+ _mainPS.println(" name,");
+ _mainPS.println(" 1,");
+ _mainPS.println(" RTEMS_MINIMUM_STACK_SIZE"
+ + ",");
+ _mainPS.println(" RTEMS_DEFAULT_MODES,");
+ _mainPS.println(" RTEMS_LOCAL,");
+ _mainPS.println(" &task_id, -1);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) "
+ + "{");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not create init task["
+ + process.getName() + "] "
+ +"(status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println();
+
+ // start pre init
+ _mainPS.println(" status = rtems_task_start(task_id, "
+ + "rtems_" + process.getName()
+ + "_init, arg);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not start init task [ "
+ + process.getName()
+ + "] (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ /*
+ _mainPS.println(" rtems_" + process.getName()
+ + "_init(arg);");
+ _mainPS.println(" rtems_task_delete(RTEMS_SELF);");
+ */
+ _mainPS.println(" }");
+ _mainPS.println();
+ }
+
+ // shaper process
+ _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+ _mainPS.println(" if ((get_id()-1) == shaper_PROCESSOR) "
+ + "{");
+ _mainPS.println(" rtems_name name = rtems_build_name"
+ +"('s', 's', '0', ' ');");
+ _mainPS.println();
+
+ // create pre task
+ _mainPS.println(" //one more init to prevent the"
+ + "blocking instatiation of scrach queue");
+ _mainPS.println(" status = rtems_task_create(");
+ _mainPS.println(" name,");
+ _mainPS.println(" 128,");
+ _mainPS.println(" RTEMS_MINIMUM_STACK_SIZE,");
+ _mainPS.println(" RTEMS_DEFAULT_MODES,");
+ _mainPS.println(" RTEMS_LOCAL,");
+ _mainPS.println(" &task_id, -1);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not create init shaper"
+ +"(status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println();
+
+ // start pre init
+ _mainPS.println(" status = rtems_task_start(task_id, "
+ + "shaping_init, arg);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not start init shaping"
+ + " (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println(" }");
+ _mainPS.println("#endif // QUEUE_BUFF_SHAPER");
+ _mainPS.println();
+
+ _mainPS.println("if (number_of_processes[get_id() - 1]"
+ + " == 0) {");
+ _mainPS.println(" printf(\"No process on processor "
+ + "%d.\", get_id());");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println("}");
+ _mainPS.println();
+
+ _mainPS.println(" rtems_task_delete(RTEMS_SELF);");
+ _mainPS.println("}");
+ _mainPS.println();
+ // end of init
+
+ processCount = 0;
+ for (Process process : x.getProcessList()) {
+ String processName = process.getName();
+ _mainPS.println("void rtems_" + process.getName()
+ + "_init(rtems_task_argument arg) {");
+ _mainPS.println(" rtems_id task_id;");
+ _mainPS.println(" rtems_status_code status;");
+
+
+ _mainPS.println(" " + process.getName()
+ + "_wrapper = "
+ + "(RtemsProcessWrapper *)malloc"
+ + "(sizeof(RtemsProcessWrapper));");
+
+ int numOfOutports = process.getNumOfOutports();
+ int numOfInports = process.getNumOfInports();
+ if (numOfOutports > 0) {
+ _mainPS.println(" int* "
+ + process.getName()
+ + "_out_port_id = (int *)malloc("
+ + numOfOutports
+ + " * sizeof(int));");
+ _mainPS.println(" SCRATCH_QUEUE_PRODUCER **"
+ + process.getName()
+ + "_out_queue_id = "
+ + "(SCRATCH_QUEUE_PRODUCER **)"
+ + "malloc("
+ + numOfOutports
+ + "*sizeof(SCRATCH_QUEUE_PRODUCER));");
+ }
+
+ if (numOfInports > 0) {
+ _mainPS.println(" int *"
+ + process.getName()
+ + "_in_port_id = (int *)malloc("
+ + numOfInports
+ + " * sizeof(int));");
+ _mainPS.println(" SCRATCH_QUEUE_CONSUMER **"
+ + process.getName()
+ + "_in_queue_id = "
+ + "(SCRATCH_QUEUE_CONSUMER **)"
+ + "malloc("
+ + numOfOutports
+ + "*sizeof(SCRATCH_QUEUE_CONSUMER));");
+ }
+ _mainPS.println();
+
+ // create task
+ _mainPS.println(" status = rtems_task_create(");
+ _mainPS.println(" " + ++processCount + ",");
+ _mainPS.println(" 1,");
+ _mainPS.println(" RTEMS_MINIMUM_STACK_SIZE,");
+ _mainPS.println(" RTEMS_DEFAULT_MODES,");
+ _mainPS.println(" RTEMS_LOCAL,");
+ _mainPS.println(" &task_id, -1);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not create task["
+ + processName + "] "
+ +"(status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+
+ _mainPS.println("#ifdef WORKLOAD_EXTRACT");
+ _mainPS.println(" SHOW_DEBUG(\"log create_task\");");
+ _mainPS.println(" SHOW_DEBUG_INT(task_id);");
+ _mainPS.println(" SHOW_DEBUG(\"log " + processName + "\");");
+ for (Port port : process.getPortList()) {
+ Channel c = (Channel) port.getPeerResource();
+ if (port.isInPort()) {
+ _mainPS.println(" SHOW_DEBUG(\"log in_port\");");
+ _mainPS.println(" SHOW_DEBUG_INT((int)" + _portMap.get(port) + ");");
+ _mainPS.println(" SHOW_DEBUG(\"log " + c.getName() + "\");");
+ }
+ if (port.isOutPort()) {
+ _mainPS.println(" SHOW_DEBUG(\"log out_port\");");
+ _mainPS.println(" SHOW_DEBUG_INT((int)" + _portMap.get(port) + ");");
+ _mainPS.println(" SHOW_DEBUG(\"log " + c.getName() + "\");");
+ }
+ }
+ _mainPS.println("#endif");
+ _mainPS.println();
+
+ // connect ports to channels
+ HashMap<Channel, Integer> channel_map =
+ new HashMap<Channel, Integer>();
+ int channelCount = 1;
+ for (Channel c : x.getChannelList()) {
+ channel_map.put(c, channelCount++);
+ }
+ _mainPS.println();
+
+ // fill the wrapper, instantiate queues
+ int i = 0, j = 0;
+ for (Port port : process.getPortList()) {
+ Channel c = (Channel)(port.getPeerResource());
+ if (port.isInPort()) {
+ _mainPS.println(" " + processName + "_in_port_id["
+ + i + "] = "
+ + _portMap.get(port) + ";");
+ _mainPS.println(" " + processName
+ + "_in_queue_id["
+ + i + "] = ");
+ _mainPS.println("#if defined (QUEUE_BUFF_IN_PRODUCER) || (QUEUE_BUFF_IN_PRODUCER_DMA)");
+ _mainPS.println(" scratch_queue_autoinit_consumer("
+ + channel_map.get(c)
+ + ", true);");
+ _mainPS.println("#elif defined (QUEUE_BUFF_IN_CONSUMER) || (QUEUE_BUFF_IN_CONSUMER_DMA)");
+ _mainPS.println(" scratch_queue_autoinit_consumer("
+ + c.getOrigin().getName()
+ + "_PROCESSOR, "
+ + channel_map.get(c) + ", "
+ + c.getSize() + ", "
+ + c.getTokenSize()
+ + ");");
+ _mainPS.println("#elif defined (QUEUE_BUFF_IN_SHARDMEM)");
+ _mainPS.println(" scratch_queue_autoinit_consumer("
+ + channel_map.get(c)
+ + ", true);");
+ _mainPS.println("#elif defined (QUEUE_BUFF_SHAPER)");
+ _mainPS.println(" scratch_queue_autoinit_consumer("
+ + channel_map.get(c)
+ + ");");
+ _mainPS.println("#endif");
+
+
+ i++;
+ } else if (port.isOutPort()) {
+ _mainPS.println(" " + processName+"_out_port_id["
+ + j + "] = "
+ + _portMap.get(port) + ";");
+ _mainPS.println(" " + processName
+ + "_out_queue_id["
+ + j + "] = ");
+
+ _mainPS.println("#if defined (QUEUE_BUFF_IN_PRODUCER) || (QUEUE_BUFF_IN_PRODUCER_DMA)");
+ _mainPS.println(" scratch_queue_autoinit_producer("
+ + c.getTarget().getName()
+ + "_PROCESSOR,"
+ + channel_map.get(c) + ", "
+ + c.getSize() + ", "
+ + c.getTokenSize()
+ + ", 0);");
+ _mainPS.println("#elif defined (QUEUE_BUFF_IN_CONSUMER) || (QUEUE_BUFF_IN_CONSUMER_DMA)");
+ _mainPS.println(" scratch_queue_autoinit_producer("
+ + channel_map.get(c)
+ + ", true);");
+ _mainPS.println("#elif defined (QUEUE_BUFF_IN_SHARDMEM)");
+ _mainPS.println(" scratch_queue_autoinit_producer("
+ + c.getTarget().getName()
+ + "_PROCESSOR,"
+ + channel_map.get(c) + ", "
+ + c.getSize() + ", "
+ + c.getTokenSize()
+ + ", 1);");
+ _mainPS.println("#elif defined (QUEUE_BUFF_SHAPER)");
+ _mainPS.println(" scratch_queue_autoinit_producer("
+ + c.getTarget().getName()
+ + "_PROCESSOR,"
+ + channel_map.get(c) + ", "
+ + c.getSize() + ", "
+ + c.getTokenSize()
+ + ");");
+ _mainPS.println("#endif");
+
+ j++;
+ }
+ }
+
+ if (numOfInports > 0) {
+ _mainPS.println(" " + processName
+ + "_wrapper->in_port_id = "
+ + processName
+ + "_in_port_id;");
+ _mainPS.println(" " + processName
+ + "_wrapper->in_queue_id = "
+ + processName
+ + "_in_queue_id;");
+ _mainPS.println(" " + processName
+ + "_wrapper->number_of_in_ports = "
+ + numOfInports + ";");
+ }
+
+ if (numOfOutports > 0) {
+ _mainPS.println(" " + processName
+ + "_wrapper->out_port_id = "
+ + processName
+ + "_out_port_id;");
+ _mainPS.println(" " + processName
+ + "_wrapper->out_queue_id = "
+ + processName
+ + "_out_queue_id;");
+ _mainPS.println(" " + processName
+ + "_wrapper->number_of_out_ports = "
+ + numOfOutports + ";");
+ }
+
+ _mainPS.println(" " + processName
+ + "_wrapper->is_detached = 0;");
+
+ int priority = 127;
+ if (mapping != null) {
+ Schedule s = mapping.getScheduleByResource(
+ process.getProcessor().getName());
+ if (s != null && s.getSchedPolicy() ==
+ SchedulingPolicy.FIXEDPRIORITY) {
+ ScheduleEntry e = s.getScheduleEntry(
+ process.getName());
+ if (e != null) {
+ String value = e.getCfgValue("priority");
+ if (value != null) {
+ priority = Integer.parseInt(value);
+ }
+ }
+ }
+ }
+ _mainPS.println(" " + processName
+ + "_wrapper->priority = " + priority + ";");
+
+ _mainPS.println(" " + processName
+ + "_wrapper->name = (char *)malloc(("
+ + processName.length()
+ + " + 1) * sizeof(char));");
+ _mainPS.println(" strcpy(" + processName
+ + "_wrapper->name, " + "\""
+ + processName + "\");");
+ _mainPS.println();
+
+ _mainPS.println(" status = rtems_task_start("
+ + "task_id, " + process.getBasename()
+ + "_task, " + "(rtems_task_argument)"
+ + process.getName() + "_wrapper);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) "
+ + "{");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not start " + process.getName()
+ + " (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println(" rtems_task_delete(RTEMS_SELF);");
+ _mainPS.println("}");
+ _mainPS.println();
+ _mainPS.println();
+ }
+ } else if (_ui.getRtemsBSP().equals("pc386")) {
+ // //////////////////// pc386 ////////////////////////
+ _mainPS.println(" int j;");
+ _mainPS.println(" rtems_id task_id[" +
+ + (x.getProcessList().size() + 1) + "];");
+ _mainPS.println(" rtems_status_code status;");
+ _mainPS.println();
+
+ //initialize process-specific information
+ for (Process process : x.getProcessList()) {
+ int numberOfPorts = x.getProcess(process.getName())
+ .getPortList().size();
+ _mainPS.println(" " + process.getName()
+ + "_wrapper = "
+ + "malloc(sizeof(RtemsProcessWrapper));");
+ _mainPS.println(" int *"
+ + process.getName() + "_port_id = malloc("
+ + numberOfPorts + " * sizeof(int));");
+ _mainPS.println(" int *"
+ + process.getName()
+ + "_port_queue_id = malloc("
+ + numberOfPorts + " * sizeof(int));");
+ _mainPS.println();
+ }
+
+ //create a task for each process
+ _mainPS.println(" for (j = 0; j < "
+ + (x.getProcessList().size()+1) + "; j++) {");
+ _mainPS.println(" status = rtems_task_create(");
+ _mainPS.println(" j + 1,");
+ _mainPS.println(" 128,");
+ _mainPS.println(" RTEMS_MINIMUM_STACK_SIZE,");
+ _mainPS.println(" RTEMS_DEFAULT_MODES,");
+ _mainPS.println(" RTEMS_DEFAULT_ATTRIBUTES,");
+ _mainPS.println(" &(task_id[j]));");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not create task[%d] (status %d).\\n\", "
+ + "(int)j, status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println(" }");
+ _mainPS.println();
+
+ //create a message queue for each channel
+ int j = 0;
+ for (Channel channel : x.getChannelList()) {
+ _mainPS.println(" status = "
+ + "rtems_message_queue_create(");
+ _mainPS.println(" " + (j + 1) + ",");
+ _mainPS.println(" " + channel.getSize()
+ + ",");
+ _mainPS.println(" 1,");
+ _mainPS.println(" RTEMS_DEFAULT_ATTR"
+ + "IBUTES,");
+ _mainPS.println(" &queue_id[" + j + "]);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) "
+ + "{");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not create queue[" + j
+ + "] (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println();
+ j++;
+ }
+
+ //connect ports to channels
+ HashMap<Channel, Integer> channel_map =
+ new HashMap<Channel, Integer>();
+ j = 0;
+ for (Channel c : x.getChannelList()) {
+ channel_map.put(c, j++);
+ }
+
+ for (Process process : x.getProcessList()) {
+ String processName = process.getName();
+ int i = 0;
+ for (Port port : process.getPortList()) {
+ Channel c = (Channel)(port.getPeerResource());
+
+ _mainPS.println(" " + processName + "_port_id["
+ + i + "] = "
+ + _portMap.get(port) + ";");
+ _mainPS.println(" " + processName
+ + "_port_queue_id[" + i + "] = queue_id["
+ + channel_map.get(c) + "];");
+ i++;
+ }
+ _mainPS.println(" " + processName
+ + "_wrapper->port_id = " + processName
+ + "_port_id;");
+ _mainPS.println(" " + processName
+ + "_wrapper->port_queue_id = "
+ + processName
+ + "_port_queue_id;");
+ _mainPS.println(" " + processName
+ + "_wrapper->number_of_ports = "
+ + i + ";");
+ _mainPS.println(" " + processName
+ + "_wrapper->is_detached = 0;");
+ _mainPS.println(" " + processName
+ + "_wrapper->name = malloc(("
+ + processName.length()
+ + " + 1) * sizeof(char));");
+ _mainPS.println(" strcpy(" + processName
+ + "_wrapper->name, " + "\""
+ + processName + "\");");
+ _mainPS.println();
+ }
+
+ //start cleanup task
+ _mainPS.println(" printf(\"[init ] "
+ + "Start cleanup.\\n\");");
+ _mainPS.println(" status = rtems_task_start(task_id[0], "
+ + "CleanupTask, 0);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) {");
+ _mainPS.println(" printf(\"[init ] Could not start "
+ + "cleanup (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println();
+
+ //start processes
+ j = 1;
+ for (Process process : x.getProcessList()) {
+ _mainPS.println(" printf(\"[init ] Start "
+ + process.getName() + ".\\n\");");
+ _mainPS.println(" status = rtems_task_start(task_id["
+ + j + "], " + process.getBasename()
+ + "_task, "
+ + "(rtems_task_argument)"
+ + process.getName()
+ + "_wrapper);");
+ _mainPS.println(" if (status != RTEMS_SUCCESSFUL) "
+ + "{");
+ _mainPS.println(" printf(\"[init ] "
+ + "Could not start " + process.getName()
+ + " (status %d).\\n\", status);");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println(" }");
+ _mainPS.println();
+ j++;
+ }
+
+ _mainPS.println(" printf(\"[init ] Done.\\n\");");
+ _mainPS.println(" rtems_task_delete(RTEMS_SELF);");
+ _mainPS.println("}");
+ _mainPS.println();
+
+ _mainPS.println("rtems_task CleanupTask(rtems_task_argument "
+ + "argument) {");
+ _mainPS.println(" printf(\"[cleanup ] Started.\\n\");");
+ _mainPS.println(" do {");
+ _mainPS.println(" rtems_task_wake_after(0);");
+ _mainPS.println(" } while (");
+ j = 0;
+ for (Process process : x.getProcessList()) {
+ _mainPS.print(" !("
+ + process.getName()
+ + "_wrapper->is_detached)");
+ j++;
+ if (j < x.getProcessList().size()) {
+ _mainPS.println(" || ");
+ } else {
+ _mainPS.println(");");
+ }
+ }
+ _mainPS.println();
+ _mainPS.println(" printf(\"[cleanup ] Shutdown.\\n\");");
+ _mainPS.println(" rtems_shutdown_executive(0);");
+ _mainPS.println("}");
+ _mainPS.println();
+ }
+ }
+ catch (Exception e) {
+ System.out.println("RtemsModuleVisitor: exception occured: "
+ + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ * @param x process that needs to be processed
+ */
+ public void visitComponent(Process x) {
+ }
+
+ /**
+ *
+ * @param x channel that needs to be processed
+ */
+ public void visitComponent(Channel x) {
+ }
+
+ protected CodePrintStream _mainPS = null;
+ protected String _dir = null;
+ protected HashMap<Port, Integer> _portMap;
+}