Making our customers successful
with what we do best:
Create best-of-class software
for Windows and Linux.

 

About Us Contact Us Free Stuff

High Quality/High Productivity Software Development Method for Event-Driven Software Programs

This article describes a software development method that I found to be very productive and resulting in software that is far more reliable than that written with other methods. The method is based heavily on the Cleanroom Software Engineering technology as described by Prowell et. al. The article first describes the method, several possible extensions, and concludes with the description of a set of C++ class templates that allow effective implementation of the method.

Review of event-driven programming

Event-driven programming is required in all situations in which a software program reacts to external events. For computers with a graphical user interface those events are mouse movements, mouse clicks, keyboard activity, and possibly buttons on peripherals (like the "scan" button on a scanner). Embedded systems may have a front panel with buttons and switches to which the software reacts.

In all event-driven programs, a particular section of code is executed in response to a particular external event. This section of code is often referred to as an event handler. Furthermore, it is only in response to events that any code is executed in a typical event-driven program (in most cases the system can generate internal events based on a timer, and in networked environments, events can also be created when data arrive or are requested on the network). 

In order for the system to fulfill its desired function, the code that is run in response to an event may need to behave in different ways, depending on the events that have taken place previously. Consider this example: My cell phone has a "menu" button. Once I click it, the menu is displayed. The menu will be displayed for a period of time. If I don't press another button during that time, the cell phone is automatically switching back to its default display. My cell phone might create a time tick event every second and switch back to the default display after 30 seconds. During the first 29 runs of the time tick event handler, the display stays the same, yet at the 30th run, the time tick event handler switches the display back to its default display. Since the time tick events are the only ones that are happening during that time (we assume that its a slow day and no one called me in those 30 seconds...), it is the time tick event handler which must do the work. The action of the time tick event handler therefore depends on up to 30 events in the past (my menu button press, and 29 time tick events).

Cleanroom Software engineering method

At the heart of the cleanroom software engineering method lies the recognition that a complete analysis of all possible events with all possible previous event sequences, and an assigned action to each analysis point completely describes the behavior of the software.

While this statement is mathematically true, by itself it is of no help. Consider 5 possible events that can occur. The possible permutations of a sequence of n events is 5n! This is open-ended, because in most systems n can be large (every time I move the mouse across my computer screen, it creates hundreds of mouse move events). 

However, often times a sequence of events is equivalent to a shorter sequence of events. When I drag the mouse across my screen, receiving two mouse move events in sequence may be equivalent to receiving only one mouse move event, because there is really nothing that changes as far as my word processor program is concerned (unless with that last mouse move I move the cursor over a button, and the cursor now must change into a pointer).

An example

Going through a full-blown example in detail is beyond the scope of this article. We will limit ourselves to a trivial example. However, a more complex example is provided for download.

Consider a device similar to the one sketched here:

A serial input of 8 bit quantities is delivered somehow. The device has two push buttons: Open, and Close, two 7-segment digit displays and an error light.

The software for our example receives a stream of bytes on "serial in". These bytes can be one of the following: ASCII codes 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, a, b, c, d, e, f, space, tab, carriage-return, line-feed. Digits and letters are interpreted as two-digit hexa-decimal numbers, the other keys are for separating these numbers. For example the input may look like this:

aAba 0a 1b 2d
0    134f

The output should be: AA/BA/0A/1B/2D/00/13/4F

If any ASCII codes not listed above are received on "serial in," the software should indicate error and ignore all further input sequences

One-digit hexadecimal numbers at the input are allowed. Their upper digit is considered 0.

Input bytes can create different events to process, depending on their value:

  • ASCII codes 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,a,b,c,d,e,f create an input that we label D (for digit)
  • space, tab, carriage-return, line-feed create an input that we label S (for separator)
  • all other values create an input E (for error)

Before any data are received, an Open button must be pushed.

To stop reception of further data on serial in, the Close button must be pushed.

The output of the software is as follows:

When the first byte of a hexadecimal number is received, it is placed into the low digit of the display. The high digit of the display is set to zero.

When the second byte of a hexadecimal number is received, the following actions take place: The digit currently displayed in the low digit is moved to the high digit, and the newly-received number is placed into the low digit.

When the software has detected an error, it indicates this with the error output. The high and low digits of the display are switched off.

When the close input is received, any existing error indication is turned off. The two digits of the display are switched off.

With these specifications, we can declare the following input events and resulting output operations. Each input and output gets a symbol (note that we have pre-pended the "o_" to output symbols to avoid confusion between input and output)

Inputs:

O Open
D Data
S Separator
C Close
E Error on input (Unrecognized character)

Outputs:

o_L Set low digit (also reset high digit to 0)
o_H Set high digit
o_E1 Set error indicator
o_E0 Reset error indicator
o_C Clear digit display

An input sequence analysis gives the following table:

Sequence Sequence Equivalent Output Comment
O      
D nil   Ignore data when not open
S nil   Ignore data when not open
C nil    
E nil   Since E can only come from erroneous input on serial port, ignore while not open
       
OO O   Open already. Ignore
OD   o_L  
OS O    
OC nil o_E0,o_C  
OE   o_E1,o_C  
       
OEO E    
OED E    
OES E    
OEC nil o_E0,o_C  
OEE E    
       
ODO OD   Open already. Ignore
ODD O o_H  
ODS O    
ODC nil o_E0,o_C  
ODE E o_E1,o_C  
       

This is the complete description of the behavior. A state diagram can be drawn directly from the sequence analysis table. Inputs are drawn as arrows, and labeled with the input name, as well as the output actions that are to be taken when the input occurs. States are drawn as bubbles. Inputs that do not change the state, and do not create output are omitted from the graph.

 

Implementation in Java

The example is implemented as a simulation in the Java applet below. On the left side are the buttons to enter a hexadecimal digit, as well as two button to enter a white space and a carriage return. Two more buttons are provided to simulate the behavior of unrecognized ASCII codes (comma and period). 
On the right hand side are two buttons to simulate open and close. Above are two fields for display. The left of them simulates the display of the hexadecimal number. The right simulates the error light by displaying "Error!" (your browser must have Java enabled for this to work).


(this is a Java applet. Click on the buttons to play with it)

Some variation on the basic methodology

- control/data path separation

Frequently (especially in communication applications), the software has two tasks: It has to move "packets" of data from one place to another, and has to keep track of the control status (for example: opening a communication channel, closing, recovering from a lost connection, treating packets that arrive out of sequence, retransmitting lost or damaged packets, etc). It would make no sense to treat every byte in the data packet as input data. Rather, if there is control information enclosed in the packet (for example in a packet header, or as check sum at the end of the packet), the control data must be extracted first, and then presented as input events to the control software.

- input abstraction

In the example above, it is likely that the "real" event that happens is the reception of an ASCII character. However, the raw character is not shown in the list of event inputs. Instead of treating '0','1',etc. as distinct inputs, they were grouped with the D input. Similarly, all separator characters (space, tab, etc.) were lumped into a single input, as were all the other characters into the E input group. This results in a reduction of input events without losing any functionality. The grouping would likely be done in a pre-processing step of the "character received" event.

- event cascading

In the example of the cell phone display above, a simple approach to event analysis, in which a sequence is explicitly written out up to the 30th time tick event would become immense and impractical. An alternate approach is to provide a counter. This counter is decremented each time a time event is received and its current value is not 0. When the counter decrements from 1 to 0, it creates an event (lets call it the timeout event). When the menu button is pressed, the counter is set to 30. If no suitable event happens within the next 30 seconds, a timeout event is being created. If any event happens (for example if I press a button to move through the menu) the counter is set to 30 again. During the sequence analysis after the menu button press event, any number of time events only cause the counter to be decremented, and the sequence is marked as identical to the current sequence without the timeout event (of course, in each step in the sequence analysis "timeout" must now be considered as an additional event).

A family class templates for small event-driven software systems

Component Software, Inc. has developed a set of class templates that allow a direct implementation of the sequence analysis table into software. The family consists of three class templates:

  1. The input sequencer
  2. The controller
  3. The processor

The classes interact with each other as shown below.

The input sequencer is optional and is used with event cascading when the processor issues events of its own. These events are stored in the sequencer's event queue and will be processed subsequently.

The controller keeps track of the event sequence that has been executed so far, and it receives events as they occur. It will cause calls into the processor depending on the past event sequence and the current event. A more specific implementation (a table-based controller) is provided as a class template. It allows the direct encoding of the sequence analysis table.

The processor is driven by the controller and implements the output actions that need to be performed. Typically the actions are kept simple. Event cascading is supported when the processor has access to the input sequencer.

Example source code

Source code for the java applet further above is available, as well as the implementation of a base64 encoder and decoder, based on the Controller/Processor C++ class family described above.

Get the source code for Windows (zip) or Linux/Unix (gz)

Bibliography

Prowell et. al. Cleanroom Software Engineering, Addison Wesley Longman ISBN 0-201-85480-5


Has this page been helpful to you? 
Do you have questions or comments?

We would very much like to hear from you. Just send us your thoughts below, or send us an e-mail at support@componentsw.com

Thank you!

 

Contact Name
Contact E-mail

Your feedback

Copyright © 2002-2005 Component Software, Inc.
All Rights Reserved

 


Helping Build the Tech Oasis - http://www.techoasis.org