About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

iop_wago.cpp

Go 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.20d --- 2011.04.26 --- c++ source docu by doxygen