iomonitor.cpp
Go to the documentation of this file.
1 /** @file iomonitor.cpp Test utility for IO devices
2 
3 
4 This tutorial demonstrates elementary access to external signals
5 via the class faudes::vDevice. It can be used as a test uitility
6 for device configuration.
7 
8 
9 @ingroup Tutorials
10 
11 @include iomonitor.cpp
12 
13 */
14 
15 
16 #include "libfaudes.h"
17 
18 #include <signal.h>
19 
20 using namespace faudes;
21 
22 ///////////////////////////////////////////////////////
23 // clean exit on signals
24 
25 // iomonitor clean-up on exit
26 void iomonitor_exit(void);
27 
28 // signal handler recursion flag
29 volatile sig_atomic_t signal_in_progress = 0;
30 
31 // signal handler to stop devices
32 void catch_signal(int sig) {
33  // detect recursion, pass on
34  if(signal_in_progress) raise(sig);
36  // report
37  std::cerr << "iomonitor: signal: " << faudes_strsignal(sig) << std::endl;
38  // call my exit function
40  // re-install default handler
41  signal(sig, SIG_DFL);
42  // pass on signal
43  raise(sig);
44 }
45 
46 // iomonitor clean-up on exit
47 void iomonitor_exit(void) {
48  // stop all devices
50 }
51 
52 
53 ///////////////////////////////////////////////////////
54 //Basic handling
55 
56 // list all known events
57 void ListEvents(const vDevice* dev) {
58  std::cout<< "% ###############################################################" << std::endl;
59  std::cout<< "% # InputEvents" << std::endl;
60  dev->Inputs().Write();
61  std::cout<< "% ###############################################################" << std::endl;
62  std::cout<< "% # OutputEvents " << std::endl;
63  dev->Outputs().Write();
64  std::cout<< "% ###############################################################" << std::endl;
65 }
66 
67 
68 ///////////////////////////////////////////////////////
69 // Query Time
70 
71 // read time
72 void ReadTime(vDevice* dev) {
73 
74  // read and report
75  std::cout << "% ###############################################################" << std::endl;
76  std::cout << "% # ReadTime: current time in ftu: " << dev->CurrentTime() << std::endl;
77  std::cout << "% # ReadTime: using scale: " << dev->TimeScale() << std::endl;
78 
79 }
80 
81 
82 ///////////////////////////////////////////////////////
83 //Signal-I/O
84 
85 // read signal value
87  // declare static buffer
88  static bool* samplePrevious=0;
89  static bool* sampleCurrent=0;
90  static int sampleSize=-1;
91  // allocate memory for buffer
92  if(sampleSize != dev->MaxBitAddress()+1) {
93  sampleSize = dev->MaxBitAddress()+1;
94  if(samplePrevious!=0) delete samplePrevious;
95  if(sampleCurrent!=0) delete sampleCurrent;
96  samplePrevious= new bool[sampleSize];
97  sampleCurrent= new bool[sampleSize];
98  }
99  // read and report
100  std::cout << "% ###############################################################" << std::endl;
101  for(int bit=0; bit<sampleSize; bit++) {
102  samplePrevious[bit]=sampleCurrent[bit];
103  }
104  for(int bit=0; bit<sampleSize; bit++) {
105  sampleCurrent[bit]=dev->ReadSignal(bit);
106  }
107  std::cout << "% # ReadValue: current input reading: " << std::endl;
108  for(int bit=0; bit<sampleSize; bit++) {
109  std::cout<< "@" << (bit < 10 ? "0" : "") << bit << ":" << sampleCurrent[bit] << " ";
110  if((bit%8)==7 || bit+1==sampleSize) std::cout << std::endl;
111  }
112  std::cout <<"% # ReadValue: edges wrt previous reading: " << std::endl;
113  int cnt =0;
114  for(int bit=0; bit<sampleSize; bit++) {
115  if(samplePrevious[bit]!=sampleCurrent[bit]) {
116  std::cout<< "@"<< (bit < 10 ? "0" : "") << bit << ":" << sampleCurrent[bit] << " ";
117  if((cnt%8)==7 || bit+1==sampleSize) std::cout << std::endl;
118  cnt+=1;
119  }
120  }
121  std::cout << "% ###############################################################" << std::endl;
122 }
123 
124 
125 // poll input signals
127  std::cout<<"ReadInputs: time (secs) to monitor input signals: ";
128  faudes_mstime_t time_all;
129  std::cin>>time_all;
130  time_all*=1000; // convert to msecs
131  std::cout<<"ReadEvents: time (msecs) to sleep between two polls: ";
132  faudes_mstime_t time_delta;
133  std::cin>>time_delta;
134  // reset all input data so far
135  sdev->Reset();
136  // report performace, part 1
137  faudes_systime_t time_start, time_stop;
138  faudes_gettimeofday(&time_start);
139 
140  // declare static buffer
141  static bool* samplePrevious=0;
142  static bool* sampleCurrent=0;
143  static int sampleSize=-1;
144  // allocate memory for buffer
145  if(sampleSize != sdev->MaxBitAddress()+1) {
146  sampleSize = sdev->MaxBitAddress()+1;
147  if(samplePrevious!=0) delete samplePrevious;
148  if(sampleCurrent!=0) delete sampleCurrent;
149  samplePrevious= new bool[sampleSize];
150  sampleCurrent= new bool[sampleSize];
151  }
152  // reset buffer
153  for(int bit=0; bit<sampleSize; bit++) {
154  samplePrevious[bit]=false;
155  sampleCurrent[bit]=false;
156  }
157 
158  // loop until time is up
159  bool edges=true;
160  for(int time_togo=time_all; time_togo>0; time_togo-=time_delta) {
161  // read
162  for(int bit=0; bit<sampleSize; bit++) {
163  sampleCurrent[bit]=sdev->ReadSignal(bit);
164  if(sampleCurrent[bit] != samplePrevious[bit]) edges=true;
165  }
166  // report
167  if(edges) {
168  std::cout << "% ###############################################################" << std::endl;
169  for(int bit=0; bit<sampleSize; bit++) {
170  std::cout<< "@"<< (bit < 10 ? "0" : "") << bit << ":" << sampleCurrent[bit];
171  if(sampleCurrent[bit] != samplePrevious[bit])
172  std::cout << "! ";
173  else
174  std::cout << " ";
175  if((bit%8)==7 || bit+1==sampleSize) std::cout << std::endl;
176  }
177  }
178  // copy
179  for(int bit=0; bit<sampleSize; bit++) {
180  samplePrevious[bit]=sampleCurrent[bit];
181  }
182  // clear edge detection
183  edges=0;
184  // sleep
185  faudes_usleep(1000*time_delta);
186  };
187 
188  // report performance, part2
189  faudes_gettimeofday(&time_stop);
190  faudes_mstime_t diffms;
191  faudes_diffsystime(time_stop,time_start,&diffms);
192  std::cout << "# performance: overall time: " << diffms << "ms" << std::endl;
193  std::cout << "# performance: sleep time: " << time_all << "ms" << std::endl;
194  std::cout << "# performance: process time per loop: " <<
195  ((double) (diffms - time_all)) / (time_all/time_delta)<< "ms" << std::endl;
196 }
197 
198 // write signal value
200  int bit, val;
201  std::cout<<"WriteValue: enter bit address (or -1 to exit): ";
202  std::cin>>bit;
203  if(bit<0) return;
204  std::cout<<"WriteValue: enter value (or -1 to exit): ";
205  std::cin>>val;
206  if(val<0) return;
207  std::cout<<"WriteValue: setting output " << bit << " to value " << val << std::endl;
208  sdev->WriteSignal(bit,val!=0);
209 }
210 
211 //////////////////////////////////////////////////////////////
212 //Event-handling
213 
214 // execute output event
216  std::cout<<"WriteOutput: enter event by name: ";
217  std::string testEvent;
218  std::cin>>testEvent;
219  if(!dev->Outputs().Exists(testEvent)) {
220  std::cout<<"Unknown output event " << std::endl;
221  return;
222  }
223  faudes::Idx fev= dev->Outputs().Index(testEvent);
224  dev->WriteOutput(fev);
225  dev->FlushOutputs();
226 }
227 
228 
229 // poll input events
231  std::cout<<"ReadInputs: time (secs) to monitor input events: ";
232  faudes_mstime_t time_all;
233  std::cin>>time_all;
234  time_all*=1000; // convert to msecs
235  std::cout<<"ReadEvents: time (msecs) to sleep between two polls: ";
236  faudes_mstime_t time_delta;
237  std::cin>>time_delta;
238  // reset all input data so far
239  dev->Reset();
240  // report performace, part 1
241  faudes_systime_t time_start, time_stop;
242  faudes_gettimeofday(&time_start);
243 
244  // loop until time is up
245  for(int time_togo=time_all; time_togo>0; time_togo-=time_delta) {
246  Idx sev=dev->ReadInput();
247  if(sev!=0)
248  std::cout<<"ReadInputs: event " << dev->Inputs().SymbolicName(sev) << std::endl;
249  faudes_usleep(1000*time_delta);
250  };
251 
252  // report performance, part2
253  faudes_gettimeofday(&time_stop);
254  faudes_mstime_t diffms;
255  faudes_diffsystime(time_stop,time_start,&diffms);
256  std::cout << "# performance: overall time: " << diffms << "ms" << std::endl;
257  std::cout << "# performance: sleep time: " << time_all << "ms" << std::endl;
258  std::cout << "# performance: process time per loop: " <<
259  ((double) (diffms - time_all)) / (time_all/time_delta)<< "ms" << std::endl;
260 
261 }
262 
263 // WaitInputEvent(vDevice* dev)
265  std::cout<<"Enter max. duration (in faudes-time units) to wait for a input-event to occur"<<std::endl;
266  std::cout<<"Note: 1 faudes-time unit is configured to " << dev->TimeScale() << " msecs" <<std::endl;
267  Time::Type duration;
268  std::cin>>duration;
269  EventSet occuredEvents;
270  //wait for input-event to occur
271  dev->WaitInputs(duration);
272  //identify occured events
273  while(Idx sev=dev->ReadInput()) occuredEvents.Insert(sev);
274  //report occured events
275  if(!occuredEvents.Empty()) std::cout << occuredEvents.ToString();
276  else std::cout<<"No event recognized";
277 }
278 
279 // FlushInputEvent(vDevice* dev)
281  //identify occured events
282  EventSet occuredEvents;
283  while(Idx sev=dev->ReadInput()) occuredEvents.Insert(sev);
284  //report occured events
285  if(!occuredEvents.Empty()) std::cout << occuredEvents.ToString();
286  else std::cout<<"No event recognized";
287 }
288 
289 
290 //////////////////////////////////////////////////////////////
291 //User-Interface loop
292 
293 int main(int argc, char* argv[]) {
294 
295  // debugging autoregistration :-(
296  /*
297  std::cerr << " ====== auto registration " << std::endl;
298  TypeRegistry::G()->Write();
299  std::cerr << " ====== registration " << std::endl;
300  AutoRegisterType<cDevice> gRtiLocalIOReg("ComediDevice");
301  TypeRegistry::G()->Write();
302  */
303 
304  // install my signal handler
306 
307  // first argument has to be filename
308  if(argc!=2) {
309  std::cerr << "iomonitor: " << VersionString() << std::endl;
310  std::cerr << "usage: iomonitor <device-file>" << std::endl;
311  return -1;
312  }
313 
314 #ifdef FAUDES_NETWORK
315 #ifdef FAUDES_WINDOWS
316  // initialise winsocks
317  WSADATA wsaData;
318  if(WSAStartup(MAKEWORD(2,2), &wsaData)!=0) {
319  std::cerr << "iomonitor: failed to initialize winsocks" << std::endl;
320  return -1;
321  }
322 #endif
323 #endif
324 
325  //initialize vDevice
326  FD_DH("Initialize vDevice");
327  std::cout << "iomonitor: instantiate device from file" << std::endl;
328  vDevice* dev;
329  dev=vDevice::FromFile(std::string(argv[1]));
330  sDevice* sdev=dynamic_cast<sDevice*>(dev);
331 
332  //start vDevice
333  std::cout << "iomonitor: starting device " << std::endl;
334  dev->Start();
335 
336  //loop until device is up
337  while(dev->Status()!=vDevice::Up){;}
338 
339  // loop until user terminates
340  while(true) {
341 
342  // set up cheap console userinterface
343  std::cout << std::endl;
344  std::cout << std::endl;
345  std::cout << "# iomonitor commands are:" << std::endl;
346  std::cout << "#" << std::endl;
347  std::cout << "# read faudes event via wait (re)" << std::endl;
348  std::cout << "# read faudes events via polling (pe)" << std::endl;
349  std::cout << "# flush faudes input events (fe)" << std::endl;
350  if(sdev) std::cout << "# read signal value by bitaddress (rs)" << std::endl;
351  if(sdev) std::cout << "# read signal values via polling (ps)" << std::endl;
352  std::cout << "#" << std::endl;
353  std::cout << "# write faudes event (we)" << std::endl;
354  if(sdev) std::cout << "# write signal value by bitaddress (ws)" << std::endl;
355  std::cout << "#" << std::endl;
356  std::cout << "# device time (time)" << std::endl;
357  std::cout << "# reset device (reset)" << std::endl;
358  std::cout << "# list all device events (list) " << std::endl;
359  std::cout << "# exit (exit) " << std::endl;
360  std::cout << "#" << std::endl;
361  std::cout << ">";
362  // get user-choice
363  std::string choice;
364  std::cin >> choice;
365  //execute user-choice
366  if(choice=="exit") break;
367  if(choice=="reset") {dev->Reset();};
368  if(choice=="time") ReadTime(dev);
369  if(choice=="list") ListEvents(dev);
370  if(choice=="pe") PollInputEvents(dev);
371  if(choice=="re") WaitInputEvent(dev);
372  if(choice=="fe") FlushInputEvents(dev);
373  if(sdev && choice=="rs") ReadSignalValue(sdev);
374  if(sdev && choice=="ps") PollInputSignals(sdev);
375  if(choice=="we") WriteOutputEvent(dev);
376  if(sdev && choice=="ws") WriteSignalValue(sdev);
377 
378  }
379 
380  std::cout << "# iomonitor: done " << std::endl;
381  std::cout << "##########################################" << std::endl;
382 
383 
384  FD_DH("Stopping vDevice");
385 
386  //stop background thread
387  dev->Stop();
388 
389  return 0;
390 }
391 
392 
393 
const char * faudes_strsignal(int sig)
void faudes_termsignal(void(*sighandler)(int))
void faudes_usleep(long int usec)
void faudes_diffsystime(const faudes_systime_t &end, const faudes_systime_t &begin, faudes_systime_t *res)
bool Exists(const Idx &rIndex) const
void SymbolicName(Idx index, const std::string &rName)
bool Insert(const Idx &rIndex)
Idx Index(const std::string &rName) const
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:170
void Write(const Type *pContext=0) const
Definition: cfl_types.cpp:140
int MaxBitAddress(void) const
Definition: iop_sdevice.h:381
void WriteSignal(int bitaddr, bool value)
virtual void Reset(void)
bool ReadSignal(int bitaddr)
virtual const EventSet & Inputs(void) const
virtual void TimeScale(unsigned int scale)
Definition: iop_vdevice.h:364
static void StopAll(void)
virtual DeviceState Status(void)
Definition: iop_vdevice.h:486
virtual void Stop(void)
virtual void Start(void)
virtual void WriteOutput(Idx output)=0
virtual void Reset(void)
static vDevice * FromFile(const std::string &rFileName)
virtual Idx ReadInput(void)
virtual bool WaitInputs(Time::Type duration)
virtual Time::Type CurrentTime(void)
virtual void FlushOutputs(void)
virtual const EventSet & Outputs(void) const
bool Empty(void) const
Definition: cfl_baseset.h:1841
int main(int argc, char *argv[])
Definition: iomonitor.cpp:293
void PollInputSignals(sDevice *sdev)
Definition: iomonitor.cpp:126
void WaitInputEvent(vDevice *dev)
Definition: iomonitor.cpp:264
void ReadTime(vDevice *dev)
Definition: iomonitor.cpp:72
void iomonitor_exit(void)
Definition: iomonitor.cpp:47
void ListEvents(const vDevice *dev)
Definition: iomonitor.cpp:57
void FlushInputEvents(vDevice *dev)
Definition: iomonitor.cpp:280
volatile sig_atomic_t signal_in_progress
Definition: iomonitor.cpp:29
void WriteOutputEvent(vDevice *dev)
Definition: iomonitor.cpp:215
void PollInputEvents(vDevice *dev)
Definition: iomonitor.cpp:230
void WriteSignalValue(sDevice *sdev)
Definition: iomonitor.cpp:199
void ReadSignalValue(sDevice *dev)
Definition: iomonitor.cpp:86
void catch_signal(int sig)
Definition: iomonitor.cpp:32
#define FD_DH(message)
Definition: iop_vdevice.h:27
uint32_t Idx
std::string VersionString()
Definition: cfl_utils.cpp:131

libFAUDES 2.33b --- 2025.05.07 --- c++ api documentaion by doxygen