Embed Linux in Monitoring and Control Systems

Set Up the Development Environment

My choice for a development environment is KDevelop from KDE, and for a toolkit, it is Qt from the Qt Project. The first step is to get the development environment and then build a "Hello World" application. So, here it is in the Fedora world:

yum install kdevelop 
yum install qt 
yum install gcc 

...and lots of other stuff. Expect to spend some time if you are not already up and running with Qt.

When you get KDevelop to load, click Session→Start New Session→New Project. This will be "Qt" and "Graphical". Make up a name (VMC for example), accept the defaults, and soon you will be presented the opportunity to "Build" and then "Execute". On "Execute", a Launch Configurations dialog box will enable you to select your project name, "Add New", and your project. A click or two later, and you should see a basic "Hello World" window appear on your screen. This you may expand into your real-time application.

The "Hello World" you see is a Qt application. Qt is an excellent toolkit that is robust and well documented—except for a few quirks. The new project build process creates a directory structure that includes ~/projects/VMC/build. To minimize hard-to-diagnose Qt build errors, keep all of your source and header files in ~/projects/VMC until you know how to do otherwise. The ~/projects/VMC/build directory is the execute directory for the purposes of KDevelop. It is here that run directory files should reside. As you add source files and libraries, you must keep ~/projects/VMC/CmakeLists.txt current.

Build the Application

Here is how to use tools available in the Linux environment to create the VMC application. First up is communications. To your application, the communication loop looks like a file stream created like this:

int hNet = open("/dev/ttyUSB0", O_RDWR);

or /dev/ttyUSBwhatever, depending upon what else is going on in your system.

Now you can read() and write() hNet and the USB<->RS422 converter will connect you to the loop. Writing is no issue up to loop speed (in this case 57600/9 = 6400 messages/second), so that is your write (hNet,...) speed limit. Reading is a different deal as read(hNet,...) is a blocking operation. A process that makes that call remains stuck there until some data arrives. Thus, you want to make your read(hNet,...) calls from a process (thread) whose only task is to catch characters as they come in and then make them available in a buffer to other processes as they need them—most briefly, in abbreviated code:

//A thread to perform the read(hNet,...) function
class COMthread : public Qthread
Q_OBJECT    //Notice use of the Qt tools
     //Start point when myThread->start(); is called
void run() 
while (1)
pthread_mutex_t mutex1\
//Lock out other processes while working
pthread_mutex_lock( &mutex1 );
          -manipulate shared variables here-
//unlock for other processes during read(hNet,...
pthread_mutex_unlock( &mutex1 );

//This is where this thread spends
read(hNet, Buf, BUF_SIZE);/////////
//99.99 (+/-) percent of its time

//Now lock while updating for new data
pthread_mutex_lock( &mutex1 );
         -buffer data and update pointers-
pthread_mutex_unlock( &mutex1 );

To activate that code, your statements in the VMC constructor are:

COMthread   *gCOMgo = new COMthread;

The complement to that loop data fetch is a character fetch routine running under some other process. That routine, using its own mutexes, extracts data from the buffer sourced by the thread above.

Now that you can send and receive data via the loop, let's look at how the application may interact with the hardware.

Figure 2 shows the Instrument Panel display as seen on a video display mounted in the driver's view.

Figure 2. Instrument Panel Display

The Tach and Speed display data are sourced from timer registers in an HIP that is timing the period between shaft rotations. The five indicators below are sourced by A/D registers in various HIPs. These seven data items are collected by sending seven nine-character data request messages to the loop and decoding the returned 63 characters (7X9). Below that is a representation of a partially populated map of a 4X4 keypad that is serviced by one of the HIPs. Each of the represented keys on that map issues a query for the HIP responsible for the physical keypad to see if its key was the last pressed. It gets back yes or no.

When you use KDevelop to create a VMC project, some files of interest to you now were created. Look in directory ~/projects/VMC, and there you will find main.cpp and VMC.cpp. File main.cpp is fine as is. It simply declares and runs the application described by the code in VMC.cpp. None of the sample code in VMC.cpp within the curly braces is useful for you, so let's replace it with the constructor for the VMC application. As I mentioned previously, this application relies upon Qt, so an important resource for you is http://qt-project.org/doc/qt-4.8/classes.html.


Rick Brown is a US Navy veteran, holds a BSEE granted in 1970 by the University of Florida, developed atmospheric research instruments as a faculty member of the University of Nevada System, and consulted in the private sector as a developer.