diff --git a/src/main/java/avatartranslator/toexecutable/AVATAR2CMBED.java b/src/main/java/avatartranslator/toexecutable/AVATAR2CMBED.java new file mode 100755 index 0000000000000000000000000000000000000000..533d8a7a203b217c9aee3769f5dd4076fd39161d --- /dev/null +++ b/src/main/java/avatartranslator/toexecutable/AVATAR2CMBED.java @@ -0,0 +1,1019 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + + + +package avatartranslator.toexecutable; + +import avatartranslator.*; +import myutil.*; + +import java.io.File; +import java.util.List; +import java.util.Vector; + +/** + * Class AVATAR2MBED + * Creation: + * @version 1.1 17/01/2018 + * @author Esteban BERNARD + */ +public class AVATAR2CMBED { + + private final static int USEC = 0; + private final static int MSEC = 1; + private final static int SEC = 2; + + + private final static String UNUSED_ATTR = "__attribute__((unused))"; + private final static String GENERATED_PATH = "generated_src" + File.separator; + private final static String UNKNOWN = "UNKNOWN"; + private final static String CR = "\n"; + + private AvatarSpecification avspec; + + private Vector warnings; + + private MainFileMbed mainFileMbed; + private Vector<TaskFileMbed> taskFilesMbed; + private String makefile_src; + private String makefile_SocLib; + + private int timeUnit; + private boolean debug; + private boolean tracing; + private boolean includeUserCode = true; + + private Plugin plugin; + + + public AVATAR2CMBED(AvatarSpecification _avspec, Plugin _plugin) { + avspec = _avspec; + plugin = _plugin; + } + + public void setTimeUnit(int _timeUnit) { + timeUnit = _timeUnit; + } + + public void includeUserCode(boolean _inc) { + includeUserCode = _inc; + } + + public static String getGeneratedPath() { + return GENERATED_PATH; + } + + + public void saveInFiles(String path) throws FileException { + + TraceManager.addDev("Generating files"); + + if (mainFileMbed != null) { + TraceManager.addDev("Generating main files in " + path + mainFileMbed.getName() + ".h"); + FileUtils.saveFile(path + GENERATED_PATH + mainFileMbed.getName() + ".h", Conversion.indentString(mainFileMbed.getHeaderCode(), 2)); + FileUtils.saveFile(path + GENERATED_PATH + mainFileMbed.getName() + ".cpp", Conversion.indentString(mainFileMbed.getMainCode(), 2)); + } + + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + FileUtils.saveFile(path + GENERATED_PATH + taskFileMbed.getName() + ".h", Conversion.indentString(taskFileMbed.getFullHeaderCode(), 2)); + FileUtils.saveFile(path + GENERATED_PATH + taskFileMbed.getName() + ".cpp", Conversion.indentString(taskFileMbed.getMainCode(), 2)); + } + + // Standard Makefile + makeMakefileSrc(GENERATED_PATH); + FileUtils.saveFile(path + "Makefile.src", makefile_src); + + // Makefile for SocLib + makeMakefileSocLib(); + FileUtils.saveFile(path + "Makefile.soclib", makefile_SocLib); + } + + + public Vector getWarnings() { + return warnings; + } + + + + public void generateCMBED(boolean _debug, boolean _tracing) { + debug = _debug; + tracing = _tracing; + + mainFileMbed = new MainFileMbed("main", plugin); + taskFilesMbed = new Vector<TaskFileMbed>(); + + avspec.removeCompositeStates(); + avspec.removeLibraryFunctionCalls (); + avspec.removeTimers(); + + + if (avspec.hasApplicationCode() && includeUserCode) { + mainFileMbed.appendToBeforeMainCode("/* User code */\n"); + mainFileMbed.appendToBeforeMainCode(avspec.getApplicationCode()); + mainFileMbed.appendToBeforeMainCode("\n/* End of User code */\n\n"); + } + + makeMainMutex(); + + makeConcurrencyMutex(); + + makeSynchronousChannels(); + + makeAsynchronousChannels(); + + makeTasks(); + + makeMainHeader(); + + makeThreadsInMain(_debug); + + } + + public void makeMainMutex() { + // Create a main mutex + mainFileMbed.appendToHCode("/* Main mutex */" + CR); + mainFileMbed.appendToBeforeMainCode("/* Main mutex */" + CR); + mainFileMbed.appendToHCode("extern rtos::Mutex __mainMutex;" + CR + CR); + mainFileMbed.appendToBeforeMainCode("rtos::Mutex __mainMutex;" + CR + CR); + + } + + public void makeConcurrencyMutex() { + // Create a main mutex + mainFileMbed.appendToHCode("/* ConcurrencyMutex mutex */" + CR); + mainFileMbed.appendToBeforeMainCode("/* ConcurrencyMutex mutex */" + CR); + mainFileMbed.appendToHCode("extern rtos::Mutex __concurrencyMutex;" + CR + CR); + mainFileMbed.appendToBeforeMainCode("rtos::Mutex __concurrencyMutex;" + CR + CR); + + } + + public void makeSynchronousChannels() { + + // Create a synchronous channel per relation/signal + mainFileMbed.appendToHCode("/* TTOOL original generator */" + CR); + mainFileMbed.appendToHCode("/* Synchronous channels */" + CR); + mainFileMbed.appendToBeforeMainCode("/* Synchronous channels */" + CR); + mainFileMbed.appendToMainCode("/* Synchronous channels */" + CR); + for(AvatarRelation ar: avspec.getRelations()) { + if (!ar.isAsynchronous()) { + for(int i=0; i<ar.nbOfSignals(); i++) { + mainFileMbed.appendToHCode("extern syncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFileMbed.appendToBeforeMainCode("syncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".inname =\"" + ar.getInSignal(i).getName() + "\";" + CR); + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".outname =\"" + ar.getOutSignal(i).getName() + "\";" + CR); + if (ar.isBroadcast()) { + mainFileMbed.appendToMainCode("setBroadcast(&__" + getChannelName(ar, i) + ", true);" + CR); + } + } + } + } + + //mainFileMbed.appendToHCode("pthread_mutex_t mainMutex;" + CR); + + } + + public void makeAsynchronousChannels() { + + // Create a synchronous channel per relation/signal + mainFileMbed.appendToHCode("/* Asynchronous channels */" + CR); + mainFileMbed.appendToBeforeMainCode("/* Asynchronous channels */" + CR); + mainFileMbed.appendToMainCode("/* Asynchronous channels */" + CR); + for(AvatarRelation ar: avspec.getRelations()) { + if (ar.isAsynchronous()) { + for(int i=0; i<ar.nbOfSignals(); i++) { + mainFileMbed.appendToHCode("extern asyncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFileMbed.appendToBeforeMainCode("asyncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".inname =\"" + ar.getInSignal(i).getName() + "\";" + CR); + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".outname =\"" + ar.getOutSignal(i).getName() + "\";" + CR); + if (ar.isBlocking()) { + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".isBlocking = 1;" + CR); + } else { + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".isBlocking = 0;" + CR); + } + mainFileMbed.appendToMainCode("__" + getChannelName(ar, i) + ".maxNbOfMessages = " + ar.getSizeOfFIFO() + ";" + CR); + } + } + } + + //mainFileMbed.appendToHCode("pthread_mutex_t mainMutex;" + CR); + + } + + public void makeTasks() { + for(AvatarBlock block: avspec.getListOfBlocks()) { + makeTask(block); + } + } + + public void makeTask(AvatarBlock block) { + TaskFileMbed taskFileMbed = new TaskFileMbed(block.getName()); + + //taskFileMbed.addToHeaderCode("#include \"main.h\"" + CR); + + //taskFileMbed.addToMainCode("#include \"" + block.getName() + ".h\""); + + if (includeUserCode) { + String tmp = block.getGlobalCode(); + if (tmp != null) { + taskFileMbed.addToMainCode(CR + "// Header code defined in the model" + CR + tmp + CR + "// End of header code defined in the model" + CR + CR); + } + } + + defineAllStates(block, taskFileMbed); + + defineAllMethods(block, taskFileMbed); + + makeMainFunction(block, taskFileMbed); + + taskFilesMbed.add(taskFileMbed); + } + + public void defineAllStates(AvatarBlock _block, TaskFileMbed _taskFile) { + int id = 1; + + _taskFile.addToMainCode("#define STATE__START__STATE 0" + CR); + + for (AvatarStateMachineElement asme: _block.getStateMachine().getListOfElements()) { + if (asme instanceof AvatarState) { + _taskFile.addToMainCode("#define STATE__" + asme.getName() + " " + id + CR); + id ++; + } + } + _taskFile.addToMainCode("#define STATE__STOP__STATE " + id + CR); + _taskFile.addToMainCode(CR); + } + + public void defineAllMethods(AvatarBlock _block, TaskFileMbed _taskFile) { + Vector<String> allNames = new Vector<String>(); + for (AvatarMethod am: _block.getMethods()) { + makeMethod(_block, am, allNames, _taskFile); + } + + // Make method of father + makeFatherMethod(_block, _block, allNames, _taskFile); + } + + private void makeFatherMethod(AvatarBlock _originBlock, AvatarBlock _currentBlock, Vector<String> _allNames, TaskFileMbed _taskFile) { + if (_currentBlock.getFather() == null) { + return; + } + + for (AvatarMethod am: _currentBlock.getFather().getMethods()) { + makeMethod(_originBlock, am, _allNames, _taskFile); + } + + makeFatherMethod(_originBlock, _currentBlock.getFather(), _allNames, _taskFile); + + } + + private void makeMethod(AvatarBlock _block, AvatarMethod _am, Vector<String> _allNames, TaskFileMbed _taskFile) { + String ret = ""; + List<AvatarAttribute> list; + List<AvatarAttribute> listA; + + String nameMethod = _block.getName() + "__" +_am.getName(); + + for(String s: _allNames) { + if (s.compareTo(nameMethod) == 0) { + return; + } + } + + list = _am.getListOfReturnAttributes(); + if (list.size() == 0) { + ret += "void"; + } else { + ret += getCTypeOf(list.get(0)); + } + + ret += " " + nameMethod + "("; + list = _am.getListOfAttributes(); + int cpt = 0; + for(AvatarAttribute aa: list) { + if (cpt != 0) { + ret += ", "; + } + ret += getCTypeOf(aa) + " " + aa.getName(); + cpt ++; + } + + ret += ") {" + CR; + + if (tracing) { + String tr = ""; + cpt = 0; + if (list.size() > 0) { + ret += "char my__attr[CHAR_ALLOC_SIZE];" + CR; + ret += "sprintf(my__attr, \""; + for(AvatarAttribute aa: list) { + if (cpt != 0) { + tr += ","; + ret += ","; + } + tr += aa.getName(); + ret += "%d"; + cpt ++; + } + ret += "\"," + tr + ");" + CR; + ret += traceFunctionCall(_block.getName(), _am.getName(), "my__attr"); + } else { + ret += traceFunctionCall(_block.getName(), _am.getName(), null); + } + } + + if (debug) { + ret += "debugMsg(\"-> ....() Executing method " + _am.getName() + "\");" + CR; + + list = _am.getListOfAttributes(); + cpt = 0; + for(AvatarAttribute aa: list) { + ret += "debugInt(\"Attribute " + aa.getName() + " = \"," + aa.getName() + ");" + CR; + } + } + + listA = list; + list = _am.getListOfReturnAttributes(); + if (list.size() != 0) { + // Returns the first attribute. If not possible, return 0; + // Implementation is provided by the user? + // In that case, no need to generate the code! + if (_am.isImplementationProvided()) { + ret += "return __userImplemented__" + nameMethod + "("; + cpt = 0; + for(AvatarAttribute aaa: listA) { + if (cpt != 0) { + ret += ", "; + } + ret += aaa.getName(); + cpt ++; + } + ret+= ");" + CR; + //TraceManager.addDev("Adding a call to the method"); + + } else { + + if (listA.size() >0) { + ret += "return " + listA.get(0).getName() + ";" + CR; + } else { + ret += "return 0;" + CR; + } + } + } else { + if (_am.isImplementationProvided()) { + ret += "__userImplemented__" + nameMethod + "("; + cpt = 0; + for(AvatarAttribute aaa: listA) { + if (cpt != 0) { + ret += ", "; + } + ret += aaa.getName(); + cpt ++; + } + ret+= ");" + CR; + + } + } + ret += "}" + CR + CR; + _taskFile.addToMainCode(ret + CR); + + } + + public void makeMainHeader() { + mainFileMbed.appendToBeforeMainCode(CR); + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + mainFileMbed.appendToBeforeMainCode("#include \"" + taskFileMbed.getName() + ".h\"" + CR); + } + mainFileMbed.appendToBeforeMainCode(CR); + + } + + public void makeMainFunction(AvatarBlock _block, TaskFileMbed _taskFile) { + int i; + + String s = "void mainFunc__" + _block.getName() + "(void *arg)"; + String sh = "extern " + s + ";" + CR; + s+= "{" + CR; + + s += makeAttributesDeclaration(_block, _taskFile); + + s+= CR + "int __currentState = STATE__START__STATE;" + CR; + + int nbOfMaxParams = _block.getMaxNbOfParams(); + //s+= "request *__req;" + CR; + for(i=0; i<_block.getMaxNbOfMultipleBranches(); i++) { + s+= UNUSED_ATTR + " request __req" + i + ";" + CR; + s+= UNUSED_ATTR + "int *__params" + i + "[" + nbOfMaxParams + "];" + CR; + } + s+= UNUSED_ATTR + "setOfRequests __list;" + CR; + + s+= UNUSED_ATTR + "size_t __myCond;" + CR; + s+= UNUSED_ATTR + "request *__returnRequest;" + CR; + + s+= CR + "char * __myname = ((owner*)arg)->ownerName;" + CR; + s+= "rtos::Thread * __myself = ((owner*)arg)->ownerThread;" + CR; + /*if (tracing) { + s+= CR + "char __value[CHAR_ALLOC_SIZE];" + CR; + }*/ + + //s+= CR + "pthread_cond_init(&__myCond, NULL);" + CR; + + s+= CR + "fillListOfRequests(&__list, __myname, __myself, &__myCond, &__mainMutex);" + CR; + + s+= "//printf(\"my name = %s\\n\", __myname);" + CR; + + s+= CR + "/* Main loop on states */" + CR; + s+= "while(__currentState != STATE__STOP__STATE) {" + CR; + + + s += "switch(__currentState) {" + CR; + + // Making start state + AvatarStateMachine asm = _block.getStateMachine(); + s += "case STATE__START__STATE: " + CR; + s += traceStateEntering("__myname", "__StartState"); + s += makeBehaviourFromElement(_block, asm.getStartState(), true); + s += "break;" + CR + CR; + + String tmp; + // Making other states + for(AvatarStateMachineElement asme: asm.getListOfElements()) { + if (asme instanceof AvatarState) { + s += "case STATE__" + asme.getName() + ": " + CR; + s += traceStateEntering("__myname", asme.getName()); + + if (includeUserCode) { + tmp = ((AvatarState)asme).getEntryCode(); + if (tmp != null) { + if (tmp.trim().length() > 0) { + s += "/* Entry code */\n" + tmp + "\n/* End of entry code */\n\n"; + } + } + } + + s += makeBehaviourFromElement(_block, asme, true); + s += "break;" + CR + CR; + } + } + + s += "}" + CR; + + s += "}" + CR; + + s+= "//printf(\"Exiting = %s\\n\", __myname);" + CR; + s+= "return ;" + CR; + s += "}" + CR; + _taskFile.addToMainCode(s + CR); + _taskFile.addToHeaderCode(sh + CR); + } + + public String makeBehaviourFromElement(AvatarBlock _block, AvatarStateMachineElement _asme, boolean firstCall) { + AvatarStateMachineElement asme0; + + + if (_asme == null) { + return ""; + } + + String ret = ""; + int i; + + if (_asme instanceof AvatarStartState) { + return makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + if (_asme instanceof AvatarTransition) { + AvatarTransition at = (AvatarTransition)_asme; + + if (at.isGuarded()) { + String g = modifyGuard(at.getGuard().toString ()); + + ret += "if (!" + g + ") {" + CR; + if (debug) { + ret += "debug2Msg(__myname, \"Guard failed: " + g + "\");" + CR; + } + ret += "__currentState = STATE__STOP__STATE;" + CR; + ret += "break;" + CR; + ret += "}" + CR; + } + + if (at.hasDelay()) { + ret+= "waitFor(" + reworkDelay(at.getMinDelay()) + ", " + reworkDelay(at.getMaxDelay()) + ");" + CR; + } + + String act; + ret += makeActionsOfTransaction(_block, at); + /*for(i=0; i<at.getNbOfAction(); i++) { + // Must know whether this is an action or a method call + act = at.getAction(i); + if (at.isAMethodCall(act)) { + ret += modifyMethodName(_block, act) + ";" + CR; + } else { + ret += act + ";" + CR; + } + }*/ + + + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + if (_asme instanceof AvatarState) { + if (!firstCall) { + if (debug) { + ret += "debug2Msg(__myname, \"-> (=====) Entering state + " + _asme.getName() + "\");" + CR; + } + return ret + "__currentState = STATE__" + _asme.getName() + ";" + CR; + } else { + if (_asme.nbOfNexts() == 0) { + return ret + "__currentState = STATE__STOP__STATE;" + CR; + } + + if (_asme.nbOfNexts() == 1) { + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + // Complex case of states -> several nexts + // Put in list all + + + // 1) Only immediatly executable transitions + for(i=0; i<_asme.nbOfNexts(); i++) { + if (_asme.getNext(i) instanceof AvatarTransition) { + AvatarTransition at = (AvatarTransition)(_asme.getNext(i)); + + if (at.hasActions()) { + ret += makeImmediateAction(at, i); + } else { + if (at.getNext(0) instanceof AvatarActionOnSignal) { + ret += makeSignalAction(at, i); + } else { + // nothing special to do : immediate choice + ret += makeImmediateAction(at, i); + } + } + } + } + + // Make all requests + // Test if at least one request in the list! + ret += "if (nbOfRequests(&__list) == 0) {" + CR; + ret += "debug2Msg(__myname, \"No possible request\");" + CR; + ret += "__currentState = STATE__STOP__STATE;" + CR; + ret += "break;" + CR; + ret += "}" + CR; + + ret += "__returnRequest = executeListOfRequests(&__list);" + CR; + ret += "clearListOfRequests(&__list);" + CR ; + ret += traceRequest(); + + // Resulting requests + for(i=0; i<_asme.nbOfNexts(); i++) { + if (i != 0) { + ret += "else "; + } + AvatarTransition at = (AvatarTransition)(_asme.getNext(i)); + if (at.hasActions()) { + ret += " if (__returnRequest == &__req" + i + ") {" + CR; + ret += makeActionsOfTransaction(_block, at); + /*for(int j=0; j<at.getNbOfAction(); j++) { + if (at.isAMethodCall(at.getAction(j))) { + ret += modifyMethodName(_block, at.getAction(j)) + ";" + CR; + } else { + ret += at.getAction(j) + ";" + CR; + + } + + }*/ + ret += makeBehaviourFromElement(_block, at.getNext(0), false) + CR + "}"; + } else { + if (at.getNext(0) instanceof AvatarActionOnSignal) { + ret += " if (__returnRequest == &__req" + i + ") {" + CR + makeBehaviourFromElement(_block, at.getNext(0).getNext(0), false) + CR + "}"; + } else { + // nothing special to do : immediate choice + ret += " if (__returnRequest == &__req" + i + ") {" + CR + makeBehaviourFromElement(_block, at.getNext(0), false) + CR + "}"; + } + } + ret += CR; + + } + return ret; + } + } + + if (_asme instanceof AvatarStopState) { + return ret + "__currentState = STATE__STOP__STATE;" + CR; + } + + if (_asme instanceof AvatarRandom) { + AvatarRandom ar = (AvatarRandom)_asme; + ret += ar.getVariable() + " = computeRandom(" + ar.getMinValue() + ", " + ar.getMaxValue() + ");" + CR; + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + if (_asme instanceof AvatarActionOnSignal) { + AvatarActionOnSignal aaos = (AvatarActionOnSignal)_asme; + ret += makeSignalAction(aaos, 0, false, "", ""); + AvatarSignal as = aaos.getSignal(); + AvatarRelation ar = avspec.getAvatarRelationWithSignal(as); + ret += executeOneRequest("__req0"); + ret += traceRequest(); + } + + // Default + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + private String makeSignalAction(AvatarTransition _at, int _index) { + String ret = ""; + AvatarActionOnSignal aaos; + + if (!(_at.getNext(0) instanceof AvatarActionOnSignal)) { + return ""; + } + + aaos = (AvatarActionOnSignal)(_at.getNext(0)); + + if (_at.isGuarded()) { + String g = modifyGuard(_at.getGuard().toString ()); + ret += "if (" + g + ") {" + CR; + } + + if (_at.hasDelay()) { + ret += makeSignalAction(aaos, _index, true, _at.getMinDelay(), _at.getMaxDelay()); + } else { + ret += makeSignalAction(aaos, _index, false, "", ""); + } + ret += "addRequestToList(&__list, &__req" + _index + ");" + CR; + + if (_at.isGuarded()) { + ret += "}" + CR; + } + + return ret; + } + + private String makeSignalAction(AvatarActionOnSignal _aaos, int _index, boolean hasDelay, String minDelay, String maxDelay) { + String ret = ""; + int i; + + AvatarSignal as = _aaos.getSignal(); + AvatarRelation ar = avspec.getAvatarRelationWithSignal(as); + + String delay; + + if (hasDelay) { + delay = "1, " + reworkDelay(minDelay) + ", " + reworkDelay(maxDelay); + } else { + delay = "0, 0, 0"; + } + + if (ar != null) { + + // Sending + if (_aaos.isSending()) { + // Putting params + for(i=0; i<_aaos.getNbOfValues() ;i++) { + ret += "__params" + _index + "[" + i + "] = &" + _aaos.getValue(i) + ";" + CR; + } + if (ar.isAsynchronous()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", SEND_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + if (ar.isBroadcast()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_BROADCAST_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } + } + + // Receiving + } else { + for(i=0; i<_aaos.getNbOfValues() ;i++) { + ret += "__params" + _index + "[" + i + "] = &" + _aaos.getValue(i) + ";" + CR; + } + if (ar.isAsynchronous()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + if (ar.isBroadcast()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_BROADCAST_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } + } + } + } + + return ret; + } + + private String makeImmediateAction(AvatarTransition _at, int _index) { + String ret = ""; + if (_at.isGuarded()) { + String g = modifyGuard(_at.getGuard().toString ()); + ret += "if (" + g + ") {" + CR; + } + + if (_at.hasDelay()) { + ret += "makeNewRequest(&__req" + _index + ", " + _at.getID() + ", IMMEDIATE, 1, " + reworkDelay(_at.getMinDelay()) + ", " + reworkDelay(_at.getMaxDelay()) + ", 0, __params" + _index + ");" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _at.getID() + ", IMMEDIATE, 0, 0, 0, 0, __params" + _index + ");" + CR; + } + ret += "addRequestToList(&__list, &__req" + _index + ");" + CR; + if (_at.isGuarded()) { + ret += "}" + CR; + } + + return ret; + + } + + private String executeOneRequest(String var) { + String ret = "__returnRequest = executeOneRequest(&__list, &" + var + ");" + CR; + ret += "clearListOfRequests(&__list);" + CR; + return ret; + } + + + public String makeAttributesDeclaration(AvatarBlock _block, TaskFileMbed _taskFile) { + String ret = ""; + for(AvatarAttribute aa: _block.getAttributes()) { + ret += getCTypeOf(aa) + " " + aa.getName() + " = " + aa.getInitialValue() + ";" + CR; + } + return ret; + } + + public void makeThreadsInMain(boolean _debug) { + mainFileMbed.appendToMainCode(CR + "/* Threads of tasks */" + CR); + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + mainFileMbed.appendToMainCode("rtos::Thread thread__" + taskFileMbed.getName() + ";" + CR); + } + + makeArgumentsInMain(_debug); + + if (_debug) { + mainFileMbed.appendToMainCode("/* Activating debug messages */" + CR); + mainFileMbed.appendToMainCode("activeDebug();" + CR); + } + + + + mainFileMbed.appendToMainCode("/* Activating randomness */" + CR); + mainFileMbed.appendToMainCode("initRandom();" + CR); + + //mainFileMbed.appendToMainCode("/* Initializing the main mutex */" + CR); + //mainFileMbed.appendToMainCode("if (pthread_mutex_init(&__mainMutex, NULL) < 0) { exit(-1);}" + CR + CR); + + mainFileMbed.appendToMainCode("/* Initializing mutex of messages */" + CR); + mainFileMbed.appendToMainCode("initMessages();" + CR); + + + if (avspec.hasApplicationCode()&& includeUserCode) { + mainFileMbed.appendToMainCode("/* User initialization */" + CR); + mainFileMbed.appendToMainCode("__user_init();" + CR); + } + + + mainFileMbed.appendToMainCode(CR + CR + mainDebugMsg("Starting tasks")); + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + mainFileMbed.appendToMainCode(CR + "owner __" + taskFileMbed.getName() + ";" + CR); + mainFileMbed.appendToMainCode("__" + taskFileMbed.getName() + ".ownerName = \"" + taskFileMbed.getName() + "\";" + CR); + mainFileMbed.appendToMainCode("__" + taskFileMbed.getName() + ".ownerThread = &thread__" + taskFileMbed.getName() + ";" + CR); + mainFileMbed.appendToMainCode("thread__" + taskFileMbed.getName() + ".start(mainFunc__" + taskFileMbed.getName() + ", (void*)&__" + taskFileMbed.getName() + ");" + CR); + + //mainFileMbed.appendToMainCode("pthread_create(&thread__" + taskFileMbed.getName() + ", NULL, mainFunc__" + taskFileMbed.getName() + ", (void *)\"" + taskFileMbed.getName() + "\");" + CR); + } + + mainFileMbed.appendToMainCode(CR + CR + mainDebugMsg("Joining tasks")); + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + mainFileMbed.appendToMainCode("thread__" + taskFileMbed.getName() + ".join();" + CR); + } + + mainFileMbed.appendToMainCode(CR + CR + mainDebugMsg("Application terminated")); + mainFileMbed.appendToMainCode("return 0;" + CR); + } + + public void makeArgumentsInMain(boolean _debug) { + mainFileMbed.appendToMainCode("/* Activating tracing */" + CR); + + if (tracing) { + mainFileMbed.appendToMainCode("if (argc>1){" + CR); + mainFileMbed.appendToMainCode("activeTracingInFile(argv[1]);" + CR + "} else {" + CR); + mainFileMbed.appendToMainCode("activeTracingInConsole();" + CR + "}" + CR); + } + } + + public void makeMakefileSrc(String _path) { + makefile_src = "SRCS = "; + makefile_src += _path + "main.c "; + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + makefile_src += _path + taskFileMbed.getName() + ".c "; + } + + } + + public void makeMakefileSocLib() { + makefile_SocLib = "objs = "; + makefile_SocLib += "main.o "; + for(TaskFileMbed taskFileMbed: taskFilesMbed) { + makefile_SocLib += taskFileMbed.getName() + ".o "; + } + + } + + + public String getCTypeOf(AvatarAttribute _aa) { + String ret = "int"; + if (_aa.getType() == AvatarType.BOOLEAN) { + ret = "bool"; + } + return ret; + } + + public String getChannelName(AvatarRelation _ar, int _index) { + return _ar.block1.getName() + "_" + _ar.getSignal1(_index).getName() + "__" + _ar.block2.getName() + "_" + _ar.getSignal2(_index).getName(); + } + + public String getChannelName(AvatarRelation _ar, AvatarSignal _as) { + int index = _ar.getIndexOfSignal(_as); + return getChannelName(_ar, index); + } + + public String modifyGuard(String _g) { + String g = Conversion.replaceAllString(_g, "[", "(").trim(); + g = Conversion.replaceAllString(g, "]", ")").trim(); + g = Conversion.replaceOp(g, "and", "&&"); + g = Conversion.replaceOp(g, "or", "||"); + g = Conversion.replaceOp(g, "not", "!"); + TraceManager.addDev("Guard=" + g); + return g; + } + + public String reworkDelay(String _delay) { + + switch(timeUnit) { + case USEC: + return _delay; + case MSEC: + return "(" + _delay + ")*1000"; + case SEC: + return "(" + _delay + ")*1000000"; + } + + return _delay; + } + + private String modifyMethodName(AvatarBlock _ab, AvatarTerm term) { + if (term instanceof AvatarAttribute) + return term.getName (); + if (term instanceof AvatarConstant) + return term.getName (); + if (term instanceof AvatarTermRaw) + return term.getName (); + if (term instanceof AvatarArithmeticOp) { + AvatarArithmeticOp aop = (AvatarArithmeticOp) term; + return this.modifyMethodName (_ab, aop.getTerm1 ()) + + aop.getOperator () + + this.modifyMethodName (_ab, aop.getTerm2 ()); + } + if (term instanceof AvatarTuple) { + boolean first = true; + String res = "("; + for (AvatarTerm tterm: ((AvatarTuple) term).getComponents ()) { + if (first) + first = false; + else + res += ", "; + res += this.modifyMethodName (_ab, tterm); + } + + return res + ")"; + } + if (term instanceof AvatarTermFunction) + return _ab.getName () + "__" + ((AvatarTermFunction) term).getMethod ().getName () + + this.modifyMethodName (_ab, ((AvatarTermFunction) term).getArgs ()); + return ""; + } + + private String traceRequest() { + if (!tracing) { + return ""; + } + return "traceRequest(__myname, __returnRequest);" + CR; + } + + private String traceVariableModification(String blockName, String varName, String type) { + if (!tracing) { + return ""; + } + + return "traceVariableModification(\"" + blockName + "\", \"" + varName + "\", " + varName + "," + type + ");" + CR; + } + + private String traceFunctionCall(String blockName, String functionName, String params) { + if (!tracing) { + return ""; + } + + if (params == null) { + params = "\"-\""; + } + return "traceFunctionCall(\"" + blockName + "\", \"" + functionName + "\", " + params + ");" + CR; + } + + private String traceStateEntering(String name, String stateName) { + if (!tracing) { + return ""; + } + return "traceStateEntering(" + name + ", \"" + stateName + "\");" + CR; + } + + private String mainDebugMsg(String s) { + if (!debug) { + return ""; + } + return "debugMsg(\"" + s + "\");" + CR; + } + + private String taskDebugMsg(String s) { + if (!debug) { + return ""; + } + + return "debug2Msg(__myname, \"" + s + "\");" + CR; + } + + public String makeActionsOfTransaction(AvatarBlock _block, AvatarTransition _at) { + String ret = ""; + String type; + for(int i=0; i<_at.getNbOfAction(); i++) { + // Must know whether this is an action or a method call + + AvatarAction act = _at.getAction(i); + TraceManager.addDev("Action=" + act); + if (act.isAMethodCall()) { + TraceManager.addDev("Method call"); + String actModified = modifyMethodName (_block, (AvatarTermFunction) act); + ret += actModified + ";" + CR; + } else { + TraceManager.addDev("Else"); + String actModified = modifyMethodName (_block, ((AvatarActionAssignment) act).getLeftHand ()) + + " = " + modifyMethodName (_block, ((AvatarActionAssignment) act).getRightHand ()); + AvatarLeftHand leftHand = ((AvatarActionAssignment) act).getLeftHand (); + ret += actModified + ";" + CR; + if (leftHand instanceof AvatarAttribute) { + if (((AvatarAttribute) leftHand).isInt()) { + type = "0"; + } else { + type = "1"; + } + ret += traceVariableModification(_block.getName(), leftHand.getName (), type); + } + + } + } + + return ret; + } + +} diff --git a/src/main/java/avatartranslator/toexecutable/AVATAR2CPOSIXArduino.java b/src/main/java/avatartranslator/toexecutable/AVATAR2CPOSIXArduino.java new file mode 100644 index 0000000000000000000000000000000000000000..d58c4fce8020c03f041b301a30f7f9721334be79 --- /dev/null +++ b/src/main/java/avatartranslator/toexecutable/AVATAR2CPOSIXArduino.java @@ -0,0 +1,1011 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + + + +package avatartranslator.toexecutable; + +import avatartranslator.*; +import myutil.*; + +import java.io.File; +import java.util.List; +import java.util.Vector; + +/** + * Class AVATAR2CPOSIXArduino + * Creation: 05/11/2017 + * @version 2 17/11/2017 + * @author Berkay KOKSAL + */ +public class AVATAR2CPOSIXArduino { + + private final static int USEC = 0; + private final static int MSEC = 1; + private final static int SEC = 2; + + + private final static String UNUSED_ATTR = "__attribute__((unused))"; + private final static String GENERATED_PATH = "generated_src" + File.separator; + private final static String UNKNOWN = "UNKNOWN"; + private final static String CR = "\n"; + + private AvatarSpecification avspec; + + private Vector warnings; + + private MainFile mainFile; + private MainFile_Arduino mainFile_Arduino; + + private Vector<TaskFile> taskFiles; + private String makefile_src; + private String makefile_SocLib; + + private int timeUnit; + private boolean debug; + private boolean tracing; + private boolean includeUserCode = true; + + private Plugin plugin; + + + public AVATAR2CPOSIXArduino(AvatarSpecification _avspec, Plugin _plugin) { + avspec = _avspec; + plugin = _plugin; + } + + public void setTimeUnit(int _timeUnit) { + timeUnit = _timeUnit; + } + + public void includeUserCode(boolean _inc) { + includeUserCode = _inc; + } + + public static String getGeneratedPath() { + return GENERATED_PATH; + } + + + public void saveInFiles(String path) throws FileException { + + TraceManager.addDev("Generating files"); + + if (mainFile_Arduino != null) { + TraceManager.addDev("Generating main files in " + path + mainFile_Arduino.getName() + ".h"); + FileUtils.saveFile(path + GENERATED_PATH + mainFile_Arduino.getName() + ".h", Conversion.indentString(mainFile_Arduino.getHeaderCode(), 2)); + FileUtils.saveFile(path + GENERATED_PATH + mainFile_Arduino.getName() + ".ino", Conversion.indentString(mainFile_Arduino.getMainCode(), 2)); + } + + for(TaskFile taskFile: taskFiles) { + FileUtils.saveFile(path + GENERATED_PATH + taskFile.getName() + ".h", Conversion.indentString(taskFile.getFullHeaderCode(), 2)); + FileUtils.saveFile(path + GENERATED_PATH + taskFile.getName() + ".c", Conversion.indentString(taskFile.getMainCode(), 2)); + } + + // Standard Makefile + makeMakefileSrc(GENERATED_PATH); + FileUtils.saveFile(path + "Makefile.src", makefile_src); + + // Makefile for SocLib + makeMakefileSocLib(); + FileUtils.saveFile(path + "Makefile.soclib", makefile_SocLib); + } + + + public Vector getWarnings() { + return warnings; + } + + + public void generateArduinoCode(boolean _debug, boolean _tracing) { + debug = _debug; + tracing = _tracing; + + mainFile_Arduino = new MainFile_Arduino("mainArduino", plugin); + taskFiles = new Vector<TaskFile>(); + + avspec.removeCompositeStates(); + avspec.removeLibraryFunctionCalls (); + avspec.removeTimers(); + + + if (avspec.hasApplicationCode() && includeUserCode) { + mainFile_Arduino.appendToBeforeMainCode("/* User code */\n"); + mainFile_Arduino.appendToBeforeMainCode(avspec.getApplicationCode()); + mainFile_Arduino.appendToBeforeMainCode("\n/* End of User code */\n\n"); + } + + //makeMainMutex(); + + //makeSynchronousChannels(); + + //makeAsynchronousChannels(); + + //makeTasks(); + + //makeMainHeader(); + + //makeThreadsInMain(_debug); + + makeMainFile(); + + + } + + + public void makeMainMutex() { + // Create a main mutex + mainFile_Arduino.appendToHCode("/* Main mutex */" + CR); + mainFile_Arduino.appendToBeforeMainCode("/* Main mutex */" + CR); + mainFile_Arduino.appendToHCode("extern pthread_mutex_t __mainMutex;" + CR + CR); + mainFile_Arduino.appendToBeforeMainCode("pthread_mutex_t __mainMutex;" + CR + CR); + + } + + public void makeMainFile() { + // Create a main mutex + mainFile_Arduino.appendToBeforeMainCode("void setup() {\n// initialize a port to work with on arduino\nSerial.begin(9600);\n}" + CR); + mainFile_Arduino.appendToMainCode("void loop() {\n//Code Comes Here\nSerial.print(\"Hello world from generated code\");\n}"); + + } + + public void makeSynchronousChannels() { + + // Create a synchronous channel per relation/signal + mainFile_Arduino.appendToHCode("/* Berkay Koksal implemented Arduino Code Generation */" + CR); + mainFile_Arduino.appendToHCode("/* Synchronous channels */" + CR); + mainFile_Arduino.appendToBeforeMainCode("/* Synchronous channels */" + CR); + mainFile_Arduino.appendToMainCode("/* Synchronous channels */" + CR); + for(AvatarRelation ar: avspec.getRelations()) { + if (!ar.isAsynchronous()) { + for(int i=0; i<ar.nbOfSignals(); i++) { + mainFile_Arduino.appendToHCode("extern syncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFile_Arduino.appendToBeforeMainCode("syncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".inname =\"" + ar.getInSignal(i).getName() + "\";" + CR); + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".outname =\"" + ar.getOutSignal(i).getName() + "\";" + CR); + if (ar.isBroadcast()) { + mainFile_Arduino.appendToMainCode("setBroadcast(&__" + getChannelName(ar, i) + ", true);" + CR); + } + } + } + } + + //mainFile.appendToHCode("pthread_mutex_t mainMutex;" + CR); + + } + + public void makeAsynchronousChannels() { + + // Create a synchronous channel per relation/signal + mainFile_Arduino.appendToHCode("/* Asynchronous channels */" + CR); + mainFile_Arduino.appendToBeforeMainCode("/* Asynchronous channels */" + CR); + mainFile_Arduino.appendToMainCode("/* Asynchronous channels */" + CR); + for(AvatarRelation ar: avspec.getRelations()) { + if (ar.isAsynchronous()) { + for(int i=0; i<ar.nbOfSignals(); i++) { + mainFile_Arduino.appendToHCode("extern asyncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFile_Arduino.appendToBeforeMainCode("asyncchannel __" + getChannelName(ar, i) + ";" + CR); + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".inname =\"" + ar.getInSignal(i).getName() + "\";" + CR); + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".outname =\"" + ar.getOutSignal(i).getName() + "\";" + CR); + if (ar.isBlocking()) { + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".isBlocking = 1;" + CR); + } else { + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".isBlocking = 0;" + CR); + } + mainFile_Arduino.appendToMainCode("__" + getChannelName(ar, i) + ".maxNbOfMessages = " + ar.getSizeOfFIFO() + ";" + CR); + } + } + } + + //mainFile.appendToHCode("pthread_mutex_t mainMutex;" + CR); + + } + + public void makeTasks() { + for(AvatarBlock block: avspec.getListOfBlocks()) { + makeTask(block); + } + } + + public void makeTask(AvatarBlock block) { + TaskFile taskFile = new TaskFile(block.getName()); + + if (includeUserCode) { + String tmp = block.getGlobalCode(); + if (tmp != null) { + taskFile.addToMainCode(CR + "// Header code defined in the model" + CR + tmp + CR + "// End of header code defined in the model" + CR + CR); + } + } + + defineAllStates(block, taskFile); + + defineAllMethods(block, taskFile); + + makeMainFunction(block, taskFile); + + taskFiles.add(taskFile); + } + + public void defineAllStates(AvatarBlock _block, TaskFile _taskFile) { + int id = 1; + + _taskFile.addToMainCode("#define STATE__START__STATE 0" + CR); + + for (AvatarStateMachineElement asme: _block.getStateMachine().getListOfElements()) { + if (asme instanceof AvatarState) { + _taskFile.addToMainCode("#define STATE__" + asme.getName() + " " + id + CR); + id ++; + } + } + _taskFile.addToMainCode("#define STATE__STOP__STATE " + id + CR); + _taskFile.addToMainCode(CR); + } + + public void defineAllMethods(AvatarBlock _block, TaskFile _taskFile) { + Vector<String> allNames = new Vector<String>(); + for (AvatarMethod am: _block.getMethods()) { + makeMethod(_block, am, allNames, _taskFile); + } + + // Make method of father + makeFatherMethod(_block, _block, allNames, _taskFile); + } + + private void makeFatherMethod(AvatarBlock _originBlock, AvatarBlock _currentBlock, Vector<String> _allNames, TaskFile _taskFile) { + if (_currentBlock.getFather() == null) { + return; + } + + for (AvatarMethod am: _currentBlock.getFather().getMethods()) { + makeMethod(_originBlock, am, _allNames, _taskFile); + } + + makeFatherMethod(_originBlock, _currentBlock.getFather(), _allNames, _taskFile); + + } + + private void makeMethod(AvatarBlock _block, AvatarMethod _am, Vector<String> _allNames, TaskFile _taskFile) { + String ret = ""; + List<AvatarAttribute> list; + List<AvatarAttribute> listA; + + String nameMethod = _block.getName() + "__" +_am.getName(); + + for(String s: _allNames) { + if (s.compareTo(nameMethod) == 0) { + return; + } + } + + list = _am.getListOfReturnAttributes(); + if (list.size() == 0) { + ret += "void"; + } else { + ret += getCTypeOf(list.get(0)); + } + + ret += " " + nameMethod + "("; + list = _am.getListOfAttributes(); + int cpt = 0; + for(AvatarAttribute aa: list) { + if (cpt != 0) { + ret += ", "; + } + ret += getCTypeOf(aa) + " " + aa.getName(); + cpt ++; + } + + ret += ") {" + CR; + + if (tracing) { + String tr = ""; + cpt = 0; + if (list.size() > 0) { + ret += "char my__attr[CHAR_ALLOC_SIZE];" + CR; + ret += "sprintf(my__attr, \""; + for(AvatarAttribute aa: list) { + if (cpt != 0) { + tr += ","; + ret += ","; + } + tr += aa.getName(); + ret += "%d"; + cpt ++; + } + ret += "\"," + tr + ");" + CR; + ret += traceFunctionCall(_block.getName(), _am.getName(), "my__attr"); + } else { + ret += traceFunctionCall(_block.getName(), _am.getName(), null); + } + } + + if (debug) { + ret += "debugMsg(\"-> ....() Executing method " + _am.getName() + "\");" + CR; + + list = _am.getListOfAttributes(); + cpt = 0; + for(AvatarAttribute aa: list) { + ret += "debugInt(\"Attribute " + aa.getName() + " = \"," + aa.getName() + ");" + CR; + } + } + + listA = list; + list = _am.getListOfReturnAttributes(); + if (list.size() != 0) { + // Returns the first attribute. If not possible, return 0; + // Implementation is provided by the user? + // In that case, no need to generate the code! + if (_am.isImplementationProvided()) { + ret += "return __userImplemented__" + nameMethod + "("; + cpt = 0; + for(AvatarAttribute aaa: listA) { + if (cpt != 0) { + ret += ", "; + } + ret += aaa.getName(); + cpt ++; + } + ret+= ");" + CR; + //TraceManager.addDev("Adding a call to the method"); + + } else { + + if (listA.size() >0) { + ret += "return " + listA.get(0).getName() + ";" + CR; + } else { + ret += "return 0;" + CR; + } + } + } else { + if (_am.isImplementationProvided()) { + ret += "__userImplemented__" + nameMethod + "("; + cpt = 0; + for(AvatarAttribute aaa: listA) { + if (cpt != 0) { + ret += ", "; + } + ret += aaa.getName(); + cpt ++; + } + ret+= ");" + CR; + + } + } + ret += "}" + CR + CR; + _taskFile.addToMainCode(ret + CR); + + } + + public void makeMainHeader() { + mainFile_Arduino.appendToBeforeMainCode(CR); + for(TaskFile taskFile: taskFiles) { + mainFile_Arduino.appendToBeforeMainCode("#include \"" + taskFile.getName() + ".h\"" + CR); + } + mainFile_Arduino.appendToBeforeMainCode(CR); + + } + + public void makeMainFunction(AvatarBlock _block, TaskFile _taskFile) { + int i; + + String s = "void *mainFunc__" + _block.getName() + "(void *arg)"; + String sh = "extern " + s + ";" + CR; + s+= "{" + CR; + + s += makeAttributesDeclaration(_block, _taskFile); + + s+= CR + "int __currentState = STATE__START__STATE;" + CR; + + int nbOfMaxParams = _block.getMaxNbOfParams(); + //s+= "request *__req;" + CR; + for(i=0; i<_block.getMaxNbOfMultipleBranches(); i++) { + s+= UNUSED_ATTR + " request __req" + i + ";" + CR; + s+= UNUSED_ATTR + "int *__params" + i + "[" + nbOfMaxParams + "];" + CR; + } + s+= UNUSED_ATTR + "setOfRequests __list;" + CR; + + s+= UNUSED_ATTR + "pthread_cond_t __myCond;" + CR; + s+= UNUSED_ATTR + "request *__returnRequest;" + CR; + + s+= CR + "char * __myname = (char *)arg;" + CR; + + /*if (tracing) { + s+= CR + "char __value[CHAR_ALLOC_SIZE];" + CR; + }*/ + + s+= CR + "pthread_cond_init(&__myCond, NULL);" + CR; + + s+= CR + "fillListOfRequests(&__list, __myname, &__myCond, &__mainMutex);" + CR; + + s+= "//printf(\"my name = %s\\n\", __myname);" + CR; + + s+= CR + "/* Main loop on states */" + CR; + s+= "while(__currentState != STATE__STOP__STATE) {" + CR; + + + s += "switch(__currentState) {" + CR; + + // Making start state + AvatarStateMachine asm = _block.getStateMachine(); + s += "case STATE__START__STATE: " + CR; + s += traceStateEntering("__myname", "__StartState"); + s += makeBehaviourFromElement(_block, asm.getStartState(), true); + s += "break;" + CR + CR; + + String tmp; + // Making other states + for(AvatarStateMachineElement asme: asm.getListOfElements()) { + if (asme instanceof AvatarState) { + s += "case STATE__" + asme.getName() + ": " + CR; + s += traceStateEntering("__myname", asme.getName()); + + if (includeUserCode) { + tmp = ((AvatarState)asme).getEntryCode(); + if (tmp != null) { + if (tmp.trim().length() > 0) { + s += "/* Entry code */\n" + tmp + "\n/* End of entry code */\n\n"; + } + } + } + + s += makeBehaviourFromElement(_block, asme, true); + s += "break;" + CR + CR; + } + } + + s += "}" + CR; + + s += "}" + CR; + + s+= "//printf(\"Exiting = %s\\n\", __myname);" + CR; + s+= "return NULL;" + CR; + s += "}" + CR; + _taskFile.addToMainCode(s + CR); + _taskFile.addToHeaderCode(sh + CR); + } + + public String makeBehaviourFromElement(AvatarBlock _block, AvatarStateMachineElement _asme, boolean firstCall) { + AvatarStateMachineElement asme0; + + + if (_asme == null) { + return ""; + } + + String ret = ""; + int i; + + if (_asme instanceof AvatarStartState) { + return makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + if (_asme instanceof AvatarTransition) { + AvatarTransition at = (AvatarTransition)_asme; + + if (at.isGuarded()) { + String g = modifyGuard(at.getGuard().toString ()); + + ret += "if (!" + g + ") {" + CR; + if (debug) { + ret += "debug2Msg(__myname, \"Guard failed: " + g + "\");" + CR; + } + ret += "__currentState = STATE__STOP__STATE;" + CR; + ret += "break;" + CR; + ret += "}" + CR; + } + + if (at.hasDelay()) { + ret+= "waitFor(" + reworkDelay(at.getMinDelay()) + ", " + reworkDelay(at.getMaxDelay()) + ");" + CR; + } + + String act; + ret += makeActionsOfTransaction(_block, at); + /*for(i=0; i<at.getNbOfAction(); i++) { + // Must know whether this is an action or a method call + act = at.getAction(i); + if (at.isAMethodCall(act)) { + ret += modifyMethodName(_block, act) + ";" + CR; + } else { + ret += act + ";" + CR; + } + }*/ + + + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + if (_asme instanceof AvatarState) { + if (!firstCall) { + if (debug) { + ret += "debug2Msg(__myname, \"-> (=====) Entering state + " + _asme.getName() + "\");" + CR; + } + return ret + "__currentState = STATE__" + _asme.getName() + ";" + CR; + } else { + if (_asme.nbOfNexts() == 0) { + return ret + "__currentState = STATE__STOP__STATE;" + CR; + } + + if (_asme.nbOfNexts() == 1) { + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + // Complex case of states -> several nexts + // Put in list all + + + // 1) Only immediatly executable transitions + for(i=0; i<_asme.nbOfNexts(); i++) { + if (_asme.getNext(i) instanceof AvatarTransition) { + AvatarTransition at = (AvatarTransition)(_asme.getNext(i)); + + if (at.hasActions()) { + ret += makeImmediateAction(at, i); + } else { + if (at.getNext(0) instanceof AvatarActionOnSignal) { + ret += makeSignalAction(at, i); + } else { + // nothing special to do : immediate choice + ret += makeImmediateAction(at, i); + } + } + } + } + + // Make all requests + // Test if at least one request in the list! + ret += "if (nbOfRequests(&__list) == 0) {" + CR; + ret += "debug2Msg(__myname, \"No possible request\");" + CR; + ret += "__currentState = STATE__STOP__STATE;" + CR; + ret += "break;" + CR; + ret += "}" + CR; + + ret += "__returnRequest = executeListOfRequests(&__list);" + CR; + ret += "clearListOfRequests(&__list);" + CR ; + ret += traceRequest(); + + // Resulting requests + for(i=0; i<_asme.nbOfNexts(); i++) { + if (i != 0) { + ret += "else "; + } + AvatarTransition at = (AvatarTransition)(_asme.getNext(i)); + if (at.hasActions()) { + ret += " if (__returnRequest == &__req" + i + ") {" + CR; + ret += makeActionsOfTransaction(_block, at); + /*for(int j=0; j<at.getNbOfAction(); j++) { + if (at.isAMethodCall(at.getAction(j))) { + ret += modifyMethodName(_block, at.getAction(j)) + ";" + CR; + } else { + ret += at.getAction(j) + ";" + CR; + + } + + }*/ + ret += makeBehaviourFromElement(_block, at.getNext(0), false) + CR + "}"; + } else { + if (at.getNext(0) instanceof AvatarActionOnSignal) { + ret += " if (__returnRequest == &__req" + i + ") {" + CR + makeBehaviourFromElement(_block, at.getNext(0).getNext(0), false) + CR + "}"; + } else { + // nothing special to do : immediate choice + ret += " if (__returnRequest == &__req" + i + ") {" + CR + makeBehaviourFromElement(_block, at.getNext(0), false) + CR + "}"; + } + } + ret += CR; + + } + return ret; + } + } + + if (_asme instanceof AvatarStopState) { + return ret + "__currentState = STATE__STOP__STATE;" + CR; + } + + if (_asme instanceof AvatarRandom) { + AvatarRandom ar = (AvatarRandom)_asme; + ret += ar.getVariable() + " = computeRandom(" + ar.getMinValue() + ", " + ar.getMaxValue() + ");" + CR; + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + if (_asme instanceof AvatarActionOnSignal) { + AvatarActionOnSignal aaos = (AvatarActionOnSignal)_asme; + ret += makeSignalAction(aaos, 0, false, "", ""); + AvatarSignal as = aaos.getSignal(); + AvatarRelation ar = avspec.getAvatarRelationWithSignal(as); + ret += executeOneRequest("__req0"); + ret += traceRequest(); + } + + // Default + return ret + makeBehaviourFromElement(_block, _asme.getNext(0), false); + } + + private String makeSignalAction(AvatarTransition _at, int _index) { + String ret = ""; + AvatarActionOnSignal aaos; + + if (!(_at.getNext(0) instanceof AvatarActionOnSignal)) { + return ""; + } + + aaos = (AvatarActionOnSignal)(_at.getNext(0)); + + if (_at.isGuarded()) { + String g = modifyGuard(_at.getGuard().toString ()); + ret += "if (" + g + ") {" + CR; + } + + if (_at.hasDelay()) { + ret += makeSignalAction(aaos, _index, true, _at.getMinDelay(), _at.getMaxDelay()); + } else { + ret += makeSignalAction(aaos, _index, false, "", ""); + } + ret += "addRequestToList(&__list, &__req" + _index + ");" + CR; + + if (_at.isGuarded()) { + ret += "}" + CR; + } + + return ret; + } + + private String makeSignalAction(AvatarActionOnSignal _aaos, int _index, boolean hasDelay, String minDelay, String maxDelay) { + String ret = ""; + int i; + + AvatarSignal as = _aaos.getSignal(); + AvatarRelation ar = avspec.getAvatarRelationWithSignal(as); + + String delay; + + if (hasDelay) { + delay = "1, " + reworkDelay(minDelay) + ", " + reworkDelay(maxDelay); + } else { + delay = "0, 0, 0"; + } + + if (ar != null) { + + // Sending + if (_aaos.isSending()) { + // Putting params + for(i=0; i<_aaos.getNbOfValues() ;i++) { + ret += "__params" + _index + "[" + i + "] = &" + _aaos.getValue(i) + ";" + CR; + } + if (ar.isAsynchronous()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", SEND_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + if (ar.isBroadcast()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_BROADCAST_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID()+ ", SEND_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } + } + + // Receiving + } else { + for(i=0; i<_aaos.getNbOfValues() ;i++) { + ret += "__params" + _index + "[" + i + "] = &" + _aaos.getValue(i) + ";" + CR; + } + if (ar.isAsynchronous()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_ASYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".asyncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + if (ar.isBroadcast()) { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_BROADCAST_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _aaos.getID() + ", RECEIVE_SYNC_REQUEST, " + delay + ", " + _aaos.getNbOfValues() + ", __params" + _index + ");" + CR; + ret += "__req" + _index + ".syncChannel = &__" + getChannelName(ar, as) + ";" + CR; + } + } + } + } + + return ret; + } + + private String makeImmediateAction(AvatarTransition _at, int _index) { + String ret = ""; + if (_at.isGuarded()) { + String g = modifyGuard(_at.getGuard().toString ()); + ret += "if (" + g + ") {" + CR; + } + + if (_at.hasDelay()) { + ret += "makeNewRequest(&__req" + _index + ", " + _at.getID() + ", IMMEDIATE, 1, " + reworkDelay(_at.getMinDelay()) + ", " + reworkDelay(_at.getMaxDelay()) + ", 0, __params" + _index + ");" + CR; + } else { + ret += "makeNewRequest(&__req" + _index + ", " + _at.getID() + ", IMMEDIATE, 0, 0, 0, 0, __params" + _index + ");" + CR; + } + ret += "addRequestToList(&__list, &__req" + _index + ");" + CR; + if (_at.isGuarded()) { + ret += "}" + CR; + } + + return ret; + + } + + private String executeOneRequest(String var) { + String ret = "__returnRequest = executeOneRequest(&__list, &" + var + ");" + CR; + ret += "clearListOfRequests(&__list);" + CR; + return ret; + } + + + public String makeAttributesDeclaration(AvatarBlock _block, TaskFile _taskFile) { + String ret = ""; + for(AvatarAttribute aa: _block.getAttributes()) { + ret += getCTypeOf(aa) + " " + aa.getName() + " = " + aa.getInitialValue() + ";" + CR; + } + return ret; + } + + public void makeThreadsInMain(boolean _debug) { + mainFile_Arduino.appendToMainCode(CR + "/* Threads of tasks */" + CR); + for(TaskFile taskFile: taskFiles) { + mainFile_Arduino.appendToMainCode("pthread_t thread__" + taskFile.getName() + ";" + CR); + } + + makeArgumentsInMain(_debug); + + if (_debug) { + mainFile_Arduino.appendToMainCode("/* Activating debug messages */" + CR); + mainFile_Arduino.appendToMainCode("activeDebug();" + CR); + } + + + + mainFile_Arduino.appendToMainCode("/* Activating randomness */" + CR); + mainFile_Arduino.appendToMainCode("initRandom();" + CR); + + mainFile_Arduino.appendToMainCode("/* Initializing the main mutex */" + CR); + mainFile_Arduino.appendToMainCode("if (pthread_mutex_init(&__mainMutex, NULL) < 0) { exit(-1);}" + CR + CR); + + mainFile_Arduino.appendToMainCode("/* Initializing mutex of messages */" + CR); + mainFile_Arduino.appendToMainCode("initMessages();" + CR); + + + if (avspec.hasApplicationCode()&& includeUserCode) { + mainFile_Arduino.appendToMainCode("/* User initialization */" + CR); + mainFile_Arduino.appendToMainCode("__user_init();" + CR); + } + + + mainFile_Arduino.appendToMainCode(CR + CR + mainDebugMsg("Starting tasks")); + for(TaskFile taskFile: taskFiles) { + mainFile_Arduino.appendToMainCode("pthread_create(&thread__" + taskFile.getName() + ", NULL, mainFunc__" + taskFile.getName() + ", (void *)\"" + taskFile.getName() + "\");" + CR); + } + + mainFile_Arduino.appendToMainCode(CR + CR + mainDebugMsg("Joining tasks")); + for(TaskFile taskFile: taskFiles) { + mainFile_Arduino.appendToMainCode("pthread_join(thread__" + taskFile.getName() + ", NULL);" + CR); + } + + mainFile_Arduino.appendToMainCode(CR + CR + mainDebugMsg("Application terminated")); + mainFile_Arduino.appendToMainCode("return 0;" + CR); + } + + public void makeArgumentsInMain(boolean _debug) { + mainFile_Arduino.appendToMainCode("/* Activating tracing */" + CR); + + if (tracing) { + mainFile_Arduino.appendToMainCode("if (argc>1){" + CR); + mainFile_Arduino.appendToMainCode("activeTracingInFile(argv[1]);" + CR + "} else {" + CR); + mainFile_Arduino.appendToMainCode("activeTracingInConsole();" + CR + "}" + CR); + } + } + + public void makeMakefileSrc(String _path) { + makefile_src = "SRCS = "; + makefile_src += _path + "main.c "; + for(TaskFile taskFile: taskFiles) { + makefile_src += _path + taskFile.getName() + ".c "; + } + + } + + public void makeMakefileSocLib() { + makefile_SocLib = "objs = "; + makefile_SocLib += "main.o "; + for(TaskFile taskFile: taskFiles) { + makefile_SocLib += taskFile.getName() + ".o "; + } + + } + + + public String getCTypeOf(AvatarAttribute _aa) { + String ret = "int"; + if (_aa.getType() == AvatarType.BOOLEAN) { + ret = "bool"; + } + return ret; + } + + public String getChannelName(AvatarRelation _ar, int _index) { + return _ar.block1.getName() + "_" + _ar.getSignal1(_index).getName() + "__" + _ar.block2.getName() + "_" + _ar.getSignal2(_index).getName(); + } + + public String getChannelName(AvatarRelation _ar, AvatarSignal _as) { + int index = _ar.getIndexOfSignal(_as); + return getChannelName(_ar, index); + } + + public String modifyGuard(String _g) { + String g = Conversion.replaceAllString(_g, "[", "(").trim(); + g = Conversion.replaceAllString(g, "]", ")").trim(); + g = Conversion.replaceOp(g, "and", "&&"); + g = Conversion.replaceOp(g, "or", "||"); + g = Conversion.replaceOp(g, "not", "!"); + TraceManager.addDev("Guard=" + g); + return g; + } + + public String reworkDelay(String _delay) { + + switch(timeUnit) { + case USEC: + return _delay; + case MSEC: + return "(" + _delay + ")*1000"; + case SEC: + return "(" + _delay + ")*1000000"; + } + + return _delay; + } + + private String modifyMethodName(AvatarBlock _ab, AvatarTerm term) { + if (term instanceof AvatarAttribute) + return term.getName (); + if (term instanceof AvatarConstant) + return term.getName (); + if (term instanceof AvatarTermRaw) + return term.getName (); + if (term instanceof AvatarArithmeticOp) { + AvatarArithmeticOp aop = (AvatarArithmeticOp) term; + return this.modifyMethodName (_ab, aop.getTerm1 ()) + + aop.getOperator () + + this.modifyMethodName (_ab, aop.getTerm2 ()); + } + if (term instanceof AvatarTuple) { + boolean first = true; + String res = "("; + for (AvatarTerm tterm: ((AvatarTuple) term).getComponents ()) { + if (first) + first = false; + else + res += ", "; + res += this.modifyMethodName (_ab, tterm); + } + + return res + ")"; + } + if (term instanceof AvatarTermFunction) + return _ab.getName () + "__" + ((AvatarTermFunction) term).getMethod ().getName () + + this.modifyMethodName (_ab, ((AvatarTermFunction) term).getArgs ()); + return ""; + } + + private String traceRequest() { + if (!tracing) { + return ""; + } + return "traceRequest(__myname, __returnRequest);" + CR; + } + + private String traceVariableModification(String blockName, String varName, String type) { + if (!tracing) { + return ""; + } + + return "traceVariableModification(\"" + blockName + "\", \"" + varName + "\", " + varName + "," + type + ");" + CR; + } + + private String traceFunctionCall(String blockName, String functionName, String params) { + if (!tracing) { + return ""; + } + + if (params == null) { + params = "\"-\""; + } + return "traceFunctionCall(\"" + blockName + "\", \"" + functionName + "\", " + params + ");" + CR; + } + + private String traceStateEntering(String name, String stateName) { + if (!tracing) { + return ""; + } + return "traceStateEntering(" + name + ", \"" + stateName + "\");" + CR; + } + + private String mainDebugMsg(String s) { + if (!debug) { + return ""; + } + return "debugMsg(\"" + s + "\");" + CR; + } + + private String taskDebugMsg(String s) { + if (!debug) { + return ""; + } + + return "debug2Msg(__myname, \"" + s + "\");" + CR; + } + + public String makeActionsOfTransaction(AvatarBlock _block, AvatarTransition _at) { + String ret = ""; + String type; + for(int i=0; i<_at.getNbOfAction(); i++) { + // Must know whether this is an action or a method call + + AvatarAction act = _at.getAction(i); + TraceManager.addDev("Action=" + act); + if (act.isAMethodCall()) { + TraceManager.addDev("Method call"); + String actModified = modifyMethodName (_block, (AvatarTermFunction) act); + ret += actModified + ";" + CR; + } else { + TraceManager.addDev("Else"); + String actModified = modifyMethodName (_block, ((AvatarActionAssignment) act).getLeftHand ()) + + " = " + modifyMethodName (_block, ((AvatarActionAssignment) act).getRightHand ()); + AvatarLeftHand leftHand = ((AvatarActionAssignment) act).getLeftHand (); + ret += actModified + ";" + CR; + if (leftHand instanceof AvatarAttribute) { + if (((AvatarAttribute) leftHand).isInt()) { + type = "0"; + } else { + type = "1"; + } + ret += traceVariableModification(_block.getName(), leftHand.getName (), type); + } + + } + } + + return ret; + } + +} diff --git a/src/main/java/avatartranslator/toexecutable/MainFileMbed.java b/src/main/java/avatartranslator/toexecutable/MainFileMbed.java new file mode 100644 index 0000000000000000000000000000000000000000..418118d33614d220fcdc9dae0699fb2063ffcc5b --- /dev/null +++ b/src/main/java/avatartranslator/toexecutable/MainFileMbed.java @@ -0,0 +1,139 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + + + +package avatartranslator.toexecutable; + +import myutil.*; + +/** + * Class MainFile + * Creation: 29/03/2011 + * @version 1.1 29/03/2011 + * @author Ludovic APVRILLE + */ +public class MainFileMbed { + + private final static String H_DEF = "#ifndef MAIN_H\n#define MAIN_H\n"; + private final static String H_END_DEF = "#endif\n"; + + private final static String INCLUDE_HEADER = "#include <mbed.h>\n#include <rtos.h>\n";//"#include <stdio.h>\n#include <pthread.h>\n#include <unistd.h>\n#include <stdlib.h>\n"; + private final static String LOCAL_INCLUDE_HEADER = "#include \"request.h\"\n#include \"syncchannel.h\"\n#include \"request_manager.h\"\n#include \"debug.h\"\n#include \"random.h\"\n#include \"tracemanager.h\""; + + private final static String MAIN_DEC = "int main(int argc, char *argv[]) {\n"; + private final static String DISABLE_BUFFERING = "/* disable buffering on stdout */\nsetvbuf(stdout, (char*)NULL, _IONBF, 0);\n"; + + private final static String CR = "\n"; + + private String name; + private String hCode; + private String beforeMainCode; + private String mainCode; + + private Plugin plugin; + + + public MainFileMbed(String _name, Plugin _plugin) { + name = _name; + plugin = _plugin; + hCode = ""; + mainCode = ""; + beforeMainCode = ""; + + } + + public String getName() { + return name; + } + + public void appendToHCode(String _code) { + hCode += _code; + } + + public void appendToBeforeMainCode(String _code) { + beforeMainCode += _code; + } + + public void appendToMainCode(String _code) { + mainCode += _code; + } + + public String getHeaderCode() { + return H_DEF + hCode + H_END_DEF; + } + + public String getMainCode() { + + String mainDec = MAIN_DEC; + + + + try { + if (plugin != null) { + mainDec = plugin.executeRetStringMethod(plugin.getClassAvatarCodeGenerator(), "getMainDeclaration"); + } + /*File file = new File(plugin); + TraceManager.addDev("Loading plugin=" + plugin); + URL[] urls = new URL[] { file.toURI().toURL() }; + ClassLoader loader = new URLClassLoader(urls); + TraceManager.addDev("Loader created"); + Class c = loader.loadClass("CustomizerAvatarJavaCodeGeneration"); + Method method = c.getMethod("getMainDeclaration"); + TraceManager.addDev("Method created"); + Object ret = method.invoke(null); + TraceManager.addDev("Method cinvoked"); + mainDec = (String)ret; + TraceManager.addDev("Conversion to String"); + TraceManager.addDev("Customized main dec:" + mainDec);*/ + } catch (Exception e) { + TraceManager.addDev("plugin exception: " + e.getMessage()); + } + + String s = INCLUDE_HEADER + "\n" + LOCAL_INCLUDE_HEADER + CR + CR; + s += beforeMainCode + CR; + s += mainDec + CR; + s += DISABLE_BUFFERING; + s += CR + mainCode + CR + "}" + CR; + + return s; + + } + +} diff --git a/src/main/java/avatartranslator/toexecutable/MainFile_Arduino.java b/src/main/java/avatartranslator/toexecutable/MainFile_Arduino.java new file mode 100644 index 0000000000000000000000000000000000000000..90ef8b57a34caa2091ab4017b16b676df543b739 --- /dev/null +++ b/src/main/java/avatartranslator/toexecutable/MainFile_Arduino.java @@ -0,0 +1,88 @@ +package avatartranslator.toexecutable; + +import myutil.Plugin; +import myutil.TraceManager; + +public class MainFile_Arduino { + + private final static String SETUP_CODE = ""; + private final static String LOOP_CODE = ""; + + private final static String H_DEF = "#ifndef MAIN_H\n#define MAIN_H\n"; + private final static String H_END_DEF = "#endif\n"; + + private final static String INCLUDE_HEADER = "#include <stdio.h>\n#include <pthread.h>\n#include <unistd.h>\n#include <stdlib.h>\n"; + private final static String LOCAL_INCLUDE_HEADER = "#include \"request.h\"\n#include \"syncchannel.h\"\n#include \"request_manager.h\"\n#include \"debug.h\"\n#include \"random.h\"\n#include \"tracemanager.h\""; + + private final static String MAIN_DEC = "int main(int argc, char *argv[]) {\n"; + private final static String DISABLE_BUFFERING = "/* disable buffering on stdout */\nsetvbuf(stdout, NULL, _IONBF, 0);\n"; + + private final static String CR = "\n"; + + + + private String name; + private String hCode; + private String beforeMainCode; + private String mainCode; + + private Plugin plugin; + + + public MainFile_Arduino(String _name, Plugin _plugin) { + name = _name; + plugin = _plugin; + hCode = ""; + mainCode = ""; + beforeMainCode = ""; + + } + + public String getName() { + return name; + } + + public void appendToHCode(String _code) { + hCode += _code; + } + + public void appendToBeforeMainCode(String _code) { + beforeMainCode += _code; + } + + public void appendToMainCode(String _code) { + mainCode += _code; + } + + public String getHeaderCode() { + return H_DEF + hCode + H_END_DEF; + } + + public String getMainCode() { + + String mainDec = MAIN_DEC; + + + + try { + if (plugin != null) { + mainDec = plugin.executeRetStringMethod(plugin.getClassAvatarCodeGenerator(), "getMainDeclaration"); + } + + } catch (Exception e) { + TraceManager.addDev("plugin exception: " + e.getMessage()); + } + + String s = INCLUDE_HEADER + "\n" + LOCAL_INCLUDE_HEADER + CR + CR; + + s += beforeMainCode + CR; + //s += DISABLE_BUFFERING; + s += CR + mainCode + CR + CR; + + return s; + + } + + + +} diff --git a/src/main/java/avatartranslator/toexecutable/TaskFileMbed.java b/src/main/java/avatartranslator/toexecutable/TaskFileMbed.java new file mode 100644 index 0000000000000000000000000000000000000000..de9e8e795fa7c696e4d1582449aec1930fba5f92 --- /dev/null +++ b/src/main/java/avatartranslator/toexecutable/TaskFileMbed.java @@ -0,0 +1,107 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + + + +package avatartranslator.toexecutable; + +/** + * Class TaskFile + * Creation: 29/03/2011 + * @version 1.2 01/07/2014 + * @author Ludovic APVRILLE, Raja GATGOUT + */ +public class TaskFileMbed { + /////////////////////RG + //1) enlever pthread.h + //2) ajouter : srl.h et mwmr.h + private final static String INCLUDE_HEADER = "#include <mbed.h>\n#include <rtos.h>\n";//"#include <stdio.h>\n#include <pthread.h>\n#include <unistd.h>\n#include <stdlib.h>\n"; + private final static String LOCAL_INCLUDE_HEADER = "#include \"request.h\"\n#include \"syncchannel.h\"\n#include \"request_manager.h\"\n#include \"debug.h\"\n#include \"defs.h\"\n#include \"mytimelib.h\"\n#include \"random.h\"\n#include \"tracemanager.h\"\n#include \"main.h\""; + + private final static String INCLUDE_HEADER_SOCLIB = "#include <mbed.h>\n#include <rtos.h>\n";//"#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n"; + private final static String LOCAL_INCLUDE_HEADER_SOCLIB = "#include \"request.h\"\n#include \"syncchannel.h\"\n#include \"request_manager.h\"\n#include \"debug.h\"\n#include \"defs.h\"\n#include \"mytimelib.h\"\n#include \"random.h\"\n#include \"tracemanager.h\"\n#include \"main.h\"\n#include \"/Users/ludovicapvrille/Prog/mutekh/libmwmr/include/mwmr/mwmr.h\"\n "; + + private final static String CR = "\n"; + + private String name; + + private String headerCode; + private String mainCode; + + + public TaskFileMbed(String _name) { + name = _name; + headerCode = ""; + mainCode = ""; + } + + public String getName() { + return name; + } + + public String getFullHeaderCode() { + String s = "#ifndef " + name + "_H\n#define " + name + "_H\n"; + s += INCLUDE_HEADER + CR + LOCAL_INCLUDE_HEADER + CR + CR; + s += headerCode; + s += "#endif\n"; + return s; + } + + public String getFullHeaderCodeSoclib() { + String s = "#ifndef " + name + "_H\n#define " + name + "_H\n"; + s += INCLUDE_HEADER_SOCLIB + CR + LOCAL_INCLUDE_HEADER_SOCLIB + CR + CR; + s += headerCode; + s += "#endif\n"; + return s; + } + + public String getMainCode() { + return "#include \"" + name + ".h\"" + CR + CR + mainCode; + } + + public void addToHeaderCode(String _code) { + headerCode += _code; + } + + public void addToMainCode(String _code) { + mainCode += _code; + } + + +} diff --git a/src/main/java/ui/window/JDialogAvatarExecutableCodeGeneration.java b/src/main/java/ui/window/JDialogAvatarExecutableCodeGeneration.java index c251b3bf23d1609f6e5b30dd4c067fcd3119bfd8..89e0fe304b122a2e7f144d09e31741941c266393 100644 --- a/src/main/java/ui/window/JDialogAvatarExecutableCodeGeneration.java +++ b/src/main/java/ui/window/JDialogAvatarExecutableCodeGeneration.java @@ -1,26 +1,26 @@ /* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille - * + * * ludovic.apvrille AT enst.fr - * + * * This software is a computer program whose purpose is to allow the * edition of TURTLE analysis, design and deployment diagrams, to * allow the generation of RT-LOTOS or Java code from this diagram, * and at last to allow the analysis of formal validation traces * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP * from INRIA Rhone-Alpes. - * + * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". - * + * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. - * + * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, @@ -31,16 +31,20 @@ * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. - * + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. */ + + package ui.window; import avatartranslator.AvatarSpecification; import avatartranslator.toexecutable.AVATAR2CPOSIX; +import avatartranslator.toexecutable.AVATAR2CMBED; +import avatartranslator.toexecutable.AVATAR2CPOSIXArduino; import launcher.LauncherException; import launcher.RshClient; import myutil.*; @@ -60,12 +64,11 @@ import java.io.File; * Class JDialogAvatarExecutableCodeGeneration * Dialog for managing the generation and compilation of AVATAR executable code * Creation: 29/03/2011 - * + * @version 1.1 29/03/2011 * @author Ludovic APVRILLE * @author (added deployment diagrams) Julien Henon, Daniela GENIUS - * @version 1.1 29/03/2011 */ -public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame implements ActionListener, Runnable, MasterProcessInterface { +public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame implements ActionListener, Runnable, MasterProcessInterface { private static String[] unitTab = {"usec", "msec", "sec"}; @@ -85,7 +88,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im // private static String unitCycle = "1"; - private static String[] codes = {"AVATAR CPOSIX"}; + private static String[] codes = {"AVATAR CPOSIX","AVATAR ARDUINO","AVATAR MBED"}; private static int selectedItem = 0; private static int selectedRun = 1; private static int selectedCompile = 0; @@ -122,14 +125,13 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im protected JTextField code1, code2, compiler1, compiler2, exe1, exe2, exe3, exe4, exe2int, simulationTraceFile, simulationsoclibTraceFile; protected JTabbedPane jp1; protected JScrollPane jsp; - protected JCheckBox removeCFiles, removeOFiles, removeXFiles, debugmode, tracemode, optimizemode, putUserCode; + protected JCheckBox removeCFiles, removeXFiles, debugmode, tracemode, optimizemode, putUserCode; protected JComboBox<String> versionCodeGenerator, units; protected JButton showSimulationTrace; private static int selectedUnit = 2; private static boolean removeCFilesValue = true; private static boolean removeXFilesValue = true; - private static boolean removeOFilesValue = false; private static boolean debugValue = false; private static boolean tracingValue = true; //private static boolean optimizeValue = true; @@ -144,23 +146,22 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im protected RshClient rshc; - /** - * Creates new form - */ - public JDialogAvatarExecutableCodeGeneration(Frame _f, MainGUI _mgui, String title, String _hostExecute, String _pathCode, - String _pathCompiler, String _pathExecute, String _pathCompilerSoclib, - String _pathExecuteSoclib, String _pathSoclibTraceFile) { + /** Creates new form */ + public JDialogAvatarExecutableCodeGeneration(Frame _f, MainGUI _mgui, String title, String _hostExecute, String _pathCode, String _pathCompiler, String _pathExecute, String _pathCompilerSoclib, String _pathExecuteSoclib, String _pathSoclibTraceFile) { super(title); f = _f; mgui = _mgui; + if (pathCode == null) { + pathCode = _pathCode; + } - pathCode = _pathCode; - - pathCompiler = _pathCompiler; + if (pathCompiler == null) + pathCompiler = _pathCompiler; - pathExecute = _pathExecute; + if (pathExecute == null) + pathExecute = _pathExecute; if (pathCompileSoclib == null) { pathCompileSoclib = _pathCompilerSoclib; @@ -170,7 +171,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im pathExecuteSoclib = _pathExecuteSoclib; } - if (pathSoclibTraceFile == null) { + if (pathSoclibTraceFile == null){ pathSoclibTraceFile = _pathSoclibTraceFile; } @@ -197,9 +198,9 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im protected void initComponents() { - if (PluginManager.pluginManager.getPluginAvatarCodeGenerator() != null) { - codes[0] = "AVATAR CPOSIX (with Plugin)"; - } + if (PluginManager.pluginManager.getPluginAvatarCodeGenerator() != null) { + codes[0] = "AVATAR CPOSIX (with Plugin)"; + } Container c = getContentPane(); setFont(new Font("Helvetica", Font.PLAIN, 14)); @@ -259,10 +260,6 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im removeXFiles.setSelected(removeXFilesValue); jp01.add(removeXFiles, c01); - removeOFiles = new JCheckBox("Remove .o files"); - removeOFiles.setSelected(removeOFilesValue); - jp01.add(removeOFiles, c01); - debugmode = new JCheckBox("Put debug information in generated code"); debugmode.setSelected(debugValue); jp01.add(debugmode, c01); @@ -292,7 +289,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im versionCodeGenerator.setSelectedIndex(selectedItem); versionCodeGenerator.addActionListener(this); jp01.add(versionCodeGenerator, c01); - // + //System.out.println("selectedItem=" + selectedItem); //devmode = new JCheckBox("Development version of the simulator"); //devmode.setSelected(true); @@ -309,7 +306,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im c02.fill = GridBagConstraints.BOTH; c02.gridheight = 1; - compilegroup = new ButtonGroup(); + compilegroup = new ButtonGroup(); compile = new JRadioButton(textSysC2, false); jp02.add(compile, c02); @@ -320,7 +317,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im //jp02.add(new JLabel("with"), c02); - compiler1 = new JTextField(pathCompiler + " -C " + pathCode, 100); + compiler1 = new JTextField(pathCompiler, 100); jp02.add(compiler1, c02); jp02.add(new JLabel(" "), c02); @@ -351,7 +348,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im exe.addActionListener(this); exegroup.add(exe); jp03.add(exe, c03); - exe2 = new JTextField(pathCode + "/" + pathExecute, 100); + exe2 = new JTextField(pathExecute, 100); jp03.add(exe2, c03); exegroup.add(exe); @@ -359,7 +356,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im exetrace.addActionListener(this); exegroup.add(exetrace); jp03.add(exetrace, c03); - exe3 = new JTextField(pathCode + "/" + pathExecute + " " + pathCode + "trace.txt", 100); + exe3 = new JTextField(pathExecute + " " + pathCode + File.separator + "trace.txt", 100); jp03.add(exe3, c03); exesoclib = new JRadioButton(textSysC6, false); @@ -399,7 +396,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im viewgroup.add(viewtrace); viewtrace.addActionListener(this); jp04.add(viewtrace, c04); - simulationTraceFile = new JTextField(pathCode + "trace.txt", 100); + simulationTraceFile = new JTextField(pathCode + File.separator + "trace.txt", 100); jp04.add(simulationTraceFile, c04); viewtracesoclib = new JRadioButton(textSysC9, false); viewgroup.add(viewtracesoclib); @@ -418,6 +415,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im jp1.add("Results", jp04); + c.add(jp1, BorderLayout.NORTH); jta = new ScrolledJTextArea(); @@ -427,7 +425,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im jta.append("Select options and then, click on 'start' to launch code generation / compilation / execution\n"); Font f = new Font("Courrier", Font.BOLD, 12); jta.setFont(f); - textAreaWriter = new JTextAreaWriter(jta); + textAreaWriter = new JTextAreaWriter( jta ); jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); @@ -454,11 +452,11 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im } - public void actionPerformed(ActionEvent evt) { + public void actionPerformed(ActionEvent evt) { String command = evt.getActionCommand(); // Compare the action command to the known actions. - if (command.equals("Start")) { + if (command.equals("Start")) { startProcess(); } else if (command.equals("Stop")) { stopProcess(); @@ -470,7 +468,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im selectedUnit = units.getSelectedIndex(); } else if (evt.getSource() == showSimulationTrace) { showSimulationTrace(); - } else if ((evt.getSource() == exe) || (evt.getSource() == exetrace) || (evt.getSource() == exesoclib)) { + } else if ((evt.getSource() == exe) || (evt.getSource() == exetrace)|| (evt.getSource() == exesoclib)) { makeSelectionExecute(); } else if ((evt.getSource() == compile) || (evt.getSource() == compilesoclib)) { makeSelectionCompile(); @@ -486,7 +484,6 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im optimizeModeSelected = optimizemode.isSelected(); removeCFilesValue = removeCFiles.isSelected(); removeXFilesValue = removeXFiles.isSelected(); - removeOFilesValue = removeOFiles.isSelected(); debugValue = debugmode.isSelected(); tracingValue = tracemode.isSelected(); static_putUserCode = putUserCode.isSelected(); @@ -542,7 +539,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im } rshc = null; - mode = STOPPED; + mode = STOPPED; setButtons(); go = false; } @@ -578,14 +575,14 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im if (removeCFiles.isSelected()) { jta.append("Removing all .h files\n"); - list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIX.getGeneratedPath(), ".h"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIX.getGeneratedPath(), ".h"); if (list.length() == 0) { jta.append("No files were deleted\n"); } else { jta.append("Files deleted:\n" + list + "\n"); } jta.append("Removing all .c files\n"); - list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIX.getGeneratedPath(), ".c"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIX.getGeneratedPath(), ".c"); if (list.length() == 0) { jta.append("No files were deleted\n"); } else { @@ -595,7 +592,7 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im if (removeXFiles.isSelected()) { jta.append("Removing all .x files\n"); - list = FileUtils.deleteFiles(code1.getText(), ".x"); + list = FileUtils.deleteFiles(code1.getText() , ".x"); if (list.length() == 0) { jta.append("No files were deleted\n"); } else { @@ -603,21 +600,152 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im } } + testGo(); + + selectedUnit = units.getSelectedIndex(); + //System.out.println("Selected item=" + selectedItem); + AvatarSpecification avspec = mgui.gtm.getAvatarSpecification(); + + // Generating code + if (avspec == null) { + jta.append("Error: No AVATAR specification\n"); + } else { + if (PluginManager.pluginManager.getPluginAvatarCodeGenerator() != null) { + TraceManager.addDev("Using customize Avatar code generator"); + } + + AVATAR2CPOSIX avatartocposix = new AVATAR2CPOSIX(avspec, PluginManager.pluginManager.getPluginAvatarCodeGenerator()); + + avatartocposix.includeUserCode(putUserCode.isSelected()); + avatartocposix.setTimeUnit(selectedUnit); + avatartocposix.generateCPOSIX(debugmode.isSelected(), tracemode.isSelected()); + testGo(); + jta.append("Generation of C-POSIX executable code: done\n"); + //t2j.printJavaClasses(); + try { + jta.append("Saving code in files\n"); + pathCode = code1.getText(); + //gene.avatartocposix.saveInFiles(pathCode);//DG 27.11. + avatartocposix.saveInFiles(pathCode); + //tml2systc.saveFile(pathCode, "appmodel"); + jta.append("Code saved\n"); + } catch (Exception e) { + jta.append("Could not generate files\n"); + } + } + } + + testGo(); + + + // Compilation + if (jp1.getSelectedIndex() == 1) { + + if (selectedCompile == 0) { + cmd = compiler1.getText(); + } else { + cmd = compiler2.getText(); + } + + jta.append("Compiling executable code with command: \n" + cmd + "\n"); + + rshc = new RshClient(hostExecute); + // Assuma data are on the remote host + // Command + try { + processCmd(cmd, jta); + //data = processCmd(cmd); + //jta.append(data); + jta.append("Compilation done\n"); + } catch (LauncherException le) { + jta.append("Error: " + le.getMessage() + "\n"); + mode = STOPPED; + setButtons(); + return; + } catch (Exception e) { + mode = STOPPED; + setButtons(); + return; + } + } + + if (jp1.getSelectedIndex() == 2) { + try { + if (selectedRun == 0) { + cmd = exe2.getText(); + } else { + if (selectedRun == 1) { + cmd = exe3.getText(); + } else { + cmd = exe4.getText(); + } + } + + jta.append("Executing code with command: \n" + cmd + "\n"); + + rshc = new RshClient(hostExecute); + // Assume data are on the remote host + // Command + + processCmd(cmd, jta); + //jta.append(data); + jta.append("Execution done\n"); + } catch (LauncherException le) { + jta.append("Error: " + le.getMessage() + "\n"); + mode = STOPPED; + setButtons(); + return; + } catch (Exception e) { + mode = STOPPED; + setButtons(); + return; + } + } + + if ((hasError == false) && (jp1.getSelectedIndex() < 2)) { + jp1.setSelectedIndex(jp1.getSelectedIndex() + 1); + } + } + + + + + + //Arduino test + + if (selectedItem == 1) { + // Code generation + if (jp1.getSelectedIndex() == 0) { + jta.append("Generating executable code Arduino\n"); - if (removeOFiles.isSelected()) { - String pathTmp = code1.getText() + "/lib/generated_src/"; - jta.append("Removing all .o files in " + pathTmp + "\n"); - list = FileUtils.deleteFiles(pathTmp, ".o"); + if (removeCFiles.isSelected()) { + jta.append("Removing all .h files\n"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIXArduino.getGeneratedPath(), ".h"); if (list.length() == 0) { jta.append("No files were deleted\n"); } else { jta.append("Files deleted:\n" + list + "\n"); } + jta.append("Removing all .c files\n"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIXArduino.getGeneratedPath(), ".c"); + if (list.length() == 0) { + jta.append("No files were deleted\n"); + } else { + jta.append("Files deleted:\n" + list + "\n"); + } + + jta.append("Removing all .ino files\n"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CPOSIXArduino.getGeneratedPath(), ".ino"); + if (list.length() == 0) { + jta.append("No files were deleted\n"); + } else { + jta.append("Files deleted:\n" + list + "\n"); + } + } - pathTmp = code1.getText() + "/lib/src/"; - jta.append("Removing all .o files in " + pathTmp + "\n"); - list = FileUtils.deleteFiles(pathTmp, ".o"); - + if (removeXFiles.isSelected()) { + jta.append("Removing all .x files\n"); + list = FileUtils.deleteFiles(code1.getText() , ".x"); if (list.length() == 0) { jta.append("No files were deleted\n"); } else { @@ -628,35 +756,34 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im testGo(); selectedUnit = units.getSelectedIndex(); - // + //System.out.println("Selected item=" + selectedItem); AvatarSpecification avspec = mgui.gtm.getAvatarSpecification(); // Generating code if (avspec == null) { jta.append("Error: No AVATAR specification\n"); } else { - if (PluginManager.pluginManager.getPluginAvatarCodeGenerator() != null) { - TraceManager.addDev("Using customize Avatar code generator"); - } - - AVATAR2CPOSIX avatartocposix = new AVATAR2CPOSIX(avspec, PluginManager.pluginManager.getPluginAvatarCodeGenerator()); - + if (PluginManager.pluginManager.getPluginAvatarCodeGenerator() != null) { + TraceManager.addDev("Using customize Avatar code generator"); + } + + AVATAR2CPOSIXArduino avatartocposix = new AVATAR2CPOSIXArduino(avspec, PluginManager.pluginManager.getPluginAvatarCodeGenerator()); + avatartocposix.includeUserCode(putUserCode.isSelected()); avatartocposix.setTimeUnit(selectedUnit); - avatartocposix.generateCPOSIX(debugmode.isSelected(), tracemode.isSelected()); + avatartocposix.generateArduinoCode(debugmode.isSelected(), tracemode.isSelected()); testGo(); - jta.append("Generation of C-POSIX executable code: done\n"); + jta.append("Generation of Arduino executable code: done\n"); //t2j.printJavaClasses(); try { jta.append("Saving code in files\n"); pathCode = code1.getText(); //gene.avatartocposix.saveInFiles(pathCode);//DG 27.11. - TraceManager.addDev("Generating files in " + pathCode); avatartocposix.saveInFiles(pathCode); //tml2systc.saveFile(pathCode, "appmodel"); jta.append("Code saved\n"); } catch (Exception e) { - jta.append("Could not generate files:\n" + e.getMessage()); + jta.append("Could not generate files\n"); } } } @@ -685,11 +812,11 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im jta.append("Compilation done\n"); } catch (LauncherException le) { jta.append("Error: " + le.getMessage() + "\n"); - mode = STOPPED; + mode = STOPPED; setButtons(); return; } catch (Exception e) { - mode = STOPPED; + mode = STOPPED; setButtons(); return; } @@ -718,11 +845,11 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im jta.append("Execution done\n"); } catch (LauncherException le) { jta.append("Error: " + le.getMessage() + "\n"); - mode = STOPPED; + mode = STOPPED; setButtons(); return; } catch (Exception e) { - mode = STOPPED; + mode = STOPPED; setButtons(); return; } @@ -732,157 +859,163 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im jp1.setSelectedIndex(jp1.getSelectedIndex() + 1); } } + + + //Arduino test fin + + + //Mbed test + + if (selectedItem == 2) { + // Code generation + if (jp1.getSelectedIndex() == 0) { + jta.append("Generating executable code Mbed\n"); - //enleve 06.02.2017 - /* if (selectedItem == 1) { - // Code generation - if (jp1.getSelectedIndex() == 0) { - jta.append("Generating executable code (SOCLIB version)\n"); + if (removeCFiles.isSelected()) { + jta.append("Removing all .h files\n"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CMBED.getGeneratedPath(), ".h"); + if (list.length() == 0) { + jta.append("No files were deleted\n"); + } else { + jta.append("Files deleted:\n" + list + "\n"); + } + jta.append("Removing all .cpp files\n"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CMBED.getGeneratedPath(), ".c"); + if (list.length() == 0) { + jta.append("No files were deleted\n"); + } else { + jta.append("Files deleted:\n" + list + "\n"); + } + /* + jta.append("Removing all .ino files\n"); + list = FileUtils.deleteFiles(code1.getText() + AVATAR2CMBED.getGeneratedPath(), ".ino"); + if (list.length() == 0) { + jta.append("No files were deleted\n"); + } else { + jta.append("Files deleted:\n" + list + "\n"); + }*/ + } - if (removeCFiles.isSelected()) { + if (removeXFiles.isSelected()) { + jta.append("Removing all .x files\n"); + list = FileUtils.deleteFiles(code1.getText() , ".x"); + if (list.length() == 0) { + jta.append("No files were deleted\n"); + } else { + jta.append("Files deleted:\n" + list + "\n"); + } + } - jta.append("Removing all .h files\n"); - //list = FileUtils.deleteFiles(code1.getText() + AVATAR2SOCLIB.getGeneratedPath(), ".h"); - list = FileUtils.deleteFiles(code1.getText() + TasksAndMainGenerator.getGeneratedPath(), ".h"); - if (list.length() == 0) { - jta.append("No files were deleted\n"); - } else { - jta.append("Files deleted:\n" + list + "\n"); - } - jta.append("Removing all .c files\n"); - list = FileUtils.deleteFiles(code1.getText() + TasksAndMainGenerator.getGeneratedPath(), ".c"); - //list = FileUtils.deleteFiles(code1.getText() + AVATAR2SOCLIB.getGeneratedPath(), ".c"); - if (list.length() == 0) { - jta.append("No files were deleted\n"); - } else { - jta.append("Files deleted:\n" + list + "\n"); - } - } + testGo(); - if (removeXFiles.isSelected()) { - jta.append("Removing all .x files\n"); - list = FileUtils.deleteFiles(code1.getText() , ".x"); - if (list.length() == 0) { - jta.append("No files were deleted\n"); - } else { - jta.append("Files deleted:\n" + list + "\n"); - } - } + selectedUnit = units.getSelectedIndex(); + //System.out.println("Selected item=" + selectedItem); + AvatarSpecification avspec = mgui.gtm.getAvatarSpecification(); - testGo(); + // Generating code + if (avspec == null) { + jta.append("Error: No AVATAR specification\n"); + } else { + if (PluginManager.pluginManager.getPluginAvatarCodeGenerator() != null) { + TraceManager.addDev("Using customize Avatar code generator"); + } + + AVATAR2CMBED avatartocmbed = new AVATAR2CMBED(avspec, PluginManager.pluginManager.getPluginAvatarCodeGenerator()); + + avatartocmbed.includeUserCode(putUserCode.isSelected()); + avatartocmbed.setTimeUnit(selectedUnit); + avatartocmbed.generateCMBED(debugmode.isSelected(), tracemode.isSelected()); + testGo(); + jta.append("Generation of Mbed executable code: done\n"); + //t2j.printJavaClasses(); + try { + jta.append("Saving code in files\n"); + pathCode = code1.getText(); + //gene.avatartocmbed.saveInFiles(pathCode);//DG 27.11. + avatartocmbed.saveInFiles(pathCode); + //tml2systc.saveFile(pathCode, "appmodel"); + jta.append("Code saved\n"); + } catch (Exception e) { + jta.append("Could not generate files\n"); + } + } + } - selectedUnit = units.getSelectedIndex(); - // - AvatarSpecification avspec = mgui.gtm.getAvatarSpecification(); + testGo(); - // Generating code - if (avspec == null) { - jta.append("Error: No AVATAR specification\n"); - } else { - //AVATAR2SOCLIB avatartocposix = new AVATAR2SOCLIB(avspec); - // avatartocposix.includeUserCode(putUserCode.isSelected()); - // avatartocposix.setTimeUnit(selectedUnit); - // avatartocposix.generateCPOSIX(debugmode.isSelected(), tracemode.isSelected()); - // julien ----------------------------------------- - ADDDiagramPanel deploymentDiagramPanel = mgui.getFirstAvatarDeploymentPanelFound(); - AvatarDeploymentPanelTranslator avdeploymenttranslator = new AvatarDeploymentPanelTranslator(deploymentDiagramPanel); - AvatarddSpecification avddspec = avdeploymenttranslator.getAvatarddSpecification(); - - TasksAndMainGenerator gene = new TasksAndMainGenerator(avddspec,avspec); - gene.includeUserCode(putUserCode.isSelected()); - gene.setTimeUnit(selectedUnit); - gene.generateSoclib(debugmode.isSelected(), tracemode.isSelected()); - - // ----------end addition julien ---------------------------------------- - - testGo(); - jta.append("Generation of C-SOCLIB executable code: done\n"); - //t2j.printJavaClasses(); - try { - jta.append("Saving code in files\n"); - pathCode = code1.getText(); - gene.saveInFiles(pathCode);//DG 27.11. - //avatartocposix.saveInFiles(pathCode); - //tml2systc.saveFile(pathCode, "appmodel"); - jta.append("Code saved\n"); - } catch (Exception e) { - jta.append("Could not generate files\n"); - } - } - } - testGo(); + // Compilation + if (jp1.getSelectedIndex() == 1) { - // Compilation - if (jp1.getSelectedIndex() == 1) { + if (selectedCompile == 0) { + cmd = compiler1.getText(); + } else { + cmd = compiler2.getText(); + } - if (selectedCompile == 0) { - cmd = compiler1.getText(); - } else { - cmd = compiler2.getText(); - } + jta.append("Compiling executable code with command: \n" + cmd + "\n"); - jta.append("Compiling executable code with command: \n" + cmd + "\n"); - - rshc = new RshClient(hostExecute); - - try { - processCmd(cmd, jta); - //data = processCmd(cmd); - //jta.append(data); - jta.append("Compilation done\n"); - } catch (LauncherException le) { - jta.append("Error: " + le.getMessage() + "\n"); - mode = STOPPED; - setButtons(); - return; - } catch (Exception e) { - mode = STOPPED; - setButtons(); - return; - } - } + rshc = new RshClient(hostExecute); + // Assuma data are on the remote host + // Command + try { + processCmd(cmd, jta); + //data = processCmd(cmd); + //jta.append(data); + jta.append("Compilation done\n"); + } catch (LauncherException le) { + jta.append("Error: " + le.getMessage() + "\n"); + mode = STOPPED; + setButtons(); + return; + } catch (Exception e) { + mode = STOPPED; + setButtons(); + return; + } + } - if (jp1.getSelectedIndex() == 2) { - try { - if (selectedRun == 0) { - cmd = exe2.getText(); - } else { - if (selectedRun == 1) { - cmd = exe3.getText(); - } else { - cmd = exe4.getText(); - } - } + if (jp1.getSelectedIndex() == 2) { + try { + if (selectedRun == 0) { + cmd = exe2.getText(); + } else { + if (selectedRun == 1) { + cmd = exe3.getText(); + } else { + cmd = exe4.getText(); + } + } - jta.append("Executing code with command: \n" + cmd + "\n"); - - rshc = new RshClient(hostExecute); - // Assume data are on the remote host - // Command - - processCmd(cmd, jta); - //jta.append(data); - jta.append("Execution done\n"); - } catch (LauncherException le) { - jta.append("Error: " + le.getMessage() + "\n"); - mode = STOPPED; - setButtons(); - return; - } catch (Exception e) { - mode = STOPPED; - setButtons(); - return; - } - } + jta.append("Executing code with command: \n" + cmd + "\n"); - if ((hasError == false) && (jp1.getSelectedIndex() < 2)) { - jp1.setSelectedIndex(jp1.getSelectedIndex() + 1); - } - } */ + rshc = new RshClient(hostExecute); + // Assume data are on the remote host + // Command - //fin ajoute DG + processCmd(cmd, jta); + //jta.append(data); + jta.append("Execution done\n"); + } catch (LauncherException le) { + jta.append("Error: " + le.getMessage() + "\n"); + mode = STOPPED; + setButtons(); + return; + } catch (Exception e) { + mode = STOPPED; + setButtons(); + return; + } + } + if ((hasError == false) && (jp1.getSelectedIndex() < 2)) { + jp1.setSelectedIndex(jp1.getSelectedIndex() + 1); + } + } + + + //Mbed test fin + } catch (InterruptedException ie) { jta.append("Interrupted\n"); @@ -893,13 +1026,13 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im checkMode(); setButtons(); - // + //System.out.println("Selected item=" + selectedItem); } protected void processCmd(String cmd, JTextArea _jta) throws LauncherException { rshc.setCmd(cmd); rshc.sendExecuteCommandRequest(); - rshc.writeCommandMessages(textAreaWriter); + rshc.writeCommandMessages( textAreaWriter ); return; } @@ -909,28 +1042,28 @@ public class JDialogAvatarExecutableCodeGeneration extends javax.swing.JFrame im } protected void setButtons() { - switch (mode) { - case NOT_STARTED: - start.setEnabled(true); - stop.setEnabled(false); - close.setEnabled(true); - //setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - getGlassPane().setVisible(false); - break; - case STARTED: - start.setEnabled(false); - stop.setEnabled(true); - close.setEnabled(false); - getGlassPane().setVisible(true); - //setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - break; - case STOPPED: - default: - start.setEnabled(false); - stop.setEnabled(false); - close.setEnabled(true); - getGlassPane().setVisible(false); - break; + switch(mode) { + case NOT_STARTED: + start.setEnabled(true); + stop.setEnabled(false); + close.setEnabled(true); + //setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + getGlassPane().setVisible(false); + break; + case STARTED: + start.setEnabled(false); + stop.setEnabled(true); + close.setEnabled(false); + getGlassPane().setVisible(true); + //setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + break; + case STOPPED: + default: + start.setEnabled(false); + stop.setEnabled(false); + close.setEnabled(true); + getGlassPane().setVisible(false); + break; } }