iomonitor.cppGo 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 < 10 ? "0" : "") << 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 < 10 ? "0" : "") << 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 // poll input signals 00126 void PollInputSignals(sDevice* sdev){ 00127 std::cout<<"ReadInputs: time (secs) to monitor input signals: "; 00128 int time_all; 00129 std::cin>>time_all; 00130 time_all*=1000; // convert to msecs 00131 std::cout<<"ReadEvents: time (msecs) to sleep between two polls: "; 00132 int time_delta; 00133 std::cin>>time_delta; 00134 // reset all input data so far 00135 sdev->Reset(); 00136 // report performace, part 1 00137 struct timeval time_start, time_stop; 00138 gettimeofday(&time_start,NULL); 00139 00140 // declare static buffer 00141 static bool* samplePrevious=0; 00142 static bool* sampleCurrent=0; 00143 static int sampleSize=-1; 00144 // allocate memory for buffer 00145 if(sampleSize != sdev->MaxBitAddress()+1) { 00146 sampleSize = sdev->MaxBitAddress()+1; 00147 if(samplePrevious!=0) delete samplePrevious; 00148 if(sampleCurrent!=0) delete sampleCurrent; 00149 samplePrevious= new bool[sampleSize]; 00150 sampleCurrent= new bool[sampleSize]; 00151 } 00152 // reset buffer 00153 for(int bit=0; bit<sampleSize; bit++) { 00154 samplePrevious[bit]=false; 00155 sampleCurrent[bit]=false; 00156 } 00157 00158 // loop until time is up 00159 bool edges=true; 00160 for(int time_togo=time_all; time_togo>0; time_togo-=time_delta) { 00161 // read 00162 for(int bit=0; bit<sampleSize; bit++) { 00163 sampleCurrent[bit]=sdev->ReadSignal(bit); 00164 if(sampleCurrent[bit] != samplePrevious[bit]) edges=true; 00165 } 00166 // report 00167 if(edges) { 00168 std::cout << "% ###############################################################" << std::endl; 00169 for(int bit=0; bit<sampleSize; bit++) { 00170 std::cout<< "@"<< (bit < 10 ? "0" : "") << bit << ":" << sampleCurrent[bit]; 00171 if(sampleCurrent[bit] != samplePrevious[bit]) 00172 std::cout << "! "; 00173 else 00174 std::cout << " "; 00175 if((bit%8)==7 || bit+1==sampleSize) std::cout << std::endl; 00176 } 00177 } 00178 // copy 00179 for(int bit=0; bit<sampleSize; bit++) { 00180 samplePrevious[bit]=sampleCurrent[bit]; 00181 } 00182 // clear edge detection 00183 edges=0; 00184 // sleep 00185 faudes_usleep(1000*time_delta); 00186 }; 00187 00188 // report performance, part2 00189 gettimeofday(&time_stop,NULL); 00190 double time_diff= ( time_stop.tv_sec - time_start.tv_sec 00191 + (time_stop.tv_usec - time_start.tv_usec) / 1000000.0 ) * 1000.0; 00192 double time_sleep=time_all; 00193 std::cout << "# performance: overall time: " << time_diff << "ms" << std::endl; 00194 std::cout << "# performance: sleep time: " << time_sleep << "ms" << std::endl; 00195 std::cout << "# performance: process time per loop: " << 00196 (time_diff - time_sleep) / (time_all/time_delta)<< "ms" << std::endl; 00197 } 00198 00199 // write signal value 00200 void WriteSignalValue(sDevice* sdev) { 00201 int bit, val; 00202 std::cout<<"WriteValue: enter bit address (or -1 to exit): "; 00203 std::cin>>bit; 00204 if(bit<0) return; 00205 std::cout<<"WriteValue: enter value (or -1 to exit): "; 00206 std::cin>>val; 00207 if(val<0) return; 00208 std::cout<<"WriteValue: setting output " << bit << " to value " << val << std::endl; 00209 sdev->WriteSignal(bit,val!=0); 00210 } 00211 00212 ////////////////////////////////////////////////////////////// 00213 //Event-handling 00214 00215 // execute output event 00216 void WriteOutputEvent(vDevice* dev) { 00217 std::cout<<"WriteOutput: enter event by name: "; 00218 std::string testEvent; 00219 std::cin>>testEvent; 00220 if(!dev->Outputs().Exists(testEvent)) { 00221 std::cout<<"Unknown output event " << std::endl; 00222 return; 00223 } 00224 faudes::Idx fev= dev->Outputs().Index(testEvent); 00225 dev->WriteOutput(fev); 00226 dev->FlushOutputs(); 00227 } 00228 00229 00230 // poll input events 00231 void PollInputEvents(vDevice* dev){ 00232 std::cout<<"ReadInputs: time (secs) to monitor input events: "; 00233 int time_all; 00234 std::cin>>time_all; 00235 time_all*=1000; // convert to msecs 00236 std::cout<<"ReadEvents: time (msecs) to sleep between two polls: "; 00237 int time_delta; 00238 std::cin>>time_delta; 00239 // reset all input data so far 00240 dev->Reset(); 00241 // report performace, part 1 00242 struct timeval time_start, time_stop; 00243 gettimeofday(&time_start,NULL); 00244 00245 // loop until time is up 00246 for(int time_togo=time_all; time_togo>0; time_togo-=time_delta) { 00247 Idx sev=dev->ReadInput(); 00248 if(sev!=0) 00249 std::cout<<"ReadInputs: event " << dev->Inputs().SymbolicName(sev) << std::endl; 00250 faudes_usleep(1000*time_delta); 00251 }; 00252 00253 // report performance, part2 00254 gettimeofday(&time_stop,NULL); 00255 double time_diff= ( time_stop.tv_sec - time_start.tv_sec 00256 + (time_stop.tv_usec - time_start.tv_usec) / 1000000.0 ) * 1000.0; 00257 double time_sleep=time_all; 00258 std::cout << "# performance: overall time: " << time_diff << "ms" << std::endl; 00259 std::cout << "# performance: sleep time: " << time_sleep << "ms" << std::endl; 00260 std::cout << "# performance: process time per loop: " << 00261 (time_diff - time_sleep) / (time_all/time_delta)<< "ms" << std::endl; 00262 } 00263 00264 // WaitInputEvent(vDevice* dev) 00265 void WaitInputEvent(vDevice* dev){ 00266 std::cout<<"Enter max. duration (in faudes-time units) to wait for a input-event to occur"<<std::endl; 00267 std::cout<<"Note: 1 faudes-time unit is configured to " << dev->TimeScale() << " msecs" <<std::endl; 00268 tpTime::Type duration; 00269 std::cin>>duration; 00270 EventSet occuredEvents; 00271 //wait for input-event to occur 00272 dev->WaitInputs(duration); 00273 //identify occured events 00274 while(Idx sev=dev->ReadInput()) occuredEvents.Insert(sev); 00275 //report occured events 00276 if(!occuredEvents.Empty()) std::cout << occuredEvents.ToString(); 00277 else std::cout<<"No event recognized"; 00278 } 00279 00280 // FlushInputEvent(vDevice* dev) 00281 void FlushInputEvents(vDevice* dev){ 00282 //identify occured events 00283 EventSet occuredEvents; 00284 while(Idx sev=dev->ReadInput()) occuredEvents.Insert(sev); 00285 //report occured events 00286 if(!occuredEvents.Empty()) std::cout << occuredEvents.ToString(); 00287 else std::cout<<"No event recognized"; 00288 } 00289 00290 00291 ////////////////////////////////////////////////////////////// 00292 //User-Interface loop 00293 00294 int main(int argc, char* argv[]) { 00295 00296 // debugging autoregistration :-( 00297 /* 00298 std::cerr << " ====== auto registration " << std::endl; 00299 TypeRegistry::G()->Write(); 00300 std::cerr << " ====== registration " << std::endl; 00301 AutoRegisterType<cDevice> gRtiLocalIOReg("ComediDevice"); 00302 TypeRegistry::G()->Write(); 00303 */ 00304 00305 // install my signal handler 00306 faudes_termsignal(catch_signal); 00307 00308 // first argument has to be filename 00309 if(argc!=2) { 00310 std::cerr << "iomonitor: " << VersionString() << std::endl; 00311 std::cerr << "usage: iomonitor <device-file>" << std::endl; 00312 return -1; 00313 } 00314 00315 #ifdef FAUDES_NETWORK 00316 #ifdef FAUDES_WINDOWS 00317 // initialise winsocks 00318 WSADATA wsaData; 00319 if(WSAStartup(MAKEWORD(2,2), &wsaData)!=0) { 00320 std::cerr << "iomonitor: failed to initialize winsocks" << std::endl; 00321 return -1; 00322 } 00323 #endif 00324 #endif 00325 00326 //initialize vDevice 00327 FD_DH("Initialize vDevice"); 00328 std::cout << "iomonitor: instantiate device from file" << std::endl; 00329 vDevice* dev; 00330 dev=vDevice::FromFile(std::string(argv[1])); 00331 sDevice* sdev=dynamic_cast<sDevice*>(dev); 00332 00333 //start vDevice 00334 std::cout << "iomonitor: starting device " << std::endl; 00335 dev->Start(); 00336 00337 //loop until device is up 00338 while(dev->Status()!=vDevice::Up){;} 00339 00340 // loop until user terminates 00341 while(true) { 00342 00343 // set up cheap console userinterface 00344 std::cout << std::endl; 00345 std::cout << std::endl; 00346 std::cout << "# iomonitor commands are:" << std::endl; 00347 std::cout << "#" << std::endl; 00348 std::cout << "# read faudes event via wait (re)" << std::endl; 00349 std::cout << "# read faudes events via polling (pe)" << std::endl; 00350 std::cout << "# flush faudes input events (fe)" << std::endl; 00351 if(sdev) std::cout << "# read signal value by bitaddress (rs)" << std::endl; 00352 if(sdev) std::cout << "# read signal values via polling (ps)" << std::endl; 00353 std::cout << "#" << std::endl; 00354 std::cout << "# write faudes event (we)" << std::endl; 00355 if(sdev) std::cout << "# write signal value by bitaddress (ws)" << std::endl; 00356 std::cout << "#" << std::endl; 00357 std::cout << "# device time (time)" << std::endl; 00358 std::cout << "# reset device (reset)" << std::endl; 00359 std::cout << "# list all device events (list) " << std::endl; 00360 std::cout << "# exit (exit) " << std::endl; 00361 std::cout << "#" << std::endl; 00362 std::cout << ">"; 00363 // get user-choice 00364 std::string choice; 00365 std::cin >> choice; 00366 //execute user-choice 00367 if(choice=="exit") break; 00368 if(choice=="reset") {dev->Reset();}; 00369 if(choice=="time") ReadTime(dev); 00370 if(choice=="list") ListEvents(dev); 00371 if(choice=="pe") PollInputEvents(dev); 00372 if(choice=="re") WaitInputEvent(dev); 00373 if(choice=="fe") FlushInputEvents(dev); 00374 if(sdev && choice=="rs") ReadSignalValue(sdev); 00375 if(sdev && choice=="ps") PollInputSignals(sdev); 00376 if(choice=="we") WriteOutputEvent(dev); 00377 if(sdev && choice=="ws") WriteSignalValue(sdev); 00378 00379 } 00380 00381 std::cout << "# iomonitor: done " << std::endl; 00382 std::cout << "##########################################" << std::endl; 00383 00384 00385 FD_DH("Stopping vDevice"); 00386 00387 //stop background thread 00388 dev->Stop(); 00389 00390 return 0; 00391 } 00392 00393 00394 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |