iop_wago.cpp
Go to the documentation of this file.
1/** @file iop_wago.cpp provides access to wago-kbus*/
2
3/*
4 FAU Discrete Event Systems Library (libfaudes)
5
6 Copyright (C) 2009, Thomas Wittmann, Thomas Moor.
7 Copyright (C) 2010, Thomas Moor.
8
9*/
10
11
12// include header
13#include "iop_wago.h"
14
15// only compile for use with wago-ipc
16#ifdef FAUDES_IODEVICE_WAGO
17
18// Include functions from "wago_ipc_kbus.c"
19extern "C" {
20 // Initialize libkbus
21 extern int kbus_init(void);
22 // Close libkbus
23 extern int kbus_shutdown(void);
24 // Start the kbus_thread used to build up the data-structures used to access the process-image.
25 extern void start_kbus_thread(void);
26 // Update a user-copy of the kbus process-image data-structures
27 extern void kbus_update_image(void);
28 // Test if failures occured which make reading form kbus impossible
29 extern int kbus_running(void);
30 // Obtain pointer to locked image
31 extern void *kbus_lock_input_image(void);
32 // Obtain pointer to locked image
33 extern void *kbus_lock_output_image(void);
34 // Release lock
35 extern void kbus_release_io_image(void);
36}
37
38namespace faudes {
39
40
41// std faudes, incl dummy
42FAUDES_TYPE_IMPLEMENTATION(WagoDevice,wDevice,sDevice)
43
44// autoregister
45AutoRegisterType<wDevice> gRtiRegisterWagoDevice("WagoDevice");
46
47//constructor
48wDevice::wDevice(void) : sDevice() {
49 FD_DHV("wDevice(" << mName << ")::wDevice()");
50 // have appropriate default label for token io
51 mDefaultLabel = "WagoDevice";
52 // pointer to kbus-I/O-image
53 pInputImage=0;
54 pOutputImage=0;
55 // no kbus-failure before kbus was even started
56 mKbusOk=true;
57}
58
59//deconstructor
60wDevice::~wDevice(void) {
61 FD_DHV("wDevice(" << mName << ")::~wDevice()");
62 Stop();
63}
64
65// Start(void)
66void wDevice::Start(void) {
67 // device is only functional in synchronous mode
68 mSyncWrite=true;
69 //open wago-device
70 if(mState!=Down) return;
71 FD_DH("wDevice(" << mName << ")::Start(): open devices");
72 // initialize kbus
73 int res = kbus_init();
74 // set up kbus-thread
75 start_kbus_thread();
76 FD_DHV("wDevice(" << mName << ")::Start(): res = " << res );
77 // throw execption if opening kbus failed
78 if(res != 0) {
79 std::stringstream errstr;
80 errstr << "cannot open kbus";
81 throw Exception("wDevice()::Start()", errstr.str(), 552);
82 }
83 // invalidate images
84 pInputImage=0;
85 pOutputImage=0;
86 // call base (incl. reset)
87 sDevice::Start();
88 // pessimistic: assume kbus-failure during start-up, let background thread figure
89 mKbusOk=false;
90 mState=StartUp;
91}//end Start()
92
93// Stop()
94void wDevice::Stop(void) {
95 //close kbus interface
96 if(mState != Up && mState != StartUp) return;
97 FD_DHV("wDevice(" << mName << ")::Stop()");
98 // close kbus
99 kbus_shutdown();
100 // call base
101 sDevice::Stop();
102
103}
104
105//DoWrite(rTr,rLabel,pContext)
106void wDevice::DoWritePreface(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
107 //dummy for token-output
108 FD_DHV("wDevice("<<mName<<")::DoWritePreface()");
109 //call base
110 sDevice::DoWritePreface(rTw,"",pContext);
111}
112
113
114//DoReadPreface(rTr,rLabel,pContext)
115void wDevice::DoReadPreface(TokenReader& rTr,const std::string& rLabel, const Type* pContext){
116 //dummy for token-input
117 FD_DHV("wDevice("<<mName<<")::DoReadPreface()");
118 //call base
119 sDevice::DoReadPreface(rTr,"",pContext);
120}
121
122
123// DoReadSignalsPre(void)
124bool wDevice::DoReadSignalsPre(void) {
125
126 static int okcnt=0;
127
128 // We still have a valid input image: fine
129 if(pInputImage) return true;
130
131 // Prevent simultanuous reading and writing since this may
132 // block the kbus thread.
133 if(pOutputImage) return false;
134
135 // Get input-image and lock kbus-mutex
136 pInputImage=(char*) kbus_lock_input_image();
137 // Test wether reading was valid
138 int kok= kbus_running();
139 // If reading was not valid...
140 if(kok==0) {
141 // ... track and report ...
142 if(mKbusOk) FD_WARN("wDevice(" << mName << ")::DoReadSignalsPre(): kbus error and friends ");
143 // ... invalidate input-image ...
144 pInputImage=0;
145 // ... releaset the mutex and ...
146 kbus_release_io_image();
147 // advertise failure
148 mKbusOk=false;
149 okcnt=0;
150 }
151 // If reading is valid ...
152 if(kok!=0) {
153 // ... wait for stable result ...
154 if(!mKbusOk) {
155 okcnt++;
156 if(okcnt>50) {
157 FD_WARN("wDevice(" << mName << ")::DoReadSignalsPre(): kbus recovered");
158 mKbusOk=true;
159 }
160 // ... release image while waiting.
161 if(!mKbusOk) kbus_release_io_image();
162 }
163 }
164 // return result
165 return mKbusOk;
166}
167
168
169// DoReadSignalsPost(void)
170void wDevice::DoReadSignalsPost(void) {
171 // If the input-image is still valid, we assume that we hold the mutex
172 // and, hence, must now release it.
173 if(pInputImage) kbus_release_io_image();
174 // invalidate input-image.
175 pInputImage=0;
176}
177
178
179//ReadSignal(int)
180bool wDevice::DoReadSignal(int bit){
181 // Read one input value, addressed by bit number (0 to 63);
182
183 // Determine byte and bit address
184 int byte = bit / 8;
185 bit = bit % 8;
186
187 // Read bit
188 return ( pInputImage[byte] & (0x01 << (bit)) ) != 0x00;
189}
190
191
192// DoWriteSignalsPre(void)
193bool wDevice::DoWriteSignalsPre(void) {
194 // We have a valid input image: error, prevent simultaneous read/write
195 if(pInputImage) return false;
196 // We have a valid output image: fine
197 if(pOutputImage) return true;
198 // Get an image and lock it
199 pOutputImage=(char*) kbus_lock_output_image();
200 // Done
201 return true;
202}
203
204
205
206// DoWrtieSignalsPost(void)
207void wDevice::DoWriteSignalsPost(void) {
208 // If there is an valid output-image, release kbus-mutex...
209 if(pOutputImage) kbus_release_io_image();
210 // ...and invalidate image.
211 pOutputImage=0;
212}
213
214
215//DoWriteSignal(int,int)
216void wDevice::DoWriteSignal(int bit, bool value){
217 // Write one actor value, adressed by bit number (0 to 63);
218
219 // Determine byte and bit addresse.
220 int byte = (bit) / 8;
221 bit = (bit) % 8;
222 // Report
223 FD_DHV("wDevice(" << mName << ")::DoWriteSignal(int): bit " << bit << " in byte " << byte);
224
225 // Write value to output-image using bit-operations
226 // Write a "1", or...
227 if(value) pOutputImage[byte] |= (0x1 << (bit));
228 // ... write a "0"
229 else pOutputImage[byte] &= ~(0x1 << (bit));
230}
231
232
233} // namespace
234
235#endif // end wago-support
#define FD_WARN(message)
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition cfl_types.h:958
#define FD_DHV(message)
Definition iop_vdevice.h:37
#define FD_DH(message)
Definition iop_vdevice.h:27

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