Home » Eclipse Projects » Papyrus for Real Time » Combining Papyrus RT with normal Code
|
Re: Combining Papyrus RT with normal Code [message #1709315 is a reply to message #1709295] |
Sat, 26 September 2015 02:52 |
|
Hi Tobias,
In a tool like Papyrus-RT, hardware interfaces are typically implemented through separate capsules that are assigned their own threads. This allow these capsules to, for example, block on interrupts without stoping the whole processing, or to perform polling on their own schedule without disrupting the rest of the system.
In your particular case, you have two devices with which to interface, a switch that is an input to the model and a LED that you would turn on or off (or are you also monitoring the state of the LED that is changed by some external source?).
What I would recommend is to create a new capsule for each of these interfaces and define protocols to access these hardware "services".
For example, the composite structure of your system (the "Top" capsule) would look like:
The protocols can also be seen in that image.
The SwitchIF's state machine would have a single state with an entry action somewhat like:
while (true)
{
On switchInterupt // Your code to determine when a switch state change is detected
{
if (switch == ON) // If the switch is now ON
{
switch.SwitchON().send(); // Send the SwitchON message through the switch port
}
else if (switch == OFF)
{
switch.SwitchOFF().send(); // Send the SwitchOFF message
}
}
If you wanted to do an operation on hardware, the pattern would be slightly different. You would need transitions to handle the various actions, that would call you hardware-specific code. Again, it would be preferable for the capsule holding that code to be on its own thread.
Assuming that the LED are being controlled from the model, You would have the state machine for the LEDIF (LED interface) have a single state with two transitions: each will be triggered by one of the protocol message and each will have the user code required to affect the hardware.
The last point is one of "zyclic" coming from a timer interrupt. Papyrus-RT does provide a timing service as part of the runtime services. You can set both one-time timers and recurring timers. This is done by adding an internal port typed with "Timing" (or UMLRTTimer) from the provided UMLRT-RTS model library to a capsule. You can then set the timers in the initial transition for the "On" state in your state machine diagram.
int numSec = 20; // Number of seconds
int numNsec = 0; // Number of nano-seconds
timerID = timing().informIn(UMLRTTimespec(numSec,numNsec));
if (! timerID.isValid() ) { logError }; // check to ensure timer was set.
Or for a recurring timer:
timerID = timing().informEvery(UMLRTTimespec(numSec,numNsec));
And a timer can be cancelled (probably in your "SwitchOff" transition from the "On" to the "Off" state:
if ( timing().cancelTimer( timerId ) ) {
log().log("timer canceled");
} else {
log().log("Failed to cancel timer");
Now, we do not yet have a nice, model-based way of assigning various capsule instances to threads. However, for the time being, it can be done through a configuration file named "Top.Controllers". Here is an example of that file's content based on the model I put together:
Top = MainThread
Top.ledInterface = LEDInterfaceThread
Top.switchInterface = SwitchInterfaceThread
Note that implicitly, any capsule part not shown in the list will be assigned to the thread of its container. So since "Top.lEDEmbedded: from my model is not explicitly assigned, it will be put on the same thread as its container, Top.
I have attached an archive of the model I created to investigate your question.
I hope this helps.
/Charles Rivet
|
|
|
Re: Combining Papyrus RT with normal Code [message #1709328 is a reply to message #1709295] |
Sat, 26 September 2015 13:37 |
|
Hi Tobias,
I forgot to provide answers to your three questions:
You asked:
- -can I use Guards for transitions (by including my own headers / static classes), so I can fire thetransitions without using protocols?
Guards are used to define a condition that would allow or prevent a transition to be taken when a signal/protocol message is received. They are not, in themselves, trigger for a transition to be taken.
The way our code is generated, you can not easily trigger a transition without going through a protocol. However, there is an API that allows you to send messages through user code, as I have shown in my previous answer.
To include your own headers and classes, you can apply the "UML-RT C++ Property Set Profile" ("RTCppProperties") to the model and then use its provided stereotypes to do so. You could, for example, use its "CapsuleProperties" stereotype to specify #includes by specifying them in the "implementationPreface" property. This would make the definitions from these includes available in all the capsule's action code.
Note, however, that you would then have to ensure that the libraries for your external functions are included in the build (there's a Make variable that can be used to add libraries). We do not yet have a user interface element to specify this at the model level.
You asked:
- -can I fire protocoll messages from my own code? How?
It all depends what you mean by "from my own code". You can fire protocol messages from any effect within the model (although, at this point, only from C++ opaque behaviours) and these effects would contain your own code.
The model-based development approach we propose means that the model is the primary artifact and would therefore contain or import the required functionality. So if "from my own code" means that the code (the "main") is external to the model, then that is much more difficult, unless they are in separate processes and you define an IPC between the two. And that approach would be, in many ways, similar to the one I mentioned in my previous post regarding the handling of hardware interfaces.
You asked:
- -can I write my own main-function / deactivate the
generation of the main function?
You can as all the runtime services, transformation, and generated code is provided. However, you would then be building your own DSML based on our work. The idea of this type of extension was anticipated, but not (yet?) documented and would require a lot of effort.
I do hope this helps.
I don't know where you are located, but if you plan on being at EclipseCon Europe, I would be happy to meet with you and discuss this further. I do have a Papyrus-RT presentation at the conference.
Thank you for your interest in our tool!
/Charles Rivet
|
|
| |
Re: Combining Papyrus RT with normal Code [message #1720230 is a reply to message #1720115] |
Fri, 15 January 2016 12:53 |
Peter Cigehn Messages: 49 Registered: September 2014 |
Member |
|
|
Dave Stikkolorum wrote on Thu, 14 January 2016 14:28Hi, tried your LedEmbedded example, but code generation fails. Validation of the model gives:
Error The required feature 'uml::CallEvent::operation' of 'LEDEmbedded::LEDProt::LEDON' must be set <Call Event> LEDON LEDEmbedded::LEDProt EMF Problem
Error The required feature 'uml::CallEvent::operation' of 'LEDEmbedded::LEDProt::<null-named-CallEventImpl>' must be set <Call Event> LEDEmbedded::LEDProt EMF Problem
Error The required feature 'uml::CallEvent::operation' of 'LEDEmbedded::LEDProt::<null-named-CallEventImpl>' must be set <Call Event> LEDEmbedded::LEDProt EMF Problem
Error The required feature 'uml::CallEvent::operation' of 'LEDEmbedded::LEDProt::<null-named-CallEventImpl>' must be set <Call Event> LEDEmbedded::LEDProt EMF Problem
Any ideas?
I checked the model and indeed it has some "dangling" call events, i.e. call events that does not refer and operation, in the LED protocol, as the validation problems indicates.
Unfortunately some of these "dangling" call event where used to specify triggers in the state machines.
I did some updates (I hope I got them right) to update the triggers to reference the correct call events, and to remove the "dangling" ones.
I am not even sure Charles originally intended the model to be able to generate code and compile, since I also had to change some opaque behaviors to specify C++ as language to be able to generate code correctly. They originally where written in "Natural language" and I changed the natural language code snippets into "C++" as comments instead.
After this, I got the model to generate code without errors in Papyrus-RT 0.7.2. It also validates without problems. I have not tested to compile the generated code though.
/Peter Cigéhn
|
|
| |
Re: Combining Papyrus RT with normal Code [message #1720240 is a reply to message #1720230] |
Fri, 15 January 2016 13:59 |
|
As Peter correctly guessed, this model was meant to illustrate the concepts.
It should also be noted that the model was created over 1.5 years ago and that Papyrus-RT has changed considerably since then, in all of DSML, runtime, code generation, and validation depth.
Thanks, Peter, for the corrections to the model!
/Charles Rivet
|
|
|
Goto Forum:
Current Time: Thu May 23 16:57:48 GMT 2024
Powered by FUDForum. Page generated in 0.04081 seconds
|