Application Note

 

 

Altia® Design

Human Interface Design Software

Integrating Altia Design with BetterState from Integrated Systems, Inc.

Overview

The floppies which accompany this note contain a link to connect an Altia Design interface to BetterState generated state machine code. BetterState is a state machine design tool with code generation capabilities for C, C++, VHDL, Verilog HDL, and other languages. Altia Design is software for quickly creating interactive, dynamic graphical representations of product user interfaces. By combining the Altia interface and the BetterState state-machine logic of a system, functional computer-based prototypes of embedded products can be quickly created, tested, and modified, helping verify product requirements early in the design process.

The fundamental concept of state-machine programming is that a system will transition from one state to another based on the occurrence of specific events. Events, which are simply variables whose values have changed, are evaluated by the state-machine to determine if a transition should be made to another state. When a state is entered, the system is told what to do. If you think of a flashlight as a state machine, turning the switch on will take you to the "on" state, and the light will go on. Turning the switch off will take you to the "off" state, and the light will go off.

With the Altia-BetterState link, an Altia interface becomes the mechanism to provide events and display results of a BetterState state-machine. In the above example, Altia would represent both the switch and the light while the BetterState state-machine would determine what to do with the light based on switch events. An Altia interface is an easy to understand and use representation of the system’s real user interface. Developers use this interface to test and demonstrate product requirements, such as usability and features, to parties not involved in the day-to-day development. Developers, project managers, customers, and others can verify and modify the product’s requirements early in the development cycle.

Using the Altia-BetterState link:

To link the two products, Altia provides a 32 bit Microsoft library and header file (absdde.lib and altiabs.h) for C and C++ that are linked directly into a program with the compiled source code generated by BetterState.

The altiabs.h header file references functions for the BetterState developer to place in the state and transition code dialogue boxes of their state machines. These functions take care of checking with an Altia interface to either verify that a variable has had an event happen to it, to check a variable’s value , or to send a value or event to the Altia interface. Based on the results of these functions, the BetterState developer can determine how they would like to transition from one state to the next.

You will need three basic components to create an Altia-BetterState simulation: an Altia interface, a BetterState state-machine, and a fairly generic C program main() routine.

Requirements

Microsoft 32-bit C/C++ compiler

Altia Design editor or runtime license and design file.

BetterState development license.

Functions referenced in altiabs.h (See also altiabs.h for documentation)

int updateIO();

int getEvent();

int getValue();

char *getText();

int setValue();

int setText();

int updateIO();

int updateIO(char *designFile, int argc, char *argv[]) is crucial to the working of the Altia-BetterState link. It initializes the Altia-to-application connection and is used in the application's main loop to coordinate events to and from the Altia interface.

On the first call of updateIO(), a connection to Altia is established. If a design file name is provided in the designFile parameter, the Altia interface is started using that filename and passing command line arguments to the Altia executable via the argc and argv[] parameters. Otherwise, it is assumed that Altia is already running, and a connection is made to that session.

On subsequent calls, updateIO() is responsible for receiving every event that happens in the Altia interface and preparing it for global use in the state-machine(s) routine(s). The parameters of updateIO() are ignored on these subsequent calls; rather updateIO() performs the function of dispatching global events from Altia to the state-machine(s). updateIO() will also block execution of the main loop until an event is received from Altia. This is a convenient and efficient way to control state-machine(s). Inputs for the state-machine(s) are simply Altia events. Events that are meaningful to the state-machine(s) cause transitions. Events that are meaningless to the state-machine(s) are checked and ignored, and their values are stored by updateIO() for further reference. Since BetterState's generated code relies on an event to transition from state to state, Altia becomes the user interface that provides these events.

int getEvent();

int getEvent(char *eventName) returns an int value if an event of eventName is pending from the Altia interface. If no event is pending, returns preprocessor #defined no_value.

Typical usage is in a Transition Code Dialogue's Condition field, e.g.

getEvent("push") == 1

If the event "push", with a value of 1 is coming from the Altia interface, then the state-machine code will make that transition.

int getValue();

int getValue(char *valueName) returns an int value if a value of valueName is held in the Altia interface. If the Altia interface does not have this valueName animation at all, either as an event or an initial value, returns preprocessor #defined no_value.

Typical usage is in a Transition Code Dialogue's Condition field when simply the value of the valueName variable is enough to make the transition. e.g.

(getValue("power_switch") == 1) && (getEvent("push") == 1)

If valueName is the name of a variable that has been/will be checked as an event, you can still check and use its value. If the event currently being routed through the state-machine(s) is evaluated with getValue(), the fact that it is an event will still be cleared after running the state machine(s).

char *getText();

char *getText(char *textName) returns a pointer to a string if a string of textName is held in the Altia interface. If the Altia interface does not have a string of textName, returns a pointer to NULL.

Typical usage is in a State/Place Code Dialogue box's Action field, e.g.

if ( strcmp( getText("message_text"), "start") == 0)

start_function();

else

stop_function();

getText() is not event based and always returns the current string held by textName, if any.

int setValue();

int setValue(char *setName, int setValue) sets an animation value of setValue to the Altia interface animation name setName. Returns zero if successful in sending the event, -1 if a communications error to Altia interface or system doesn't have enough memory to store another variable.

Typical use is for sending events to the Altia interface or for storing int values in your state-machine(s) without having to declare the variables first. Their values can later be referenced with getValue(setName). Often used in a State/Place Code Dialogue box's Action field, e.g.

if ( getValue("power_switch") == 1)

setValue("power_light", 1);

int setText();

int setText(char *textName, char *String) sets a string variable of textName (usually an Altia Text I/O object) in the Altia interface to the value held by String. Returns 0 if successful, -1 if not. If textName does not exist in the Altia interface, the string is stored anyway and can be accessed using getText() above. This provides a convenient method of storing and retrieving strings without having to declare them as variables in our state-machine(s) code.

Typical usage is for sending string messages to Altia. Often used in State/Place Code Dialogue box's Action field. e.g.

if ( getValue("power_switch") == 1)

setText("message_text", "Powering up!");

else

setText("message_text", "Powering down!");

 

 

Using absdde.lib and altiabs.h with your BetterState state-machines

Create a BetterState state-machine to represent your system using the above functions in the state Action and Transition code dialogue boxes.

Use the BetterState Code Generator to create the source code for your state-machine(s). In the BetterState code generation options page, choose the "Misc" tab and type the following in the "header files to include" field:

#include "altiabs.h"

Copy the files absdde.lib and altiabs.h to the directory of your choice (perhaps \usr\altia\lib\ms32 or \bstate41\dlls\lib\lib32) and make sure that your compiler can search these directories at compile time.

In the Microsoft Visual C/C++ development environment, create a new project workspace and choose to create a console application. Add the following files to the projects:

absdde.lib

yourstate.c /* the source code of your state-machine(s) generated from BetterState */

Create and add the following file to your project:

main.c /* a main loop program */

Use the following as a guide for creating your main.c program. You may wish to use it directly.

/* Typical main() routine linking Altia and BetterState */

#include <stdio.h>

#include "altiabs.h"

/* include the header for the absdde.lib */

extern int CHRT_test();

/* Declare C function generated from BetterState file */

void main( argv, argc)

int argv;

char *argc[];

{

CHRT_test(1);

/* initialize state machine routine(s)from BetterState */

while ( updateIO("myfile.dsn",NULL,NULL) != -1 )

/* As long as we receive events from the Altia interface*/

{

CHRT_test(0);

/* Run state machine(s) with new event from Altia */

} /* end while */

} /* end main() */

You are ready to compile and run the system. It is recommended that you study the enclosed test2.dsd and test.dsn for an example of a working project. Source files for main.c and test.c (the code generated by BetterState) are included.

Miscellaneous

Interactive Animation of state-charts: BetterState provides an option during code generation for interactive animation of the BetterState state-chart. When this option is chosen and an application is compiled, the Altia-BetterState link will work with this feature. Performance of the BetterState Interactive Animation is best when simply stepping through the model from the Altia interface. It provides a very useful step-by-step debugging tool; as you press buttons on the Altia interface, you can watch the state-machine chart highlight the current state and transition, verifying your model. To use this feature, check the "Code for Interactive Animation (via bs_dde.dll)" box on the "Visual Debugging" tab of BetterState’s code generator. No changes are necessary to your main() routine or state-chart.

Multiple state-machines: The Altia-BetterState link was developed with the idea that multiple state-machines might be created and run together. The state-machine developer should simply list the state-machine functions generated by BetterState in the main() routine’s while loop in the order he or she would like them executed. The state-machine developer should keep in mind that updateIO() prepares one global event at a time for state-machine(s) to evaluate. Each time updateIO() is called, it assumes that the previous event has been used to the state-machine(s) satisfaction and then throws it away in order to retrieve the next event. The state-machine developer should keep this principle in mind as they develop their state machine(s)- Does each state-machine work well evaluating the same global event and then going on to the next one? Could you expect one state-machine to advance more than one state while others remain stagnant?

Asynchronous vs. Synchronous behavior of state-machines: Due to the random- access nature of an Altia interface, the Altia-BetterState link was developed with an asynchronous behavior in mind- when you press a button in the Altia interface and the event means something to the state-machine(s), the state-machine transitions. If, instead of user-based input on an Altia interface, you would like to simulate synchronous (regular interval) behavior, it is recommended that you create a Stimulus Timer in Altia to generate a consistent event at a regular interval, such as a tick = 1 event every one second. Each BetterState transition code dialogue for the state-machine would then execute based on this event and the value of some other variable’s value:

(getEvent("tick") == 1) && (getValue("seconds") < 59)

Accuracy of this approach at extremely fast rates (< 100 ms) cannot be guaranteed. How fast is the Windows clock?

Hybrid Altia-BetterState link and Altia API applications: The Altia-BetterState link was developed with the aid of the Altia API described in the Altia Design Reference Manual. Nothing prevents the direct use of these API functions throughout your BetterState state-chart(s) and your main() routine. With a goal of simplicity, however, it is recommended that you stick with the functions referenced in altiabs.h. They should provide all that you need to make complex state-machines that link with an Altia interface.

Description of Altia/BetterState Demo Floppy Files

abslink.exe A self extracting .zip file for the link, containing:

 

ABSlink.doc This file.

readme.txt A text file describing the package contents

absdde.lib Altia-BetterState link library; using a dde connection between the compiled application and Altia.

altiabs.h header file for absdde.lib. See this file for link documentation and

use.

test.dsn An altia.dsn test file for trying the BetterState connection

test.rtm the .rtm file associated with test.dsn

beep.wav A sound file used by the libtest demonstration.

test2.dsd A BetterState test model.

test.c State-machine code generated from test2.dsd

main.c Generic main routine linking Altia and BetterState models.

libtest.exe Resulting demonstration program

altiart.exe Altia runtime engine for running the libtest demonstration.

fonts.ali A font aliasing file used by altiart.exe