About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

iomonitor.cpp

Go to the documentation of this file.
00001 /** @file iomonitor.cpp  Test utility for IO devices
00002 
00003 
00004 This tutorial demonstrates elementary access to external signals
00005 via the class faudes::vDevice. It can be used as a test uitility
00006 for device configuration. 
00007 
00008 
00009 @ingroup Tutorials
00010 
00011 @include iomonitor.cpp
00012 
00013 */
00014 
00015 
00016 #include "libfaudes.h"
00017 
00018 #include <sys/time.h>
00019 #include <signal.h>
00020 
00021 
00022 
00023 // fix windows/mingw definition                                                          
00024 #ifdef FAUDES_WINEXTRA
00025 #define sleep(sec) Sleep((sec) * 1000)
00026 #define usleep(usec) Sleep((usec) / 1000)
00027 #define SIGQUIT SIGBREAK
00028 #define SIGHUP SIGBREAK
00029 #define strsignal(sig) "unknown"
00030 #endif
00031 
00032 using namespace faudes;
00033 
00034 ///////////////////////////////////////////////////////
00035 // clean exit on signals
00036 
00037 // iomonitor clean-up on exit
00038 void iomonitor_exit(void);
00039 
00040 // signal handler recursion flag
00041 volatile sig_atomic_t signal_in_progress = 0;
00042 
00043 // signal handler to stop devices
00044 void catch_signal(int sig) {
00045   // detect recursion, pass on
00046   if(signal_in_progress) raise(sig);
00047   signal_in_progress = 1;
00048   // report
00049   std::cerr << "iomonitor: signal: " << strsignal(sig) << std::endl;
00050   // call my exit function
00051   iomonitor_exit();
00052   // re-install default handler
00053   signal(sig, SIG_DFL);
00054   // pass on signal
00055   raise(sig);
00056 }
00057 
00058 // iomonitor clean-up on exit
00059 void iomonitor_exit(void) {
00060   // stop all devices
00061   vDevice::StopAll();
00062 }
00063 
00064 
00065 ///////////////////////////////////////////////////////
00066 //Basic handling
00067 
00068 // list all known events
00069 void ListEvents(const vDevice* dev) {
00070   std::cout<< "% ###############################################################" << std::endl;
00071   std::cout<< "% # InputEvents" << std::endl;
00072   dev->Inputs().Write();
00073   std::cout<< "% ###############################################################" << std::endl;
00074   std::cout<< "% # OutputEvents " << std::endl;
00075   dev->Outputs().Write();
00076   std::cout<< "% ###############################################################" << std::endl;
00077 }
00078 
00079 
00080 ///////////////////////////////////////////////////////
00081 // Query Time
00082 
00083 // read time
00084 void ReadTime(vDevice* dev) {
00085 
00086   // read and report
00087   std::cout << "% ###############################################################" << std::endl;
00088   std::cout << "% # ReadTime: current time in ftu: " << dev->CurrentTime() << std::endl;
00089   std::cout << "% # ReadTime: using scale: " << dev->TimeScale() << std::endl;
00090 
00091 }
00092 
00093 
00094 ///////////////////////////////////////////////////////
00095 //Signal-I/O
00096 
00097 // read signal value
00098 void ReadSignalValue(sDevice* dev) {
00099   // declare static buffer
00100   static bool* samplePrevious=0;
00101   static bool* sampleCurrent=0;
00102   static int sampleSize=-1;
00103   // allocate memory for buffer
00104   if(sampleSize != dev->MaxBitAddress()+1) {
00105     sampleSize = dev->MaxBitAddress()+1;
00106     if(samplePrevious!=0) delete samplePrevious;
00107     if(sampleCurrent!=0) delete sampleCurrent;
00108     samplePrevious= new bool[sampleSize];
00109     sampleCurrent= new bool[sampleSize];
00110   }
00111   // read and report
00112   std::cout << "% ###############################################################" << std::endl;
00113   for(int bit=0; bit<sampleSize; bit++) {
00114     samplePrevious[bit]=sampleCurrent[bit];
00115   }
00116   for(int bit=0; bit<sampleSize; bit++) {
00117     sampleCurrent[bit]=dev->ReadSignal(bit);
00118   }
00119   std::cout << "% # ReadValue: current input reading: " << std::endl;
00120   for(int bit=0; bit<sampleSize; bit++) {
00121     std::cout<< "@"<< bit << ":" << sampleCurrent[bit] << "   ";
00122     if((bit%8)==7 || bit+1==sampleSize) std::cout << std::endl;
00123   }
00124   std::cout <<"% # ReadValue: edges wrt previous reading: " << std::endl;
00125   int cnt =0;
00126   for(int bit=0; bit<sampleSize; bit++) {
00127     if(samplePrevious[bit]!=sampleCurrent[bit]) {
00128       std::cout<< "@"<< bit << ":" << sampleCurrent[bit] << "   ";
00129       if((cnt%8)==7 || bit+1==sampleSize) std::cout << std::endl;
00130       cnt+=1;
00131     }
00132   }   
00133   std::cout << "% ###############################################################" << std::endl;
00134 }
00135 
00136 
00137 // write signal value
00138 void WriteSignalValue(sDevice* dev) {
00139   int bit, val;
00140   std::cout<<"WriteValue: enter bit address (or -1 to exit): ";
00141   std::cin>>bit;
00142   if(bit<0) return;
00143   std::cout<<"WriteValue: enter value (or -1 to exit): ";
00144   std::cin>>val;
00145   if(val<0) return;
00146   std::cout<<"WriteValue: setting output " << bit << " to value " << val << std::endl;
00147   dev->WriteSignal(bit,val!=0);
00148 }
00149 
00150 //////////////////////////////////////////////////////////////
00151 //Event-handling
00152 
00153 // execute output event
00154 void WriteOutputEvent(vDevice* dev) {
00155   std::cout<<"WriteOutput: enter event by name: ";  
00156   std::string testEvent;
00157   std::cin>>testEvent;
00158   if(!dev->Outputs().Exists(testEvent)) {
00159     std::cout<<"Unknown output event " << std::endl;  
00160     return;
00161   }
00162   faudes::Idx fev= dev->Outputs().Index(testEvent);
00163   dev->WriteOutput(fev);
00164   dev->FlushOutputs();
00165 }
00166 
00167 
00168 // poll input events
00169 void PollInputEvent(vDevice* dev){
00170   std::cout<<"ReadInputs: time (secs) to monitor input events: ";    
00171   int time_all;
00172   std::cin>>time_all;
00173   time_all*=1000; // convert to msecs
00174   std::cout<<"ReadEvents: time (msecs) to sleep between two polls: ";    
00175   int  time_delta;
00176   std::cin>>time_delta;
00177   // reset all input data so far
00178   dev->Reset();
00179   // report performace, part 1
00180   struct timeval time_start, time_stop;
00181   gettimeofday(&time_start,NULL);
00182 
00183   // loop until time is up
00184   for(int time_togo=time_all; time_togo>0; time_togo-=time_delta) {
00185     Idx sev=dev->ReadInput();
00186     if(sev!=0) 
00187       std::cout<<"ReadInputs: event " << dev->Inputs().SymbolicName(sev) << std::endl;
00188     usleep(1000*time_delta); 
00189   };
00190 
00191   // report performance, part2
00192   gettimeofday(&time_stop,NULL);
00193   double time_diff= ( time_stop.tv_sec - time_start.tv_sec
00194     + (time_stop.tv_usec - time_start.tv_usec) / 1000000.0 ) * 1000.0;
00195   double time_sleep=time_all; 
00196   std::cout << "# performance: overall time: " << time_diff << "ms" << std::endl;
00197   std::cout << "# performance: sleep time:   " << time_sleep << "ms" << std::endl;
00198   std::cout << "# performance: process time per loop:   " << 
00199     (time_diff - time_sleep) / (time_all/time_delta)<< "ms" << std::endl;
00200 }
00201 
00202 // WaitInputEvent(vDevice* dev)
00203 void WaitInputEvent(vDevice* dev){
00204   std::cout<<"Enter max. duration (in faudes-time units) to wait for a input-event to occur"<<std::endl;
00205   std::cout<<"Note: 1 faudes-time unit is configured to " << dev->TimeScale() << " msecs" <<std::endl;
00206   tpTime::Type duration;
00207   std::cin>>duration;
00208   EventSet occuredEvents;
00209   //wait for input-event to occur
00210   dev->WaitInputs(duration); 
00211   //identify occured events
00212   while(Idx sev=dev->ReadInput()) occuredEvents.Insert(sev); 
00213   //report occured events
00214   if(!occuredEvents.Empty()) std::cout << occuredEvents.ToString();
00215   else std::cout<<"No event recognized";
00216 }
00217 
00218 // FlushInputEvent(vDevice* dev)
00219 void FlushInputEvents(vDevice* dev){
00220   //identify occured events
00221   EventSet occuredEvents;
00222   while(Idx sev=dev->ReadInput()) occuredEvents.Insert(sev); 
00223   //report occured events
00224   if(!occuredEvents.Empty()) std::cout << occuredEvents.ToString();
00225   else std::cout<<"No event recognized";
00226 }
00227 
00228 
00229 //////////////////////////////////////////////////////////////
00230 //User-Interface loop
00231 
00232 int main(int argc, char* argv[]) {
00233 
00234   // install my signal handler
00235   signal(SIGTERM, catch_signal);
00236   signal(SIGINT, catch_signal);
00237   signal(SIGQUIT, catch_signal);
00238   signal(SIGHUP, catch_signal);
00239   signal(SIGABRT, catch_signal);
00240 
00241   // first argument has to be filename
00242   if(argc!=2) {
00243     std::cerr << "iomonitor: " << FDVersionString()  << std::endl;
00244     std::cerr << "usage: iomonitor <device-file>" << std::endl;
00245     return -1;
00246   }
00247 
00248   //initialize vDevice
00249   FD_DH("Initialize vDevice");
00250   vDevice* dev;
00251   dev=vDevice::FromFile(std::string(argv[1]));
00252   sDevice* sdev=dynamic_cast<sDevice*>(dev);
00253 
00254   //start vDevice
00255   dev->Start();
00256 
00257   //loop until device is up
00258   while(dev->Status()!=vDevice::Up){;}
00259 
00260   // loop until user terminates
00261   while(true) {
00262 
00263   // set up console userinterface
00264   std::cout << std::endl;
00265   std::cout << "# iomonitor commands are:" << std::endl;
00266   std::cout << "#   read faudes events via wait          (re)" << std::endl;
00267   std::cout << "#   read faudes events via polling       (rep)" << std::endl;
00268   std::cout << "#   flush faudes events                  (rf)" << std::endl;
00269   if(sdev) std::cout << "#   read signal value by bitaddress      (rv)" << std::endl;
00270   std::cout << "#   write faudes event               (we)" << std::endl;
00271   if(sdev) std::cout << "#   write signal value by bitaddress     (wv)" << std::endl;
00272   std::cout << "#   device time                    (time)" << std::endl;
00273   std::cout << "#   reset device                   (reset)" << std::endl;
00274   std::cout << "#   list all device events             (list) " << std::endl;
00275   std::cout << "#   exit                               (exit) " << std::endl;
00276   std::cout << ">";
00277   // get user-choice
00278   std::string choice;
00279   std::cin >> choice;
00280   //execute user-choice
00281   if(choice=="exit") break;
00282   if(choice=="reset") {dev->Reset();};
00283   if(choice=="time") ReadTime(dev);
00284   if(choice=="list") ListEvents(dev); 
00285   if(sdev && choice=="rv") ReadSignalValue(sdev);   
00286   if(choice=="rp") PollInputEvent(dev);
00287   if(choice=="re") WaitInputEvent(dev);
00288   if(choice=="rf") FlushInputEvents(dev);
00289   if(sdev && choice=="wv") WriteSignalValue(sdev);  
00290   if(choice=="we") WriteOutputEvent(dev); 
00291 
00292   }
00293   
00294   std::cout << "# iomonitor: done " << std::endl;
00295   std::cout << "##########################################" << std::endl;
00296 
00297  
00298   FD_DH("Stopping vDevice");
00299   //stop background thread
00300   
00301   dev->Stop();
00302   
00303   return 0;
00304 }
00305 
00306 
00307 

libFAUDES 2.20s --- 2011.10.12 --- c++ source docu by doxygen