user’s guide - utah state...

26
SDM User’s Guide 1. Introduction 2. Installation 3. Using a makefile 4. Booting the SAIC minisys 4.1 Changing consoles 4.2 Starting application executables 4.3 Starting up the SDM on a single machine (giving specific scripts) 4.4 Running the SDM on a distributed network (giving specific scripts) 5. Common Problems 5.1 Finding libraries and installing 5.2 Port unable to bind 5.3 No network communication in a distributed system 6. Example applications 6.1 producer 6.2 consumer 6.3 converter Appendix A: Useful Linux commands

Upload: buidan

Post on 01-Apr-2018

220 views

Category:

Documents


1 download

TRANSCRIPT

SDM User’s Guide1. Introduction

2. Installation

3. Using a makefile

4. Booting the SAIC minisys

4.1 Changing consoles

4.2 Starting application executables

4.3 Starting up the SDM on a single machine (giving specific scripts)

4.4 Running the SDM on a distributed network (giving specific scripts)

5. Common Problems

5.1 Finding libraries and installing

5.2 Port unable to bind

5.3 No network communication in a distributed system

6. Example applications

6.1 producer

6.2 consumer

6.3 converter

Appendix A: Useful Linux commands

1. Introduction

This version of the Satellite Data Model (SDM) is intended to run under a Linux 2.6 kernel. It has been tested with the Fedora Core 3 distribution of Linux and the SAIC “minisys” embeddable Linux kernel. Application development is intended to be done using GNU tools on a Linux PC running a distribution such as the Fedora Core 3. Executable files are then moved to a PC running the “minisys” kernel for execution with the SDM.

2. Installation

A set of example applications has been provided. Each application is associated with a specific makefile to specify sources and command lines for preparing the executable. To install the example directories, insert the CD. When the CD shows up on the desktop open it and copy the Example and Includes folder. Once the folders have been copied they can be pasted into any convenient location on the computer.

3. Using a Makefile

To use the makefile under Fedora Core 3 simply bring up a command terminal and change to the directory that the makefile is in. If the makefile is just named makefile then just type make. If the makefile has some other name such as makefile_61, then you would type make –f makefile_61.

4. Booting the SAIC minisys

Download the SAIC minisys iso from http://www.cs.usu.edu/~scott/sdm/sdm2.htm. Then burn the iso image with your favorite CD burning utility. To start the system up insert the SAIC minisys CD and boot from the CD drive. The minisys is completely embedded and does not affect the operating system you currently have installed. It is entirely memory resident and requires no disk files or installation. The minisys utilizes a standard Linux disk directory structure, but all files are actually memory resident.

When the system starts up you will have the choice of what resolution to use. The one we found worked the best for us is svga. If this does not work for you try the other two options and find the one that works best for you. When the system has finished booting you will have a command prompt. Type cd /root. This will put you in the main working directory. (If you type ls you can see all the files currently in the directory.) Now you will want to set up a few aliases that will make it easier for you to move files from the Fedora Core 3 system to this system. Here are a few helpful commands;

$ alias mf=”/dev/sda1 /mnt –t vfat”

$ alias umf=”umount /mnt”With these aliases, the following procedure can be used to copy files on a flash (thumb) drive to a minisys machine. SDM executables can be downloaded from http://www.cs.usu.edu/~scott/sdm/sdm2.htm and need to be unzipped first. The files contained in the zip file are dm, tm, sm, pm, installSDM, and startSDM. The install file is a script that will let you install all the managers and the startSDM file with one simple command. The startSDM file will allow, on a single machine, you to start all the managers on a single console. This allows the other 5 consoles to be available for application use. Copy the unzipped files onto a flash drive. All application files with have to be copied separately. Insert the drive into a USB connector and wait a few seconds for it to be recognized. Now, mount the volume and copy the files;

$ mf$ cp /mnt/SDM.tar.gz .$ cp /mnt/yourFileName .$ umf$ tar –xz –f SDM.tar.gz$ ./installSDM

The system is now ready to run.

4.1 Changing ConsolesThe SAIC minisys has 6 consoles to provide 6 different nodes or active processes.. These can be accessed by doing ALT-F1 through ALT-F6 to bring up the various consoles. Changing consoles does not affect the processes currently running on those consoles – you just won’t see the output of the hidden console until you return to it. Think of this as emulating 6 different PCs each with its own monitor; only one monitor at a time can be viewed.

4.2 Starting application executablesTo start any executable under Linux, type

./yourFileName

This will start the executable with that file name in the current directory. For example should I want to start the Data Manager I would type ./dm.

4.3 Starting up the SDM on a single machineThere are four (4) manager processes associated with the SDM. Each of these managers must be running before an application can be started. While all can be run under the same console, it is better to run them in separate consoles so that output and error messages are easier to identify and understand. The following is a suggested set of ordered steps;

console 1: $ /root/dmconsole 2: $ /root/tm console 3: $ /root/sm localconsole 4: $ /root/pm local local

or if you will be running the test suite examples

console 1: $ /root/startSDM

Applications can now be run on the remaining consoles. It is not necessary to start the SDM prior to plugging in sensors. After starting the SDM, sensors can be added or removed at any time, although it may take 5-10 seconds after making a device change for the SDM to appropriately respond.

4.4 Running the SDM on a distributed networkTo be able to run the SDM on a distributed network you will need these items: First, an Ethernet switch or router is required. Second, machines must have Ethernet cards recognized by the SAIC minisys. Not all brands and flavors of Ethernet cards have been included in the kernel, for obvious reasons. We believe that Ethernet cards in most Dell machines should work, plus there are some other machines that will have compatible Ethernet cards. To be able to tell if the machine has a compatible card do the following steps.1. Boot the SAIC minisys2. Type: $ ifconfig eth0 192.168.7.1

Now type ifconfig again and see that the Ethernet card has an ip address. Once you have checked all machines for compatible Ethernet cards and know which ones will work for you, then you can start setting up the distributed network. This network will work on a minimum of two machines and a maximum of as many machines as your switch or router will support. If your router has a bridge or uplink port, it should not be utilized. This is sometimes referred to as the routing port.

Any of the SDM managers can be run anywhere in a distributed network, but some must know the location of the data manager (dm), or task manager (tm), or both. For example:

machine 1 at 192.168.1.2: $ /root/dmmachine 2 at 192.168.1.3: $ /root/tm machine 3: $ /root/sm 192.168.1.2machine 4: $ /root/pm 192.168.1.3 192.168.1.2

5. Common Problems

These are some of the common problems that you might run across as you are working with the SDM and the solutions to those problems.

5.1 Finding and installing librariesQ. When I try to run my program I get an error that a library is not found.

A. This typically occurs when the development PC’s distribution of Linux is somewhat different than that assumed by the minisys. Make note of what library is missing. Then go to your development machine and locate the missing library file and copy it to the corresponding directory under the minisys. For example: On the development system, type cd /lib. Then type ls and the file name you made note of earlier. If it is found copy it to a flash drive. (If the file is not found then type cd /usr/lib as an alternate possibility.) Then copy to your flash drive and transfer to the SAIC minisys under /lib( or /usr/lib as appropriate).

5.2 Port unable to bindQ. When I try to run my application I get a message indicating that the port cannot be

bound.

A. This type of error usually occurs when a program has a segmentation fault or is not properly shutdown. Use the ps utility and look for a program that you have started, but that should no longer be running. If you find the program, use the kill command to terminate the process. If you cannot find an associated process to kill, you may need to reboot the minisys kernel.

5.3 No network communication in a distributed systemQ. When I try to run the SDM on a distributed network, I see no communications

between the managers or application.

A. Since you are running in a local or closed network, there are no name or IP address services available. Each message sending process must know the numeric IP address of the intended destination (see Running the SDM on a distributed network.) If the Ethernet card on your machine was not previously configured for a permanent IP address, you can do so with the following command. Ethernet addresses beginning with 192.168 are available for experimental systems and these are typically utilized, although this isn’t critical in a local network. For example, to set the IP address to 192.168.1.2;

$ ifconfig eth0 192.168.1.2

You should also check your network cabling. Each network machine should have a cable to a local-machine port on a network router. The gateway or upstream port on the router should not be utilized.

6. Example applications

This section is consists of a suite of applications forming a functionality test of the SDM. The suite consists of three concurrent applications; a producer, consumer and a consumer/producer application.

To install the test suite. Download the Demo Appliations from the SDM website onto your flash drive. Then use these commands:

$ mf$ cp /mnt/Examples.tar.gz .$ umf$ tar –xz –f Examples.tar.gz$ ./installExamples

To start the test suite once the SDM is running.On a single machineconsole 4: $ /root/producer local localconsole 5: $ /root/converter local localconsole 6: $ /root/consumer local local

On a distributed networkconsole 4: $ /root/producer TM-ip-address DM-ip-addressconsole 5: $ /root/converter TM-ip-address DM-ip-addressconsole 6: $ /root/consumer TM-ip-address DM-ip-address

where TM-ip-address and DM-ip-address are replaced with the numeric IP addresses of the machines hosting the TM and DM respectively.

6.1 producer

This application is a producer of data. It posts its xTEDS to the DM and subsequently receives a subscription from the consumer (see 6.2) to which is publishes a stream of data (random integers).

To start this application type

$ ./producer TM-ip-address DM-ip-address

TM-ip-address and DM-ip-address can be the symbolic constant local (or nothing can be put in for either and local will be assumed on both) for a single machine implementation.

//A sample producer#include "../../common/message/SDMmessage.h"#include <string.h>#include <sys/types.h>

#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>

#define MYPORT 4801int main(int argc,char** argv){

//initialize connection with SDM systemif(argc == 1){

//assume local localsetTM_IP("127.0.0.1");setDM_IP("127.0.0.1");

}else{

if (strcmp(argv[1],"local")==0)setTM_IP("127.0.0.1");

elsesetTM_IP(argv[1]);

if (strcmp(argv[2],"local")==0)setDM_IP("127.0.0.1");

elsesetDM_IP(argv[2]);

}

unsigned short int_strain;int i;

SDMxTEDS xteds; // create an xTEDS registration messageSDMSubreqst request; // create a message to receive a subscription

message requestSDMData dat; // create a message to send a data messageSDMCancelxTEDS cancel;

strcpy (xteds.xTEDS,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xTEDS xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"C:\\Documents and Settings\\Todd\\Desktop\\xTEDS1[1].10.piz\\xTEDS.1.10.xsd\" VERSION=\"Text\" NAME=\"String\" DESCRIPTION=\"Text\" xmnls=\"String\">\n\t<DEVICE NAME=\"producer\" KIND=\"data\"/>\n\t<VARIABLE NAME=\"data\" FORMAT=\"Integer\"

KIND=\"data\" QUALIFIER=\"Single Value\"/>\n\t<DATA_MSG NAME=\"all\" ID=\"1\" DATARATE=\"Stream\">\n\t\t<VARIABLE NAME=\"data\"/>\n\t</DATA_MSG>\n</xTEDS>\n"); // set xTEDS

xteds.sensor_id = 1; // set the id of this applicationcancel.sensor_id=xteds.sensor_id;xteds.port = MYPORT;cancel.port = xteds.port;printf("Registering xTEDS\n");xteds.Send(); // register with the SDM

for (i=0;i<100;i++) // now wait for subscription and stream 100 data messages

{if(i == 0){

printf("Waiting for subscription.\n");request.Recv(MYPORT);

}int_strain = rand()%65536;printf("%d\n",int_strain);memcpy(dat.msg,&int_strain,2);dat.sensor_id = request.sensor_id;dat.msg_id = request.msg_id;dat.geo_location = 0;dat.Send(request.IP_addr, request.port,2); // return to requestersleep(1);

}printf("Canceling xTEDS\n");cancel.Send();

}

Typical output to be expected as data messages are streamed to the consumer:

65432453244512843565435 …Canceling xTEDS

6.2 consumer

This application requests a source of data from the DM and then subscribes to the indicated producer. Once it receives that data, it queries the DM for the service (converter) application capable of converting an integer to a float (example 6.3) and sends it the integer from the producer to get it converted into a float between 0 and 1.

To start this application type $ ./consumer TM-ip-address DM-ip-address

TM-ip-address and DM-ip-address can be the defined constant local (or nothing can be put in for either and local will be assumed on both) for a single machine implementation.

//A sample consumer#include "../../common/message/SDMmessage.h"

#include <string.h>#include <unistd.h>#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>

#define INT_PORT 4701#define SERVICE_PORT 4702

int main(int argc,char** argv){

SDMData dat;SDMData serv_dat;SDMService request;SDMConsume consume;SDMRegInfo info;SDMReqReg req_reg;

int result;int length;int start_byte;int pid_parent,pid_timeout;float strain;int status;

//initialize connection with SDM systemif(argc == 1)

{//assume local localsetTM_IP("127.0.0.1");setDM_IP("127.0.0.1");

}else{

if (strcmp(argv[1],"local")==0)setTM_IP("127.0.0.1");

elsesetTM_IP(argv[1]);

if (strcmp(argv[2],"local")==0)setDM_IP("127.0.0.1");

elsesetDM_IP(argv[2]);

}

//subscribe to integer datastrcpy(req_reg.item_name,"data"); //Set variable namestrcpy(req_reg.quallist,"< FORMAT=\"Integer\"/>"); //Set the quallist can

be empty//query DM for provider of strain datado{

sleep(1);req_reg.Send(); //Send the req_reg messageresult = info.Recv(); //Receive the response into infoif (result==SDM_NO_DATA_PROVIDER) //Check to see if there is a

Data providerprintf("Searching for Integer Data . . .\n");

} while(result==SDM_NO_DATA_PROVIDER);

start_byte= 0;length = 2;

//register as consumer of int dataconsume.period = 1000; //Set the periodconsume.port = INT_PORT; //Set the port we will be receiving onconsume.sensor_id=info.sensor_id; //copy the sensor id into the consume

messageconsume.msg_id=info.msg_id; //copy the msg id into the consume messageconsume.Send(); //Send the consume message

//clear out other possible providers

while(result!=SDM_NO_DATA_PROVIDER){result=info.Recv();}

while(1){

strcpy(req_reg.item_name,"data"); //Set variable namestrcpy(req_reg.quallist,"< FORMAT=\"Integer\"/>"); //Set the

quallist can be empty

pid_parent = getpid(); //Get the id of the parentpid_timeout = fork(); //Fork a child process

if (pid_timeout != 0) //If not child process{

//get integer strain datadat.Recv(INT_PORT,2); //Receive the data from strain gaugekill(pid_timeout,SIGTERM); //Kill the child processwait(&status);

}else{

while(1){

sleep(5); //wait for five seconds for msgprintf("Integer Data Provider not responding\n");do{

req_reg.Send(); //Send the req_reg messageresult = info.Recv(); //Receive the response into

infoif (result==SDM_NO_DATA_PROVIDER)

//Check to see if there is a Data provider{

printf("Searching for Integer Data . . .\n");sleep(1);

}} while(result==SDM_NO_DATA_PROVIDER);

consume.sensor_id=info.sensor_id; //copy the sensor id into the consume message

consume.msg_id=info.msg_id; //copy the msg id into the consume message

consume.Send(); //Send the consume message

//clear out other possible providerswhile(result!=SDM_NO_DATA_PROVIDER){result=info.Recv();}

}

}

//find service providerdo{

//set up service request for conversionstrcpy(req_reg.item_name,"convert"); //Set var name to

convert which we already knowreq_reg.quallist[0] = '\0'; //We will not be using wildcards

//Sleep for 1 secondreq_reg.Send(); //Send a message to find convertresult = info.Recv(); //Get the xTED for convertif (result == SDM_NO_DATA_PROVIDER) //If no data provider{

printf("Searching for Service Provider . . .\n");sleep(1);

}} while(result==SDM_NO_DATA_PROVIDER);

//prepare service requestrequest.sensor_id=info.sensor_id; //copy sensor id into service requestrequest.service_id=info.msg_id; //copy msg id into service requestrequest.port=SERVICE_PORT; //Set service request recieverequest.length = 2; //set the length we are sending//copy integer data into service requestmemcpy(request.data,dat.msg+start_byte,2); //copy the integer data into

the service request data//send requestrequest.Send();

//clear out other possible providerswhile(result!=SDM_NO_DATA_PROVIDER){result=info.Recv();}

//recieve service results

pid_parent = getpid(); //Get the parent idpid_timeout = fork(); //Fork a child

if (pid_timeout != 0) //If not child{

//get integer strain dataserv_dat.Recv(SERVICE_PORT,4);kill(pid_timeout,SIGTERM); //Kill the childwait(&status);

}else //Child will only kill parent if service exists and does not respond{

while(1){

sleep(5); //wait for five seconds for service//find service providerprintf("Service Provider has not responded.\nSearching for

New Service Provider.\n");req_reg.Send();result = info.Recv();if (result == SDM_NO_DATA_PROVIDER){

do{

sleep(1); //Sleep for 1 secondreq_reg.Send(); //Send a message to

find convertresult = info.Recv(); //Get the xTEDS for

convertif (result ==

SDM_NO_DATA_PROVIDER) //If no data providerprintf("Searching for Service

Provider . . .\n");} while(result==SDM_NO_DATA_PROVIDER);

}

//prepare service requestrequest.sensor_id=info.sensor_id; //copy sensor name

into service requestrequest.service_id=info.msg_id; //copy msg name into

service requestrequest.port=SERVICE_PORT; //Set service request

recieverequest.length = 2; //set the length we are sending//copy integer data into service request

memcpy(request.data,dat.msg+start_byte,2); //copy the strain gauge integer into the service request data

//send requestrequest.Send();

//clear out other possible providerswhile(result!=SDM_NO_DATA_PROVIDER){result=info.Recv();}

}}//extract and display resultsprintf("Float Data -- %f\n",serv_dat.getFloat(0));

}}

Expected output would look something like this:

Float Data -- 0.095782Float Data -- 0.842387Float Data -- 0.095782Float Data -- 0.842387Float Data -- 0.095782Float Data -- 0.842387Float Data -- 0.095782Float Data -- 0.842387Float Data -- 0.095782Float Data -- 0.842387Searching for Service Provider ….

This continues until the user terminates the application

6.3 converter

This application receives data from the consumer, example 6.2, and then once it receives that data it converters it from an integer into a float between 0 and 1.

To start this application type $ ./converter TM-ip-address DM-ip-address

Again, Tm-ip-address and DM-ip-address can be local (or nothing can be put in for either and local will be assumed on both).

//A sample converter#include "../../common/message/SDMmessage.h"#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>

#define MYPORT 4737int main(int argc,char** argv){

//initialize connection with SDM systemif(argc == 1){

//assume local localsetTM_IP("127.0.0.1");setDM_IP("127.0.0.1");

}else{

if (strcmp(argv[1],"local")==0)setTM_IP("127.0.0.1");

elsesetTM_IP(argv[1]);

if (strcmp(argv[2],"local")==0)setDM_IP("127.0.0.1");

elsesetDM_IP(argv[2]);

}

unsigned short int_data;float float_data;

int i;

SDMxTEDS xteds; // create an xTEDS registration messageSDMSerreqst request; // create a message to receive a service message requestSDMData dat; // create a message to receive a data messageSDMCancelxTEDS cancel;

strcpy (xteds.xTEDS,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xTEDS xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"C:\\Documents and Settings\\Todd\\Desktop\\Parser\\xTEDS[1].1.11.xsd\" VERSION=\"Text\" NAME=\"String\" xmnls=\"String\">\n\t<DEVICE NAME=\"Convert\" KIND=\"Software\"/>\n\t<VARIABLE NAME=\"data\" FORMAT=\"Float\" KIND=\"Float Data\" QUALIFIER=\"Single Value\"/>\n\t<VARIABLE NAME=\"convertee\" FORMAT=\"Integer\" KIND=\"Int Data\" QUALIFIER=\"Single Value\"/>\n\t<DATA_MSG NAME=\"results\" ID=\"2\" DATARATE=\"Aysnc\">\n\t\t<VARIABLE NAME=\"data\"/>\n\t</DATA_MSG>\n\t<COMMAND_MSG NAME=\"convert\" ID=\"1\">\n\t\t<VARIABLE NAME=\"convertee\"/>\n\t</COMMAND_MSG>\n\t<SERVICE CMD_MSG_NAME=\"convert\" DATA_MSG_NAME=\"results\"/>\n</xTEDS>");

// set xTEDS

xteds.sensor_id = 1; // set the id of this applicationcancel.sensor_id=xteds.sensor_id;cancel.port = MYPORT;xteds.port = MYPORT;printf("Registering xTEDS\n");xteds.Send(); // register with the SDM

for (i=0;i<100;i++) // now wait for and handle 10 service request messages

{printf("Waiting for service request.\n");request.Recv(MYPORT);

// request contains the service request parameters: request.service = "convert" and 2 raw data bytes// representing a unsigned integer strain.

// The following converts the raw parameter bytes into a float and copies it into variable temp.

memcpy(&int_data,request.data,2); // copy integer parameter into variable int_strain

float_data = int_data/(float)0xffff; // convert to float between 0 and 1printf("Converted %d to %f\n",int_data,float_data);dat.sensor_id = request.sensor_id;dat.msg_id = request.service_id; // fill in other fields

memcpy (dat.msg, &float_data, 4); // convert float_data to raw data bytes

printf("Sending reply.\n");dat.Send (request.IP_addr, request.port,4); // return to requester

}printf("Canceling xTEDS\n");cancel.Send();

}

Expected output would look something like this:

Registering xTEDSWaiting for Service RequestConverted 9217 to 0.144459Sending replyWaiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply Waiting for Service RequestConverted 9217 to 0.144459Sending reply …Canceling xTEDS

Appendix A

Useful Linux commands

alias - allow for the use of a simple command to do something complexex. alias mf=”mount /dev/sda1 /mnt –t vfat”

cd - change directoryex. cd /root

CNTL-C - Kills a currently running application

cp - copyex. cp /mnt/dm /root/.

ifconfig - Configure Ethernetex. ifconfig eth0 129.123.7.14

kill - kills a currently running process by process id numberex. kill 708

ls - list directoryex. ls /root

make - run the makefileex. make –f makefile_61

mkdir - make a directoryex. mkdir dir3

mount - mount a device into the filesystemex. mount /dev/sda1 /mnt

ps - list currently running processes this will give you the process id number

rm - remove a fileex. rm strain.xted

umount - umount a device from the filesystemex. umount /mnt