iop_sdevice.h
Go to the documentation of this file.
1/** @file iop_sdevice.h Virtual device for signal based io */
2
3/*
4 FAU Discrete Event Systems Library (libfaudes)
5
6 Copyright (C) 2008, Thomas Moor
7 Exclusive copyright is granted to Klaus Schmidt
8
9*/
10
11
12
13#ifndef FAUDES_SDEVICE_H
14#define FAUDES_SDEVICE_H
15
16#include "corefaudes.h"
17#include "iop_vdevice.h"
18
19
20
21namespace faudes {
22
23
24/**
25 * Configuration of a signal based output mapping.
26 *
27 * An output mapping consists of a list of actions that to be performed when the
28 * event is executed. Each action may set or clear the physical output line
29 * specified by an abstract bitaddress.
30 *
31 */
32
34
36
37public:
38
39 /** Default constructor (no actions at all) */
41
42 /** Copy - constructor */
44 { DoAssign(rOtherAttr); };
45
46 /** Test for default value (never) */
47 virtual bool IsDefault(void) const {return false;};
48
49 /** Clear */
50 virtual void Clear(void) {mActions.clear();};
51
52 /** Enum for action */
53 typedef enum { Set, Clr, Inv } Value;
54
55 /** Typedef for a single output action */
56 class Action {
57 public:
58 Action(void) {mBit=0;mValue=Clr;};
59 int mBit; //// Bitaddress (numeric)
60 Value mValue; //// Value to set (enum: set,clr,inv)
61 };
62
63 /** List of actions to perform */
64 std::vector<Action> mActions;
65
66 protected:
67
68 /**
69 * Copy method
70 *
71 * @param rSrcAttr
72 * Source to copy from
73 */
74 void DoAssign(const AttributeSignalOutput& rSrcAttr);
75
76 /**
77 * Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
78 *
79 * If the current token indicates an output mapping, the method reads that
80 * section. Else it does nothing. Exceptions may only be thrown
81 * on invalid data within the section. The label argument is ignored, we the hardcoded
82 * output for output device attributes. The context argument is ignored.
83 *
84 * @param rTr
85 * TokenReader to read from
86 * @param rLabel
87 * Section to read
88 * @param pContext
89 * Read context to provide contextual information
90 *
91 * @exception Exception
92 * - IO error (id 1)
93 */
94 virtual void DoRead(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
95
96 /**
97 * Writes the attribute to TokenWriter, see AttributeVoid for public wrappers.
98 *
99 * Writes the output mapping data. The label argument is ignored, we use
100 * the hardcoded section "Output". The context argument is ignored.
101 *
102 * @param rTw
103 * TokenWriter to write to
104 * @param rLabel
105 * Section to write
106 * @param pContext
107 * Read context to provide contextual information
108 *
109 * @exception Exception
110 * - IO error (id 2)
111 */
112 virtual void DoWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
113
114}; // end class AttributeSignalOutput
115
116
117
118
119
120
121/**
122 * Configuration of a signal based input mapping.
123 *
124 * A input mapping consists of a list of abstract bitaddresses with an
125 * edge polarity each. When on one of respecive physical input lines an edge
126 * with matching priority is sensed, the logical event is triggered.
127 *
128 */
129
131
133
134public:
135
136 /** Default constructor (no triggers) */
138
139 /** Copy constructor */
141 { DoAssign(rOtherAttr); };
142
143 /** Test for default value (never) */
144 virtual bool IsDefault(void) const {return false;};
145
146 /** Clear */
147 virtual void Clear(void) {mTriggers.clear();};
148
149 /** Typedef for a single input trigger */
150 class Trigger {
151 public:
152 Trigger(void) {mBit=0; mPos=false; mNeg=false;};
153 int mBit; //// Bitaddress
154 bool mPos; //// Positive edge triggers event
155 bool mNeg; //// Negative edge triggers event
156 };
157
158 /** List of triggers */
159 std::vector<Trigger> mTriggers;
160
161 protected:
162
163 /**
164 * Copy method
165 *
166 * @param rSrcAttr
167 * Source to copy from
168 */
169 void DoAssign(const AttributeSignalInput& rSrcAttr);
170
171 /**
172 * Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
173 *
174 * If the current token indicates a input mapping, the method reads that
175 * section. Else it does nothing. Exceptions may only be thrown
176 * on invalid data within the section. The label argument is ignored, we use the
177 * hardcoded section "Input" for input attributes. The context argument is ignored.
178 *
179 * @param rTr
180 * TokenReader to read from
181 * @param rLabel
182 * Section to read
183 * @param pContext
184 * Read context to provide contextual information
185 *
186 * @exception Exception
187 * - IO error (id 1)
188 */
189 virtual void DoRead(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
190
191
192 /**
193 * Writes the attribute to TokenWriter, see AttributeVoid for public wrappers.
194 *
195 * Writes the input mapping data.The label argument is ignored, we use the
196 * hardcoded section "Input". The context argument is ignored.
197 *
198 * @param rTw
199 * TokenWriter to write to
200 * @param rLabel
201 * Section to write
202 * @param pContext
203 * Read context to provide contextual information
204 *
205 * @exception Exception
206 * - IO error (id 2)
207 */
208
209 virtual void DoWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
210
211}; // end class AttributeSignalInput
212
213
214
215
216/**
217 * Configuration of a signal based input or output
218 *
219 * This class is derived from the AttributeDeviceEvent to specialise
220 * for signal based input and output mapping.
221 *
222 */
223
225
227
228 public:
229
230 /** Default constructor (no mapping at all) */
232
233 /** Copy constructor */
234 AttributeSignalEvent(const AttributeSignalEvent& rOtherAttr);
235
236 /** Test for default value (never) */
237 virtual bool IsDefault(void) const {return false;};
238
239 /** Clear */
240 virtual void Clear(void) { AttributeDeviceEvent::Clear(); };
241
242 /** Get output mapping */
243 const AttributeSignalOutput* Outputp(void) const {
244 return static_cast<AttributeSignalOutput*>(mpOutputAttribute); };
246 return static_cast<AttributeSignalOutput*>(mpOutputAttribute); };
247
248 /** Get input mapping */
249 const AttributeSignalInput* Inputp(void) const {
250 return static_cast<AttributeSignalInput*>(mpInputAttribute); };
252 return static_cast<AttributeSignalInput*>(mpInputAttribute); };
253
254 protected:
255
256 /** DoAssign */
258 { AttributeDeviceEvent::DoAssign(rSrc);};
259
260 /** Prototype, input (construct on first use static) */
261 static const AttributeSignalInput* InputPrototypep(void);
262
263 /** Prototype, output (construct on first use static) */
264 static const AttributeSignalOutput* OutputPrototypep(void);
265
266}; // class AttributeSignalEvent
267
268
269
270/**
271 * An sDevice implements signal based semantics for faudes events.
272 *
273 * The class is configured by AttributeSignalEvents, which in turn consist of
274 * either a AttributeSignalInput or a AttributeSignalOutput. Thus,
275 * we set and clear output signals for output events, while edges on input
276 * signals trigger input events.
277 *
278 * Sensing edges is done by separate thread that is started by Start().
279 *
280 * This class is still virtual in that it does not provide the code for actually
281 * reading or writing signals. See cDevice and pDevice for derived device classes
282 * that implement digital io via comedi or the parallel printer port, respectively.
283 *
284 * @ingroup IODevicePlugin
285 */
286
287class FAUDES_API sDevice : public vDevice {
288
289 // provide all access to background task
290 friend void* SDeviceSynchro(void*);
291
292 public:
293
294 // have my types
298
299 /**
300 * Default constructor
301 */
302 sDevice(void);
303
304 /**
305 * copy-constructor
306 */
307 sDevice(const sDevice& rOtherDevice);
308
309 /**
310 * Explicit destructor.
311 */
312 virtual ~sDevice(void);
313
314
315 /**
316 * Clear all configuration.
317 * This implies Stop().
318 */
319 virtual void Clear(void);
320
321 /**
322 *
323 * Build up internal data-structure (e.g. signal-event - mapping)
324 *
325 */
326 virtual void Compile(void);
327
328 /**
329 * Insert event as input event.
330 * Note: you can only configure events
331 * while the device is down.
332 *
333 * @param event
334 * Event by name.
335 */
336 void InsInputEvent(const std::string& event);
337
338
339 /**
340 * Add a trigger condition.
341 * Note: you can only add a trigger condition to an
342 * input event; you can only (re)-configure events
343 * while the device is down.
344 *
345 * @param event
346 * Event
347 * @param trigger
348 * Trigger to append
349 */
350 void AppendTrigger(const std::string& event, const Trigger& trigger);
351
352 /**
353 * Insert event as output event.
354 * Note: you can only configure event
355 * while the device is down.
356 *
357 * @param event
358 * Event by name.
359 */
360 void InsOutputEvent(const std::string& event);
361
362 /**
363 * Add an action.
364 * Note: you can only add a actions to an
365 * output event; you can only (re)-configure events
366 * while the device is down.
367 *
368 * @param event
369 * Event
370 * @param action
371 * Action to append
372 */
373 void AppendAction(const std::string& event, const Action& action);
374
375 /**
376 * Report max bit address.
377 *
378 * @return
379 * Set of all configured inputs
380 */
381 int MaxBitAddress(void) const { return mMaxBitAddress;};
382
383
384 /**
385 * Activate the device. This function enables output execution and input reading.
386 * It starts the background thread for edge detection and input event buffer.
387 *
388 * @exception Exception
389 * - Not yet configured (id 551)
390 */
391 virtual void Start(void);
392
393 /**
394 * Deactivate the device. This function disables output execution and input reading.
395 * It stops the backhround thread and resets all output signals to 0.
396 */
397 virtual void Stop(void);
398
399
400 /**
401 * Clear dynamic data and restart device
402 */
403 virtual void Reset(void);
404
405
406 /**
407 * Run output command.
408 *
409 * @exception Exception
410 * - unknown output event (id 65)
411 */
412 virtual void WriteOutput(Idx output);
413
414
415
416 /**
417 * Set output signal.
418 *
419 *
420 * This function provides user level access to output signals.
421 * It executes the virtual pre and post hook methods
422 * and the virtual actual harware access to set the signal level
423 * via DoWriteSignal(int,bool).
424 *
425 * @param bitaddr
426 * Abstract bit address
427 * @param value
428 * True for active/high/1/set;
429 * false for passive/low/0/clr;
430 *
431 */
432 void WriteSignal(int bitaddr, bool value);
433
434 /**
435 * Get input signal.
436 *
437 * This function provides user level access to input signals.
438 * It executes the virtual pre and post hook methods
439 * and the virtual actual harware access to sample an input signal via DoReadSignal(int).
440 *
441 * @param bitaddr
442 * Abstract bit address
443 * @return
444 * True for logic level high;
445 */
446 bool ReadSignal(int bitaddr);
447
448
449 /**
450 * Report cycle time
451 *
452 * @return
453 * Actual cycle time in ussecs
454 */
455
456 virtual int CycleTime() const;
457
458 /**
459 * Set cycle time
460 *
461 * @param cycleTime
462 * Desired cycle time in usecs
463 */
464
465 virtual void CycleTime(int cycleTime);
466
467 protected:
468
469 /** Overall configuration (with actual type) */
471
472 /** Reverse input map: map signal edges to logical event sets */
473 std::map<int, EventSet> mInputPosEdgeIndexMap;
474
475 /** Reverse input map: map signal edges to logical event sets */
476 std::map<int, EventSet> mInputNegEdgeIndexMap;
477
478 /** Reverse output map: map signal addres to events that affect the resp. line */
479 std::map<int, EventSet> mOutputLevelIndexMap;
480
481 /** Address range */
483
484 /**
485 * Writes non-event-related configuration to TokenWriter
486 *
487 * Device data will be written bottom-to-top along the class-hierarchy,
488 * see also vDevice::DoWritePreface.
489 *
490 * Note: in order to keep the outputfile-layout as simple as possible no label will
491 * be used to separate this data-section.
492 *
493 * @param rTw
494 * TokenWriter to write
495 * @param rLabel
496 * Section to write
497 * @param pContext
498 * Context to provide contextual information
499 *
500 * */
501 void DoWritePreface(TokenWriter& rTw, const std::string& rLabel, const Type* pContext=0) const;
502
503 /**
504 * Reads non-event-related configuration from TokenReader
505 *
506 * Device date is read bottom-to-top along the class-hierarchy;
507 * see also vDevice::DoReadPreface.
508 *
509 *
510 * Note: in order to keep the inputfile-layout as simple as possible no label will
511 * be used to separate this data-section.
512 *
513 * @param rTr
514 * TokenReader to read from
515 * @param rLabel
516 * Section to read
517 * @param pContext
518 * Read context to provide contextual information
519 *
520 * */
521 virtual void DoReadPreface(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
522
523 /**
524 * IO Hook, inputs
525 *
526 * The background thread calls this hook before reading input signals.
527 * You may reimplement this method to e.g. prepare a process image.
528 *
529 * @return
530 * True on success, false on error
531 *
532 */
533 virtual bool DoReadSignalsPre(void) {return true;};
534
535 /**
536 * IO Hook, inputs
537 *
538 * The background thread calls this hook after reading input signals.
539 * You may reimplement this method to e.g. release a process image.
540 *
541 *
542 */
543 virtual void DoReadSignalsPost(void) {};
544
545 /**
546 * Sample input signal.
547 *
548 * Reimplement this function to implements actual harware access to sample an input signal.
549 * This function gets
550 * called from the periodic background thread to sense edges.
551 * It is guaranteed that the pre-hook was called befor and returned "true".
552 * The post-hook will be invoked after relevant signals have been sampled.
553 *
554 * @param bitaddr
555 * Abstract bit address
556 * @return
557 * True for logic level high;
558 */
559 virtual bool DoReadSignal(int bitaddr)=0;
560
561 /**
562 * IO Hook, outputs
563 *
564 * This hook is invoked before writing a signal value.
565 * You may reimplement this method to e.g. assemble a process image.
566 *
567 * @return
568 * True on success, false on error
569 *
570 */
571 virtual bool DoWriteSignalsPre(void) {return true;};
572
573 /**
574 * IO Hook, output
575 *
576 * This hook is invoked after writing a signal value.
577 * You may reimplement this method to e.g. assemble a process image.
578 *
579 *
580 */
581 virtual void DoWriteSignalsPost(void) {};
582
583 /**
584 * Reimplement this function in a derived class for actual harware access
585 * to set or clear an output signal. Hooks are executed appropriately.
586 * If the device is configured for synchronous write, the background task
587 * is used to write signals. Otherwise, signal values are written instantly.
588 *
589 * @param bitaddr
590 * Abstract bit address
591 * @param value
592 * True for active/high/1/set;
593 * false for passive/low/0/clr;
594 *
595 */
596 virtual void DoWriteSignal(int bitaddr, bool value)=0;
597
598
599 /**
600 * Loop hook.
601 * This function is called once during each cycle of the
602 * backgroud thread
603 *
604 */
605 virtual void DoLoopCallback(void) {};
606
607
608 /** Background: mutex for below shared variables*/
609 faudes_mutex_t mMutex;
610
611 /** True for synchronous output writes */
613
614 private:
615
616 /** Background: thread handle (global) */
617 faudes_thread_t mThreadSynchro;
618
619 /** Cycle time of background thread in nsecs (shared) */
621
622 /** Background: cycle counter (shared) */
624
625 /** Background: cycle count (global only) */
627
628 /** Background: type def for edge detection */
629 typedef struct {
630 bool current; //// current value (most recent reading)
631 bool past; //// past value (reading before)
632 bool posrel; //// positive edge is relevant for some input event
633 bool negrel; //// negative edge is relevant for some input event
634 bool pos; //// positive edge detected
635 bool neg; //// negative edge detected
636 bool lost; //// relevant edge has been lost
637 } Edges;
638
639 /** Background: accumulated edges (shared) */
641
642 /** Background: recently accumulated edges (global only) */
644
645 /** Background: some input event did occur (shared) */
647
648 /** Background: type def output values */
649 typedef struct {
650 bool current; //// current value (actual line level)
651 bool next; //// next value (buffered line level, flush on sync write)
652 bool edge; //// value will change
653 bool lost; //// edgle will be lost
654 bool rel; //// relevant to some output event
655 } Levels;
656
657 /** Background: accumulated output values (shared) */
659
660 /** Background: terminate-flag for background task */
662
663 /** clear all input states */
664 void ClrInputSignals(void);
665
666 /** clear all output values */
667 void ClrOutputSignals(void);
668
669};
670
671// declare background thread
672void* SDeviceSynchro(void*);
673
674}
675
676
677#endif
678
#define FAUDES_API
#define FAUDES_TYPE_DECLARATION(ftype, ctype, cbase)
Definition cfl_types.h:879
const AttributeSignalInput * Inputp(void) const
void DoAssign(const AttributeSignalEvent &rSrc)
virtual void Clear(void)
virtual bool IsDefault(void) const
AttributeSignalInput * Inputp(void)
AttributeSignalOutput * Outputp(void)
const AttributeSignalOutput * Outputp(void) const
AttributeSignalInput(const AttributeSignalInput &rOtherAttr)
virtual void Clear(void)
virtual bool IsDefault(void) const
std::vector< Trigger > mTriggers
virtual void Clear(void)
Definition iop_sdevice.h:50
virtual bool IsDefault(void) const
Definition iop_sdevice.h:47
std::vector< Action > mActions
Definition iop_sdevice.h:64
AttributeSignalOutput(const AttributeSignalOutput &rOtherAttr)
Definition iop_sdevice.h:43
sDevice(const sDevice &rOtherDevice)
virtual void DoReadSignalsPost(void)
AttributeSignalOutput::Value Value
virtual void DoWriteSignalsPost(void)
std::map< int, EventSet > mInputNegEdgeIndexMap
Edges * mpRecentInputEdges
virtual bool DoWriteSignalsPre(void)
faudes_thread_t mThreadSynchro
int MaxBitAddress(void) const
Edges * mpInputEdges
virtual void DoLoopCallback(void)
faudes_mutex_t mMutex
virtual bool DoReadSignal(int bitaddr)=0
virtual void DoWriteSignal(int bitaddr, bool value)=0
virtual bool DoReadSignalsPre(void)
AttributeSignalInput::Trigger Trigger
TaNameSet< AttributeSignalEvent > * pConfiguration
std::map< int, EventSet > mInputPosEdgeIndexMap
AttributeSignalOutput::Action Action
std::map< int, EventSet > mOutputLevelIndexMap
Levels * mpOutputLevels
uint32_t Idx
void * SDeviceSynchro(void *arg)

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen