Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Haug2015-12-23 11:35:03 +0000
committerJuergen Haug2016-02-28 17:01:11 +0000
commit81750c5e633ad14e7ab25b016564af20fec0a1cc (patch)
tree951ca972625f09ffee924496591e97d927a74f0d /plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c
parentdc98de4bb145d8d3789909e32c11765596165fbb (diff)
downloadorg.eclipse.etrice-81750c5e633ad14e7ab25b016564af20fec0a1cc.tar.gz
org.eclipse.etrice-81750c5e633ad14e7ab25b016564af20fec0a1cc.tar.xz
org.eclipse.etrice-81750c5e633ad14e7ab25b016564af20fec0a1cc.zip
[generators] added cpp generator draft
Diffstat (limited to 'plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c')
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend153
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend92
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend275
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend31
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java12
5 files changed, 267 insertions, 296 deletions
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
index 03c557429..c4d14fa5e 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
@@ -4,11 +4,11 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* CONTRIBUTORS:
* Henrik Rentz-Reichert (initial contribution)
* Thomas Schuetz (changed for C code generator)
- *
+ *
*******************************************************************************/
package org.eclipse.etrice.generator.c.gen
@@ -19,7 +19,6 @@ import org.eclipse.etrice.core.fsm.fSM.ComponentCommunicationType
import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass
import org.eclipse.etrice.core.genmodel.etricegen.Root
import org.eclipse.etrice.core.genmodel.fsm.base.ILogger
-import org.eclipse.etrice.core.room.ActorClass
import org.eclipse.etrice.core.room.CommunicationType
import org.eclipse.etrice.core.room.Operation
import org.eclipse.etrice.core.room.ProtocolClass
@@ -33,7 +32,7 @@ import org.eclipse.etrice.generator.generic.RoomExtensions
@Singleton
class ActorClassGen extends GenericActorClassGenerator {
-
+
@Inject protected extension RoomExtensions
@Inject extension CExtensions
@Inject extension ProcedureHelpers
@@ -42,16 +41,16 @@ class ActorClassGen extends GenericActorClassGenerator {
@Inject protected ILanguageExtension langExt
@Inject IGeneratorFileIo fileIO
@Inject ILogger logger
-
+
def doGenerate(Root root) {
for (xpac: root.xpActorClasses) {
val path = xpac.actorClass.generationTargetPath+xpac.actorClass.getPath
val infopath = xpac.actorClass.generationInfoPath+xpac.actorClass.getPath
var file = xpac.actorClass.getCHeaderFileName
-
+
// header file
fileIO.generateFile("generating ActorClass header", path, infopath, file, root.generateHeaderFile(xpac))
-
+
// utils file
file = xpac.actorClass.getCUtilsFileName
fileIO.generateFile("generating ActorClass utils", path, infopath, file, root.generateUtilsFile(xpac))
@@ -66,7 +65,7 @@ class ActorClassGen extends GenericActorClassGenerator {
}
}
}
-
+
def private generateHeaderFile(Root root, ExpandedActorClass xpac) {
val ac = xpac.actorClass
val eventPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::EVENT_DRIVEN)
@@ -77,20 +76,20 @@ class ActorClassGen extends GenericActorClassGenerator {
val hasConstData = !(eventPorts.empty && recvPorts.empty && ac.allSAPs.empty && ac.allServiceImplementations.empty)
|| Main::settings.generateMSCInstrumentation
val hasVarData = !(sendPorts.empty && ac.allAttributes.empty && xpac.stateMachine.empty && !hasConstData)
-
+
'''
/**
* @author generated by eTrice
*
* Header File of ActorClass «ac.name»
- *
+ *
*/
-
+
«generateIncludeGuardBegin(ac)»
-
+
#include "etDatatypes.h"
#include "messaging/etMessage.h"
-
+
«FOR dataClass : root.getReferencedDataClasses(ac)»
#include «dataClass.includePath»
«ENDFOR»
@@ -100,17 +99,17 @@ class ActorClassGen extends GenericActorClassGenerator {
«FOR pc : root.getReferencedProtocolClasses(ac)»
#include «pc.includePath»
«ENDFOR»
-
+
«ac.userCode(1, true)»
-
+
typedef struct «ac.name» «ac.name»;
-
+
/* const part of ActorClass (ROM) */
«IF hasConstData»
typedef struct «ac.name»_const {
«IF Main::settings.generateMSCInstrumentation»
const char* instName;
-
+
«ENDIF»
/* simple ports */
«FOR ep : eventPorts»
@@ -118,7 +117,7 @@ class ActorClassGen extends GenericActorClassGenerator {
const «ep.getPortClassName()» «ep.name»;
«ENDIF»
«ENDFOR»
-
+
/* data receive ports */
«FOR ep : recvPorts»
«IF ep.multiplicity==1»
@@ -130,14 +129,14 @@ class ActorClassGen extends GenericActorClassGenerator {
«FOR sap: ac.allSAPs»
const «sap.getPortClassName()» «sap.name»;
«ENDFOR»
-
+
/* replicated ports */
«FOR ep : ac.allEndPorts»
«IF ep.multiplicity!=1»
const etReplPort «ep.name»;
«ENDIF»
«ENDFOR»
-
+
/* services */
«FOR svc : ac.allServiceImplementations»
const etReplPort «svc.spp.name»;
@@ -146,18 +145,18 @@ class ActorClassGen extends GenericActorClassGenerator {
«ELSE»
/* this actor class has no ports and thus no constant data */
«ENDIF»
-
+
«IF !xpac.stateMachine.empty»
-
+
«xpac.genHeaderConstants»
«ENDIF»
-
+
/* variable part of ActorClass (RAM) */
«IF hasVarData»
struct «ac.name» {
«IF hasConstData»
const «ac.name»_const* const constData;
-
+
«ENDIF»
/* data send ports */
«FOR ep : sendPorts»
@@ -165,11 +164,11 @@ class ActorClassGen extends GenericActorClassGenerator {
«ep.getPortClassName()» «ep.name»;
«ENDIF»
«ENDFOR»
-
+
«ac.allAttributes.attributes»
-
+
«IF !xpac.stateMachine.empty»
-
+
«xpac.genDataMembers»
«ENDIF»
};
@@ -186,23 +185,22 @@ class ActorClassGen extends GenericActorClassGenerator {
void «ac.name»_init(«ac.name»* self);
void «ac.name»_receiveMessage(void* self, const void* ifitem, const etMessage* msg);
-
+
«IF dataDriven || async»
void «ac.name»_execute(«ac.name»* self);
«ENDIF»
-
- «IF ac.allStructors.exists[isConstructor]»«getConstructorSignature(ac.name)»;«ENDIF»
- «IF ac.allStructors.exists[!isConstructor]»«getDestructorSignature(ac.name)»;«ENDIF»
-
+
+ «ac.userStructorsDeclaration»
+
«ac.latestOperations.operationsDeclaration(ac.name)»
-
+
«ac.userCode(2, true)»
-
+
«generateIncludeGuardEnd(ac)»
-
+
'''
}
-
+
def private generateUtilsFile(Root root, ExpandedActorClass xpac) {
val ac = xpac.actorClass
val eventPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::EVENT_DRIVEN)
@@ -211,23 +209,23 @@ class ActorClassGen extends GenericActorClassGenerator {
val recvPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::DATA_DRIVEN && !p.conjugated && p.multiplicity==1)
val portsWithOperations = ac.allInterfaceItems.filter(p|p.portClass!=null && p.portClass.operations.size>0)
val filename = (ac.eContainer as RoomModel).name.replaceAll("\\.","_")+"_"+ac.name+"_Utils"
-
+
'''
/**
* @author generated by eTrice
*
* Utils File of ActorClass «ac.name»
- *
+ *
*/
-
+
«generateIncludeGuardBegin(filename)»
-
+
#include «ac.includePath»
-
+
/*
* access macros for ports, operations and attributes
*/
-
+
/* simple event ports */
«FOR ep : eventPorts.filter[multiplicity==1]»
«FOR msg : ep.outgoing»
@@ -236,14 +234,14 @@ class ActorClassGen extends GenericActorClassGenerator {
#define «ep.name»_«msg.name»(«data1») «ep.portClassName»_«msg.name»(&self->constData->«ep.name»«data2»)
«ENDFOR»
«ENDFOR»
-
+
/* data receive ports */
«FOR ep : recvPorts»
«FOR msg : ep.incoming»
#define «ep.name»_«msg.name» «ep.portClassName»_«msg.name»_get(&self->constData->«ep.name»)
«ENDFOR»
«ENDFOR»
-
+
/* data send ports */
«FOR ep : sendPorts»
«FOR msg : ep.outgoing»
@@ -261,7 +259,7 @@ class ActorClassGen extends GenericActorClassGenerator {
#define «sap.name»_«msg.name»(«data1») «sap.portClassName»_«msg.name»(&self->constData->«sap.name»«data2»)
«ENDFOR»
«ENDFOR»
-
+
/* replicated event ports */
«IF !replEventPorts.empty»
#define ifitem_index (((etReplSubPort*)ifitem)->index)
@@ -274,7 +272,7 @@ class ActorClassGen extends GenericActorClassGenerator {
#define «ep.name»_«msg.name»(idx«data2») «ep.portClassName»_«msg.name»(&self->constData->«ep.name», idx«data2»)
«ENDFOR»
«ENDFOR»
-
+
/* services */
«FOR svc : ac.allServiceImplementations»
«FOR msg : svc.spp.outgoing»
@@ -284,18 +282,18 @@ class ActorClassGen extends GenericActorClassGenerator {
#define «svc.spp.name»_«msg.name»(idx«data2») «svc.spp.portClassName»_«msg.name»(&self->constData->«svc.spp.name», idx«data2»)
«ENDFOR»
«ENDFOR»
-
+
/* operations */
«FOR op : ac.latestOperations»
«val args = op.argList»
#define «op.name»(«args») «ac.name»_«op.name»(self«IF !op.arguments.empty», «args»«ENDIF»)
«ENDFOR»
-
+
/* attributes */
«FOR a : ac.allAttributes»
#define «a.name» (self->«a.name»)
«ENDFOR»
-
+
/* port operations */
«FOR p : portsWithOperations»
«FOR op : p.portClass.operations»
@@ -303,33 +301,33 @@ class ActorClassGen extends GenericActorClassGenerator {
#define «p.name»_«op.name»(«args») «p.portClassName»_«op.name»((«p.portClassName»*)&self->constData->«p.name»«IF !op.arguments.empty», «args»«ENDIF»)
«ENDFOR»
«ENDFOR»
-
+
«generateIncludeGuardEnd(filename)»
-
+
'''
}
-
+
private def argList(Operation op) {
'''«FOR a : op.arguments SEPARATOR ", "»«a.name»«ENDFOR»'''
}
-
+
def private generateSourceFile(Root root, ExpandedActorClass xpac) {
val ac = xpac.actorClass
val async = ac.commType==ComponentCommunicationType::ASYNCHRONOUS
val eventDriven = ac.commType==ComponentCommunicationType::EVENT_DRIVEN
val dataDriven = ac.commType==ComponentCommunicationType::DATA_DRIVEN
val handleEvents = async || eventDriven
-
+
'''
/**
* @author generated by eTrice
*
* Source File of ActorClass «ac.name»
- *
+ *
*/
#include "«ac.getCHeaderFileName»"
-
+
#include "modelbase/etActor.h"
#include "debugging/etLogger.h"
#include "debugging/etMSCLogger.h"
@@ -339,9 +337,9 @@ class ActorClassGen extends GenericActorClassGenerator {
«FOR pc : root.getReferencedProtocolClasses(ac)»
#include «pc.includePath»
«ENDFOR»
-
+
#include "«ac.getCUtilsFileName»"
-
+
«ac.userCode(3, true)»
/* interface item IDs */
@@ -350,7 +348,7 @@ class ActorClassGen extends GenericActorClassGenerator {
«IF !xpac.stateMachine.empty»
«xpac.genStateMachine()»
«ENDIF»
-
+
void «ac.name»_init(«ac.name»* self){
ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "init")
«IF !xpac.stateMachine.empty»
@@ -358,8 +356,8 @@ class ActorClassGen extends GenericActorClassGenerator {
«ENDIF»
ET_MSC_LOGGER_SYNC_EXIT
}
-
-
+
+
void «ac.name»_receiveMessage(void* self, const void* ifitem, const etMessage* msg){
ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "_receiveMessage")
«IF !xpac.stateMachine.empty»
@@ -369,47 +367,30 @@ class ActorClassGen extends GenericActorClassGenerator {
«langExt.operationScope(ac.name, false)»receiveEventInternal(self);
«ENDIF»
«ENDIF»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
-
+
«IF dataDriven || async»
void «ac.name»_execute(«ac.name»* self) {
ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "_execute")
«IF !xpac.stateMachine.empty»
-
+
«IF handleEvents»
«langExt.operationScope(ac.name, false)»receiveEvent(self, NULL, 0, NULL);
«ELSE»
«langExt.operationScope(ac.name, false)»receiveEventInternal(self);
«ENDIF»
«ENDIF»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
«ENDIF»
-
- «classStructors(ac)»
-
+
+ «ac.userStructorsImplementation»
+
«operationsImplementation(ac.latestOperations, ac.name)»
-
- '''
- }
-
- def protected classStructors(ActorClass ac){
- val ctors = ac.allStructors.filter[isConstructor]
- val dtors = ac.allStructors.filter[!isConstructor]
- '''
- «IF !ctors.isEmpty»
- «getConstructorSignature(ac.name)»{
- «ctors.map[translator.getTranslatedCode(detailCode).asBlock].join»
- }
- «ENDIF»
- «IF !dtors.isEmpty»
- «getDestructorSignature(ac.name)»{
- «dtors.map[translator.getTranslatedCode(detailCode).asBlock].join»
- }
- «ENDIF»
+
'''
}
}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
index fcb2d9da7..6ecaca306 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
@@ -4,11 +4,11 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* CONTRIBUTORS:
* Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
* Thomas Schuetz (changed for C code generator)
- *
+ *
*******************************************************************************/
/*
@@ -61,7 +61,7 @@ class CExtensions implements ILanguageExtension {
override String accessLevelPrivate(){"static "}
override String accessLevelProtected(){"static "}
override String accessLevelPublic(){""}
-
+
override String memberAccess(){"self->"}
override String selfPointer(String classname, boolean hasArgs){
classname+
@@ -70,7 +70,7 @@ class CExtensions implements ILanguageExtension {
else
"* self"
}
-
+
override String selfPointer(boolean hasArgs) { if (hasArgs) "self, " else "self" }
override String operationScope(String classname, boolean isDeclaration){classname+"_"}
@@ -78,14 +78,14 @@ class CExtensions implements ILanguageExtension {
override String memberInDeclaration(String namespace, String member) {
return namespace+"_"+member
}
-
+
override String memberInUse(String namespace, String member) {
return namespace+"_"+member
}
//**** C-Specific
- /* TODO: move specific code elsewhere */
+ /* TODO: move specific code elsewhere */
// used
def String getCHeaderFileName(RoomClass rc) {
return rc.name+".h";
@@ -108,7 +108,7 @@ class CExtensions implements ILanguageExtension {
def String getDispSourceFileName(RoomClass rc) {
return rc.name+"_Disp.h";
}
-
+
// used
def String getCHeaderFileName(NodeRef nr, SubSystemInstance ssi) {
return nr.name+"_"+ssi.name+".h";
@@ -152,19 +152,19 @@ class CExtensions implements ILanguageExtension {
#endif /* «filename.getIncludeGuardString» */
'''
}
-
+
override boolean usesInheritance() {
return false
}
-
+
override boolean usesPointers() {
return true
}
-
+
override String genEnumeration(String name, List<Pair<String, String>> entries) {
if (entries.empty)
return "/* empty enum not generated */"
-
+
'''
enum «name» {
«FOR entry: entries SEPARATOR ","»
@@ -177,32 +177,16 @@ class CExtensions implements ILanguageExtension {
override String booleanConstant(boolean b) {
if (b) "ET_TRUE" else "ET_FALSE"
}
-
+
override String pointerLiteral() { "*" }
override String nullPointer() { "NULL" }
override String voidPointer() { "void*" }
-
- override String arrayDeclaration(String type, int size, String name, boolean isRef) {
- if (isRef){
- type+"* "+name+"["+size+"]";
- }else {
- type+" "+name+"["+size+"]";
- }
- }
-
- override String constructorName(String cls) {
- "ctor"
- }
- override String destructorName(String cls) {
- "dtor"
- }
- override String constructorReturnType() {
- "void"
- }
- override String destructorReturnType() {
- "void"
- }
-
+ override String typeArrayModifier() { pointerLiteral }
+
+ override String arrayDeclaration(String type, int size, String name, boolean isRef)'''
+ «type»«IF isRef»*«ENDIF» «name»[«size»]
+ '''
+
override String superCall(String baseClassName, String method, String args) {
""
}
@@ -220,10 +204,10 @@ class CExtensions implements ILanguageExtension {
case "boolean":
if (value.equals("true")) "ET_TRUE" else "ET_FALSE"
default:
- value
+ value
}
}
-
+
override toEnumLiteral(EnumerationType type, String value) {
if(value.contains(',') || value.contains('{')){
var singleValues = value.replace('{', '').replace('}', '').trim.split(',')
@@ -231,7 +215,7 @@ class CExtensions implements ILanguageExtension {
} else
convertStringEnumLiteral(type, value)
}
-
+
def private convertStringEnumLiteral(EnumerationType type, String value){
var v = value
if (v.startsWith(type.name))
@@ -253,7 +237,7 @@ class CExtensions implements ILanguageExtension {
diagnostician.error("external type "+dt.name + "has no default initialization", dt.eContainer, dt.eContainingFeature)
""
}
- DataClass:
+ DataClass:
'''
{
«FOR att : dt.allAttributes SEPARATOR ","»
@@ -263,14 +247,14 @@ class CExtensions implements ILanguageExtension {
'''
}
}
-
+
def String getDefaultValue(EnumerationType type) {
if (type.getLiterals().isEmpty())
""
else
getCastedValue(type.getLiterals().get(0))
}
-
+
override initializationWithDefaultValues(DataType dt, int size) {
val dv = dt.defaultValue
dv.initializer(size)
@@ -291,7 +275,7 @@ class CExtensions implements ILanguageExtension {
else
dv
}
-
+
def initializationWithDefaultValues(Attribute att) {
val dv = att.defaultValueLiteral
if (dv!=null) {
@@ -306,15 +290,15 @@ class CExtensions implements ILanguageExtension {
else
att.type.type.initializationWithDefaultValues(att.size)
}
-
+
override generateArglistAndTypedData(EObject d) {
if (d==null || !(d instanceof VarDecl))
return newArrayList("", "", "")
-
+
val data = d as VarDecl
if (data==null)
return newArrayList("", "", "")
-
+
var typeName = if (data.getRefType().getType() instanceof PrimitiveType)
(data.getRefType().getType() as PrimitiveType).targetName
else if (data.getRefType().getType() instanceof EnumerationType)
@@ -323,7 +307,7 @@ class CExtensions implements ILanguageExtension {
(data.getRefType().getType() as ExternalType).targetName
else
data.getRefType().getType().getName()
-
+
var castTypeName = if (data.getRefType().getType() instanceof PrimitiveType) {
val ct = (data.getRefType().getType() as PrimitiveType).getCastName()
if (ct!=null && !ct.isEmpty())
@@ -338,7 +322,7 @@ class CExtensions implements ILanguageExtension {
typeName
castTypeName = castTypeName+"*"
var deRef = "*"
-
+
val isRef = data.getRefType().isRef()
val isPrim = (data.getRefType().getType() instanceof PrimitiveType || data.getRefType().getType() instanceof EnumerationType)
if (isRef) {
@@ -351,41 +335,41 @@ class CExtensions implements ILanguageExtension {
deRef = ""
}
}
-
+
val typedData = typeName+" "+data.getName() + " = "+deRef+"(("+castTypeName+") generic_data__et);\n"
val dataArg = ", "+data.getName()
val typedArgList = ", "+typeName+" "+data.getName()
-
+
return newArrayList(dataArg, typedData, typedArgList);
}
-
+
def getIncludePath(RoomClass rc) {
"\""+(rc.eContainer as RoomModel).name.replaceAll("\\.","/")+"/"+rc.getCHeaderFileName+"\""
}
-
+
override getTargetType(EnumerationType type) {
if (type.getPrimitiveType()!=null)
type.getPrimitiveType().getTargetName()
else
type.getName()
}
-
+
override getCastedValue(EnumLiteral literal) {
val type = literal.eContainer() as EnumerationType
val cast = type.targetType
-
+
if (type.primitiveType==null)
Long.toString(literal.getLiteralValue())
else
"(("+cast+")"+Long.toString(literal.getLiteralValue())+")"
}
-
+
override getCastType(EnumerationType type) {
if (type.getPrimitiveType()!=null)
type.getPrimitiveType().getCastName()
else
type.getName()
}
-
+
}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend
index 34c27b984..1e849d8c2 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend
@@ -4,11 +4,11 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* CONTRIBUTORS:
* Henrik Rentz-Reichert (initial contribution)
* Thomas Schuetz (changed for C code generator)
- *
+ *
*******************************************************************************/
package org.eclipse.etrice.generator.c.gen
@@ -50,19 +50,19 @@ import org.eclipse.etrice.generator.generic.TypeHelpers
@Singleton
class NodeGen {
-
+
@Inject extension RoomHelpers
@Inject extension CExtensions
@Inject extension RoomExtensions
@Inject extension TypeHelpers
@Inject extension ProcedureHelpers helpers
-
+
@Inject IGeneratorFileIo fileIO
@Inject Initialization attrInitGenAddon
@Inject ILanguageExtension languageExt
@Inject IDiagnostician diagnostician
@Inject ILogger logger;
-
+
def doGenerate(Root root) {
for (nr : ETMapUtil::getNodeRefs()) {
for (instpath : ETMapUtil::getSubSystemInstancePaths(nr)) {
@@ -71,19 +71,19 @@ class NodeGen {
val filepath = ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath
val infopath = ssi.subSystemClass.generationInfoPath+ssi.subSystemClass.getPath
var file = nr.getCHeaderFileName(ssi)
-
+
checkDataPorts(ssi)
-
+
val usedThreads = ETMapUtil::getUsedThreads(nr, ssi)
-
+
fileIO.generateFile("generating Node declaration", filepath, infopath, file, root.generateHeaderFile(ssi))
-
+
file = nr.getCSourceFileName(ssi)
fileIO.generateFile("generating Node implementation", filepath, infopath, file, root.generateSourceFile(ssi, usedThreads))
-
+
file = nr.getInstSourceFileName(ssi)
fileIO.generateFile("generating Node instance file", filepath, infopath, file, root.generateInstanceFile(ssi, usedThreads))
-
+
file = nr.getDispSourceFileName(ssi)
fileIO.generateFile("generating Node dispatcher file", filepath, infopath, file, root.generateDispatcherFile(ssi, usedThreads))
}
@@ -100,40 +100,40 @@ class NodeGen {
* @author generated by eTrice
*
* Header File of Node «nr.name» with SubSystem «ssi.name»
- *
+ *
*/
-
+
«generateIncludeGuardBegin(clsname)»
-
+
#include "etDatatypes.h"
««« TODOCGENPHYS: user code?
«helpers.userCode(ssc.userCode1)»
-
-
+
+
/* lifecycle functions
* init -> start -> run (loop) -> stop -> destroy
*/
-
+
void «clsname»_init(void); /* lifecycle init */
void «clsname»_start(void); /* lifecycle start */
-
+
void «clsname»_run(etBool runAsTest); /* lifecycle run */
-
+
void «clsname»_stop(void); /* lifecycle stop */
void «clsname»_destroy(void); /* lifecycle destroy */
-
+
void «clsname»_shutdown(void); /* shutdown the dispatcher loop */
-
+
««« TODOCGENPHYS: user code?
«helpers.userCode(ssc.userCode2)»
-
+
«generateIncludeGuardEnd(clsname)»
-
-
+
+
'''
}
-
+
def private generateSourceFile(Root root, SubSystemInstance ssi, Collection<PhysicalThread> usedThreads) {
val nr = ETMapUtil::getNodeRef(ssi)
val ssc = ssi.subSystemClass
@@ -145,13 +145,13 @@ class NodeGen {
* @author generated by eTrice
*
* Source File of Node «nr.name» with SubSystem «ssi.name»
- *
+ *
*/
-
+
#include <stdio.h>
#include <string.h>
-
-
+
+
#include "«nr.getCHeaderFileName(ssi)»"
#include "debugging/etLogger.h"
@@ -165,18 +165,18 @@ class NodeGen {
««« TODOCGENPHYS: user code?
«helpers.userCode(ssc.userCode3)»
-
+
/* data for Node «nr.name» with SubSystem «ssi.name» */
typedef struct «clsname» {
char *name;
volatile int shutdownRequest;
} «clsname»;
-
+
static «clsname» «clsname»Inst = {"«clsname»", 0};
-
+
static void «clsname»_initActorInstances(void);
static void «clsname»_constructActorInstances(void);
-
+
/* include instances for all classes */
#include "«nr.getInstSourceFileName(ssi)»"
#include "«nr.getDispSourceFileName(ssi)»"
@@ -185,7 +185,7 @@ class NodeGen {
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "initMessageServices")
{
etTime interval;
-
+
/* initialization of all message services */
«FOR thread: threads»
«IF thread.execmode==ExecMode::POLLED || thread.execmode==ExecMode::MIXED»
@@ -202,56 +202,56 @@ class NodeGen {
interval,
MsgDispatcher_«thread.name»_receiveMessage,
EXECMODE_«thread.execmode.toString.toUpperCase»);
-
+
«ENDFOR»
}
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
static void «clsname»_startMessageServices(void) {
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "startMessageServices")
-
+
«FOR thread: threads.sortBy[getPrio].reverse»
etMessageService_start(&msgService_«thread.name»);
«ENDFOR»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
static void «clsname»_stopMessageServices(void) {
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "stopMessageServices")
-
+
«FOR thread: threads»
etMessageService_stop(&msgService_«thread.name»);
«ENDFOR»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
static void «clsname»_destroyMessageServices(void) {
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "destroyMessageServices")
-
+
«FOR thread: threads»
etMessageService_destroy(&msgService_«thread.name»);
«ENDFOR»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
-
+
void «clsname»_init(void) {
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "init")
etLogger_logInfoF("%s_init", «clsname»Inst.name);
-
+
/* construct all actors */
«clsname»_constructActorInstances();
-
+
/* initialization of all message services */
«clsname»_initMessageServices();
-
+
/* init all actors */
«clsname»_initActorInstances();
-
+
«IF logData»
«FOR thread: threads»
MsgDispatcher_«thread.name»_logDataHeaders();
@@ -260,21 +260,21 @@ class NodeGen {
MsgDispatcher_«thread.name»_logData();
«ENDFOR»
«ENDIF»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
-
+
void «clsname»_start(void) {
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "start")
etLogger_logInfoF("%s_start", «clsname»Inst.name);
«clsname»_startMessageServices();
ET_MSC_LOGGER_SYNC_EXIT
}
-
+
void «clsname»_run(etBool runAsTest) {
- #ifdef ET_RUNNER_ACTIVATE
+ #ifdef ET_RUNNER_ACTIVATE
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "run")
-
+
if (runAsTest) {
etSema_waitForWakeup(etRuntime_getTerminateSemaphore());
}
@@ -283,70 +283,67 @@ class NodeGen {
fflush(stdout);
while (ET_TRUE) {
char line[64];
-
+
if (fgets(line, 64, stdin) != NULL) {
if (strncmp(line, "quit", 4)==0)
break;
}
}
}
-
+
ET_MSC_LOGGER_SYNC_EXIT
- #endif
+ #endif
}
-
+
void «clsname»_stop(void){
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "stop")
etLogger_logInfoF("%s_stop", «clsname»Inst.name);
-
+
«clsname»_stopMessageServices();
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
-
+
void «clsname»_destroy(void){
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "destroy")
etLogger_logInfoF("%s_destroy", «clsname»Inst.name);
- «FOR ai : ssi.allContainedInstances.reverseView»
- «IF ai.actorClass.allStructors.exists[!isConstructor]»
- «languageExt.memberInUse(ai.actorClass.name, languageExt.destructorName(ai.actorClass.name))»(&«ai.path.getPathName()»);
- «ENDIF»
+
+ «FOR ai : ssi.allContainedInstances»
+ «invokeUserStructor(ai.actorClass, '&'+ai.path.getPathName(), false)»
«ENDFOR»
-
+
«clsname»_destroyMessageServices();
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
void «clsname»_shutdown(void){
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "shutdown")
etLogger_logInfoF("%s_shutdown", «clsname»Inst.name);
-
+
«clsname»Inst.shutdownRequest = 1;
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
static void «clsname»_constructActorInstances(void){
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "constructActorInstances")
-
+
«FOR ai : ssi.allContainedInstances»
- «IF ai.actorClass.allStructors.exists[isConstructor]»
- «languageExt.memberInUse(ai.actorClass.name, languageExt.constructorName(ai.actorClass.name))»(&«ai.path.getPathName()»);
- «ENDIF»
+ «invokeUserStructor(ai.actorClass, '&'+ai.path.getPathName(), true)»
«ENDFOR»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
static void «clsname»_initActorInstances(void){
ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "initActorInstances")
-
+
«FOR ai : ssi.allContainedInstances»
«ai.actorClass.name»_init(&«ai.path.getPathName()»);
«ENDFOR»
-
+
ET_MSC_LOGGER_SYNC_EXIT
}
'''
@@ -374,23 +371,23 @@ class NodeGen {
«FOR protocolClass : root.getReferencedProtocolClasses(ssi.subSystemClass)»
#include «protocolClass.includePath»
«ENDFOR»
-
+
/* instantiation of message services and message buffers */
«FOR thread: nr.type.threads.filter(t|usedThreads.contains(t))»
/* «thread.name» */
#define «thread.name.toUpperCase»_POOL_SIZE «thread.msgpoolsize»
#define «thread.name.toUpperCase»_BLOCK_SIZE «thread.msgblocksize»
- static uint8 msgBuffer_«thread.name»[«thread.name.toUpperCase»_POOL_SIZE * «thread.name.toUpperCase»_BLOCK_SIZE];
+ static uint8 msgBuffer_«thread.name»[«thread.name.toUpperCase»_POOL_SIZE * «thread.name.toUpperCase»_BLOCK_SIZE];
static etMessageService msgService_«thread.name»;
«ENDFOR»
-
+
/* declarations of all ActorClass instances (const and variable structs) */
/* forward declaration of variable actor structs */
«FOR ai : ssi.allContainedInstances»
static «ai.actorClass.name» «ai.path.getPathName()»;
«ENDFOR»
-
+
/* forward declaration of variable port structs */
«FOR ai: ssi.allContainedInstances»
«IF ai.orderedIfItemInstances.empty»
@@ -402,13 +399,13 @@ class NodeGen {
«FOR Integer i:1.. if(pi.peers.size==0)1 else pi.peers.size SEPARATOR ', '»
«attrInitGenAddon.generateAttributeInit(pi, pi.interfaceItem.portClass.attributes)»
«ENDFOR»};
- «ENDIF»
+ «ENDIF»
«ENDFOR»
- «ENDIF»
+ «ENDIF»
«ENDFOR»
-
+
«FOR ai : ssi.allContainedInstances»
-
+
/* instance «ai.path.getPathName()» */
«IF !Main::settings.generateMSCInstrumentation && ai.orderedIfItemInstances.empty»
/* no ports/saps/services - nothing to initialize statically */
@@ -416,47 +413,47 @@ class NodeGen {
«genActorInstanceInitializer(root, ai)»
«ENDIF»
«ENDFOR»
-
+
'''
}
-
+
def private genActorInstanceInitializer(Root root, ActorInstance ai) {
val instName = ai.path.pathName
-
+
// list of replicated interface items (all are event driven ports)
val replEventItems = new ArrayList<InterfaceItemInstance>()
replEventItems.addAll(ai.orderedIfItemInstances.filter(e|e.replicated))
val haveReplSubItems = replEventItems.findFirst(e|!e.peers.empty)!=null
val replEventPorts = replEventItems.filter(i|i.interfaceItem instanceof Port)
val replEventSPPs = replEventItems.filter(i|i.interfaceItem instanceof SPP)
-
+
val simplePorts = ai.orderedIfItemInstances.filter(e|e.simple)
-
+
// list of simple event interface items
val simpleEventItems = new ArrayList<InterfaceItemInstance>()
simpleEventItems.addAll(simplePorts.filter(p|p.protocol.commType==CommunicationType::EVENT_DRIVEN))
-
+
// lists of event driven ports and saps
val simpleEventPorts = simpleEventItems.filter(i|i.interfaceItem instanceof Port)
val simpleEventSAPs = simpleEventItems.filter(i|i.interfaceItem instanceof SAP)
-
+
val dataPorts = simplePorts.filter(p|p.protocol.commType==CommunicationType::DATA_DRIVEN)
val recvPorts = dataPorts.filter(p|p instanceof PortInstance && !(p as PortInstance).port.conjugated)
val sendPorts = dataPorts.filter(p|p instanceof PortInstance && (p as PortInstance).port.conjugated)
-
- // compute replicated port offsets
+
+ // compute replicated port offsets
val offsets = new HashMap<InterfaceItemInstance, Integer>()
var offset = 0
for (p: replEventItems) {
offsets.put(p, offset)
offset = offset + p.peers.size
}
-
+
var replSubPortsArray = if (haveReplSubItems) instName+"_repl_sub_ports" else "NULL"
val haveConstData = !simpleEventItems.empty || !recvPorts.empty || !replEventItems.empty
|| Main::settings.generateMSCInstrumentation
val sep = new IntelligentSeparator(",");
-
+
val const = if (Main::settings.generateMSCInstrumentation) "/*const*/" else "const"
'''
«IF Main::settings.generateMSCInstrumentation»
@@ -474,29 +471,29 @@ class NodeGen {
static «const» «ai.actorClass.name»_const «instName»_const = {
«IF Main::settings.generateMSCInstrumentation»
«sep»"«ai.path»"
-
+
«ENDIF»
/* Ports: {varData, msgService, peerAddress, localId} */
/* simple ports */
«FOR pi : simpleEventPorts»
«sep»«genPortInitializer(root, ai, pi)»
«ENDFOR»
-
+
/* data receive ports */
«FOR pi : recvPorts»
«sep»«genRecvPortInitializer(root, ai, pi)»
«ENDFOR»
-
+
/* saps */
«FOR pi : simpleEventSAPs»
«sep»«genPortInitializer(root, ai, pi)»
«ENDFOR»
-
+
/* replicated ports */
«FOR pi : replEventPorts»
«sep»{«pi.peers.size», «replSubPortsArray»+«offsets.get(pi)»}
«ENDFOR»
-
+
/* services */
«FOR pi : replEventSPPs»
«sep»{«pi.peers.size», «replSubPortsArray»+«offsets.get(pi)»}
@@ -506,20 +503,20 @@ class NodeGen {
static «ai.actorClass.name» «instName» = {
«IF haveConstData»
&«instName»_const,
-
- «ENDIF»
+
+ «ENDIF»
/* data send ports */
«FOR pi : sendPorts»
«pi.genSendPortInitializer»,
«ENDFOR»
-
+
/* attributes */
«attrInitGenAddon.generateAttributeInit(ai, ai.actorClass.allAttributes)»
-
+
/* state and history are initialized in init function */
};
'''}
-
+
private def genPeerPortArrays(Root root, ActorInstance ai) {
val simplePorts = ai.orderedIfItemInstances.filter(e|e.simple && e instanceof PortInstance).map(inst|inst as PortInstance)
val sendPorts = simplePorts.filter(p|p.port.conjugated && p.protocol.commType==CommunicationType::DATA_DRIVEN)
@@ -539,7 +536,7 @@ class NodeGen {
«ENDIF»
'''
}
-
+
def private String genPortInitializer(Root root, ActorInstance ai, InterfaceItemInstance pi) {
val objId = if (pi.peers.empty) 0 else pi.peers.get(0).objId
val idx = if (pi.peers.empty) 0 else pi.peers.get(0).peers.indexOf(pi)
@@ -551,8 +548,8 @@ class NodeGen {
peerInst = if (!pi.peers.empty) "\""+(pi.peers.get(0).eContainer as ActorInstance).path+"\"\n#endif\n"
else "\n#endif\n"
}
-
- "{"+getInterfaceItemInstanceData(pi)+", "
+
+ "{"+getInterfaceItemInstanceData(pi)+", "
+msgSvc+", "
+(objId+idx)+"+BASE_ADDRESS, "
+(root.getExpandedActorClass(ai).getInterfaceItemLocalId(pi.interfaceItem)+1)
@@ -560,7 +557,7 @@ class NodeGen {
+peerInst
+"} /* Port "+pi.name+" */"
}
-
+
def private genSendPortInitializer(InterfaceItemInstance pi) {
val pc = (pi as PortInstance).port.protocol as ProtocolClass
var messages = pc.allIncomingMessages.filter(m|m.data!=null)
@@ -568,7 +565,7 @@ class NodeGen {
val boolMsgs = messages.filter(m|m.data.refType.type.isBoolean)
val usesMSC = Main::settings.generateMSCInstrumentation && !(enumMsgs.empty && boolMsgs.empty)
val instName = (pi.eContainer as ActorInstance).path
-
+
'''
{
«FOR m : pc.incomingMessages SEPARATOR ","»
@@ -583,7 +580,7 @@ class NodeGen {
} /* send port «pi.name» */
'''
}
-
+
def private getInterfaceItemInstanceData(InterfaceItemInstance pi){
if (pi.protocol.getPortClass(pi.conjugated)== null) return "NULL"
if (pi.protocol.getPortClass(pi.conjugated).attributes.empty){
@@ -592,8 +589,8 @@ class NodeGen {
return "&"+pi.path.pathName+"_var"
}
}
-
-
+
+
def private String genRecvPortInitializer(Root root, ActorInstance ai, InterfaceItemInstance pi) {
var sentMsgs = pi.interfaceItem.incoming.filter(m|m.data!=null)
val enumMsgs = sentMsgs.filter(m|m.data.refType.type.isEnumeration)
@@ -610,22 +607,22 @@ class NodeGen {
}
enumVal = "\n#ifdef ET_ASYNC_MSC_LOGGER_ACTIVATE"+enumVal+"\n#endif\n"
}
-
+
if (pi.peers.empty)
return "{NULL"+enumVal+"}"
var peer = pi.peers.get(0)
var peerInst = pi.peers.get(0).eContainer() as ActorInstance
var instName = peerInst.path.pathName
-
+
"{&"+instName+"."+peer.name+enumVal+"}"
}
-
+
def private String genReplSubPortInitializers(Root root, ActorInstance ai, InterfaceItemInstance pi) {
var result = ""
val myInst = if (Main::settings.generateMSCInstrumentation) "\n#ifdef ET_ASYNC_MSC_LOGGER_ACTIVATE\n,\""+(pi.eContainer as ActorInstance).path+"\"\n"
else ""
-
+
for (p: pi.peers) {
val idx = pi.peers.indexOf(p)
val comma = if (idx<pi.peers.size-1) "," else ""
@@ -635,7 +632,7 @@ class NodeGen {
else ""
iiiD = if (iiiD.equals("NULL")) iiiD+"," else iiiD+"["+idx+"],"
result = result +
- "{{"+iiiD
+ "{{"+iiiD
+"&msgService_"+thread+", "
+p.objId+"+BASE_ADDRESS, "
+(root.getExpandedActorClass(ai).getInterfaceItemLocalId(pi.interfaceItem)+1)
@@ -645,15 +642,15 @@ class NodeGen {
+idx
+"}"+comma+" /* Repl Sub Port "+pi.name+" idx +"+idx+"*/\n"
}
-
+
return result
}
-
+
def private generateDispatcherFile(Root root, SubSystemInstance ssi, Collection<PhysicalThread> usedThreads) {
val nr = ETMapUtil::getNodeRef(ssi)
val logData = Main::settings.generateDataInstrumentation && ssi.subSystemClass.annotations.isAnnotationPresent("DataLogging")
val loggedPorts = if(logData) ssi.loggedPorts else newArrayList
-
+
'''
/**
* @author generated by eTrice
@@ -661,16 +658,16 @@ class NodeGen {
* Dispatcher File of Node «nr.name» with SubSystem «ssi.name»
* contains a generated message dispatcher (receiveMessage) for each MessageService (Thread)
*/
-
+
#include "messaging/etMessageReceiver.h"
#include "debugging/etLogger.h"
#include "debugging/etMSCLogger.h"
-
+
«FOR thread: nr.type.threads.filter(t|usedThreads.contains(t)) SEPARATOR "\n"»
«val instancesOnThread = ssi.allContainedInstances.filter(ai|ETMapUtil::getMappedThread(ai).thread==thread)»
«val dispatchedInstances = instancesOnThread.filter(ai|ai.actorClass.commType == ComponentCommunicationType::EVENT_DRIVEN || ai.actorClass.commType == ComponentCommunicationType::ASYNCHRONOUS)»
«val executedInstances = instancesOnThread.filter(ai|ai.actorClass.commType == ComponentCommunicationType::DATA_DRIVEN || ai.actorClass.commType == ComponentCommunicationType::ASYNCHRONOUS)»
-
+
«IF executedInstances.size > 0»
/**
* generated execute function for all cyclic execute calls for the async or datadriven actor instances of thread "«thread.name»"
@@ -696,14 +693,14 @@ class NodeGen {
}
«ENDIF»
«ENDIF»
-
+
/**
* generated dispatch function for all messages for the thread "«thread.name»"
*/
static etBool MsgDispatcher_«thread.name»_receiveMessage(const etMessage* msg){
ET_MSC_LOGGER_SYNC_ENTRY("MsgDispatcher_«thread.name»", "receiveMessage")
switch(msg->address){
-
+
case MESSAGESERVICE_ADDRESS:
«IF !executedInstances.empty»
if (msg->evtID == etSystemProtocol_IN_poll) {
@@ -718,7 +715,7 @@ class NodeGen {
return ET_FALSE;
break;
«FOR ai : dispatchedInstances»
-
+
/* interface items of «ai.path» */
«FOR pi : ai. orderedIfItemInstances.filter(p|p.protocol.commType==CommunicationType::EVENT_DRIVEN)»
«IF pi.replicated»
@@ -733,7 +730,7 @@ class NodeGen {
«ENDFOR»
default: «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»], msg);
break;
- }
+ }
«ELSE»
«IF Main::settings.generateMSCInstrumentation»
ET_MSC_LOGGER_ASYNC_IN(
@@ -748,7 +745,7 @@ class NodeGen {
«ENDFOR»
«ELSE»
case «pi.objId»+BASE_ADDRESS:
- «IF (pi.protocol.handlesReceive(pi.isConjugated()))»
+ «IF (pi.protocol.handlesReceive(pi.isConjugated()))»
switch (msg->evtID){
«FOR h:getReceiveHandlers(pi.protocol,pi.isConjugated())»
case «pi.protocol.name»_«h.msg.codeName»:
@@ -772,7 +769,7 @@ class NodeGen {
«ENDIF»
«ENDFOR»
«ENDFOR»
-
+
default:
etLogger_logErrorF("MessageService_«thread.name»_receiveMessage: address %d does not exist ", msg->address);
break;
@@ -783,14 +780,14 @@ class NodeGen {
«ENDFOR»
'''
}
-
+
def private createLoggerCall(PortInstance pi) {
val msg = pi.protocol.incomingMessages.filter(m|m.data!=null && m.data.refType.type.enumerationOrPrimitive).get(0)
val ai = pi.eContainer as ActorInstance
val data = ai.path.pathName+"."+pi.name+"."+msg.name
val type = if (msg.data.refType.type instanceof EnumerationType) LiteralType.INT
else (msg.data.refType.type as PrimitiveType).type
-
+
switch (type) {
case LiteralType.BOOL: "ET_DATA_LOGGER_LOG_BOOL((int)"+data+")"
case LiteralType.CHAR: "ET_DATA_LOGGER_LOG_INT((int)"+data+")"
@@ -799,21 +796,21 @@ class NodeGen {
default: "internal error: unknown primitive type"
}
}
-
+
def private loggedPorts(SubSystemInstance ssi) {
val ArrayList<PortInstance> result = newArrayList
-
+
if (ssi.subSystemClass.annotations.isAnnotationPresent("DataLogging")) {
logger.logInfo("Data Logging is configured by annotation");
-
+
val filters = ssi.subSystemClass.annotations.getAttribute("DataLogging", "pathlist")
val filterList = filters.split(",")
for (filter: filterList) {
logger.logInfo(" filter: "+filter);
}
-
+
val ArrayList<String> notLogged = newArrayList
-
+
logger.logInfo(" logged ports:");
var iter = ssi.eAllContents
while (iter.hasNext) {
@@ -854,16 +851,16 @@ class NodeGen {
}
}
}
-
+
logger.logInfo(" NOT logged ports:");
for (nl: notLogged) {
logger.logInfo(nl);
}
}
-
+
return result
}
-
+
def private checkDataPorts(SubSystemInstance comp) {
val found = new HashSet<String>()
for (ai: comp.allContainedInstances) {
@@ -888,5 +885,5 @@ class NodeGen {
}
}
}
- }
+ }
}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
index d2787cffd..4d1fcc834 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
@@ -4,10 +4,10 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* CONTRIBUTORS:
* Henrik Rentz-Reichert (initial contribution)
- *
+ *
*******************************************************************************/
package org.eclipse.etrice.generator.c.gen
@@ -22,9 +22,9 @@ import org.eclipse.etrice.core.genmodel.fsm.fsmgen.ExpandedModelComponent
@Singleton
class StateMachineGen extends GenericStateMachineGenerator {
-
+
@Inject extension RoomExtensions
-
+
def genHeaderConstants(ExpandedActorClass xpac) {
val ac = xpac.actorClass
/* TODO: can save one entry if NO_STATE=-1 but influences Java */
@@ -34,7 +34,7 @@ class StateMachineGen extends GenericStateMachineGenerator {
#define «ac.name.toUpperCase»_HISTORY_SIZE «historySize»
'''
}
-
+
def genDataMembers(ExpandedActorClass xpac) {
val ac = xpac.actorClass
'''
@@ -43,7 +43,7 @@ class StateMachineGen extends GenericStateMachineGenerator {
etInt16 history[«ac.name.toUpperCase»_HISTORY_SIZE];
'''
}
-
+
def genInitialization(ExpandedActorClass xpac) {
val ac = xpac.actorClass
'''
@@ -56,8 +56,11 @@ class StateMachineGen extends GenericStateMachineGenerator {
«langExt.operationScope(ac.name, false)»executeInitTransition(self);
'''
}
-
- override public genExtra(ExpandedModelComponent xpmc) {
+
+ /**
+ * @param generateImplementation NOT used
+ */
+ override public genExtra(ExpandedModelComponent xpmc, boolean generateImplementation) {
val mc = xpmc.modelComponent
val states = xpmc.stateMachine.baseStateList.getLeafStatesLast
'''
@@ -66,28 +69,28 @@ class StateMachineGen extends GenericStateMachineGenerator {
static char* stateStrings[] = {"<no state>","<top>",«FOR state : states SEPARATOR ","»"«state.genStatePathName»"
«ENDFOR»};
«ENDIF»
-
+
«langExt.accessLevelPrivate»void setState(«mc.componentName»* self, «stateType» new_state) {
self->state = new_state;
«IF Main::settings.generateMSCInstrumentation»
ET_MSC_LOGGER_CHANGE_STATE(self->constData->instName, stateStrings[new_state])
«ENDIF»
}
-
+
«langExt.accessLevelPrivate»«stateType» getState(«mc.componentName»* self) {
return self->state;
}
'''
}
-
+
override public stateType() {
"etInt16"
}
-
+
override boolType() {
"etBool"
}
-
+
override markVariableUsed(String varname) {
'''
((void)trigger__et); /* avoids unused warning */
@@ -96,5 +99,5 @@ class StateMachineGen extends GenericStateMachineGenerator {
override public unreachableReturn() {
"/* return NO_STATE; // required by CDT but detected as unreachable by JDT because of while (true) */"
}
-
+
}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java
index f6a9ec701..8bee75795 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java
@@ -4,10 +4,10 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* CONTRIBUTORS:
* Henrik Rentz-Reichert (initial contribution)
- *
+ *
*******************************************************************************/
package org.eclipse.etrice.generator.c.setup;
@@ -17,9 +17,13 @@ import org.eclipse.etrice.generator.base.AbstractGeneratorBaseModule;
import org.eclipse.etrice.generator.base.IDataConfiguration;
import org.eclipse.etrice.generator.base.ITranslationProvider;
import org.eclipse.etrice.generator.c.Main;
+import org.eclipse.etrice.generator.c.gen.ActorClassGen;
import org.eclipse.etrice.generator.c.gen.CExtensions;
import org.eclipse.etrice.generator.c.gen.CTranslationProvider;
+import org.eclipse.etrice.generator.c.gen.ProtocolClassGen;
import org.eclipse.etrice.generator.config.DataConfiguration;
+import org.eclipse.etrice.generator.generic.GenericActorClassGenerator;
+import org.eclipse.etrice.generator.generic.GenericProtocolClassGenerator;
import org.eclipse.etrice.generator.generic.ILanguageExtension;
import com.google.inject.Binder;
@@ -29,8 +33,10 @@ public class GeneratorModule extends AbstractGeneratorBaseModule {
// @Override
public void configure(Binder binder) {
super.configure(binder);
-
+
binder.bind(AbstractGenerator.class).to(Main.class);
+ binder.bind(GenericProtocolClassGenerator.class).to(ProtocolClassGen.class);
+ binder.bind(GenericActorClassGenerator.class).to(ActorClassGen.class);
}
@Override

Back to the top