Accessing Databases from Esterel

David White & Gerald Lüttgen

A current limitation in embedded controller design and programming is the lack of database support in development tools such as Esterel Studio. This research proposes a way of integrating databases and Esterel by providing two Application Programming Interfaces (APIs) which enable the use of relational databases inside Esterel programs. As databases and Esterel programs are often executed on different machines, result sets returned as responses to database queries may be processed either locally and according to Esterel's synchrony hypothesis, or remotely along several of Esterel's execution cycles. These different scenarios are reflected in the design and usage rules of the two APIs presented in this research, which rely on Esterel's facilities for extending the language by external data types, external functions and procedures, as well as tasks.

The APIs' utility is demonstrated by means of a case study modelling an automated warehouse storage system, which is constructed using Lego Mindstorms robotics kits. The robot's controller is programmed in Esterel in a way that takes dynamic ordering information and the warehouse's floor layout into account, both of which are stored in a MySQL database.

This research was supported by an Undergraduate Research Bursary of the Nuffeld Foundation (grant no. URB/01528/G).

Table of Contents

Detailed Overview

Case Study

Local Result Set API

Remote Result Set API

Detailed Overview

One of the current limitations in the programming of embedded controllers is the lack of database support available within languages such as Esterel and Lustre, and their development environments, Esterel Studio and SCADE, respectively. These environments are used by large avionics manufacturers and vendors of digital signal processing solutions for developing the software of complex, and often safety-critical, embedded systems. Both Esterel and Lustre are synchronous languages which aim at describing reactions in cycle-based reactive systems, including embedded controllers. Such systems continuously interact with their physical environment by (i) reading in signals representing sensor values, such as an aircraft's speed, altitude and attitude, (ii) computing a reaction based on these values, such as a rudder angle, and (iii) emitting signals carrying the computed values to the environment, e.g., to the hydraulic system moving the rudders. While Esterel is a textual, imperative language that aims at modelling control flow and has semantical similarities to Statecharts, Lustre is best suited for modelling data flow and is a graphical language centred around block diagrams, very much like Simulink.

The Problem

What all development environments that are available for these languages have in common is that they support the automatic generation of code, such as C, Ada or VHDL code, from abstract program descriptions. In this way, they aim to make embedded software design and programming more cost-effective when compared to traditional software development processes. However, Esterel Studio and SCADE do not provide an easy way of integrating databases within an application. Other reactive systems design tools are very limited in this respect as well, including Simulink/Stateflow and Statemate. As is, a system designer needs to modify auto-generated code by hand in order to interface to databases, which is both difficult and error-prone. This is a problem very much relevant in industry since some reactive systems programmed in synchronous languages would benefit from an easy model of database interaction. For example, synchronous languages are often used to build the flight software for aeroplanes. Adding database interaction would enable spacial and mapping data to be retrieved and processed directly by the reactive kernel implementing an auto pilot. Further examples are infotainment systems in the automotive sector, particularly navigation systems, or process control systems in nuclear reactors where regulators require that logs of data are recorded and kept.

Our Contribution

This work addresses the aforementioned limitation by providing Application Programming Interfaces (APIs) for using relational databases within the Esterel programming language. We choose MySQL as the database and, since reactive kernels are produced as C programs by the Esterel compiler, the APIs are implemented using the MySQL C interface whose functionality we aim to mirror in our APIs for Esterel. MySQL is selected here simply for its convenience and since it is widely used. However, our approach can as easily be applied to other relational databases. To the best of our knowledge, no work on database integration within Esterel, or similar languages, has been published in the literature before. This does not mean, however, that we are the first to integrate an existing synchronous language with a database system. The problem is that other works are commercial and not in the open domain. This includes National Instruments' LabVIEW Database Connectivity Toolkit which is a set of tools for connecting programs designed in LabVIEW to popular databases, such as Microsoft Access, SQL Server and Oracle, and for implementing many common database operations without having to perform SQL programming.

Because database transactions are relatively complex when compared to responses of Esterel reactive kernels, databases and reactive programs must be considered as running asynchronously to each other. This is true regardless of whether they reside on the same machine or on different machines. In the former case, however, result sets to database queries may reasonably be assumed to be processed within a single synchronous step of the reactive kernel. In the latter case, result sets are necessarily read asynchronously to the reactive kernel. For these reasons, one API for each situation is provided: a Local Result Set API and a Remote Result Set API. The realisation of both APIs relies on Esterel's support for extending the language via external data types, external functions and procedures, and tasks. For example, the Local Result Set API makes heavy use of external functions and procedures. This is because these are considered to execute instantaneously, i.e., within a single reaction cycle, and therefore do not interfere with the synchronous nature of Esterel programs. On the other hand, the Remote Result Set API is implemented using Esterel's task mechanism which allows external code to run asynchronously to an Esterel program, i.e., alongside several program cycles, but still be controlled by it.

Case Study

We demonstrate the utility of our APIs by means of a case study involving a warehouse storage system. The idea behind this is that of a direct order company, i.e., orders must be picked from items stored in a warehouse. Accordingly, a robot is built and programmed to pick up and drop off items, therefore making it possible for a complete order to be collected and stored. The orders and the information about the items are provided by a database. Part of the information stored on an item is its position in the warehouse, thereby providing mapping data for the robot. The case study is realised using Lego Mindstorms robotics, which provide a small programmable brick, called the RCX, that houses a microcomputer capable of running an Esterel reactive kernel. Sensors and actuators connected to the RCX, such as touch, light and rotation sensors and motors, respectively, permit interaction with the RCX's environment. The RCX also has a built-in infrared port, which we use to communicate with the warehouse database on the server.

Movies of the Case Study

Pictures of the Case Study

Local Result Set API

The table below details the functionality of the local result set API.

type MYSQL_RES_ptr;
type MYSQL_ROW;

procedure appstr() (string, string);
procedure appint() (string, integer);
procedure appbol() (string, boolean);
procedure appflt() (string, float);
procedure appdou() (string, double);

output <Signal name for emitting query> : string;
input <Signal name for returning results> : MYSQL_RES_ptr;

function check_result(MYSQL_RES_ptr) : boolean;
function get_next_row(MYSQL_RES_ptr) : MYSQL_ROW;
function num_rows(MYSQL_RES_ptr) : integer;

function getstr(MYSQL_ROW, integer) : string;
function getint(MYSQL_ROW, integer) : integer;
function getbol(MYSQL_ROW, integer) : boolean;
function getflt(MYSQL_ROW, integer) : float;
function getdou(MYSQL_ROW, integer) : double;

function num_affected_rows(MYSQL_RES_ptr) : integer;
procedure clear_results() (MYSQL_RES_ptr);

The script is called as follows:

local_api_script.pl <Main Module Name> <Max length of strings and queries> <DB Name> <Host> <User> <Password> <Signal name for emitting query> <Signal name for returning results>

The parameters in the above code have the following meaning:

Remote Result Set API

The table below details the functionality of the remote result set API.

procedure appstr() (string, string);
procedure appint() (string, integer);
procedure appbol() (string, boolean);
procedure appflt() (string, float);
procedure appdou() (string, double);

task <db_id>_perform_query () (string);
return <db_id>_perform_query_complete0(boolean);

task <db_id>_get_row () ();
return <db_id>_get_row_complete0(boolean);

task <db_id>_clear () ();
return <db_id>_clear_complete0;

function <db_id>_getint(integer) : integer;
function <db_id>_getstr(integer) : string;
function <db_id>_getbol(integer) : boolean;
function <db_id>_getdou(integer) : double;
function <db_id>_getflt(integer) : float;
endcodeblock();

The script is called as follows:

remote_api_script.pl <Main Module Name> <Max length of strings and queries> <DB Name> <Host> <User> <Password> <Task, return signal and 'get functions' prefix> <Num of query return signals> <Num of get row return signals> <Num of clear results return signals>

The parameters in the above code have the following meaning:

© David White & Gerald Lüttgen 2008