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

libFAUDES 2.22k --- 2013.04.02 --- c++ source docu by doxygen