From 71eb4f676641be0449b72eb0464fdd5a7ac84836 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Fri, 25 May 2018 16:45:26 +0200
Subject: [PATCH] Rebuilt single RasPi unit generator with new architecture.

Signed-off-by: Florian Hoelzl <hoelzl@fortiss.org>
---
 .../raspberry/generator/executable/.ratings   |    6 +-
 .../executable/PWMActuatorExecutable.java     |   42 +-
 .../executable/RaspberryPIExecutable.java     |   23 +-
 .../executable/SingleUnitMainGenerator.java   | 1086 +++++------------
 .../generator/executable/framework/.ratings   |    6 +-
 .../framework/IInitializationExecutable.java  |   35 +
 .../framework/IReadableExecutable.java        |   34 +
 ...> ISingletonInitializationExecutable.java} |   15 +-
 .../framework/ITerminationExecutable.java     |   28 +
 .../framework/IWriteableExecutable.java       |   34 +
 .../generator/executable/gamepad/.ratings     |    6 +-
 .../gamepad/ButtonExecutableBase.java         |   16 +-
 .../gamepad/GamepadExecutableBase.java        |   19 +-
 .../gamepad/StickExecutableBase.java          |   16 +-
 .../generator/executable/rumblepad/.ratings   |    6 +-
 .../rumblepad/ButtonExecutableBase.java       |   16 +-
 .../rumblepad/RumblepadExecutableBase.java    |   19 +-
 .../rumblepad/StickExecutableBase.java        |   16 +-
 18 files changed, 582 insertions(+), 841 deletions(-)
 create mode 100644 org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IInitializationExecutable.java
 create mode 100644 org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IReadableExecutable.java
 rename org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/{ISingletonInitializableExecutable.java => ISingletonInitializationExecutable.java} (78%)
 create mode 100644 org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ITerminationExecutable.java
 create mode 100644 org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IWriteableExecutable.java

diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/.ratings b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/.ratings
index f8248be7..582e164b 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/.ratings
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/.ratings
@@ -4,6 +4,6 @@ CanTransmissionCatalog.java ec4637eda80234429a9f382a37713588a0fbb83a RED
 ConsoleOutputExecutable.java 5b8c50f2236ad49958a0a0b599a7e60265a6fc06 YELLOW
 HeaderCopyGenerator.java 18239a3adae35256e32dad19df9d8f38acbf7e66 RED
 MultiUnitMainGenerator.java 458754b89c2d79db3fee08baa444424772e40fb7 RED
-PWMActuatorExecutable.java 9068846c7ff04c034da6493067fcebf73051de98 YELLOW
-RaspberryPIExecutable.java f94071537e9596817e7895cf79e4202d24224087 RED
-SingleUnitMainGenerator.java e1df0d82804fd0622b97ecde827844da30370e14 RED
+PWMActuatorExecutable.java 3273e75ecbb8e41984e8b66cfe8f16bc87256150 YELLOW
+RaspberryPIExecutable.java cafff8199da9cc59688289c9c26097e6872e9702 RED
+SingleUnitMainGenerator.java 9ae8b9a5d40c1415720a7bcad2378376474ca70b RED
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java
index 9068846c..3273e75e 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/PWMActuatorExecutable.java
@@ -15,21 +15,16 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.funcCall;
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.intConst;
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.stringConst;
-
 import org.fortiss.af3.component.model.OutputPort;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.language.executable.IInitializableExecutable;
-import org.fortiss.af3.platform.language.executable.ITerminatableExecutable;
-import org.fortiss.af3.platform.language.executable.IWritableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IInitializationExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.ITerminationExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IWriteableExecutable;
 import org.fortiss.af3.platform.raspberry.generator.executable.library.PiHALLibraryExecutableBase;
 import org.fortiss.af3.platform.raspberry.model.ActuatorPWM;
 
 /** Executable for {@link ActuatorPWM}. */
 public class PWMActuatorExecutable extends PiHALLibraryExecutableBase<ActuatorPWM> implements
-		IInitializableExecutable, IWritableExecutable, ITerminatableExecutable {
+		IInitializationExecutable, IWriteableExecutable, ITerminationExecutable {
 	/** Constructor. */
 	public PWMActuatorExecutable(ActuatorPWM modelElement) {
 		super(modelElement);
@@ -37,25 +32,38 @@ public class PWMActuatorExecutable extends PiHALLibraryExecutableBase<ActuatorPW
 
 	/** {@inheritDoc} */
 	@Override
-	public IExpressionTerm getInitialization() {
-		return funcCall("temp_actuator_initialize", stringConst("/dev/ttyACM0"));
+	public String getHeaderFileName() {
+		return "temp_actuator.h";
 	}
 
 	/** {@inheritDoc} */
 	@Override
-	public IExpressionTerm getTermination() {
-		return funcCall("temp_actuator_terminate");
+	public String getVariableDeclaration(String prefix) {
+		return "int " + prefix + "actuator_pwm = -1;\n";
 	}
 
 	/** {@inheritDoc} */
 	@Override
-	public IExpressionTerm getValueWriteAccessor(OutputPort logicalSignal, IExpressionTerm value) {
-		return funcCall("temp_actuator_set_target", intConst(modelElement.getChannelID()), value);
+	public String getInitializationCode(String prefix) {
+		return prefix + "actuator_pwm = temp_actuator_initialize(\"/dev/ttyACM0\");\n";
 	}
 
 	/** {@inheritDoc} */
 	@Override
-	public String getHeaderFileName() {
-		return "temp_actuator.h";
+	public String getTerminationCode(String prefix) {
+		return "temp_actuator_terminate();\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getWriteCode(String prefix, OutputPort logicalSignal, String value) {
+		return "temp_actuator_set_target(" + prefix + "actuator_pwm, " +
+				modelElement.getChannelID() + ", " + value + ");\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getNoValWriteCode(String prefix, OutputPort logicalSignal) {
+		return null;
 	}
 }
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
index f9407153..cafff819 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/RaspberryPIExecutable.java
@@ -28,8 +28,10 @@ import static org.fortiss.tooling.kernel.utils.TransformationUtils.createTransfo
 import static org.fortiss.tooling.kernel.utils.TransformationUtils.createTransformedObjectWithoutExceptionFor;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.conqat.lib.commons.collections.Pair;
@@ -84,6 +86,9 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 	private CanTransmissionCatalog canCatalog;
 	/** The list of atomic components deployed on this execution unit. */
 	private List<Component> atomics = new ArrayList<>();
+	/** The map from platform elements to executables. */
+	private Map<PlatformConnectorUnit, ExecutableBase<?>> platformConnector2ExecutableBase =
+			new HashMap<>();
 
 	// code generator output
 	/** The C source package produced by this generator. */
@@ -105,10 +110,10 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 		try {
 			addEclipseCProjectFiles();
 			addConfigureAndMakedefsFiles();
-			addPlatformElementsCode(deployedPorts);
+			Set<String> headers = addPlatformElementsCode(deployedPorts);
 			addDataDictionaryCode();
 			addLogicalComponentCode(deployedComponents);
-			addMainFile(deployedComponents, deployedPorts);
+			addMainFile(deployedComponents, deployedPorts, headers);
 		} catch(Exception ex) {
 			error(AF3PlatformRaspberryActivator.getDefault(), ex.getMessage(), ex);
 			ex.printStackTrace();
@@ -116,8 +121,12 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 		return generatorResult;
 	}
 
-	/** Adds the libraries and header files required by the used platform elements. */
-	private void addPlatformElementsCode(List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
+	/**
+	 * Adds the libraries and header files required by the used platform elements and returns the
+	 * set of header file names.
+	 */
+	private Set<String> addPlatformElementsCode(
+			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
 		Set<String> includedHeaders = new HashSet<>();
 		Set<String> includedSources = new HashSet<>();
 		Set<String> includedLibraries = new HashSet<>();
@@ -125,6 +134,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 			PlatformConnectorUnit pcu = pair.getFirst();
 			ExecutableBase<?> executable =
 					createTransformedObjectWithoutExceptionFor(pcu, ExecutableBase.class, context);
+			platformConnector2ExecutableBase.put(pcu, executable);
 			if(executable instanceof IRasPiHeaderExecutable) {
 				IRasPiHeaderExecutable headerExec = (IRasPiHeaderExecutable)executable;
 				if(!includedHeaders.contains(headerExec.getHeaderFileName())) {
@@ -153,6 +163,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 				// ignore library file, since it is already included
 			}
 		}
+		return includedHeaders;
 	}
 
 	/** Initializes the generator result source package. */
@@ -228,7 +239,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 
 	/** Creates the main file by using the {@link SingleUnitMainGenerator} helper class. */
 	private void addMainFile(List<Pair<ExecutionUnit, Component>> deployedComponents,
-			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
+			List<Pair<PlatformConnectorUnit, Port>> deployedPorts, Set<String> headers) {
 		CSourcePackage srcGenPack = (CSourcePackage)generatorResult.getSrcGenPackage();
 		if(canCatalog != null) {
 			MultiUnitMainGenerator mg =
@@ -238,7 +249,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
 		} else {
 			SingleUnitMainGenerator mg =
 					new SingleUnitMainGenerator(modelElement, deployedComponents, deployedPorts,
-							context);
+							platformConnector2ExecutableBase, headers, context);
 			srcGenPack.addUnit(mg.createSingleUnitMain());
 		}
 	}
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/SingleUnitMainGenerator.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/SingleUnitMainGenerator.java
index e1df0d82..9ae8b9a5 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/SingleUnitMainGenerator.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/SingleUnitMainGenerator.java
@@ -18,7 +18,10 @@ package org.fortiss.af3.platform.raspberry.generator.executable;
 import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getSingleUnitMainCFile;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.conqat.lib.commons.collections.Pair;
 import org.fortiss.af3.component.model.Component;
@@ -26,154 +29,52 @@ import org.fortiss.af3.component.model.InputPort;
 import org.fortiss.af3.component.model.OutputPort;
 import org.fortiss.af3.component.model.Port;
 import org.fortiss.af3.generator.common.model.source.AbstractUnit;
+import org.fortiss.af3.platform.language.executable.ExecutableBase;
 import org.fortiss.af3.platform.model.ExecutionUnit;
 import org.fortiss.af3.platform.model.PlatformConnectorUnit;
 import org.fortiss.af3.platform.model.Receiver;
 import org.fortiss.af3.platform.model.Transmitter;
-import org.fortiss.af3.platform.raspberry.model.ActuatorPWM;
-import org.fortiss.af3.platform.raspberry.model.ConsoleOutput;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IInitializationExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IReadableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.ISingletonInitializationExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IWriteableExecutable;
 import org.fortiss.af3.platform.raspberry.model.RaspberryPi;
-import org.fortiss.af3.platform.raspberry.model.brick.AccelerationXSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.AccelerationYSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.AccelerationZSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.ActuatorDigits;
-import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityXSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityYSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.AngularVelocityZSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.LEDButtonBActuator;
-import org.fortiss.af3.platform.raspberry.model.brick.LEDButtonGActuator;
-import org.fortiss.af3.platform.raspberry.model.brick.LEDButtonRActuator;
-import org.fortiss.af3.platform.raspberry.model.brick.LaserRangeSensor;
-import org.fortiss.af3.platform.raspberry.model.brick.UIDUnit;
-import org.fortiss.af3.platform.raspberry.model.brick.UltraSonicSensor;
-import org.fortiss.af3.platform.raspberry.model.camera.CameraDetectionStateLeft;
-import org.fortiss.af3.platform.raspberry.model.camera.CameraDetectionStateRight;
-import org.fortiss.af3.platform.raspberry.model.camera.CameraDistanceLeft;
-import org.fortiss.af3.platform.raspberry.model.camera.CameraDistanceRight;
-import org.fortiss.af3.platform.raspberry.model.camera.CameraYawAngle;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Button1;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Button2;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Button3;
-import org.fortiss.af3.platform.raspberry.model.gamepad.Button4;
-import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL2;
-import org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR2;
-import org.fortiss.af3.platform.raspberry.model.gamepad.GamepadReceiverBase;
-import org.fortiss.af3.platform.raspberry.model.motorcontrol.MotorControlInput;
-import org.fortiss.af3.platform.raspberry.model.motorcontrol.MotorControlOutput;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonA;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonB;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonHome;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonSelect;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonStart;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonX;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonY;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadDown;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadLeft;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadRight;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.DPadUp;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.L2_Position;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.R2_Position;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.RumbleMagnitudeStrong;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.RumbleMagnitudeWeak;
-import org.fortiss.af3.platform.raspberry.model.rumblepad.RumblepadReceiverBase;
 import org.fortiss.tooling.kernel.extension.data.ITransformationContext;
 
 /** Separate class for generating the main.c file for deployments ion single {@link RaspberryPi}. */
 class SingleUnitMainGenerator {
-	private static final int WAITING_SLEEP_IN_MICROS = 250;
+	/** The current execution unit. */
 	private RaspberryPi executionUnit;
+	/** The deployed components. */
 	private List<Pair<ExecutionUnit, Component>> deployedComponents;
+	/** The deployed ports. */
 	private List<Pair<PlatformConnectorUnit, Port>> deployedPorts;
+	/** The transformation context. */
 	private ITransformationContext context;
-
-	/** LED_Button UIDs to RGB value array. */
-	private HashMap<String, String[]> ledButtons = new HashMap<>();
-
-	/** LED_Button UIDs to RGB local variable array. */
-	private HashMap<String, String[]> ledButtonsLocalVariable = new HashMap<>();
-
-	private boolean useCamera;
-	private boolean useGamepad;
-	private boolean useRumblepad;
-	private boolean useDigits;
-	private boolean useLEDButton;
-	private boolean usePWM;
-	private boolean useUS;
-	private boolean useLaser;
-	private boolean useACC;
-	private boolean useConsole;
-	private boolean useRumble;
-	private OutputPort rumbleWeakPort = null;
-	private OutputPort rumbleStrongPort = null;
-	private int nrOfUsSensors = 0;
-	private boolean useVesc;
+	/** The set of platform header files to be included. */
+	private Set<String> headers;
+	/** The map from platform elements to executables. */
+	private Map<PlatformConnectorUnit, ExecutableBase<?>> platformConnector2ExecutableBase =
+			new HashMap<>();
 
 	/** Constructor. */
 	public SingleUnitMainGenerator(RaspberryPi executionUnit,
 			List<Pair<ExecutionUnit, Component>> deployedComponents,
-			List<Pair<PlatformConnectorUnit, Port>> deployedPorts, ITransformationContext context) {
+			List<Pair<PlatformConnectorUnit, Port>> deployedPorts,
+			Map<PlatformConnectorUnit, ExecutableBase<?>> platformConnector2ExecutableBase,
+			Set<String> headers, ITransformationContext context) {
 		this.executionUnit = executionUnit;
 		this.deployedComponents = deployedComponents;
 		this.deployedPorts = deployedPorts;
+		this.headers = headers;
 		this.context = context;
-		for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
-			if(!useGamepad && (p.getFirst() instanceof GamepadReceiverBase)) {
-				useGamepad = true;
-			}
-			if(!useRumblepad && p.getFirst() instanceof RumblepadReceiverBase ||
-					p.getFirst() instanceof RumbleMagnitudeWeak ||
-					p.getFirst() instanceof RumbleMagnitudeStrong) {
-				useRumblepad = true;
-			}
-			if(!usePWM && p.getFirst() instanceof ActuatorPWM) {
-				usePWM = true;
-			}
-			if(!useUS && p.getFirst() instanceof UltraSonicSensor) {
-				useUS = true;
-			}
-			if(!useLaser && p.getFirst() instanceof LaserRangeSensor) {
-				useLaser = true;
-			}
-			if(!useDigits && p.getFirst() instanceof ActuatorDigits) {
-				useDigits = true;
-			}
-			if((p.getFirst() instanceof LEDButtonRActuator ||
-					p.getFirst() instanceof LEDButtonGActuator || p.getFirst() instanceof LEDButtonBActuator)) {
-				extractRGBforLEDButton(p);
-				useLEDButton = true;
-
-			}
-			if(!useACC &&
-					(p.getFirst() instanceof AccelerationXSensor ||
-							p.getFirst() instanceof AccelerationYSensor ||
-							p.getFirst() instanceof AccelerationZSensor ||
-							p.getFirst() instanceof AngularVelocityXSensor ||
-							p.getFirst() instanceof AngularVelocityYSensor || p.getFirst() instanceof AngularVelocityZSensor)) {
-				useACC = true;
-			}
-			if(!useConsole && p instanceof ConsoleOutput) {
-				useConsole = true;
-			}
-
-			if(!useVesc &&
-					(p.getFirst() instanceof MotorControlOutput || p.getFirst() instanceof MotorControlInput)) {
-				useVesc = true;
-			}
-
-			if(!useCamera &&
-					(p.getFirst() instanceof CameraYawAngle ||
-							p.getFirst() instanceof CameraDistanceLeft ||
-							p.getFirst() instanceof CameraDistanceRight || p.getFirst() instanceof CameraDetectionStateLeft) ||
-					p.getFirst() instanceof CameraDetectionStateRight) {
-				useCamera = true;
-			}
-		}
+		this.platformConnector2ExecutableBase.putAll(platformConnector2ExecutableBase);
 	}
 
 	/** 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 includes = createIncludes();
+		String initCode = createInitCode();
 		String sensorVariables = createVariables(deployedComponents, deployedPorts);
 		String workerCode = createWorkerCode(deployedComponents, deployedPorts);
 		return getSingleUnitMainCFile(executionUnit.getName(), executionUnit.getCycleTime(),
@@ -181,47 +82,18 @@ class SingleUnitMainGenerator {
 	}
 
 	/** Creates the includes of the system headers. */
-	private String createIncludes(List<Pair<ExecutionUnit, Component>> deployedComponents,
-			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
+	private String createIncludes() {
+		// create includes for logical components
 		StringBuilder sb = new StringBuilder();
 		for(Pair<ExecutionUnit, Component> p : deployedComponents) {
 			Component c = p.getSecond();
 			sb.append("#include <" + c.getName() + "_ID_" + c.getId() + ".h>\n");
 		}
-		if(useCamera) {
-			sb.append("#include <camera_client.h>\n");
-		}
-		if(useGamepad) {
-			sb.append("#include <gamepad.h>\n");
-		}
-		if(useRumblepad) {
-			sb.append("#include <rumblepad.h>\n");
-		}
-		if(usePWM) {
-			sb.append("#include <temp_actuator.h>\n");
-		}
-		if(useUS || useLaser || useDigits || useACC || useLEDButton) {
-			sb.append("#include <ip_connection.h>\n");
-		}
-		if(useUS) {
-			sb.append("#include <bricklet_distance_us.h>\n");
-		}
-		if(useLaser) {
-			sb.append("#include <bricklet_laser_range_finder.h>\n");
-		}
-		if(useACC) {
-			sb.append("#include <brick_imu_v2.h>\n");
-		}
-		if(useDigits) {
-			sb.append("#include <bricklet_segment_display_4x7.h>\n");
-		}
-		if(useLEDButton) {
-			sb.append("#include <bricklet_rgb_led_button.h>\n");
-		}
-		if(useVesc) {
-			sb.append("#include <commands.h>\n");
-			sb.append("#include <hal.h>\n");
+		// create includes for platform header files
+		for(String header : headers) {
+			sb.append("#include <" + header + ">\n");
 		}
+		// create standard includes
 		sb.append("#include <stdio.h>\n");
 		return sb.toString();
 	}
@@ -230,27 +102,23 @@ class SingleUnitMainGenerator {
 	private String createWorkerCode(List<Pair<ExecutionUnit, Component>> deployedComponents,
 			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
 		StringBuilder sb = new StringBuilder();
-		if(useUS || useLaser || useACC) {
-			// Get Current time for the sensors
-			sb.append("uint64_t curr_time = time_util_get_current_micros();\n");
-		}
+		// if(useUS || useLaser || useACC) {
+		// // Get Current time for the sensors
+		// sb.append("uint64_t curr_time = time_util_get_current_micros();\n");
+		// }
 		for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
 			if(p.getFirst() instanceof Receiver && p.getSecond() instanceof InputPort) {
 				sb.append(createReadCode((Receiver)p.getFirst(), (InputPort)p.getSecond()));
 			}
 		}
 		for(Pair<ExecutionUnit, Component> p : deployedComponents) {
-			Component c = p.getSecond();
-			sb.append(makeCall("perform_step", c));
+			sb.append(makeCall("perform_step", p.getSecond()));
 		}
 		for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
 			if(p.getFirst() instanceof Transmitter && p.getSecond() instanceof OutputPort) {
 				sb.append(createWriteCode((Transmitter)p.getFirst(), (OutputPort)p.getSecond()));
 			}
 		}
-		if(useRumble) {
-			sb.append(createRumbleCode());
-		}
 		return sb.toString();
 	}
 
@@ -258,140 +126,140 @@ class SingleUnitMainGenerator {
 	private String createVariables(List<Pair<ExecutionUnit, Component>> deployedComponents,
 			List<Pair<PlatformConnectorUnit, Port>> deployedPorts) {
 		StringBuilder sb = new StringBuilder();
-		if(usePWM) {
-			sb.append("int maestro_fd = -1;\n");
-		}
-		if(useDigits) {
-			sb.append("SegmentDisplay4x7 segment_display;\n");
-			sb.append("static void set_led_display (SegmentDisplay4x7 *segment_display, uint16_t value, bool showHex) {\n");
-			sb.append("static const uint8_t digits[] = {0x3f,0x06,0x5b,0x4f,\n");
-			sb.append("                                 0x66,0x6d,0x7d,0x07,\n");
-			sb.append("                                 0x7f,0x6f,0x77,0x7c,\n");
-			sb.append("                                 0x39,0x5e,0x79,0x71};\n");
-			sb.append("if(showHex) {\n");
-			sb.append("uint8_t segments[4] = {digits[(value >> 12) & 0x0F], digits[(value >> 8) & 0x0F], digits[(value >> 4) & 0x0F], digits[value & 0x0F]};\n");
-			sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
-			sb.append("} else {\n");
-			sb.append("uint8_t segments[4] = {digits[(value%10000)/1000], digits[(value%1000)/100], digits[(value%100)/10], digits[value%10]};\n");
-			sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
-			sb.append("}\n");
-			sb.append("}\n\n");
-		}
-		if(useLEDButton) {
-			// for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
-			for(String uid : ledButtons.keySet()) {
-				sb.append("RGBLEDButton rlb_" + uid + ";\n");
-			}
-			for(String[] arr : ledButtonsLocalVariable.values()) {
-				for(String var : arr) {
-					sb.append("uint8_t " + var + " = 0;\n");
-				}
-			}
-			// extractRGBforLEDButton(p);
-			// }
-		}
-		if(useUS) {
-			sb.append("uint16_t ultra_sonic_A;\n");
-			sb.append("uint64_t us_A_last_cb_time = 0;\n");
-			sb.append("char* uid_us_A = \"zpW\";\n");
-			sb.append("void us_A_callback(uint16_t distance, void *data) {\n");
-			sb.append("ultra_sonic_A = distance;\n");
-			sb.append("us_A_last_cb_time = time_util_get_current_micros();\n");
-			sb.append("}\n");
-			sb.append("uint16_t ultra_sonic_B;\n");
-			sb.append("uint64_t us_B_last_cb_time = 0;\n");
-			sb.append("char* uid_us_B = \"zqN\";\n");
-			sb.append("void us_B_callback(uint16_t distance, void *data) {\n");
-			sb.append("ultra_sonic_B = distance;\n");
-			sb.append("us_B_last_cb_time = time_util_get_current_micros();\n");
-			sb.append("}\n\n");
-		}
-		if(useLaser) {
-			sb.append("int16_t laser_distance;\n");
-			sb.append("uint64_t laser_last_cb_time = 0;\n");
-			sb.append("void laser_callback(uint16_t distance, void *data) {\n");
-			sb.append("laser_distance = distance;\n");
-			sb.append("laser_last_cb_time = time_util_get_current_micros();\n");
-			sb.append("}\n\n");
-		}
-		if(useACC) {
-			sb.append("float Q = 0.022;\n");
-			sb.append("float R = 0.917;\n");
-			sb.append("float estimates[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
-			sb.append("float last_p[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
-			sb.append("float kalman_filter(float value, int sensor) {\n");
-			sb.append("if(sensor < 0 || sensor > 5) return -1;\n");
-			sb.append("float temp_est = estimates[sensor];\n");
-			sb.append("float p_temp = last_p[sensor] + Q;\n");
-			sb.append("float K = p_temp * (1.0/(p_temp + R));\n");
-			sb.append("float est = temp_est + K * (value - temp_est);\n");
-			sb.append("float P = (1-K)*p_temp;\n");
-			sb.append("last_p[sensor] = P;\n");
-			sb.append("estimates[sensor] = est;\n");
-			sb.append("return est;\n");
-			sb.append("}\n\n");
-			sb.append("float acceleration_X, acceleration_Y, acceleration_Z;\n");
-			sb.append("uint64_t acc_last_cb_time = 0;\n");
-			sb.append("void acc_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
-			sb.append("if (abs(x - acceleration_X) > 2 * 10 * 100 ||\n");
-			sb.append("abs(y - acceleration_Y) > 2 * 10 * 100 ||\n");
-			sb.append("abs(z - acceleration_Z) > 2 * 10 * 100)\n");
-			sb.append("    return;\n");
-			sb.append("acceleration_X = kalman_filter(x, 0) / 100.0;\n");
-			sb.append("acceleration_Y = kalman_filter(y, 1) / 100.0;\n");
-			sb.append("acceleration_Z = kalman_filter(z, 2) / 100.0;\n");
-			sb.append("acc_last_cb_time = time_util_get_current_micros();\n");
-			sb.append("}\n\n");
-			sb.append("float angularVelocity_X, angularVelocity_Y, angularVelocity_Z;\n");
-			sb.append("uint64_t angV_last_cb_time = 0;\n");
-			sb.append("void angV_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
-			sb.append("angularVelocity_X = kalman_filter(x, 3) / 16;\n");
-			sb.append("angularVelocity_Y = kalman_filter(y, 4) / 16;\n");
-			sb.append("angularVelocity_Z = kalman_filter(z, 5) / 16;\n");
-			sb.append("angV_last_cb_time = time_util_get_current_micros();\n");
-			sb.append("}\n\n");
-		}
+		// if(usePWM) {
+		// sb.append("int maestro_fd = -1;\n");
+		// }
+		// if(useDigits) {
+		// sb.append("SegmentDisplay4x7 segment_display;\n");
+		// sb.append("static void set_led_display (SegmentDisplay4x7 *segment_display, uint16_t value, bool showHex) {\n");
+		// sb.append("static const uint8_t digits[] = {0x3f,0x06,0x5b,0x4f,\n");
+		// sb.append("                                 0x66,0x6d,0x7d,0x07,\n");
+		// sb.append("                                 0x7f,0x6f,0x77,0x7c,\n");
+		// sb.append("                                 0x39,0x5e,0x79,0x71};\n");
+		// sb.append("if(showHex) {\n");
+		// sb.append("uint8_t segments[4] = {digits[(value >> 12) & 0x0F], digits[(value >> 8) & 0x0F], digits[(value >> 4) & 0x0F], digits[value & 0x0F]};\n");
+		// sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
+		// sb.append("} else {\n");
+		// sb.append("uint8_t segments[4] = {digits[(value%10000)/1000], digits[(value%1000)/100], digits[(value%100)/10], digits[value%10]};\n");
+		// sb.append("segment_display_4x7_set_segments(segment_display, segments, 5, false);\n");
+		// sb.append("}\n");
+		// sb.append("}\n\n");
+		// }
+		// if(useLEDButton) {
+		// // for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
+		// for(String uid : ledButtons.keySet()) {
+		// sb.append("RGBLEDButton rlb_" + uid + ";\n");
+		// }
+		// for(String[] arr : ledButtonsLocalVariable.values()) {
+		// for(String var : arr) {
+		// sb.append("uint8_t " + var + " = 0;\n");
+		// }
+		// }
+		// // extractRGBforLEDButton(p);
+		// // }
+		// }
+		// if(useUS) {
+		// sb.append("uint16_t ultra_sonic_A;\n");
+		// sb.append("uint64_t us_A_last_cb_time = 0;\n");
+		// sb.append("char* uid_us_A = \"zpW\";\n");
+		// sb.append("void us_A_callback(uint16_t distance, void *data) {\n");
+		// sb.append("ultra_sonic_A = distance;\n");
+		// sb.append("us_A_last_cb_time = time_util_get_current_micros();\n");
+		// sb.append("}\n");
+		// sb.append("uint16_t ultra_sonic_B;\n");
+		// sb.append("uint64_t us_B_last_cb_time = 0;\n");
+		// sb.append("char* uid_us_B = \"zqN\";\n");
+		// sb.append("void us_B_callback(uint16_t distance, void *data) {\n");
+		// sb.append("ultra_sonic_B = distance;\n");
+		// sb.append("us_B_last_cb_time = time_util_get_current_micros();\n");
+		// sb.append("}\n\n");
+		// }
+		// if(useLaser) {
+		// sb.append("int16_t laser_distance;\n");
+		// sb.append("uint64_t laser_last_cb_time = 0;\n");
+		// sb.append("void laser_callback(uint16_t distance, void *data) {\n");
+		// sb.append("laser_distance = distance;\n");
+		// sb.append("laser_last_cb_time = time_util_get_current_micros();\n");
+		// sb.append("}\n\n");
+		// }
+		// if(useACC) {
+		// sb.append("float Q = 0.022;\n");
+		// sb.append("float R = 0.917;\n");
+		// sb.append("float estimates[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
+		// sb.append("float last_p[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};\n");
+		// sb.append("float kalman_filter(float value, int sensor) {\n");
+		// sb.append("if(sensor < 0 || sensor > 5) return -1;\n");
+		// sb.append("float temp_est = estimates[sensor];\n");
+		// sb.append("float p_temp = last_p[sensor] + Q;\n");
+		// sb.append("float K = p_temp * (1.0/(p_temp + R));\n");
+		// sb.append("float est = temp_est + K * (value - temp_est);\n");
+		// sb.append("float P = (1-K)*p_temp;\n");
+		// sb.append("last_p[sensor] = P;\n");
+		// sb.append("estimates[sensor] = est;\n");
+		// sb.append("return est;\n");
+		// sb.append("}\n\n");
+		// sb.append("float acceleration_X, acceleration_Y, acceleration_Z;\n");
+		// sb.append("uint64_t acc_last_cb_time = 0;\n");
+		// sb.append("void acc_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
+		// sb.append("if (abs(x - acceleration_X) > 2 * 10 * 100 ||\n");
+		// sb.append("abs(y - acceleration_Y) > 2 * 10 * 100 ||\n");
+		// sb.append("abs(z - acceleration_Z) > 2 * 10 * 100)\n");
+		// sb.append("    return;\n");
+		// sb.append("acceleration_X = kalman_filter(x, 0) / 100.0;\n");
+		// sb.append("acceleration_Y = kalman_filter(y, 1) / 100.0;\n");
+		// sb.append("acceleration_Z = kalman_filter(z, 2) / 100.0;\n");
+		// sb.append("acc_last_cb_time = time_util_get_current_micros();\n");
+		// sb.append("}\n\n");
+		// sb.append("float angularVelocity_X, angularVelocity_Y, angularVelocity_Z;\n");
+		// sb.append("uint64_t angV_last_cb_time = 0;\n");
+		// sb.append("void angV_callback(int16_t x, int16_t y, int16_t z, void* data) {\n");
+		// sb.append("angularVelocity_X = kalman_filter(x, 3) / 16;\n");
+		// sb.append("angularVelocity_Y = kalman_filter(y, 4) / 16;\n");
+		// sb.append("angularVelocity_Z = kalman_filter(z, 5) / 16;\n");
+		// sb.append("angV_last_cb_time = time_util_get_current_micros();\n");
+		// sb.append("}\n\n");
+		// }
 		return sb.toString();
 	}
 
 	/**
 	 * @param p
 	 */
-	private void extractRGBforLEDButton(Pair<PlatformConnectorUnit, Port> p) {
-		final String UNKNOWN = "unknown";
-		String uid = UNKNOWN;
-		int rgb = -1;
-		if(p.getFirst() instanceof LEDButtonRActuator) {
-			LEDButtonRActuator sensor = (LEDButtonRActuator)p.getFirst();
-			uid = sensor.getUniqueBrickletID();
-			rgb = 0;
-		}
-		if(p.getFirst() instanceof LEDButtonGActuator) {
-			LEDButtonGActuator sensor = (LEDButtonGActuator)p.getFirst();
-			uid = sensor.getUniqueBrickletID();
-			rgb = 1;
-		}
-		if(p.getFirst() instanceof LEDButtonBActuator) {
-			LEDButtonBActuator sensor = (LEDButtonBActuator)p.getFirst();
-			uid = sensor.getUniqueBrickletID();
-			rgb = 2;
-		}
-		if(!uid.equals(UNKNOWN) && !ledButtons.containsKey(uid)) {
-			String[] rgbArray = new String[3];
-			rgbArray[rgb] = portName(p.getSecond());
-			ledButtons.put(uid, rgbArray);
-			String[] localVar = new String[3];
-			localVar[rgb] =
-					"rgbButton_" + uid + "_lastValue_" + (rgb == 0 ? "r" : rgb == 1 ? "g" : "b");
-			ledButtonsLocalVariable.put(uid, localVar);
-		} else if(ledButtons.containsKey(uid)) {
-			String[] rgbArray = ledButtons.get(uid);
-			rgbArray[rgb] = portName(p.getSecond());
-			String[] localVar = ledButtonsLocalVariable.get(uid);
-			localVar[rgb] =
-					"rgbButton_" + uid + "_lastValue_" + (rgb == 0 ? "r" : rgb == 1 ? "g" : "b");
-		}
-	}
+	// private void extractRGBforLEDButton(Pair<PlatformConnectorUnit, Port> p) {
+	// final String UNKNOWN = "unknown";
+	// String uid = UNKNOWN;
+	// int rgb = -1;
+	// if(p.getFirst() instanceof LEDButtonRActuator) {
+	// LEDButtonRActuator sensor = (LEDButtonRActuator)p.getFirst();
+	// uid = sensor.getUniqueBrickletID();
+	// rgb = 0;
+	// }
+	// if(p.getFirst() instanceof LEDButtonGActuator) {
+	// LEDButtonGActuator sensor = (LEDButtonGActuator)p.getFirst();
+	// uid = sensor.getUniqueBrickletID();
+	// rgb = 1;
+	// }
+	// if(p.getFirst() instanceof LEDButtonBActuator) {
+	// LEDButtonBActuator sensor = (LEDButtonBActuator)p.getFirst();
+	// uid = sensor.getUniqueBrickletID();
+	// rgb = 2;
+	// }
+	// if(!uid.equals(UNKNOWN) && !ledButtons.containsKey(uid)) {
+	// String[] rgbArray = new String[3];
+	// rgbArray[rgb] = portName(p.getSecond());
+	// ledButtons.put(uid, rgbArray);
+	// String[] localVar = new String[3];
+	// localVar[rgb] =
+	// "rgbButton_" + uid + "_lastValue_" + (rgb == 0 ? "r" : rgb == 1 ? "g" : "b");
+	// ledButtonsLocalVariable.put(uid, localVar);
+	// } else if(ledButtons.containsKey(uid)) {
+	// String[] rgbArray = ledButtons.get(uid);
+	// rgbArray[rgb] = portName(p.getSecond());
+	// String[] localVar = ledButtonsLocalVariable.get(uid);
+	// localVar[rgb] =
+	// "rgbButton_" + uid + "_lastValue_" + (rgb == 0 ? "r" : rgb == 1 ? "g" : "b");
+	// }
+	// }
 
 	/** Returns the port and ID identifier. */
 	private String portName(Port port) {
@@ -400,485 +268,185 @@ class SingleUnitMainGenerator {
 
 	/** Creates the read code for the given receiver and port. */
 	private String createWriteCode(Transmitter transmitter, OutputPort outport) {
-		if(transmitter instanceof ActuatorPWM) {
-			ActuatorPWM act = (ActuatorPWM)transmitter;
-			String result = "if(!noval_" + portName(outport) + ") {\n";
-			if(act.getChannelID() == 0) {
-				result +=
-						"temp_actuator_device_set_target(maestro_fd, 0, (uint16_t)" +
-								portName(outport) + ");\n";
-			} else {
-				result +=
-						"temp_actuator_device_set_target(maestro_fd, 1, (uint16_t)" +
-								portName(outport) + ");\n";
-			}
-			result += "}\n";
-			return result;
-		}
-		if(transmitter instanceof ActuatorDigits) {
-			ActuatorDigits digits = (ActuatorDigits)transmitter;
-			String result = "if(!noval_" + portName(outport) + ") {\n";
-			result +=
-					"set_led_display(&segment_display, (uint16_t)" + portName(outport) + ", " +
-							digits.isShowHexValue() + ");\n";
-			result += "}\n";
-			return result;
-		}
-		if(transmitter instanceof LEDButtonRActuator) {
-			// TODO(JE): if a red actuator port is found the previously saved rgb values are used.
-			LEDButtonRActuator digits = (LEDButtonRActuator)transmitter;
-			String uniqueBrickletID = digits.getUniqueBrickletID();
-			String[] rgb = ledButtons.get(uniqueBrickletID);
-			String[] localRgbValue = ledButtonsLocalVariable.get(uniqueBrickletID);
-
-			String result =
-					"if(!noval_" + portName(outport) + " && (" + rgb[0] + " != " +
-							localRgbValue[0] + " || " + rgb[1] + " != " + localRgbValue[1] +
-							" || " + rgb[2] + " != " + localRgbValue[2] + ")) {\n";
-			result +=
-					"rgb_led_button_set_color(&rlb_" + uniqueBrickletID + ", " + rgb[0] + ", " +
-							rgb[1] + ", " + rgb[2] + " );\n";
-			result += localRgbValue[0] + " = " + rgb[0] + ";\n";
-			result += localRgbValue[1] + " = " + rgb[1] + ";\n";
-			result += localRgbValue[2] + " = " + rgb[2] + ";\n";
-			result += "}\n";
-			return result;
-		}
-		if(transmitter instanceof ConsoleOutput) {
-			String result = "\tif(!noval_" + portName(outport) + ") {\n";
-			result +=
-					"\t\tprintf(\"" + outport.getName() + " = %i\\n\", " + portName(outport) +
-							");\n";
-			result += "\t} else {\n";
-			result += "\t\tprintf(\"" + outport.getName() + " = NoVal\\n\");\n";
-			result += "\t}\n";
-			return result;
-		}
-		if(transmitter instanceof RumbleMagnitudeWeak) {
-			useRumble = true;
-			rumbleWeakPort = outport;
-		}
-		if(transmitter instanceof RumbleMagnitudeStrong) {
-			useRumble = true;
-			rumbleStrongPort = outport;
-		}
-		if(transmitter instanceof MotorControlOutput) {
-			String result = "if(!noval_" + portName(outport) + ") {\n";
-			result += "setVelocity(" + portName(outport) + ");\n";
-			result += "}\n";
-			return result;
-		}
-		return "";
-	}
-
-	/** Creates Code for Rumble */
-	private String createRumbleCode() {
-		StringBuilder sb = new StringBuilder();
-		sb.append("rumblepad_set_rumble(");
-		if(rumbleStrongPort != null) {
-			sb.append("!noval_" + portName(rumbleStrongPort) + " ? " + portName(rumbleStrongPort) +
-					" : 0, ");
-		} else {
-			sb.append("0, ");
-		}
-		if(rumbleWeakPort != null) {
-			sb.append("!noval_" + portName(rumbleWeakPort) + " ? " + portName(rumbleWeakPort) +
-					" : 0, ");
-		} else {
-			sb.append("0, ");
-		}
-		sb.append("cycle_time * 0.9, 0);\n");
-		return sb.toString();
+		ExecutableBase<?> exec = platformConnector2ExecutableBase.get(transmitter);
+		if(exec instanceof IWriteableExecutable) {
+			IWriteableExecutable wexec = (IWriteableExecutable)exec;
+			// TODO: NoVal support
+			return wexec.getWriteCode(getPrefix(transmitter), outport, portName(outport));
+		}
+		return "FIXME(\"No executable available to write " + outport.getName() + " to " +
+				transmitter.getName() + "\");\n";
 	}
 
 	/** Creates the read code for the given receiver and port. */
 	private String createReadCode(Receiver receiver, InputPort inport) {
-		if(receiver instanceof CameraDistanceLeft) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport)).append(" = camera_client_get_distance_left();\n");
-			return sb.toString();
-		}
-		if(receiver instanceof CameraDistanceRight) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport)).append(" = camera_client_get_distance_right();\n");
-			return sb.toString();
-		}
-		if(receiver instanceof CameraDetectionStateLeft) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport)).append(" = camera_client_get_detection_state_left();\n");
-			return sb.toString();
-		}
-		if(receiver instanceof CameraDetectionStateRight) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport)).append(" = camera_client_get_detection_state_right();\n");
-			return sb.toString();
-		}
-		if(receiver instanceof CameraYawAngle) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport)).append(" = camera_client_get_yaw_angle();\n");
-			return sb.toString();
-		}
-		if(receiver instanceof UltraSonicSensor) {
-			StringBuilder sb = new StringBuilder();
-			UltraSonicSensor sensor = (UltraSonicSensor)receiver;
-			if(nrOfUsSensors == 0) {
-				sb.append("noval_" + portName(inport) + " = true;\n");
-				sb.append("if (!strcmp(\"" + sensor.getUniqueBrickletID() + "\", uid_us_A)) {\n");
-				sb.append("float diff_A = (curr_time - us_A_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-				sb.append("if (diff_A < 1.0) {\n");
-				sb.append("noval_" + portName(inport) + " = false;\n");
-				sb.append(portName(inport) + " = ultra_sonic_A;\n}\n");
-				sb.append("}\n");
-			} else if(nrOfUsSensors == 1) {
-				sb.append("noval_" + portName(inport) + " = true;\n");
-				sb.append("if (!strcmp(\"" + sensor.getUniqueBrickletID() + "\", uid_us_B)){\n");
-				sb.append("float diff_B = (curr_time - us_B_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-				sb.append("if (diff_B < 1.0) {\n");
-				sb.append("noval_" + portName(inport) + " = false;\n");
-				sb.append(portName(inport) + " = ultra_sonic_B;\n}\n");
-				sb.append("}\n");
-			}
-			nrOfUsSensors++;
-			return sb.toString();
-		}
-		if(receiver instanceof LaserRangeSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_laser = (curr_time - laser_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_laser < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append("if(laser_distance == 1){\n");
-			sb.append(portName(inport) + " = 4000;\n");
-			sb.append("} else {\n");
-			sb.append(portName(inport) + " = laser_distance;\n");
-			sb.append("}\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof AccelerationXSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_accX = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_accX < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = acceleration_X;\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof AccelerationYSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_accY = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_accY < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = acceleration_Y;\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof AccelerationZSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_accZ = (curr_time - acc_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_accZ < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = acceleration_Z;\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof AngularVelocityXSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_angV_X = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_angV_X < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = angularVelocity_X;\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof AngularVelocityYSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_angV_Y = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_angV_Y < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = angularVelocity_Y;\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof AngularVelocityZSensor) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("float diff_angV_Z = (curr_time - angV_last_cb_time) / (1.0 * SECONDS_IN_MICROS);\n");
-			sb.append("if (diff_angV_Z < 1.0) {\n");
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = angularVelocity_Z;\n");
-			sb.append("} else {\n");
-			sb.append("noval_" + portName(inport) + " = true;\n");
-			sb.append("}\n");
-			return sb.toString();
-		}
-		if(receiver instanceof MotorControlInput) {
-			StringBuilder sb = new StringBuilder();
-			sb.append("noval_" + portName(inport) + " = false;\n");
-			sb.append(portName(inport) + " = getVelocity();\n");
-			return sb.toString();
-		}
-		if(receiver instanceof Button1) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_1", inport);
-		}
-		if(receiver instanceof Button2) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_2", inport);
-		}
-		if(receiver instanceof Button3) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_3", inport);
-		}
-		if(receiver instanceof Button4) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_4", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.ButtonL1) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_L1", inport);
-		}
-		if(receiver instanceof ButtonL2) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_L2", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.ButtonR1) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_R1", inport);
-		}
-		if(receiver instanceof ButtonR2) {
-			return gamepadReadCode("gamepad_get_button_state", "GAMEPAD_BUTTON_R2", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickX_Position) {
-			return gamepadReadCode("gamepad_get_axis_position",
-					"GAMEPAD_AXIS_RIGHT_STICK_HORIZONTAL", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Right_StickY_Position) {
-			return gamepadReadCode("gamepad_get_axis_position",
-					"GAMEPAD_AXIS_RIGHT_STICK_VERTICAL", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickX_Position) {
-			return gamepadReadCode("gamepad_get_axis_position",
-					"GAMEPAD_AXIS_LEFT_STICK_HORIZONTAL", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.gamepad.Left_StickY_Position) {
-			return gamepadReadCode("gamepad_get_axis_position", "GAMEPAD_AXIS_LEFT_STICK_VERTICAL",
-					inport);
-		}
-		if(receiver instanceof ButtonA) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_A", inport);
-		}
-		if(receiver instanceof ButtonB) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_B", inport);
-		}
-		if(receiver instanceof ButtonX) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_X", inport);
-		}
-		if(receiver instanceof ButtonY) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_Y", inport);
-		}
-		if(receiver instanceof ButtonStart) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_START", inport);
-		}
-		if(receiver instanceof ButtonSelect) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_SELECT", inport);
-		}
-		if(receiver instanceof ButtonHome) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_MODE", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonL1) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_L1", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonR1) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_R1", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonL3) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_L3", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.ButtonR3) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_BUTTON_R3", inport);
-		}
-		if(receiver instanceof L2_Position) {
-			return gamepadReadCode("rumblepad_get_axis_position", "RUMBLEPAD_AXIS_L2", inport);
-		}
-		if(receiver instanceof R2_Position) {
-			return gamepadReadCode("rumblepad_get_axis_position", "RUMBLEPAD_AXIS_R2", inport);
-		}
-		if(receiver instanceof DPadDown) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_DOWN", inport);
-		}
-		if(receiver instanceof DPadUp) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_UP", inport);
-		}
-		if(receiver instanceof DPadLeft) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_LEFT", inport);
-		}
-		if(receiver instanceof DPadRight) {
-			return gamepadReadCode("rumblepad_get_button_state", "RUMBLEPAD_DPAD_RIGHT", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Left_StickX_Position) {
-			return gamepadReadCode("rumblepad_get_axis_position",
-					"RUMBLEPAD_AXIS_LEFT_STICK_HORIZONTAL", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Left_StickY_Position) {
-			return gamepadReadCode("rumblepad_get_axis_position",
-					"RUMBLEPAD_AXIS_LEFT_STICK_VERTICAL", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Right_StickX_Position) {
-			return gamepadReadCode("rumblepad_get_axis_position",
-					"RUMBLEPAD_AXIS_RIGHT_STICK_HORIZONTAL", inport);
-		}
-		if(receiver instanceof org.fortiss.af3.platform.raspberry.model.rumblepad.Right_StickY_Position) {
-			return gamepadReadCode("rumblepad_get_axis_position",
-					"RUMBLEPAD_AXIS_RIGHT_STICK_VERTICAL", inport);
-		}
-		return "";
-	}
-
-	/** Creates read code for gamepad state. */
-	private String gamepadReadCode(String gamepadFun, String btnId, InputPort inport) {
-		String noval = "noval_" + portName(inport) + " = false;\n";
-		String setBtn = portName(inport) + " = " + gamepadFun + "(" + btnId + ");\n";
-		return noval + setBtn;
+		ExecutableBase<?> exec = platformConnector2ExecutableBase.get(receiver);
+		if(exec instanceof IReadableExecutable) {
+			IReadableExecutable rexec = (IReadableExecutable)exec;
+			// TODO: NoVal support
+			return rexec.getReadCode(getPrefix(receiver), inport);
+		}
+		return "FIXME\"No executable available to read " + inport.getName() + " from " +
+				receiver.getName() + "\");\n";
 	}
 
 	/** Create the initialize code. */
-	private String createInitCode(List<Pair<ExecutionUnit, Component>> deployedComponents) {
-		int createdUsSensors = 0;
+	private String createInitCode() {
 		StringBuilder sb = new StringBuilder();
-		if(useCamera) {
-			String addr = executionUnit.getCameraServerAddress();
-			String port = executionUnit.getCameraServerPort();
-			sb.append("camera_client_initialize(\"" + addr + "\", \"" + port + "\");\n");
-		}
-		if(useUS || useLaser || useDigits || useACC) {
-			sb.append("IPConnection brick_connection;\n");
-			sb.append("ipcon_create(&brick_connection);\n");
-			sb.append("if(ipcon_connect(&brick_connection, BRICK_HOST, BRICK_PORT) < 0) {\n");
-			sb.append("perror(\"Failed to connect to brick sub-system.\");\n");
-			sb.append("return 1;\n");
-			sb.append("}\n\n");
-		}
-		if(useUS) {
-			System.out.println("useUs");
-			for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
-				if(createdUsSensors >= 2)
-					break;
-				if(p.getFirst() instanceof UltraSonicSensor) {
-					UltraSonicSensor sensor = (UltraSonicSensor)p.getFirst();
-					if(createdUsSensors == 0) {
-						sb.append("DistanceUS DistanceUS_A;\n");
-						sb.append("uid_us_A = \"" + sensor.getUniqueBrickletID() + "\";\n");
-						sb.append("distance_us_create(&DistanceUS_A, \"" +
-								sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
-						sb.append("distance_us_register_callback(&DistanceUS_A, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_A_callback, NULL);\n");
-						sb.append("distance_us_set_distance_callback_period(&DistanceUS_A, 10);\n");
-					} else if(createdUsSensors == 1) {
-						sb.append("DistanceUS DistanceUS_B;\n");
-						sb.append("uid_us_B = \"" + sensor.getUniqueBrickletID() + "\";\n");
-						sb.append("distance_us_create(&DistanceUS_B, \"" +
-								sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
-						sb.append("distance_us_register_callback(&DistanceUS_B, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_B_callback, NULL);\n");
-						sb.append("distance_us_set_distance_callback_period(&DistanceUS_B, 10);\n");
-					}
-					createdUsSensors++;
-				}
-			}
-		}
-		if(useLaser) {
-			for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
-				if(p.getFirst() instanceof LaserRangeSensor) {
-					LaserRangeSensor sensor = (LaserRangeSensor)p.getFirst();
-					sb.append("LaserRangeFinder laser;\n");
-					sb.append("laser_range_finder_create(&laser, \"" +
-							sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
-					sb.append("laser_range_finder_enable_laser(&laser);\n");
-					sb.append("laser_range_finder_register_callback(&laser, LASER_RANGE_FINDER_CALLBACK_DISTANCE, (void*)laser_callback, NULL);\n");
-					sb.append("laser_range_finder_set_distance_callback_period(&laser, 10);\n");
-					break;
+		Set<String> singletonInitDone = new HashSet<>();
+		for(PlatformConnectorUnit pcu : platformConnector2ExecutableBase.keySet()) {
+			ExecutableBase<?> exec = platformConnector2ExecutableBase.get(pcu);
+			if(exec instanceof ISingletonInitializationExecutable) {
+				ISingletonInitializationExecutable singletonExec =
+						(ISingletonInitializationExecutable)exec;
+				String ident = singletonExec.getSingletonInitializationIdentifier();
+				if(!singletonInitDone.contains(ident)) {
+					singletonInitDone.add(ident);
+					sb.append(singletonExec.getSingletonInitializationCode());
 				}
 			}
-		}
-		if(useDigits) {
-			for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
-				if(p.getFirst() instanceof ActuatorDigits) {
-					ActuatorDigits sensor = (ActuatorDigits)p.getFirst();
-					sb.append("segment_display_4x7_create(&segment_display, \"" +
-							sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
-					break;
-				}
+			if(exec instanceof IInitializationExecutable) {
+				IInitializationExecutable initExec = (IInitializationExecutable)exec;
+				String prefix = getPrefix(pcu);
+				sb.append(initExec.getInitializationCode(prefix));
 			}
 		}
-		if(useLEDButton) {
-			for(String uid : ledButtons.keySet()) {
-				sb.append("rgb_led_button_create(&rlb_" + uid + ", \"" + uid +
-						"\", &brick_connection);\n");
-			}
-			// break; TODO(JE): those break statements only allow one element of each type!
-		}
-		if(useACC) {
-			sb.append("IMUV2 imu;\n");
-			for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
-				if(p.getFirst() instanceof AccelerationXSensor ||
-						p.getFirst() instanceof AccelerationYSensor ||
-						p.getFirst() instanceof AccelerationZSensor ||
-						p.getFirst() instanceof AngularVelocityXSensor ||
-						p.getFirst() instanceof AngularVelocityYSensor ||
-						p.getFirst() instanceof AngularVelocityZSensor) {
-					UIDUnit sensor = (UIDUnit)p.getFirst();
-					sb.append("imu_v2_create(&imu, \"" + sensor.getUniqueBrickletID() +
-							"\", &brick_connection);\n");
-					break;
-				}
-			}
-			sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_LINEAR_ACCELERATION, (void*)acc_callback, NULL);\n");
-			sb.append("imu_v2_set_linear_acceleration_period(&imu, 5);\n");
-			sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_ANGULAR_VELOCITY, (void*)angV_callback, NULL);\n");
-			sb.append("imu_v2_set_angular_velocity_period(&imu, 5);\n");
-		}
-		if(usePWM) {
-			sb.append("maestro_fd = temp_actuator_initialize(\"/dev/Maestro0\");\n");
-		}
-		if(useGamepad) {
-			sb.append("gamepad_configuration_t* gamepad_config = malloc(sizeof(gamepad_configuration_t));\n");
-			sb.append("gamepad_config->device_id = \"/dev/input/js0\";\n");
-			sb.append("gamepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
-					";\n");
-			sb.append("gamepad_config->axis_callback = NULL;\n");
-			sb.append("gamepad_config->button_callback = NULL;\n");
-			sb.append("gamepad_initialize(gamepad_config);\n\n");
-		}
-		if(useRumblepad) {
-			sb.append("while(access(\"/dev/input/event0\", F_OK) == -1) {\n");
-			sb.append("sleep(1);\n");
-			sb.append("printf(\"Could not access gamepad device. Trying again in 1s.\\n\");\n");
-			sb.append("}\n");
-			sb.append("rumblepad_configuration_t* rumblepad_config = malloc(sizeof(rumblepad_configuration_t));\n");
-			sb.append("rumblepad_config->device_id = \"/dev/input/event0\";\n");
-			sb.append("rumblepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
-					";\n");
-			sb.append("rumblepad_config->axis_callback = NULL;\n");
-			sb.append("rumblepad_config->button_callback = NULL;\n");
-			sb.append("rumblepad_initialize(rumblepad_config);\n\n");
-		}
-		if(useVesc) {
-			sb.append("initUSB(\"/dev/vesc\", B115200);\n");
-		}
-		for(Pair<ExecutionUnit, Component> p : deployedComponents) {
-			Component c = p.getSecond();
-			sb.append(makeCall("init", c));
-		}
 		return sb.toString();
 	}
 
+	/** Returns a unique prefix for this {@link PlatformConnectorUnit}. */
+	private String getPrefix(PlatformConnectorUnit pcu) {
+		return pcu.getName().replace(' ', '_') + pcu.getId() + '_';
+	}
+
+	private void temp() {
+		// int createdUsSensors = 0;
+		// StringBuilder sb = new StringBuilder();
+		// if(useCamera) {
+		// String addr = executionUnit.getCameraServerAddress();
+		// String port = executionUnit.getCameraServerPort();
+		// sb.append("camera_client_initialize(\"" + addr + "\", \"" + port + "\");\n");
+		// }
+		// if(useUS || useLaser || useDigits || useACC) {
+		// sb.append("IPConnection brick_connection;\n");
+		// sb.append("ipcon_create(&brick_connection);\n");
+		// sb.append("if(ipcon_connect(&brick_connection, BRICK_HOST, BRICK_PORT) < 0) {\n");
+		// sb.append("perror(\"Failed to connect to brick sub-system.\");\n");
+		// sb.append("return 1;\n");
+		// sb.append("}\n\n");
+		// }
+		// if(useUS) {
+		// System.out.println("useUs");
+		// for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
+		// if(createdUsSensors >= 2)
+		// break;
+		// if(p.getFirst() instanceof UltraSonicSensor) {
+		// UltraSonicSensor sensor = (UltraSonicSensor)p.getFirst();
+		// if(createdUsSensors == 0) {
+		// sb.append("DistanceUS DistanceUS_A;\n");
+		// sb.append("uid_us_A = \"" + sensor.getUniqueBrickletID() + "\";\n");
+		// sb.append("distance_us_create(&DistanceUS_A, \"" +
+		// sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
+		// sb.append("distance_us_register_callback(&DistanceUS_A, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_A_callback, NULL);\n");
+		// sb.append("distance_us_set_distance_callback_period(&DistanceUS_A, 10);\n");
+		// } else if(createdUsSensors == 1) {
+		// sb.append("DistanceUS DistanceUS_B;\n");
+		// sb.append("uid_us_B = \"" + sensor.getUniqueBrickletID() + "\";\n");
+		// sb.append("distance_us_create(&DistanceUS_B, \"" +
+		// sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
+		// sb.append("distance_us_register_callback(&DistanceUS_B, DISTANCE_US_CALLBACK_DISTANCE, (void*)us_B_callback, NULL);\n");
+		// sb.append("distance_us_set_distance_callback_period(&DistanceUS_B, 10);\n");
+		// }
+		// createdUsSensors++;
+		// }
+		// }
+		// }
+		// if(useLaser) {
+		// for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
+		// if(p.getFirst() instanceof LaserRangeSensor) {
+		// LaserRangeSensor sensor = (LaserRangeSensor)p.getFirst();
+		// sb.append("LaserRangeFinder laser;\n");
+		// sb.append("laser_range_finder_create(&laser, \"" +
+		// sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
+		// sb.append("laser_range_finder_enable_laser(&laser);\n");
+		// sb.append("laser_range_finder_register_callback(&laser, LASER_RANGE_FINDER_CALLBACK_DISTANCE, (void*)laser_callback, NULL);\n");
+		// sb.append("laser_range_finder_set_distance_callback_period(&laser, 10);\n");
+		// break;
+		// }
+		// }
+		// }
+		// if(useDigits) {
+		// for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
+		// if(p.getFirst() instanceof ActuatorDigits) {
+		// ActuatorDigits sensor = (ActuatorDigits)p.getFirst();
+		// sb.append("segment_display_4x7_create(&segment_display, \"" +
+		// sensor.getUniqueBrickletID() + "\", &brick_connection);\n");
+		// break;
+		// }
+		// }
+		// }
+		// if(useLEDButton) {
+		// for(String uid : ledButtons.keySet()) {
+		// sb.append("rgb_led_button_create(&rlb_" + uid + ", \"" + uid +
+		// "\", &brick_connection);\n");
+		// }
+		// // break; TODO(JE): those break statements only allow one element of each type!
+		// }
+		// if(useACC) {
+		// sb.append("IMUV2 imu;\n");
+		// for(Pair<PlatformConnectorUnit, Port> p : deployedPorts) {
+		// if(p.getFirst() instanceof AccelerationXSensor ||
+		// p.getFirst() instanceof AccelerationYSensor ||
+		// p.getFirst() instanceof AccelerationZSensor ||
+		// p.getFirst() instanceof AngularVelocityXSensor ||
+		// p.getFirst() instanceof AngularVelocityYSensor ||
+		// p.getFirst() instanceof AngularVelocityZSensor) {
+		// UIDUnit sensor = (UIDUnit)p.getFirst();
+		// sb.append("imu_v2_create(&imu, \"" + sensor.getUniqueBrickletID() +
+		// "\", &brick_connection);\n");
+		// break;
+		// }
+		// }
+		// sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_LINEAR_ACCELERATION, (void*)acc_callback, NULL);\n");
+		// sb.append("imu_v2_set_linear_acceleration_period(&imu, 5);\n");
+		// sb.append("imu_v2_register_callback(&imu, IMU_V2_CALLBACK_ANGULAR_VELOCITY, (void*)angV_callback, NULL);\n");
+		// sb.append("imu_v2_set_angular_velocity_period(&imu, 5);\n");
+		// }
+		// if(usePWM) {
+		// sb.append("maestro_fd = temp_actuator_initialize(\"/dev/Maestro0\");\n");
+		// }
+		// if(useGamepad) {
+		// sb.append("gamepad_configuration_t* gamepad_config = malloc(sizeof(gamepad_configuration_t));\n");
+		// sb.append("gamepad_config->device_id = \"/dev/input/js0\";\n");
+		// sb.append("gamepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
+		// ";\n");
+		// sb.append("gamepad_config->axis_callback = NULL;\n");
+		// sb.append("gamepad_config->button_callback = NULL;\n");
+		// sb.append("gamepad_initialize(gamepad_config);\n\n");
+		// }
+		// if(useRumblepad) {
+		// sb.append("while(access(\"/dev/input/event0\", F_OK) == -1) {\n");
+		// sb.append("sleep(1);\n");
+		// sb.append("printf(\"Could not access gamepad device. Trying again in 1s.\\n\");\n");
+		// sb.append("}\n");
+		// sb.append("rumblepad_configuration_t* rumblepad_config = malloc(sizeof(rumblepad_configuration_t));\n");
+		// sb.append("rumblepad_config->device_id = \"/dev/input/event0\";\n");
+		// sb.append("rumblepad_config->waiting_sleep_in_micros = " + WAITING_SLEEP_IN_MICROS +
+		// ";\n");
+		// sb.append("rumblepad_config->axis_callback = NULL;\n");
+		// sb.append("rumblepad_config->button_callback = NULL;\n");
+		// sb.append("rumblepad_initialize(rumblepad_config);\n\n");
+		// }
+		// if(useVesc) {
+		// sb.append("initUSB(\"/dev/vesc\", B115200);\n");
+		// }
+		// for(Pair<ExecutionUnit, Component> p : deployedComponents) {
+		// Component c = p.getSecond();
+		// sb.append(makeCall("init", c));
+		// }
+		// return sb.toString();
+	}
+
 	/** Creates the function call code. */
 	private String makeCall(String function, Component c) {
 		StringBuilder sb = new StringBuilder();
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/.ratings b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/.ratings
index 9e391e52..e883d333 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/.ratings
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/.ratings
@@ -1,4 +1,8 @@
+IInitializationExecutable.java 1633bcca794b274fe27bb009ff18f7a7acecd79e YELLOW
 IRasPiHeaderExecutable.java f14b5714e7b982e097f6ac6e95eb91223a30d048 YELLOW
 IRasPiLibraryBasedExecutable.java cf3548f22185e666fdcf6d4658b783734c0e5e8e YELLOW
 IRasPiSourceBasedExecutable.java 79646213964346ace17013f5c8df5de13dafb1f0 YELLOW
-ISingletonInitializableExecutable.java 64e05ca55f07855b4b241ee48810fbe3e9d6ad22 YELLOW
+IReadableExecutable.java 14fdbe86fd5a31f1fe073da4c77f4ea1675e293e YELLOW
+ISingletonInitializationExecutable.java f654ebf031b805e10ef6e0f0fbf3df179b20e20e YELLOW
+ITerminationExecutable.java 61a81fcc3be00df33cf96e764d03686a423abcd9 YELLOW
+IWriteableExecutable.java 9bbb6b6644f69e3b3ba9255862b89d79bcc00c2c YELLOW
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IInitializationExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IInitializationExecutable.java
new file mode 100644
index 00000000..1633bcca
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IInitializationExecutable.java
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2018 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.af3.platform.raspberry.generator.executable.framework;
+
+import org.fortiss.af3.platform.language.executable.ExecutableBase;
+
+/**
+ * Interface for {@link ExecutableBase}s, which require initialization including static variables in
+ * the main program (e.g. a Unix file descriptor).
+ * 
+ * @author hoelzl
+ */
+public interface IInitializationExecutable {
+	/**
+	 * Returns the variable declarations needed by this executable. The prefix is given by the code
+	 * generator to ensure uniqueness of variables for platform elements of the same type.
+	 */
+	String getVariableDeclaration(String prefix);
+
+	/** Returns the initialization code. */
+	String getInitializationCode(String prefix);
+}
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IReadableExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IReadableExecutable.java
new file mode 100644
index 00000000..14fdbe86
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IReadableExecutable.java
@@ -0,0 +1,34 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2018 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.af3.platform.raspberry.generator.executable.framework;
+
+import org.fortiss.af3.component.model.InputPort;
+
+/**
+ * Executable for platform elements that can be written (e.g. actuators and busses).
+ * 
+ * @author hoelzl
+ */
+public interface IReadableExecutable {
+	/** Returns the read code for the given port. */
+	String getReadCode(String prefix, InputPort logicalSignal);
+
+	/**
+	 * Returns the read code to determine whether the value of the platform element is NoVal. May
+	 * return {@code null}, to indicate that NoVal is not supported.
+	 */
+	String getNoValReadCode(String prefix, InputPort logicalSignal);
+}
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ISingletonInitializableExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ISingletonInitializationExecutable.java
similarity index 78%
rename from org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ISingletonInitializableExecutable.java
rename to org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ISingletonInitializationExecutable.java
index 64e05ca5..f654ebf0 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ISingletonInitializableExecutable.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ISingletonInitializationExecutable.java
@@ -15,17 +15,22 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.framework;
 
-import org.fortiss.af3.platform.language.executable.IInitializableExecutable;
-
 /**
  * Interface implemented by platform-specific executables, which need
- * initialization during system start-up. In contrast to {@link IInitializableExecutable},
+ * initialization during system start-up. In contrast to {@link IInitializationExecutable},
  * if there are more than one actuator or sensor with the singleton identifier, the
- * initialization is only included once in the generated code.
+ * common initialization code is only included once in the generated code and it is included before
+ * all other initialization code.
  * 
  * @author hoelzl
  */
-public interface ISingletonInitializableExecutable extends IInitializableExecutable {
+public interface ISingletonInitializationExecutable {
 	/** Returns the singleton identifier. */
 	String getSingletonInitializationIdentifier();
+
+	/** Returns the code to initialize local variables used by the initialization code. */
+	String getSingletonVariableDeclarationCode();
+
+	/** Returns the common initialization code. */
+	String getSingletonInitializationCode();
 }
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ITerminationExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ITerminationExecutable.java
new file mode 100644
index 00000000..61a81fcc
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/ITerminationExecutable.java
@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2018 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.af3.platform.raspberry.generator.executable.framework;
+
+import org.fortiss.af3.platform.language.executable.ExecutableBase;
+
+/**
+ * Interface for {@link ExecutableBase}s, which require to be terminated during program shutdown.
+ * 
+ * @author hoelzl
+ */
+public interface ITerminationExecutable {
+	/** Returns an termination code. */
+	String getTerminationCode(String prefix);
+}
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IWriteableExecutable.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IWriteableExecutable.java
new file mode 100644
index 00000000..9bbb6b66
--- /dev/null
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/framework/IWriteableExecutable.java
@@ -0,0 +1,34 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2018 fortiss GmbH                                              |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.af3.platform.raspberry.generator.executable.framework;
+
+import org.fortiss.af3.component.model.OutputPort;
+
+/**
+ * Executable for platform elements that can be written (e.g. actuators and busses).
+ * 
+ * @author hoelzl
+ */
+public interface IWriteableExecutable {
+	/** Returns the write code for the given port. */
+	String getWriteCode(String prefix, OutputPort logicalSignal, String value);
+
+	/**
+	 * Returns the write code for the given port if the value to be written is NoVal. May return
+	 * {@code null}, to indicate that NoVal is not supported.
+	 */
+	String getNoValWriteCode(String prefix, OutputPort logicalSignal);
+}
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/.ratings b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/.ratings
index a6a6e091..1f383e03 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/.ratings
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/.ratings
@@ -2,14 +2,14 @@ Button1Executable.java 4419314d71af50239cf6933a83a0f652614cf368 YELLOW
 Button2Executable.java 3af03ceea3aa09178fe88fe630c94282de0b72f2 YELLOW
 Button3Executable.java 964fbe4e0b5282ab617c4be2bed31afa8b4f394f YELLOW
 Button4Executable.java 53db1cce9e3dfface4027f883586bf90638cd4ff YELLOW
-ButtonExecutableBase.java 02e5bb6aa21183fc9444ec1874c67660908a55d2 YELLOW
+ButtonExecutableBase.java e8f53ecacbd60802fd37314d5c46989f83314ad3 YELLOW
 ButtonL1Executable.java ab68cddae1d323ff0ecd7956133c44d1ef0f9168 YELLOW
 ButtonL2Executable.java 336b9d8d26a682b701f7a2ca078369c9cc621fbb YELLOW
 ButtonR1Executable.java 700ef701ed77a0d3f8141166fe647ac5cd4ad570 YELLOW
 ButtonR2Executable.java 9b4acdc37505f41c60d8216c92bcbd3f43a2ccec YELLOW
-GamepadExecutableBase.java 5b769ad3d004d5b9c2ced63258a6d63eb6c41579 YELLOW
+GamepadExecutableBase.java e79e9e5823e14a15f62c8a18a4025241896e998c YELLOW
 Left_StickXExecutable.java c3e7f28f44fa27bd79e14ed7e60f44be2dc5a9ab YELLOW
 Left_StickYExecutable.java f81cc1e3124eb712507825bc54e7d0f633fde640 YELLOW
 Right_StickXExecutable.java ade165c88d0c6758efa167e5ba445eff87a0fd79 YELLOW
 Right_StickYExecutable.java 891ea877d8c3f4bab6072a02b17bb92a6caa055d YELLOW
-StickExecutableBase.java 970b8645af2ab59b9a4f8286f59e27fa38f6c1c0 YELLOW
+StickExecutableBase.java 7f1fb5e30585fdb3cbafe06e3e4311cbc0f5bf21 YELLOW
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/ButtonExecutableBase.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/ButtonExecutableBase.java
index 02e5bb6a..e8f53eca 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/ButtonExecutableBase.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/ButtonExecutableBase.java
@@ -15,13 +15,9 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.gamepad;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.funcCall;
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.rawString;
-
 import org.eclipse.emf.ecore.EObject;
 import org.fortiss.af3.component.model.InputPort;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.language.executable.IReadableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IReadableExecutable;
 
 /**
  * Base class for executables reading gamepad buttons.
@@ -37,8 +33,14 @@ abstract class ButtonExecutableBase<T extends EObject> extends GamepadExecutable
 
 	/** {@inheritDoc} */
 	@Override
-	public final IExpressionTerm getValueReadAccessor(InputPort logicalSignal) {
-		return funcCall("gamepad_get_button_state", rawString(getButtonIdentifier()));
+	public final String getReadCode(String prefix, InputPort logicalSignal) {
+		return "gamepad_get_button_state(" + getButtonIdentifier() + ");\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public final String getNoValReadCode(String prefix, InputPort logicalSignal) {
+		return null;
 	}
 
 	/** Returns the button identifier as defined in {@code gamepad.h}. */
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/GamepadExecutableBase.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/GamepadExecutableBase.java
index 5b769ad3..e79e9e58 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/GamepadExecutableBase.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/GamepadExecutableBase.java
@@ -15,11 +15,8 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.gamepad;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.rawString;
-
 import org.eclipse.emf.ecore.EObject;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.raspberry.generator.executable.framework.ISingletonInitializableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.ISingletonInitializationExecutable;
 import org.fortiss.af3.platform.raspberry.generator.executable.library.PiHALLibraryExecutableBase;
 import org.fortiss.af3.platform.raspberry.model.gamepad.GamepadPackage;
 
@@ -29,7 +26,7 @@ import org.fortiss.af3.platform.raspberry.model.gamepad.GamepadPackage;
  * @author hoelzl
  */
 abstract class GamepadExecutableBase<T extends EObject> extends PiHALLibraryExecutableBase<T>
-		implements ISingletonInitializableExecutable {
+		implements ISingletonInitializationExecutable {
 	/** Constructor. */
 	public GamepadExecutableBase(T modelElement) {
 		super(modelElement);
@@ -37,13 +34,19 @@ abstract class GamepadExecutableBase<T extends EObject> extends PiHALLibraryExec
 
 	/** {@inheritDoc} */
 	@Override
-	public final IExpressionTerm getInitialization() {
-		return rawString("gamepad_configuration_t* gamepad_config = malloc(sizeof(gamepad_configuration_t));\n"
+	public final String getSingletonInitializationCode() {
+		return "gamepad_configuration_t* gamepad_config = malloc(sizeof(gamepad_configuration_t));\n"
 				+ "gamepad_config->device_id = \"/dev/input/js0\";\n"
 				+ "gamepad_config->waiting_sleep_in_micros = 250;\n"
 				+ "gamepad_config->axis_callback = NULL;\n"
 				+ "gamepad_config->button_callback = NULL;"
-				+ "gamepad_initialize(gamepad_config);\n\n");
+				+ "gamepad_initialize(gamepad_config);\n\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public final String getSingletonVariableDeclarationCode() {
+		return "";
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/StickExecutableBase.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/StickExecutableBase.java
index 970b8645..7f1fb5e3 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/StickExecutableBase.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/gamepad/StickExecutableBase.java
@@ -15,13 +15,9 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.gamepad;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.funcCall;
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.rawString;
-
 import org.eclipse.emf.ecore.EObject;
 import org.fortiss.af3.component.model.InputPort;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.language.executable.IReadableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IReadableExecutable;
 
 /**
  * Base class for executables reading gamepad sticks.
@@ -37,8 +33,14 @@ abstract class StickExecutableBase<T extends EObject> extends GamepadExecutableB
 
 	/** {@inheritDoc} */
 	@Override
-	public final IExpressionTerm getValueReadAccessor(InputPort logicalSignal) {
-		return funcCall("gamepad_get_axis_position", rawString(getAxisIdentifier()));
+	public final String getReadCode(String prefix, InputPort logicalSignal) {
+		return "gamepad_get_axis_position(" + getAxisIdentifier() + ");\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getNoValReadCode(String prefix, InputPort logicalSignal) {
+		return null;
 	}
 
 	/** Returns the axis identifier as defined in {@code gamepad.h}. */
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/.ratings b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/.ratings
index 90b84b78..1df68179 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/.ratings
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/.ratings
@@ -1,6 +1,6 @@
 ButtonAExecutable.java bbcb151d851b1b3d3e97b7e11b790fa13559fd96 YELLOW
 ButtonBExecutable.java d659e04dc60cba0808bd2fceae22fcbc1bd203a9 YELLOW
-ButtonExecutableBase.java fd0f182816404870725255efeebfbc07c22a8295 YELLOW
+ButtonExecutableBase.java 168dede764665f721862d2b7aed3a5de5668c1f1 YELLOW
 ButtonHomeExecutable.java e3a19a82d2cafd3bc75b6a7fc1a75df5656df48c YELLOW
 ButtonL1Executable.java 68fac6c2abc7ea40eb7cc16839677a4cdc24111a YELLOW
 ButtonL3Executable.java 2d04b51ee7ab822419140cf69821bbcbcfded359 YELLOW
@@ -20,6 +20,6 @@ Left_StickYExecutable.java cc2b36f9bca913dc1956f34495cf9c77acb13c88 YELLOW
 R2PositionExecutable.java 19f778392841d02d281fd856564b75e1333dffaa YELLOW
 Right_StickXExecutable.java 97656a2ae56a70eac88153b123f2cd9c584af967 YELLOW
 Right_StickYExecutable.java f3d942123ca47d0ddbf32f4f46bfaf2b21732653 YELLOW
-RumblepadExecutableBase.java 35438b51af2212c2e169fb7008e9fe45c9b1aef6 YELLOW
+RumblepadExecutableBase.java 876ab9c58e37837b273bfcbbc62233ca4d0576cc YELLOW
 SimpleRumbleFeatureExecutable.java 413b6fb3f5847f0d09f52341c98b95f74c352016 YELLOW
-StickExecutableBase.java 372150ca78a1ee736bbb2910b266ca05d52aa04f YELLOW
+StickExecutableBase.java 7004e20d199bec82752b870db259786602db9766 YELLOW
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/ButtonExecutableBase.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/ButtonExecutableBase.java
index fd0f1828..168dede7 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/ButtonExecutableBase.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/ButtonExecutableBase.java
@@ -15,13 +15,9 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.rumblepad;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.funcCall;
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.rawString;
-
 import org.eclipse.emf.ecore.EObject;
 import org.fortiss.af3.component.model.InputPort;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.language.executable.IReadableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IReadableExecutable;
 
 /**
  * Base class for executables reading rumblepad buttons.
@@ -37,8 +33,14 @@ abstract class ButtonExecutableBase<T extends EObject> extends RumblepadExecutab
 
 	/** {@inheritDoc} */
 	@Override
-	public final IExpressionTerm getValueReadAccessor(InputPort logicalSignal) {
-		return funcCall("rumblepad_get_button_state", rawString(getButtonIdentifier()));
+	public final String getReadCode(String prefix, InputPort logicalSignal) {
+		return "rumblepad_get_button_state(" + getButtonIdentifier() + ");\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public final String getNoValReadCode(String prefix, InputPort logicalSignal) {
+		return null;
 	}
 
 	/** Returns the button identifier as defined in {@code rumblepad.h}. */
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/RumblepadExecutableBase.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/RumblepadExecutableBase.java
index 35438b51..876ab9c5 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/RumblepadExecutableBase.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/RumblepadExecutableBase.java
@@ -15,11 +15,8 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.rumblepad;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.rawString;
-
 import org.eclipse.emf.ecore.EObject;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.raspberry.generator.executable.framework.ISingletonInitializableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.ISingletonInitializationExecutable;
 import org.fortiss.af3.platform.raspberry.generator.executable.library.PiHALLibraryExecutableBase;
 import org.fortiss.af3.platform.raspberry.model.rumblepad.RumblepadPackage;
 
@@ -29,7 +26,7 @@ import org.fortiss.af3.platform.raspberry.model.rumblepad.RumblepadPackage;
  * @author hoelzl
  */
 abstract class RumblepadExecutableBase<T extends EObject> extends PiHALLibraryExecutableBase<T>
-		implements ISingletonInitializableExecutable {
+		implements ISingletonInitializationExecutable {
 	/** Constructor. */
 	public RumblepadExecutableBase(T modelElement) {
 		super(modelElement);
@@ -37,13 +34,19 @@ abstract class RumblepadExecutableBase<T extends EObject> extends PiHALLibraryEx
 
 	/** {@inheritDoc} */
 	@Override
-	public final IExpressionTerm getInitialization() {
-		return rawString("rumblepad_configuration_t* rumblepad_config = malloc(sizeof(rumblepad_configuration_t));\n"
+	public final String getSingletonVariableDeclarationCode() {
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public final String getSingletonInitializationCode() {
+		return "rumblepad_configuration_t* rumblepad_config = malloc(sizeof(rumblepad_configuration_t));\n"
 				+ "rumblepad_config->device_id = \"/dev/input/js0\";\n"
 				+ "rumblepad_config->waiting_sleep_in_micros = 50;\n"
 				+ "rumblepad_config->axis_callback = NULL;\n"
 				+ "rumblepad_config->button_callback = NULL;"
-				+ "rumblepad_initialize(rumblepad_config);\n\n");
+				+ "rumblepad_initialize(rumblepad_config);\n\n";
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/StickExecutableBase.java b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/StickExecutableBase.java
index 372150ca..7004e20d 100644
--- a/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/StickExecutableBase.java
+++ b/org.fortiss.af3.platform.raspberry/src/org/fortiss/af3/platform/raspberry/generator/executable/rumblepad/StickExecutableBase.java
@@ -15,13 +15,9 @@
 +--------------------------------------------------------------------------*/
 package org.fortiss.af3.platform.raspberry.generator.executable.rumblepad;
 
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.funcCall;
-import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.rawString;
-
 import org.eclipse.emf.ecore.EObject;
 import org.fortiss.af3.component.model.InputPort;
-import org.fortiss.af3.expression.model.terms.IExpressionTerm;
-import org.fortiss.af3.platform.language.executable.IReadableExecutable;
+import org.fortiss.af3.platform.raspberry.generator.executable.framework.IReadableExecutable;
 
 /**
  * Base class for executables reading rumblepad sticks and axis inputs.
@@ -37,8 +33,14 @@ abstract class StickExecutableBase<T extends EObject> extends RumblepadExecutabl
 
 	/** {@inheritDoc} */
 	@Override
-	public final IExpressionTerm getValueReadAccessor(InputPort logicalSignal) {
-		return funcCall("rumblepad_get_axis_position", rawString(getAxisIdentifier()));
+	public final String getReadCode(String prefix, InputPort logicalSignal) {
+		return "rumblepad_get_axis_position(" + getAxisIdentifier() + ");\n";
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public final String getNoValReadCode(String prefix, InputPort logicalSignal) {
+		return null;
 	}
 
 	/** Returns the axis identifier as defined in {@code rumblepad.h}. */
-- 
GitLab