From eab763b8866fbd3f342f229d8824a570b8bea0b8 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Fri, 17 Nov 2017 14:25:05 +0000
Subject: [PATCH] Temporary support for single RasPi execution unit
 deployments. refs 3079

---
 .../generator/executable/MainGenerator.java   | 12 +++-
 .../executable/RaspberryPIExecutable.java     |  2 +-
 .../generator/templates/MakedefsFile.stg      |  4 +-
 .../generator/templates/RasPiCTemplates.java  | 14 +++++
 .../templates/SingleUnitMainFile.stg          | 61 +++++++++++++++++++
 5 files changed, 89 insertions(+), 4 deletions(-)
 create mode 100644 org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg

diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java
index 7ffc80ed..925b6555 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/MainGenerator.java
@@ -18,6 +18,7 @@ $Id$
 package org.fortiss.af3.platform.raspberry.generator.executable;
 
 import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getMainCFile;
+import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getSingleUnitMainCFile;
 
 import java.util.List;
 
@@ -78,7 +79,7 @@ class MainGenerator {
 		}
 	}
 
-	/** Creates the main.c file. */
+	/** Creates the main.c file for deployments with distributed execution units. */
 	public AbstractUnit createMain() {
 		String includes = createIncludes(deployedComponents, deployedPorts);
 		// TODO: compute syncBox size
@@ -91,6 +92,15 @@ class MainGenerator {
 				WAITING_SLEEP_IN_MICROS, includes, syncBoxSize, "// TODO\n", initCode, workerCode);
 	}
 
+	/** Creates the main.c file for deployments with a single execution units. */
+	public AbstractUnit createSingleUnitMain() {
+		String includes = createIncludes(deployedComponents, deployedPorts);
+		String initCode = createInitCode(deployedComponents);
+		String workerCode = createWorkerCode(deployedComponents, deployedPorts);
+		return getSingleUnitMainCFile(executionUnit.getName(), executionUnit.getCycleTime(),
+				includes, initCode, workerCode);
+	}
+
 	/** Creates the includes of the system headers. */
 	private String createIncludes(List<Pair<ExecutionUnit, Component>> deployedComponents,
 			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
index 070ede94..3b13ce75 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
@@ -109,7 +109,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 		CSourcePackage srcGenPack = (CSourcePackage)sourcePackage.getSrcGenPackage();
 		MainGenerator mg =
 				new MainGenerator(modelElement, deployedComponents, deployedPorts, context);
-		srcGenPack.addUnit(mg.createMain());
+		srcGenPack.addUnit(mg.createSingleUnitMain());
 	}
 
 	/** Adds the build process files: configure and Makedefs. */
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/MakedefsFile.stg b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/MakedefsFile.stg
index a0bc6cbc..41cca0b8 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/MakedefsFile.stg
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/MakedefsFile.stg
@@ -22,8 +22,8 @@ ifndef CROSSLD
 endif
 
 # The flags which are passed to the compiler and the linker.
-CCFLAGS+=-std=c99 -Wall -pedantic -c \${patsubst %,-I%,\${subst :, ,\${IPATH}}}
-LDFLAGS+=-std=c99 -Wall -pedantic \${patsubst %,-L%,\${subst :, ,\${LPATH}}} 
+CCFLAGS+=-std=gnu99 -Wall -pedantic -c \${patsubst %,-I%,\${subst :, ,\${IPATH}}}
+LDFLAGS+=-std=gnu99 -Wall -pedantic \${patsubst %,-L%,\${subst :, ,\${LPATH}}} 
 LIBFLAGS=\${patsubst %,-l%,\${subst :, ,\${LIBS}}}
 
 # The default rules, i.e. the entry point.
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java
index d55a37e6..81490d83 100644
--- a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/RasPiCTemplates.java
@@ -60,6 +60,20 @@ public final class RasPiCTemplates {
 		return unit;
 	}
 
+	/** Returns the 'main.c' file configured using the given arguments. */
+	public static AbstractUnit getSingleUnitMainCFile(String unitName, int cycletimeInMillis,
+			String systemIncludes, String systemInitCode, String workerCode) {
+		StringTemplate template = makeTemplate("SingleUnitMainFile.stg", "MainFile");
+		template.setAttribute("UNIT_NAME", unitName);
+		template.setAttribute("CYCLE_TIME_IN_MILLIS", cycletimeInMillis);
+		template.setAttribute("SYSTEM_INCLUDES", systemIncludes);
+		template.setAttribute("SYSTEM_INIT_CODE", systemInitCode);
+		template.setAttribute("WORKER_CODE", workerCode);
+		StaticContentSourceUnit unit =
+				createStaticContentSourceUnit("main.c", template.toString(), false);
+		return unit;
+	}
+
 	/** Returns the '.project' file used for Eclipse project. */
 	public static AbstractUnit getEclipseProjectFile(String projectName) {
 		StringTemplate template = makeTemplate("ProjectFile.stg", "ProjectFile");
diff --git a/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg
new file mode 100644
index 00000000..53f92dfd
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/trunk/src/org/fortiss/af3/platform/raspberry/generator/templates/SingleUnitMainFile.stg
@@ -0,0 +1,61 @@
+group MainFile;
+
+MainFile(UNIT_NAME,
+	CYCLE_TIME_IN_MILLIS,
+	SYSTEM_INCLUDES,
+	SYSTEM_INIT_CODE,
+	WORKER_CODE) ::= <<
+// due to current data dictionary declaration of GENTYPE_boolean
+// system include must be first
+$SYSTEM_INCLUDES$
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <af3.h>
+#include <debugprint.h>
+#include <timeutil.h>
+
+#define STOP_AT_LOGICAL_CLOCK			(uint64_t)0 // run infinitely
+
+#define BRICK_HOST "localhost"
+#define BRICK_PORT 4223
+
+static uint64_t step = 0;
+
+static void worker() {
+	step++;
+	$WORKER_CODE$
+}
+
+int global_debug_print_level = DEBUG_PRINT_LEVEL_NONE;
+
+static uint64_t start_time_in_micros;
+static uint64_t delta_time_in_micros;
+static uint64_t local_logical_clock;
+
+int main(int argc, char** argv) {
+	// set AF3 unit name used when communicating with CC
+	af3_set_execution_unit_identifier("$UNIT_NAME$");
+	// TODO: initialize ControlCenter connection
+
+	$SYSTEM_INIT_CODE$
+	start_time_in_micros = time_util_get_current_micros();
+	while(local_logical_clock != STOP_AT_LOGICAL_CLOCK) {
+		worker();		
+		delta_time_in_micros = time_util_get_elapsed_micros_since(start_time_in_micros);
+		if(delta_time_in_micros > $CYCLE_TIME_IN_MILLIS$ * MILLIS_IN_MICROS) {
+			debug_print(DEBUG_PRINT_LEVEL_FEW, "Remaining cycle time negative! Deadline broken. Shutting down.\n");
+			return -1;
+		}
+		uint64_t remaining_time_in_micros = $CYCLE_TIME_IN_MILLIS$ * MILLIS_IN_MICROS - delta_time_in_micros;
+		time_util_sleep_micros(remaining_time_in_micros);
+		// increase logical clock
+		local_logical_clock++;
+		// increase start time
+		start_time_in_micros += $CYCLE_TIME_IN_MILLIS$ * MILLIS_IN_MICROS;
+	}
+	return 0;
+}
+>>
-- 
GitLab