SimpleEntity
module SimpleEntity:
%% declarations
% ADU type
type COMMAND;
% ADUs received from the network
input RcvRequest:COMMAND,
RcvResponse:COMMAND;
% ADUs sent to the network
output SndRequest:COMMAND,
SndResponse:COMMAND;
% input signal
input Request;
% output signal
output Print:string;
% functions
function Build_Request():COMMAND,
Build_Response():COMMAND;
%% body
every RcvRequest do
emit SndResponse(Build_Response());
end every
||
every Request do
emit SndRequest(Build_Request());
await RcvResponse;
emit Print("Response Received");
end every
end module
Here the example is extremely simple and do not give more semantics to the ADUs than the one expressed by their names.
If you are under Emacs the menu "Alfred" should be added in the tool bar for the esterel+alfred mode. Press "Start ALFred" to enable ALFred menu for QoS setting.Now you just have to click on the ADU type COMMAND and fill in the pop up menu with the following values: partial-reliable/in-sequence/non-real-time/unicast.
This will create a file called "SimpleEntity.qos":
$ more SimpleEntity.qos COMMAND reliable in-sequence non-real-time unicastIf you do not want to use emacs menu you can also create this file yourself with one line per ADU type. The first column contains the ADU type, the second one the reliability parameter, the third one the order of delivery parameter, the fourth one the real-time parameter and the fifth one the mode parameter. The allowed values must have the following syntax:
SimpleEntityFor SimpleEntity the following files are generated by the parser:
$ ls SimpleEntity.strl SimpleEntity.qos $ java inria.alfred.parser.Tool -f SimpleEntity $ ls AlfAppli.strl QoSsetting.java AlfAppliInterface.java AlfAuto0Interface.java AlfAuto0.strl AlfAppliRun.java COMMAND.java
The parser also pops up a menu to enter more detailed QoS and/or modify the previously defined high-level QoS parameters. You can look for example at the menu display for the JukeBox application.
Let us have a look at the "AlfAppli.strl" file (we show only the newly generated code):
module AlfAppli :
:
:
output RemoveCOMMAND : COMMAND ;
input ApplClose;
abort
:
||
every Request do
:
await RcvResponse do emit RemoveCOMMAND ( ? RcvResponse ) end await ;
:
end every
when ApplClose
end module
As you can see the signals RemoveCOMMAND and ApplClose have been added to the specification in order to handle asynchronous reception of
ADUs from the network and top level abortion.
The interface skeleton is in the file "AlfAppliInterface.strl":
/**
* automatically generated by the alfred compiler (Tool.java).
* skeleton of the data interface for the esterel application.
* to be completed by the user ...
*/
// generated by inria.alfred.parser.Tool
import inria.alfred.lib.*;
import java.net.*;
import java.io.*;
import java.util.*;
// ----------------
// Interface class
// ----------------
public class AlfAppliInterface {
// BEGIN of <<do not touch this part of code>>
protected AppliHandler handler;
protected AlfAppli auto;
public void setAppliHandler (AppliHandler h) {
handler=h;
}
public void setAppliAuto (AlfAppli a) {
auto=a;
}
//
// treatment of ADUs
//
public void outRemoveCOMMAND (COMMAND val) {
handler.removeAdu("COMMAND", val); // val:COMMAND
}
public void outSndRequest (COMMAND val) {
handler.sendAdu("COMMAND", (SndRequest)val); // val:SndRequest
}
public void outSndResponse (COMMAND val) {
handler.sendAdu("COMMAND", (SndResponse)val); // val:SndResponse
}
// END of <<do not touch this part of code>>
//
// output signals
//
public void outPrint (String val) {
System.out.println("Print");
}
//
// sensors
//
//
// functions
//
public COMMAND Build_Request () {
return new COMMAND();
}
public COMMAND Build_Response () {
return new COMMAND();
}
//
// procedures
//
}
and in the file "COMMAND.strl":
//
// ADU Type class
//
import inria.alfred.lib.ADU;
public class COMMAND implements ADU {
public COMMAND () {}
}
class RcvRequest extends COMMAND {
}
class RcvResponse extends COMMAND {
}
class SndRequest extends COMMAND {
}
class SndResponse extends COMMAND {
}
The execution program has to be defined in the file "AlfAppliRun.java":
/**
* automatically generated by the alfred compiler (Tool.java).
* skeleton of the data interface for the esterel application.
* to be completed by the user ...
*/
// generated by inria.alfred.parser.Tool
import inria.alfred.lib.*;
import java.net.*;
import java.io.*;
import java.util.*;
// ----------------------------
// Application class definition
// ----------------------------
public class AlfAppliRun extends Thread implements QoSsetting {
private AppliHandler handler=null;
private AlfAppli auto;
public AlfAppli getAuto () {
return auto;
}
public void init () {
// initialisation of QoS parameters by application
AlfredService.setADU_TYPES_NB(ADU_TYPES_NB);
AlfredService.setADUTYPE_NAME(ADUTYPE_NAME);
AlfredService.setADU_NB(ADU_NB);
AlfredService.setADU_NAME(ADU_NAME);
AlfredService.setINPUT_ADU_NAME(INPUT_ADU_NAME);
AlfredService.setQoS_table(QoS_table);
AlfredService.setSEND_ONLY(SEND_ONLY);
AlfredService.setRECV_ONLY(RECV_ONLY);
AlfredService.setMechan_table(Mechan_table);
AlfredService.setRbfcParams(RbfcParams);
AlfredService.setINTERACTIVE(interactive);
AlfredService.setTYPE_OF_DATA(type_of_data);
// initialisation of application handler
handler= new AppliHandler();
AlfredService.setAppliHandler(handler);
}
public void run() {
try {
auto= (AlfAppli)handler.getAuto();
auto.getInterface().setAppliHandler(handler);
auto.getInterface().setAppliAuto(auto);
// BEGIN of user application code
// ... auto.CSTE=...; auto.inputS(); (boolean)handler.runAuto(); ...
// methods available: AlfredService.getAduPort(String adu_type) -> int
// AlfredService.getDestAddr(String adu_type) -> String
// END of user application code
} catch(Exception e) {
System.err.println("Exception: " + e.getClass().getName());
System.err.println(e.getMessage());
e.printStackTrace();
}
}
// if you want to define some command parameters uncoment
// the two following methods.
// public static void showUsage () {}
// public static String[] parseParameters(String args[]) {
// String[] aux = new String [argv.length];
// int j=0;
//
// for (int i = 0 ; i < argv.length ; i++) {
//
// if(argv[i].equals("-...")) {
//
// ......
//
// } else {
// aux[j++]=argv[i];
// }
// }
//
// return aux;
// }
}
As you can see, if you want to define command parameters
you have to specify the two methods
showUsage and parseParameters.
If you redefine a command parameter that is already in
ALFred top level command, it's the user level parameter that will be treated.
The price to pay to give advantage to application level
command parameters is to return the array of parameters not
treated by application in parseParameters.
SimpleEntity executable code
To compile the Esterel specification of control part of application/protocols
you can proceed in two steps:
first you translate the specification into ssc formalism, second you compile
the result into Java with the ocjava tool.
See Using ALFred for details.
The last step of
compilation to java and then into executable code is also clearly described
in the real case study of the JukeBox.
Note that Esterel is equipped with a comfortable programming environment including symbolic debugging, simulation tools (xes X-window simulation), compilation into both automata and circuits, graphical representation of automata, optimization and verification tools, etc. See the Esterel home page for more details.