libFAUDES
Sections
Index
|
iop_wago.cppGo to the documentation of this file.00001 /** @file iop_wago.cpp provides access to wago-kbus*/ 00002 00003 /* 00004 FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2009, Thomas Wittmann, Thomas Moor. 00007 Copyright (C) 2010, Thomas Moor. 00008 00009 */ 00010 00011 00012 // include header 00013 #include "iop_wago.h" 00014 00015 // only compile for use with wago-ipc 00016 #ifdef FAUDES_IODEVICE_WAGO 00017 00018 // Include functions from "wago_ipc_kbus.c" 00019 extern "C" { 00020 // Start the kbus_thread used to build up the data-structures used to access the process-image. 00021 extern void start_kbus_thread(void); 00022 // Update a user-copy of the kbus process-image data-structures 00023 extern void kbus_update_image(void); 00024 // Test if failures occured which make reading form kbus impossible 00025 extern int kbus_running(void); 00026 } 00027 00028 namespace faudes { 00029 00030 00031 // std faudes, incl dummy 00032 FAUDES_TYPE_IMPLEMENTATION(WagoDevice,wDevice,sDevice) 00033 00034 // autoregister 00035 AutoRegisterType<wDevice> gRtiRegisterWagoDevice("WagoDevice"); 00036 00037 //constructor 00038 wDevice::wDevice(void) : sDevice() { 00039 FD_DHV("wDevice(" << mName << ")::wDevice()"); 00040 // have appropriate default label for token io 00041 mDefaultLabel = "WagoDevice"; 00042 // pointer to kbus-I/O-image 00043 pInputImage=0; 00044 pOutputImage=0; 00045 // no kbus-failure before kbus was even started 00046 mKbusOk=true; 00047 } 00048 00049 //deconstructor 00050 wDevice::~wDevice(void) { 00051 FD_DHV("wDevice(" << mName << ")::~wDevice()"); 00052 Stop(); 00053 } 00054 00055 // Start(void) 00056 void wDevice::Start(void) { 00057 //open wago-device 00058 if(mState!=Down) return; 00059 FD_DH("wDevice(" << mName << ")::Start(): open devices"); 00060 // initialize kbus 00061 int res = kbus_init(); 00062 // set up kbus-thread 00063 start_kbus_thread(); 00064 FD_DHV("wDevice(" << mName << ")::Start(): res = " << res ); 00065 // throw execption if opening kbus failed 00066 if(res != 0) { 00067 std::stringstream errstr; 00068 errstr << "cannot open kbus"; 00069 throw Exception("wDevice()::Start()", errstr.str(), 552); 00070 } 00071 // invalidate images 00072 pInputImage=0; 00073 pOutputImage=0; 00074 // call base (incl. reset) 00075 sDevice::Start(); 00076 // pessimistic: assume kbus-failure during start-up, let background thread figure 00077 mKbusOk=false; 00078 mState=StartUp; 00079 }//end Start() 00080 00081 // Stop() 00082 void wDevice::Stop(void) { 00083 //close kbus interface 00084 if(mState != Up && mState != StartUp) return; 00085 FD_DHV("wDevice(" << mName << ")::Stop()"); 00086 // close kbus 00087 kbus_shutdown(); 00088 // call base 00089 sDevice::Stop(); 00090 00091 } 00092 00093 //DoWrite(rTr,rLabel,pContext) 00094 void wDevice::DoWritePreface(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00095 //dummy for token-output 00096 FD_DHV("wDevice("<<mName<<")::DoWritePreface()"); 00097 //call base 00098 sDevice::DoWritePreface(rTw,"",pContext); 00099 } 00100 00101 00102 //DoReadPreface(rTr,rLabel,pContext) 00103 void wDevice::DoReadPreface(TokenReader& rTr,const std::string& rLabel, const Type* pContext){ 00104 //dummy for token-input 00105 FD_DHV("wDevice("<<mName<<")::DoReadPreface()"); 00106 //call base 00107 sDevice::DoReadPreface(rTr,"",pContext); 00108 } 00109 00110 00111 // DoReadSignalsPre(void) 00112 bool wDevice::DoReadSignalsPre(void) { 00113 00114 static int okcnt=0; 00115 00116 // We still have a valid input image: fine 00117 if(pInputImage) return true; 00118 00119 // Prevent simultanuous reading and writing since this may 00120 // block the kbus thread. 00121 if(pOutputImage) return false; 00122 00123 // Get input-image and lock kbus-mutex 00124 pInputImage=(char*) kbus_lock_input_image(); 00125 // Test wether reading was valid 00126 int kok= kbus_running(); 00127 // If reading was not valid... 00128 if(kok==0) { 00129 // ... track and report ... 00130 if(mKbusOk) FD_WARN("wDevice(" << mName << ")::DoReadSignalsPre(): kbus error and friends "); 00131 // ... invalidate input-image ... 00132 pInputImage=0; 00133 // ... releaset the mutex and ... 00134 kbus_release_io_image(); 00135 // advertise failure 00136 mKbusOk=false; 00137 okcnt=0; 00138 } 00139 // If reading is valid ... 00140 if(kok!=0) { 00141 // ... wait for stable result ... 00142 if(!mKbusOk) { 00143 okcnt++; 00144 if(okcnt>50) { 00145 FD_WARN("wDevice(" << mName << ")::DoReadSignalsPre(): kbus recovered"); 00146 mKbusOk=true; 00147 } 00148 // ... release image while waiting. 00149 if(!mKbusOk) kbus_release_io_image(); 00150 } 00151 } 00152 // return result 00153 return mKbusOk; 00154 } 00155 00156 00157 // DoReadSignalsPost(void) 00158 void wDevice::DoReadSignalsPost(void) { 00159 // If the input-image is still valid, we assume that we hold the mutex 00160 // and, hence, must now release it. 00161 if(pInputImage) kbus_release_io_image(); 00162 // invalidate input-image. 00163 pInputImage=0; 00164 } 00165 00166 00167 //ReadSignal(int) 00168 bool wDevice::DoReadSignal(int bit){ 00169 // Read one input value, addressed by bit number (0 to 63); 00170 00171 // Determine byte and bit address 00172 int byte = bit / 8; 00173 bit = bit % 8; 00174 00175 // Read bit 00176 return ( pInputImage[byte] & (0x01 << (bit)) ) != 0x00; 00177 } 00178 00179 00180 // DoWriteSignalsPre(void) 00181 bool wDevice::DoWriteSignalsPre(void) { 00182 // We have a valid input image: error, prevent simultaneous read/write 00183 if(pInputImage) return false; 00184 // We have a valid output image: fine 00185 if(pOutputImage) return true; 00186 // Get an image and lock it 00187 pOutputImage=(char*) kbus_lock_output_image(); 00188 // Done 00189 return true; 00190 } 00191 00192 00193 00194 // DoWrtieSignalsPost(void) 00195 void wDevice::DoWriteSignalsPost(void) { 00196 // If there is an valid output-image, release kbus-mutex... 00197 if(pOutputImage) kbus_release_io_image(); 00198 // ...and invalidate image. 00199 pOutputImage=0; 00200 } 00201 00202 00203 //DoWriteSignal(int,int) 00204 void wDevice::DoWriteSignal(int bit, bool value){ 00205 // Write one actor value, adressed by bit number (0 to 63); 00206 00207 // Determine byte and bit addresse. 00208 int byte = (bit) / 8; 00209 bit = (bit) % 8; 00210 // Report 00211 FD_DHV("wDevice(" << mName << ")::DoWriteSignal(int): bit " << bit << " in byte " << byte); 00212 00213 // Write value to output-image using bit-operations 00214 // Write a "1", or... 00215 if(value) pOutputImage[byte] |= (0x1 << (bit)); 00216 // ... write a "0" 00217 else pOutputImage[byte] &= ~(0x1 << (bit)); 00218 } 00219 00220 00221 } // namespace 00222 00223 #endif // end wago-support |
libFAUDES 2.20s --- 2011.10.12 --- c++ source docu by doxygen