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 // 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