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