28
Draft - Not for Distribution 2/11/2004 9:04 AM Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) provides a way of specifying components and their assemblies, checking static constraints defined by the CCL language, checking static constraints defined by analysis technologies (called “reasoning frameworks”), and for generating C code for the Pin component technology, and for generating analysis models for reasoning frameworks (called “interpretation”). 1.1 Objectives of this tutorial The objective of this tutorial is to get you started using CCL to generate Pin assemblies. It is by no means a complete summary of the language—such a summary does not yet exist. However, the basic ideas are simple and can be showed by example. The examples provided also give an overview of how to use the CCL processor, and how to interact with the RTX SDK. 1.2 Caveats and Limitations CCL is a work in progress. What you have installed and will be interacting with as numerous limitations. Nonetheless, despite its rather severe limitations in its current form, you will be able to use CCL to develop small applications, and to experiment with the Pin code generator. What CCL doesn’t do you can fill in by hand, once you get familiar with the structure of Pin components. CCL can help with that, too: the generated code tends to be quite readable and even commented. It is convenient to distinguish between limitations in the CCL frontend—the part that does static analysis, and the CCL backend—the part that generates code. (There are actually several backends, one for each interpretation. But that is another story.) Frontend limitations: The processor does its best to catch static semantic errors and give sensible error messages. Occasionally, however, the frontend will get confused. A sure sign of confusion is an “assert” violation. If this happens to you, look for the first reported error and repair it. Please send any source files that produce assertion errors to [email protected] . There are several semantic constraints that have not been implemented, including: o No checking on singleton instantiations of services. o No checking on optional versus mandatory source pins in assembly.

Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Embed Size (px)

Citation preview

Page 1: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft - Not for Distribution

2/11/2004 9:04 AM

Using CCL with Pin: A Tutorial

1. Introduction The Construction and Composition Language (CCL) provides a way of specifying components and their assemblies, checking static constraints defined by the CCL language, checking static constraints defined by analysis technologies (called “reasoning frameworks”), and for generating C code for the Pin component technology, and for generating analysis models for reasoning frameworks (called “interpretation”).

1.1 Objectives of this tutorial The objective of this tutorial is to get you started using CCL to generate Pin assemblies. It is by no means a complete summary of the language—such a summary does not yet exist. However, the basic ideas are simple and can be showed by example. The examples provided also give an overview of how to use the CCL processor, and how to interact with the RTX SDK.

1.2 Caveats and Limitations CCL is a work in progress. What you have installed and will be interacting with as numerous limitations. Nonetheless, despite its rather severe limitations in its current form, you will be able to use CCL to develop small applications, and to experiment with the Pin code generator. What CCL doesn’t do you can fill in by hand, once you get familiar with the structure of Pin components. CCL can help with that, too: the generated code tends to be quite readable and even commented. It is convenient to distinguish between limitations in the CCL frontend—the part that does static analysis, and the CCL backend—the part that generates code. (There are actually several backends, one for each interpretation. But that is another story.) Frontend limitations:

• The processor does its best to catch static semantic errors and give sensible error messages. Occasionally, however, the frontend will get confused. A sure sign of confusion is an “assert” violation. If this happens to you, look for the first reported error and repair it. Please send any source files that produce assertion errors to [email protected].

• There are several semantic constraints that have not been implemented, including: o No checking on singleton instantiations of services. o No checking on optional versus mandatory source pins in assembly.

Page 2: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 2 of 2

o It is possible to violate the prohibition on 1:N synchronous interaction topology by successively connecting a synchronous source pin to > 1 sink pin.

Backend limitations:

• Hierarchical assembly is not yet supported. • Arrays of any kind are not yet supported. • Built-in string operations are not yet provided. • Timed transitions are not yet supported.

1.3 Organization of this tutorial This tutorial presents a series of six examples. The examples are found in the Pin distribution in CCL/Examples. Each example is presented in four parts:

• The Assembly: A description of the assembly—what the example does, and why it is presented.

• Construction: How you build the assembly. Mostly, this is routine. • The CCL: The specification source as found on disk. In future versions of this

tutorial this will include discussion of language features and semantics. • Exercises: Mostly this is not defined, but it will eventually be. Perhaps you have

some ideas? The examples all have trivial functionality, but they will help you to get started.

1.4 Typographical conventions In general, 10 pt courier font is used for CCL text; 10 pt bold courier is used for reserved words in CCL. 12 pt courier is used for text that you will enter in command windows. Italics are sometimes used for emphasis.

Note: This indicates something worth keeping in mind. IMPORTANT: This is something you had probably should keep in mind. WARNING: This is something you really must pay attention to.

1.5 Getting Ready. Install Pin and the RTX runtime environment, as described elsewhere. Then set the following environment variables, which are assumed in this tutorial (you may of course change the specifics):

• PINSRC=c:Program Files\Microsoft Visual Studio\MyProjects\

Page 3: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 3 of 3

• CCLSRC=%PINSRC%\CCL • CCL_GENERATED_CODE_DIR=%PINSRC%\Working • CCL_TEMPLATE_DIR=%CCLSRC%\Support

Also, add %CCLSRC%\CCLBack\Debug to your PATH environment variable

2. A Simple I/O Assembly

2.1 The Assembly Let’s build something. The SimpleIO assembly is possibly the simplest assembly that can be built. In fact, you won’t even develop a component in this example: we will use two environment-provided services, one to accept keyboard input from the external world, and one to put strings to a console device in the external world. Here is a graphical depiction of the SimpleIO assembly in the Pin visual language:

OutputComponent::cns>>

KeyboardComponent::kb >>

SimpleIO::simpleIO() (RTX::rtx)

putKeyboard (produce string msg);

putConsole (consume string msg);

Note: We use the convention type-name::instance-name in the graphical notation; this convention has no counterpart in CCL.

2.2 Construction To build a runtime implementation of this assembly, open a command window and do the following: > cd %CCLSRC%\Examples\Ex1 > ccl.exe -gn -BKeyboardComponent -BOutputComponent SimpleIO.ccl The meaning of the command line arguments:

Page 4: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 4 of 4

• -g: generate code for components and services, and for each deployed assembly generate a controller. (A controller can be thought of as the composite of a set of component and service instances in a generic container).

• -n: suppress warning messages that arise during the code generation process. • -B<component-name>: do not generate code for named component or service. • SimpleIO.ccl: this is the name of the CCL specification being processed.

Invoking this command in a command window should yield the following output: 0 syntax errors, 0 static errors, 0 warnings OutputComponent: Builtin Component or Service (skipping code generation) KeyboardComponent: Builtin Component or Service (skipping code generation) Press any key to continue Also, the following files will be found in the current working directory, (or the directory specified by the environment variable CCL_GENERATED_CODE_DIR if you started this tutorial following the instructions in 1. Introduction):

• common (folder) • KeyboardComponent (folder) • OutputComponent (folder) • SimpleIO (folder) • simpleIO.dsw (Visual Studio workspace)

Only SimpleIO and simpleIO.dsw were generated as a result of the above command. Open simpleIO.dsw using Visual Visual C++ V6, and view the contents using the FileView tab of your workspace. You should see something like this:

Page 5: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 5 of 5

We’ve opened up the simpleIO.c file. This source file is the C implementation of the controller, or container, for the simpleIO assembly. From the Build menu, set the active configuration of the KeyboardComponent project to “KeyboardComponent – Win32 RTSS Release,” and build it. Do the same for each of the other projects in the simpleIO workspace. To run this assembly you will need to start a few Pin services. Presumably, you have already installed RTX (if not, you will need to do so now). Launch the RTSS Task Manager from the VenturCom RTX menu. You should see this:

Page 6: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 6 of 6

Now you must use Start Task to initialize Pin. Use Start Task twice:

1. Browse to locate the ABB_IPC distribution, and within this distribution navigate to PinDirectoryServer\PinDirectoryServer___Win32_RTSS_Release, and run PinDirectoryServer.rtss as an RTSS process.

2. Browse to IPC_LIB\IPC_LIB___Win32_RTSS_Release\IPC_LIB.rtdll. Instead of running this, you will register it as an RTDLL. IMPORTANT: You must select the “Share Between Processes” check box. This selection is not the default setting, and a failure to select it will result in runtime errors.

The RTSS Task Manager should look like this:

Now that Pin is officially “started,” you can run the application. You could also use the task manager to register components and run their assemblies. However, this can also be done programmatically. In your working directory you will find several .bat files, one corresponding to each example. Open simpleIO.bat in a text editor if you care to see what is being run. Otherwise, run simpleIO in a command shell (in the working directory), and arrange you’re the your windows in a tidy way. This is what my screen looks like:

Page 7: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 7 of 7

The green indicators show the RTDLLs that are currently loaded (in memory). You can also see that the simpleIO.rtss program is running (as is the Pin directory server). Now enter some strings in the keyboard console. These strings should be displayed on the output console. It isn’t very pretty, but it works. There is only one thing left to do—quit the application. Type RtxExit in the keyboard console. You should notice two things.

1. The green indicators on the RTDLLs have switched to purple (or perhaps chartreuse). This indicates that these RTDLLs are registered, but they have been unloaded from memory.

2. The Keyboard Console has disappeared, but the Output Console remains. This is unfortunate, but we won’t bother to explain here why this relic of the application remains. You must exit the console yourself (with the ‘x’ window button).

So that’s all there is to it. Now let’s have a closer look at SimpleIO.ccl.

2.3 The CCL Specification Here is the corresponding CCL specification for this assembly, found in the file named SimpleIO.ccl:

Page 8: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 8 of 8

environment RTX() { singleton service KeyboardComponent () { source unicast putKeyboard (produce string msg); threaded react eternal_TBD (putKeyboard) { start -> putting { } putting->putting { } } } singleton service OutputComponent () { sink asynch putConsole (consume string msg); threaded react eternal_TBD (putConsole) { start -> writing { } writing -> writing { } } } } Assembly SimpleIO () (RTX) { assume { RTX:KeyboardComponent keyb(); RTX:OutputComponent outp(); } keyb:putKeyboard ~> outp:putConsole; expose {} } RTX env() { RTX:KeyboardComponent kb(); RTX:OutputComponent cns(); }; SimpleIO simpleIO() {

SimpleIO:keyb = env:kb; SimpleIO:outp = env:cns; };

WARNING: The Pin component technology currently limits the length of service and component instance names to eight (8) characters or less. This restriction is not statically enforced, and violating this rule results in an obscure runtime error. This is not an inherent limitation of Pin, however, and will not be imposed in future releases of the component technology.

Also observe that comments are introduced into CCL specifications with ‘//’ and continue until end of line.

2.4 Exercises There isn’t a whole lot we can do yet, but here are a few ideas.

• Easy: Try making changes to the specification that you think should be erroneous. For example, try instantiating more than one keyboard or console service. What happens? Let me know!

Page 9: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 9 of 9

3. Adding a One Place Buffer 3.1 The Assembly In this example we will specify and build our first component, and it will again be quite simple—but with it we will introduce behavior specification in CCL.

OutputComponent:con>>

KeyboardComponent:kbd

Buffer_1>> >>

>>

put (consume string s)

rid (produce string s)

Buffer1 oneItem () (RTX rtx)

Here the name Buffer_1 is suggestive of a one-place buffer, but that of course isn’t enough. To specify the behavior of the buffer we need to specify the behavior of its reactions. We use a variant of UML Statecharts, and the quasi-C action language FiniteC to specify component behavior.

Page 10: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 10 of 10

listen

/buffdx = 0;

^put(item); [buffdx == 0]/{ buffdx = 1; $put();}

^put(temp); [buffdx == 1]/ ^rid(item);

$rid();/ { item = temp; $put(); }

ridding

threaded reaction buffReact (put, rid)

buffReact variables: string item, temp int buffdx

The above specification says that buffReact is a non-terminating process that accepts stimulus on the sink pin called put, and, when its buffer is full, emits an event on the source pin called rid. The symbol ^ denotes the beginning of an interaction between components, while the symbol $ denotes the end of an interaction. Thus, ^put(…) denotes the beginning of an interaction on put. 3.2 Construction To build a runtime implementation of this assembly, open a command window and do the following: > cd %CCLSRC%\Examples\Ex2 > ccl.exe -gn -BKeyboardComponent –BoutputComponent buffer_v1.ccl 0 syntax errors, 0 static errors, 0 warnings OutputComponent: Builtin Component or Service (skipping code generation) KeyboardComponent: Builtin Component or Service (skipping code generation) Press any key to continue You will now find the additional folder called Buffer (this is the generated implementation of the Buffer_1) and the assembly simpleBuffered. Compile these, as before. This time (after you compile the above) we will start Pin and register the components from the command line.

Page 11: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 11 of 11

To start the Pin runtime, open a command window (we will call it “MAIN”) and do the following: > cd %PINSRC%/ABB_IPC > pinstart.bat This will bring up the Pin console and start the Pin directory server. Now open two command windows. In the first one (we will call it “INPUT”) do the following: > cd %PINSRC%/ABB_IPC/RTX_KeyboardConsole/Release > RTX_KeyboardeConsole.exe In the second command window (we will call it “OUTPUT”, do this: > cd %PINSRC%/ABB_IPC/RTX_OutputConsole/Release > RTX_OutputConsole.exe In your MAIN window, do this: > cd %CCLSRC%\Examples\Buffer_1 > regandrun.bat This will register the components and launch the program. If you arrange your screen you might get something looking like this:

Page 12: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 12 of 12

The INPUT window is in the upper left, OUTPUT window in lower left, and MAIN in the upper right. The green indicators in the RTSS task manager show that the component DLLs are loaded, and the RTX server console shows the state of the application. Now, as before, type strings in the INPUT window and see what happens. As you might have expected, the new assembly buffers one input string. When the buffer is full (one item fills the buffer), it prints its current buffer and then accepts the new item. Unfortunately, there is a problem here. How do you quite the application? Typing “quit” in the INPUT window does what you expect there—it terminates the input console. Likewise <ctrl>C in the OUTPUT window terminates the output console. But you can see that the application is still running. The problem is that our assembly did not have logic to terminate (check the state machine). The best way to get out of the current situation is to issue an RTX command to terminate the assembly. In the MAIN window, enter: > rtsskill /b 002 where 002 is the process number displayed by the RTSS Task Manager for the simpleBuffered assembly (check it—it might be different for you, depending on what you have done recently with RTX). We will see in the next example how to specify termination actions in CCL.

Page 13: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 13 of 13

3.3 The CCL Specification #include "rtx.ccl" component Buffer_1 () { sink asynch put(consume string s); source unicast rid (produce string s); threaded react buffReact (put, rid) { string item, temp; int buffdx; start -> listen { action buffdx = 0; } listen -> listen { trigger ^put(item); guard buffdx == 0; action { buffdx = 1; $put(); } } listen -> ridding { trigger ^put(temp); guard buffdx == 1; action ^rid(item); } ridding -> listen { trigger $rid(); action { item = temp; $put(); } } } } Assembly Buffered () (RTX) { assume { RTX:KeyboardComponent keyb(); RTX:OutputComponent outp(); } Buffer_1 buff();

Page 14: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 14 of 14

keyb:putKeyboard ~> buff:put; buff:rid ~> outp:putConsole; expose {} } RTX env() { RTX:KeyboardComponent kb(); RTX:OutputComponent cns(); }; Buffered simpleBuffered() { Buffered:keyb = env:kb; Buffered:outp = env:cns; };

Note: #include is the only pre-processing directive supported at this time by the CCL processor. Note: The current CCL processor is not very clever about keeping track of line numbers when the #include directive is used. This can be a problem correlating error messages from the processor to the specification source.

3.4 Exercises 4. Communicating with the Controller with Alert The previous example showed that components must have a way of communicating with their environments. This is accomplished with the alert() action. We illustrate this, and a few more aspects of CCL, in this example.

4.1 The Assembly

Page 15: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 15 of 15

listen

^put(item); [buffdx == 0]/buffdx = 1;}^put(temp); [buffdx == 1]/ ^rid(item);

$rid();/ item = temp;

ridding

threaded reaction buffReact (put, rid)

reaction state variables: string item, temp; int buffdx = 0; int numIter = 0;

Here we use staticinitialization rather than anexplicit action on the starttransition.

TimeToGoEntry: numIter++;

[numIter < DONE]/$put() [numIter == DONE]/ { alert(NORMAL_SHUTDOWN, “Goodbye, World!\\n”); $put();}

component Buffer_1

component state variables: const int NORMAL_SHUTDOWN = 0; const int DONE = 5;

A few new aspects of CCL are introduced here. First, we can introduce state variables at the component level. These variables will be visible to all reactions within the component. We also defined these variables as const, with the obvious intended meaning. In fact, constants do not really define state variables; they are the CCL alternative to the #define preprocessor directive used in C and C++. Second, states may have entry and exit actions. Here the entry action to the state TimeToGo increments a counter (no exit actions are shown). However, states may not define…state, which sounds odd, but it really means that no variables can be declared within a state. Put another way, states in CCL do not define a scope for names. Third, the action alert(NORMAL_SHUTDOWN, “Goodbye, World\\n”) shows how components communicate with their environment. Here NORMAL_SHUTDOWN is defined as a constant in the component scope. Later, we will show the proper way of doing this, and what other kinds of alerts can be sent to the environment.

Page 16: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 16 of 16

Note: It might seem to be more natural if alert(…) actions that result in termination of component execution were chosen as actions on transitions to “final” states. However, CCL has no notion of final state, although this might change. The current assumption is that component behavior is always non-terminating, and that it is the task of the environment to stop component execution.

4.2 Construction To build this application, use the same instructions provided for example 2, substituting the directory Ex3 for Ex2 of course. What is the behavior of the application now? Does it, as expected, terminate cleanly after five input strings are presented? What other changes do you detect?1 Can you guess why?

4.3 The CCL The only changes made to the previous example are found in the buffer component, so only that fragment is shown. component Buffer_1 () { const int NORMAL_SHUTDOWN = 0; const int DONE = 5; sink asynch put(consume string s); source unicast rid (produce string s); threaded react buffReact (put, rid) { string item, temp; int buffdx = 0; int numIter = 0; state timeToGo { entry numIter++; } start -> listen { } listen -> timeToGo { trigger ^put(item); guard buffdx == 0; action buffdx = 1; } listen -> ridding { trigger ^put(temp); guard buffdx == 1; 1 Hint: Did the keyboard input console wind up in the same state in both example 2 and example 3?

Page 17: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 17 of 17

action ^rid(item); } ridding -> timeToGo { trigger $rid(); action item = temp; } timeToGo -> listen { guard numIter < DONE; action $put(); } timeToGo -> listen { guard numIter == DONE; action { alert(NORMAL_SHUTDOWN, "Goodbye, World!\\n"); $put(); } } } }

4.4 Exercises

5 The CCL Escape Clause: The Almighty Verbatim CCL is a work in progress. In lay terms, that means it is missing many features of an industrial strength specification language. In particular, we still have basic questions about how rich the action language (FiniteC) should be. One view is that FiniteC should be sufficient only to specify design details; this is the view taken by executable specification languages such Promela. Another view is that FiniteC should be a complete programming language (in which case it probably wouldn’t be called FiniteC). The bottom line is that CCL is missing features that will be necessary in any non-trivial use. Our temporary solution (read: “hack”) to the limitations in CCL expressiveness is through what I like to refer to as “the almighty verbatim.” This is a construct in the action language that allows arbitrary C code (really, arbitrary text) to be inserted into CCL specifications. There is also a mechanism to make variables declared in CCL visible to this inserted C code. A verbatim block begins with the token %{ and ends with %}. The code generator passes everything between these tokens “verbatim” to the generated code file—with one exception. Strings in the verbatim block prefixed by $ccl$ are mangled to refer to variable defined in the nearest enclosing scope of the suffix of a $ccl$ string. Those

Page 18: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 18 of 18

familiar with the bison and yacc parser generators will immediately recognize the convention. To illustrate, let’s take the previous example, again, once again, and change it to shut down cleanly after receiving “done” from the keyboard, rather than shutting down after some number of inputs. For this we will use the verbatim mechanism to access the string comparison operations defined in C. Of course, it would be better if FiniteC had string operations, and that is on my “to do” list, but in the meantime there is always the almighty verbatim.

5.1 The Assembly Once again we change only the behavior of Buffer_1 reaction, buffReact.

listen

$rid();/ item = temp;

ridding

threaded reaction buffReact (put, rid)

reaction state variables: string item, temp; int buffdx = 0; boolean doQuit;

component Buffer_1

component state variables: const string done = “done”; const int NORMAL_SHUTDOWN = 0;

checkQuit

^put(temp); /%{ $ccl$doQuit = !Rt_strcmp($ccl$temp, $ccl$done);%}

[doQuit]/ { alert(NORMAL_SHUTDOWN, “Goodbye, World!\\n”); $put();}

[!doQuit && buffdx == 0]/ { buffdx++; item = temp;}

[!doQuit && buffdx == 1]/ ^rid(item);

Note: The CCL processor generates C code, not C++ code. One consequence of this is that the management of “instance data” for component runtime instances is more complex. In practice this means that you must not allocate storage in verbatim blocks unless it is for strings declared in CCL. As you can see, the almighty verbatim is still quite limited.

Page 19: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 19 of 19

5.2 Construction Build this assembly exactly as you did for examples 2 and 3, substituting the directory (folder) name Ex4 for Ex3, as before.

5.3 The CCL Also, as before, we show only what has changed—the component specification. component Buffer_1 () { const int NORMAL_SHUTDOWN = 0; const string done = "done"; sink asynch put(consume string s); source unicast rid (produce string s); threaded react buffReact (put, rid) { string item, temp; int buffdx = 0; boolean doQuit; start -> listen { } listen -> checkQuit { trigger ^put(temp); action %{ $ccl$doQuit = !Rt_strcmp($ccl$temp, $ccl$done); %} } checkQuit -> listen { guard doQuit; action { alert(NORMAL_SHUTDOWN, "Goodbye, World!\\n"); $put(); } } checkQuit -> listen { guard !doQuit && buffdx == 0;

Page 20: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 20 of 20

action { buffdx++; item = temp; $put(); } } checkQuit -> ridding { guard !doQuit && buffdx == 1; action ^rid(item); } ridding -> listen { trigger $rid(); action { item = temp; $put(); } } } }

5.4 Exercises

6 A Multi-Component Assembly What if we want a buffer of three instead of one? We could use an array to do this in the buffer component (and we will, later). But why not at least see if we can achieve the effect by stringing together some simple one-element buffers. There really isn’t anything new in this example. But it is a starting point for subsequent discussion.

6.1 The Assembly

Page 21: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 21 of 21

OutputComponent:con>>

KeyboardComponent:kbd

Buffer_1>> >>

>>

put (consume string s)

rid (produce string s)

Buffer1 oneItem () (RTX rtx)

Buffer_1

Buffer_1

>> >>

>> >>

6.2 Construction Build this example in the same manner as the previous example. When you execute this assembly you should have to enter four strings in the keyboard console before seeing the first output on the output console.

6.3 The CCL This time all that has changed is the specification of the assembly. Now, three buffers are instantiated and put in sequence. assembly Buffered () (RTX) { assume { RTX:KeyboardComponent keyb(); RTX:OutputComponent outp(); } Buffer_1 buff1(), buff2(), buff3(); keyb:putKeyboard ~> buff1:put; buff1:rid ~> buff2:put; buff2:rid ~> buff3:put; buff3:rid ~> outp:putConsole; expose {} }

Page 22: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 22 of 22

6.4 Exercises

7. Silly Calc The next example introduces the use of synchronous pins—so far we have used only asynchronous pins. The advantage of synchronous pins is that data can flow in two directions on one pin; the disadvantage is the potential for unbounded blocking2.

7.1 The Assembly You have already seen this example if you ran the test program that comes with the Pin/CCL installation. We implement a simple multiplication function that accepts as an instance parameter (like a parameter on a constructor in an object oriented language) that specifies a constant multiplier to apply to future multiplication requests.

2 This can also be true of asynchronous pins, depending on the interaction protocol on the pin. In fact, the ABB-provided IPC mechanism used in the current Pin prototype will block callers on an IPC queue that is full. We are not discussing how these protocols are specified in this tutorial. CCL provides annotations to specify properties e.g. length of interaction queues. This also is not discussed in this tutorial.

Page 23: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 23 of 23

This assembly looks complicated, and it is, but the functionality is once again quite trivial. In the behavior specification we will again take recourse to the verbatim block to obtain access to standard C library-like functions; these have been adapted slightly to work in the RTX environment. To see which standard library operations are available have a look at the Libc_support.h file, which can be found with the generated component implementations.

OutputComponent:con

ConvertToString:conCvt

TimesX:times2

KeyboardComponent:kbd

Arithmetic:arith

ConvertFromString:kbdCvt

Double double () (RTX rtx)

>>

putKeyboard: produce string

getStr: consume string

putInt: produce int

putStr: produce string

op: consume int

fun: produce int, produce boolean, consume int, consume string

intResult: produce int op: consume int, consume boolean, produce int, produce string

getInt: consume int

getString: consume string

putString: produce string

putConsole: consume string

>>

>>

>>

>> >>

>>

>>

>>

>

>

TimesX returns an the value of aprovided int by a constant (here,2), and the string “made it odd” or“made it even” depending onwhether it decides also to add 1 tothe result. This decision is madebased on an internal booleantoggle.

>>stringResult: produce string

>>

Not all source pins must beconnected. CCL has syntax todenote optional source pins.NOTE: This static constraint is notyet checked by the CCL frontend.

Page 24: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 24 of 24

The Arithmetic:Perform reaction is paradigmatic of state machines in CCL. You have already seen that CCL state machines specify non-terminating behavior. Here you also see another rule: each ^source begin interaction event must be followed immediately, with no intervening actions, by a $source end interaction event, consumed as a trigger on transitions. You may be wondering why TimesX has been given the peculiar behavior of adding 1 to its answers. The answer is simple: the example was really a test of the Pin callback mechanism. At this point you have seen enough CCL specifications that you might appreciate having a closer look at the generated code.

7.2 Construction Follow the same pattern as the previous examples.

7.3 The CCL Here is the CCL specification for the silly calculator. #include "../../Specs/rtx.ccl" component Arithmetic () { sink asynch op(consume int operand);

waiting ^op(val) [!add1] /$op(val * timesVal, “make even int”)

TimesX:multiplier

waiting

operating

putString

^op(operand)/{ makeOdd = !makeOdd ; ^fun(operand, makeOdd ) }

$fun(resultand, msg)/^stringResult(msg)

$stringResult()/^intResult(resultand)

Arithmetic:perform

>>op: consume int operand

>fun: produce int, consume int resultand

reportInt: produce int>>

intTimesX:timesVal

>

op: consume int val, consume boolean add1, produce int val, produce string msg

^op(val) [add1]/$op(val * timesVal + 1, “make odd int”)

booleanArithmetic:perform:makeOdd/makeOdd = True

putInt$intResult()/$op() reportString: produce string

>>

Page 25: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 25 of 25

source synch fun (produce int operand, produce boolean odd, consume int resultand, consume string msg);

source unicast reportInt (produce int resultand); source unicast reportString (produce string msg); threaded react perform (op, fun, reportInt, reportString) { boolean makeOdd; int operand, resultand; string msg; start -> waiting{action makeOdd = True;} waiting -> operating { trigger ^op(operand); action { makeOdd = !makeOdd; ^fun(operand, makeOdd); } } operating->putString { trigger $fun(resultand, msg); action ^reportString(msg); } putString->putInt { trigger $reportString(); action ^reportInt(resultand); } putInt -> waiting { trigger $reportInt(); action $op(); } } } component TimesX(int timesVal) { sink mutex op(

consume int val, consume boolean add1, produce int newVal, produce string msg);

threaded react multiplier (op) { int val; boolean add1; start -> waiting {} waiting -> waiting { trigger ^op(val, add1); guard add1; action $op(val * timesVal + 1, "make odd int:"); } waiting -> waiting {

Page 26: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 26 of 26

trigger ^op(val, add1); guard !add1; action $op(val * timesVal, "make even int:"); } } } component ConvertToString() { sink asynch getInt(consume int val); sink asynch getString(consume string val); source unicast putString(produce string val); threaded react Convert (getInt, getString, putString) { string strVal, tempStrVal; int intVal; start -> wait {} wait -> putIntVal { trigger ^getInt(intVal); action { %{

$ccl$strVal = RtAllocateLockedMemory(128);

Rt_itoa($ccl$intVal, $ccl$strVal, 10); Rt_strcat($ccl$strVal, "\n"); %} ^putString(strVal); } } putIntVal -> wait { trigger $putString(); action $getInt(); } wait -> putStrVal { trigger ^getString(strVal); action ^putString(strVal); } putStrVal -> wait { trigger $putString(); action $getString(); } } } component ConvertFromString() { sink asynch getStr(consume string val); source unicast putInt(produce int val); source unicast putStr(produce string val); threaded react Convert (getStr, putInt, putStr) { string val; int converted; start -> wait {} wait -> convertToInt { trigger ^getStr(val);

Page 27: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 27 of 27

action { %{ if (!Rt_strcmp($ccl$val, "quit")) { NotifyContoller(Reaction->Instance,

SUCCESS, "normal shutdown"); } $ccl$converted = Rt_atoi($ccl$val); %} ^putInt(converted); } } convertToInt -> convertToStr { trigger $putInt(); action ^putStr(val); } convertToStr -> wait { trigger $putStr(); action $getStr(); } } } assembly TimesTwo()(RTX) { assume { RTX:KeyboardComponent kbd(); RTX:OutputComponent con(); } TimesX times2(2); Arithmetic arith(); ConvertToString conCvt(); ConvertFromString kbdCvt(); kbd:putKeyboard ~> kbdCvt:getStr; kbdCvt:putInt ~> arith:op; arith:fun ~> times2:op; arith:reportString ~> conCvt:getString; arith:reportInt ~> conCvt:getInt; conCvt:putString ~> con:putConsole; expose {} } RTX env() { RTX:KeyboardComponent kbd(); RTX:OutputComponent cnsl(); }; TimesTwo timesTwo() { TimesTwo:kbd = env:kbd; TimesTwo:con = env:cnsl; };

Page 28: Using CCL with Pin: A Tutorial - MDH Projects/Project 2 Resource… · Using CCL with Pin: A Tutorial 1. Introduction The Construction and Composition Language (CCL) ... • The CCL:

Draft-Not for Distribution

2/11/2004 9:04 AM Page 28 of 28

7.4 Exercises