Skip to content
Snippets Groups Projects
Commit c536254e authored by Florian Hölzl's avatar Florian Hölzl
Browse files

Generating main.c works for an initial version.

refs 3079
parent 8d88f427
No related branches found
No related tags found
No related merge requests found
Showing
with 256 additions and 8 deletions
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2017 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;
import static org.fortiss.af3.generator.common.utils.SourceModelElementFactory.createByteContentUnitForPluginFile;
import org.fortiss.af3.generator.common.model.c.CSourcePackage;
import org.fortiss.af3.generator.common.model.source.ByteContentUnit;
import org.fortiss.af3.platform.raspberry.AF3PlatformRaspberryActivator;
/**
* Class for copying the header files to the target folder.
*
* @author hoelzl
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
final class HeaderCopyGenerator {
/** Adds the header files to the given target {@link CSourcePackage}. */
public static void copyHeaderFiles(CSourcePackage incLibPack) throws Exception {
incLibPack.addUnit(copyAF3Hal("af3.h"));
incLibPack.addUnit(copyAF3Hal("cancatalog.h"));
incLibPack.addUnit(copyAF3Hal("caninbox.h"));
incLibPack.addUnit(copyAF3Hal("canoutbox.h"));
incLibPack.addUnit(copyAF3Hal("cansocket.h"));
incLibPack.addUnit(copyAF3Hal("canthread.h"));
incLibPack.addUnit(copyAF3Hal("debugprint.h"));
incLibPack.addUnit(copyAF3Hal("gamepad.h"));
incLibPack.addUnit(copyAF3Hal("protocol_can.h"));
incLibPack.addUnit(copyAF3Hal("protocol_control_center.h"));
incLibPack.addUnit(copyAF3Hal("protocol_coordinator.h"));
incLibPack.addUnit(copyAF3Hal("protocol_factory.h"));
incLibPack.addUnit(copyAF3Hal("protocol_worker.h"));
incLibPack.addUnit(copyAF3Hal("timeutil.h"));
}
/** Copies the AF3 HAL header file. */
private static ByteContentUnit copyAF3Hal(String header) throws Exception {
return copyHeader("af3pihal/", header);
}
/** Copies the brick header file. */
private static ByteContentUnit copyBrick(String header) throws Exception {
return copyHeader("brick/", header);
}
/** Copies the header file from the plugin path. */
private static ByteContentUnit copyHeader(String subDir, String headerName) throws Exception {
return createByteContentUnitForPluginFile(AF3PlatformRaspberryActivator.PLUGIN_ID,
"code-gen-hal/inc/" + subDir, headerName, false);
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2017 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;
import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getMainCFile;
import java.util.List;
import org.conqat.lib.commons.collections.Pair;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.model.Port;
import org.fortiss.af3.generator.common.model.source.AbstractUnit;
import org.fortiss.af3.platform.model.ExecutionUnit;
import org.fortiss.af3.platform.model.PlatformConnectorUnit;
import org.fortiss.af3.platform.raspberry.model.RaspberryPi;
import org.fortiss.tooling.kernel.extension.data.ITransformationContext;
/**
* Separate class for generating the main.c file.
*
* @author hoelzl
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
class MainGenerator {
/** Creates the main.c file. */
public AbstractUnit createMain(RaspberryPi executionUnit,
List<Pair<ExecutionUnit, Component>> deployedComponents,
List<Pair<PlatformConnectorUnit, Port>> deployedPorts, ITransformationContext context) {
// TODO: generate worker and syncbox code
return getMainCFile(executionUnit.getName(), executionUnit.isCoordinatorUnit(),
executionUnit.getCanCoordinationID(), executionUnit.getCycleTime(), 250,
"// TODO\n", "// TODO\n");
}
}
......@@ -21,6 +21,7 @@ import static org.fortiss.af3.expression.utils.ExpressionModelElementFactory.cre
import static org.fortiss.af3.generator.common.utils.CLanguageModelElementFacade.addUserHeaderInclude;
import static org.fortiss.af3.generator.common.utils.CLanguageModelElementFactory.createCSourcePackage;
import static org.fortiss.af3.generator.common.utils.SourceModelElementFactory.createByteContentUnitForPluginFile;
import static org.fortiss.af3.platform.raspberry.generator.executable.HeaderCopyGenerator.copyHeaderFiles;
import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getConfigureFile;
import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getEclipseProjectFile;
import static org.fortiss.af3.platform.raspberry.generator.templates.RasPiCTemplates.getMakedefsFile;
......@@ -64,7 +65,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
/** Folder name for library source files. */
private static final String SRC_LIB_SUB_PACKAGE_NAME = "src-lib";
/** Folder name for library include files. */
private static final String INC_LIB_SUB_PACKAGE_NAME = "inc-lib";
public static final String INC_LIB_SUB_PACKAGE_NAME = "inc-lib";
/** Folder name for linkable static library files. */
private static final String LIB_SUB_PACKAGE_NAME = "lib";
......@@ -87,6 +88,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
addEclipseCProjectFiles(sourcePackage, modelElement.getName());
addStaticLibraries(sourcePackage);
addConfigureAndMakedefsFiles(sourcePackage, modelElement.getName());
addMainFile(sourcePackage, deployedComponents, deployedPorts, context);
} catch(Exception ex) {
error(AF3PlatformRaspberryActivator.getDefault(), ex.getMessage(), ex);
ex.printStackTrace();
......@@ -94,6 +96,15 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
return sourcePackage;
}
/** Creates the main file by using the {@link MainGenerator} helper class. */
private void addMainFile(CSourcePackage sourcePackage,
List<Pair<ExecutionUnit, Component>> deployedComponents,
List<Pair<PlatformConnectorUnit, Port>> deployedPorts, ITransformationContext context) {
CSourcePackage srcGenPack = (CSourcePackage)sourcePackage.getSrcGenPackage();
MainGenerator mg = new MainGenerator();
srcGenPack.addUnit(mg.createMain(modelElement, deployedComponents, deployedPorts, context));
}
/** Adds the build process files: configure and Makedefs. */
private void addConfigureAndMakedefsFiles(CSourcePackage sourcePackage, String binaryName) {
sourcePackage.addUnit(getConfigureFile(binaryName));
......@@ -117,6 +128,7 @@ public class RaspberryPIExecutable extends ExecutionUnitExecutableBase<Raspberry
sourcePackage.getSubPackages().add(lib);
lib.addUnit(getStaticLibraryUnit("libbrick.a"));
lib.addUnit(getStaticLibraryUnit("libaf3pihal.a"));
copyHeaderFiles(incLib);
}
/** Creates a {@link ByteContentUnit} for the given static library. */
......
group ConfigureFile;
ConfigureFile(binary) ::= <<
ConfigureFile(UNIT_NAME) ::= <<
#!/bin/sh
# The application's name.
APPL="$binary$";
APPL="$UNIT_NAME$";
# The root path for this script.
if [ -z "\$ROOT" ]; then ROOT="."; fi;
......
group MainFile;
MainFile(UNIT_NAME,
COORDINATOR_OR_WORKER,
CAN_ID_UNIT_DONE,
CYCLE_TIME_IN_MILLIS,
WAITING_SLEEPTIME_IN_MICROS,
SYNC_BOX_SETUP_CODE,
WORKER_CODE) ::= <<
#include <stdbool.h>
#include <stddef.h>
#include <unistd.h>
#include <af3.h>
#include <cancatalog.h>
#include <caninbox.h>
#include <canoutbox.h>
#include <debugprint.h>
#include <protocol_control_center.h>
#include <protocol_coordinator.h>
#include <protocol_factory.h>
#define WAITING_SLEEPTIME_IN_MICROS (uint64_t)$WAITING_SLEEPTIME_IN_MICROS$
#define STOP_AT_LOGICAL_CLOCK (uint64_t)0 // run infinitely
#define BRICK_HOST "localhost"
#define BRICK_PORT 4223
#define CAN_ID_GLOBAL_SHUTDOWN 0x00
#define CAN_ID_COORDINATOR_CLOCK 0x01
#define CAN_ID_UNIT_DONE $CAN_ID_UNIT_DONE$
static const char* can_device = "can0";
static can_inbox_t* app_inbox = NULL;
static can_inbox_t* sync_inbox= NULL;
static can_outbox_t* app_outbox = NULL;
static uint64_t step = 0;
static void worker() {
step++;
$WORKER_CODE$
}
int main(int argc, char** argv) {
// initialize CAN interface with catalog implementation
can_catalog_initialize(can_device, $WAITING_SLEEPTIME_IN_MICROS$);
// set AF3 unit name used when communicating with CC
af3_set_execution_unit_identifier("$UNIT_NAME$");
// TODO: initialize ControlCenter connection
// snychronization message box
sync_inbox = can_inbox_create("$UNIT_NAME$_sync_inbox", 2);
$SYNC_BOX_SETUP_CODE$
// application message boxes
app_inbox = can_inbox_create("$UNIT_NAME$_app_inbox", 1);
app_outbox = can_outbox_create("$UNIT_NAME$_sensor_app_outbox");
protocol_can_config_t* can_config = protocol_can_config_create(
$CAN_ID_UNIT_DONE$,
CAN_ID_COORDINATOR_CLOCK,
CAN_ID_GLOBAL_SHUTDOWN);
protocol_worker_clock_config_t* clock_config = protocol_worker_clock_config_create(
$CYCLE_TIME_IN_MILLIS$,
STOP_AT_LOGICAL_CLOCK,
$WAITING_SLEEPTIME_IN_MICROS$);
protocol_worker_computation_config_t* computation_config = protocol_worker_computation_config_create(
"$UNIT_NAME$",
worker,
sync_inbox,
app_inbox,
app_outbox,
0);
#if $COORDINATOR_OR_WORKER$
int result = protocol_coordinator_main(can_config, clock_config, computation_config);
#else
int result = protocol_worker_main(can_config, clock_config, computation_config);
#endif
debug_print(DEBUG_PRINT_LEVEL_NONE, "$UNIT_NAME$ main() returned %i.\n", result);
// clean up
can_inbox_destroy(sync_inbox);
can_inbox_destroy(app_inbox);
can_outbox_destroy(app_outbox);
free(can_config);
free(clock_config);
free(computation_config);
return result;
}
>>
......@@ -48,5 +48,8 @@ clean:
\${BPATH}/%.run:
@echo "linking application '\${@}' ..."
@\${CROSSLD} \${LDFLAGS} -o \${@} \$(filter %.o %.a, \${^})
# The rule to clean and remove generated Makefile
mrproper: clean
@rm -f Makefile
>>
group ProjectFile;
ProjectFile(projectname) ::= <<
ProjectFile(PROJECT_NAME) ::= <<
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>$projectname$</name>
<name>$PROJECT_NAME$</name>
<comment></comment>
<projects>
</projects>
......
......@@ -39,10 +39,27 @@ import org.fortiss.af3.generator.common.model.source.StaticContentSourceUnit;
* @ConQAT.Rating RED Hash:
*/
public final class RasPiCTemplates {
/** Returns the 'main.c' file configured using the given arguments. */
public static AbstractUnit getMainCFile(String unitName, boolean coordinatorOrWorker,
int canIdUnitDone, int cycletimeInMillis, int waitingSleepInMicros,
String syncBoxSetupCode, String workerCode) {
StringTemplate template = makeTemplate("MainFile.stg", "MainFile");
template.setAttribute("UNIT_NAME", unitName);
template.setAttribute("COORDINATOR_OR_WORKER", coordinatorOrWorker ? 1 : 0);
template.setAttribute("CAN_ID_UNIT_DONE", canIdUnitDone);
template.setAttribute("CYCLE_TIME_IN_MILLIS", cycletimeInMillis);
template.setAttribute("WAITING_SLEEPTIME_IN_MICROS", waitingSleepInMicros);
template.setAttribute("SYNC_BOX_SETUP_CODE", syncBoxSetupCode);
template.setAttribute("WORKER_CODE", workerCode);
StaticContentSourceUnit unit =
createStaticContentSourceUnit("main.c", template.toString(), false);
return unit;
}
/** Returns the '.project' file used for Eclipse project. */
public static AbstractUnit getEclipseProjectFile(String projectName) {
StringTemplate template = makeTemplate("ProjectFile.stg", "ProjectFile");
template.setAttribute("projectname", projectName);
template.setAttribute("PROJECT_NAME", projectName);
StaticContentSourceUnit unit =
createStaticContentSourceUnit(".project", template.toString(), false);
return unit;
......@@ -51,7 +68,7 @@ public final class RasPiCTemplates {
/** Returns the 'configure' file used to create a Makefile. */
public static AbstractUnit getConfigureFile(String binaryName) {
StringTemplate template = makeTemplate("ConfigureFile.stg", "ConfigureFile");
template.setAttribute("binary", binaryName);
template.setAttribute("UNIT_NAME", binaryName);
return createStaticContentSourceUnit("configure", template.toString(), true);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment