|
libFAUDES
Sections
Index
|
iop_xdevice.cppGo to the documentation of this file.00001 /** @file iop_xdevice.cpp Device container with vDevice interface */ 00002 00003 /* 00004 FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2008, Thomas Moor 00007 Exclusive copyright is granted to Klaus Schmidt 00008 00009 */ 00010 00011 00012 00013 #include "iop_xdevice.h" 00014 #include "sys/time.h" 00015 #include "iop_simplenet.h" 00016 #include "iop_comedi.h" 00017 #include "iop_wago.h" 00018 00019 namespace faudes { 00020 00021 /* 00022 ********************************************** 00023 ********************************************** 00024 ********************************************** 00025 00026 implementation: xDevice 00027 00028 ********************************************** 00029 ********************************************** 00030 ********************************************** 00031 */ 00032 00033 // std faudes 00034 FAUDES_TYPE_IMPLEMENTATION(DeviceContainer,xDevice,vDevice) 00035 00036 // autoregister 00037 AutoRegisterType<xDevice> gRtiRegisterDeviceContainer("DeviceContainer"); 00038 00039 //constructor 00040 xDevice::xDevice(void) : vDevice() { 00041 FD_DHV("xDevice(" << mName << ")::xDevice()"); 00042 mName="IoDevices"; 00043 // have appropriate default label 00044 mDefaultLabel="DeviceContainer"; 00045 00046 // auto register fix: 00047 // for some reasons the global register objects do not work properly. 00048 // since the xdevice is autoregeistered by the rti, we ask the constructor 00049 // to register the other devices 00050 00051 #ifdef FAUDES_IODEVICE_SIMPLENET 00052 static AutoRegisterType<nDevice> gRtiIORegisterSimplenetDevice("SimplenetDevice"); 00053 #endif 00054 #ifdef FAUDES_IODEVICE_COMEDI 00055 static AutoRegisterType<cDevice> gRtiIORegisterComediDevice("ComediDevice"); 00056 #endif 00057 #ifdef FAUDES_IODEVICE_WAGO 00058 static AutoRegisterType<wDevice> gRtiIORegisterWagoDevice("WagoDevice"); 00059 #endif 00060 00061 } 00062 00063 // destructor 00064 xDevice::~xDevice(void) { 00065 FD_DHV("xDevice(" << mName << ")::~xDevice()"); 00066 // loop to free devices. 00067 Iterator dit; 00068 for(dit=Begin();dit!=End();dit++){ 00069 delete (*dit); 00070 } 00071 } 00072 00073 //FromTokenReader(rTr) 00074 xDevice* xDevice::FromTokenReader(TokenReader& rTr) { 00075 // construct from token reader 00076 FD_DHV("xDevice::FromTokenReader()"); 00077 // allocate 00078 xDevice* dev=new xDevice(); 00079 // read 00080 dev->DoRead(rTr); 00081 return dev; 00082 } 00083 00084 //FromFile(rFilename) 00085 xDevice* xDevice::FromFile(const std::string& rFileName) { 00086 // construct from file 00087 FD_DHV("xDevice()::FromFile(" << rFileName <<")"); 00088 // peek first token 00089 TokenReader tr(rFileName); 00090 return FromTokenReader(tr); 00091 } 00092 00093 00094 //Status(void) 00095 xDevice::DeviceState xDevice::Status(void){ 00096 00097 FD_DHV("xDevice(" << mName << ")::Status() "); 00098 //prepare result 00099 xDevice::DeviceState res; 00100 //vector to store states of all devices integrated in xdevice 00101 std::vector<xDevice::DeviceState> states; 00102 //vector iterator 00103 std::vector<DeviceState>::iterator vit; 00104 vit = states.begin(); 00105 //device iterator 00106 iterator dit; 00107 //identify device state 00108 for(dit=Begin();dit!=End();dit++){ 00109 //get state of current device and insert it in vector 00110 states.push_back((DeviceState)(*dit)->Status()); 00111 //make sure it isnt the first entry 00112 if(vit != states.begin()){ 00113 //if current entry doesnt equal previous 00114 //decide depending on last command 00115 if (*vit!=*vit--){ 00116 //if last command was start: "StartUp" 00117 if(lastCommandWasStart){ 00118 res = StartUp; 00119 break; 00120 } 00121 //if last command was stop: "ShutDown" 00122 if(!lastCommandWasStart){ 00123 res = ShutDown; 00124 break; 00125 } 00126 } 00127 } 00128 //move on to next device 00129 vit++; 00130 } 00131 //if for-loop finished all entries of vector "states" are equal 00132 res = *states.begin(); 00133 return res; 00134 } 00135 00136 // Start(void) 00137 void xDevice::Start(void) { 00138 00139 FD_DHV("xDevice(" << mName <<")::Start()"); 00140 // start implies reset 00141 Reset(); 00142 //start all existing devices 00143 Iterator dit; 00144 for(dit = Begin();dit!=End();dit++){ 00145 (*dit)->Start(); 00146 } 00147 //remember this command 00148 lastCommandWasStart = true; 00149 } 00150 00151 // Stop(void) 00152 void xDevice::Stop(void) { 00153 00154 FD_DHV("xDevice(" << mName <<")::Stop()"); 00155 // xDevice Reset 00156 Reset(); 00157 // stop all existing devices 00158 Iterator dit; 00159 for(dit=Begin();dit!=End();dit++){ 00160 (*dit)->Stop(); 00161 } 00162 //remember this command 00163 lastCommandWasStart = false; 00164 } 00165 00166 // Reset(void) 00167 void xDevice::Reset(void){ 00168 //clear dynamic data 00169 00170 FD_DHV("xDevice(" << mName <<")::Reset()"); 00171 // device-iterator 00172 Iterator dit; 00173 for(dit=Begin();dit!=End();dit++){ 00174 (*dit)->Reset(); 00175 } 00176 // call base to reset time and fifo 00177 vDevice::Reset(); 00178 } 00179 00180 // Clear(void) 00181 void xDevice::Clear(void){ 00182 //clear static data 00183 00184 FD_DHV("xDevice(" << mName << ")::Clear()"); 00185 // Stop running devices 00186 Stop(); 00187 // device-iterator 00188 Iterator dit; 00189 // and clear all devices 00190 for(dit=Begin();dit!=End();dit++){ 00191 (*dit)->Clear(); 00192 } 00193 // destroy existing data 00194 for(dit=Begin();dit!=End();dit++){ 00195 delete (*dit); 00196 } 00197 // compile with empty containers 00198 Compile(); 00199 } 00200 00201 // Insert(vDevice*) 00202 void xDevice::Insert(vDevice* device){ 00203 00204 FD_DHV("xDevice("<<mName<<")::Insert(" << device << "):" << device->Name()); 00205 // insert any vdevice, but no xdevice 00206 if(dynamic_cast<xDevice*>(device)) { 00207 std::stringstream errstr; 00208 errstr << "Attempt to insert xDevice into xDevice"; 00209 throw Exception("xDevice::Compile", errstr.str(), 550); 00210 } 00211 // add to mDevices 00212 mDevices.push_back(device); 00213 // and update compiled data 00214 Compile(); 00215 } 00216 00217 //Insert(rFilename) 00218 void xDevice::Insert(const std::string& rFileName){ 00219 //inserts a device by filename 00220 00221 FD_DHV("xDevice("<<mName<<")::Insert(rFileName)"); 00222 //read device 00223 vDevice* pdev = vDevice::FromFile(rFileName); 00224 //insert device 00225 Insert(pdev); 00226 //and remember its name 00227 mDeviceNames.push_back(rFileName); 00228 } 00229 00230 00231 // Compile(void) 00232 void xDevice::Compile(void) { 00233 //build up internal data-structures 00234 00235 FD_DHV("xDevice("<<mName<<")::Compile()"); 00236 Stop(); 00237 // build up (event-idx,int)-map and memorize all existing events 00238 // prepare containers 00239 mInputs.Clear(); 00240 mOutputs.Clear(); 00241 mInputToDevice.clear(); 00242 mOutputToDevice.clear(); 00243 // temporary container 00244 EventSet tmpSenEvents; 00245 EventSet tmpActEvents; 00246 // event-iterator 00247 EventSet::Iterator eit; 00248 // device-iterator 00249 Iterator dit; 00250 // helper 00251 int j; 00252 // iterate over existing devices 00253 for(dit=Begin(), j=0; dit!=End(); dit++,j++){ 00254 // get events by Index 00255 tmpSenEvents = (*dit)->Inputs(); 00256 tmpActEvents = (*dit)->Outputs(); 00257 //insert output-events in map 00258 for(eit=tmpActEvents.Begin();eit!=tmpActEvents.End();eit++){ 00259 // test if actual event already exists in map 00260 if(mOutputs.Exists(*eit)){ 00261 //throw exeption 00262 std::stringstream errstr; 00263 errstr << "Event already exists!"; 00264 throw Exception("xDevice()::Compile", errstr.str(), 550); 00265 } 00266 mOutputToDevice[*eit] = j; 00267 } 00268 // memorize events 00269 mInputs.InsertSet(tmpSenEvents); 00270 mOutputs.InsertSet(tmpActEvents); 00271 // tell the device which mutex/condition-pair to use 00272 (*dit)->UseCondition(pWaitMutex,pWaitCondition); 00273 (*dit)->UseBuffer(pBufferMutex,pInputBuffer); 00274 }//end iteration over existing devices 00275 // set time scale from first device 00276 if(Size()!=0) (*Begin())->TimeScale(mTimeScale); 00277 } 00278 00279 00280 //Configure(event,attr) 00281 void xDevice::Configure(Idx event, const AttributeDeviceEvent& attr){ 00282 (void) event; (void) attr; 00283 // cannot do vDevice style configuration of events 00284 00285 FD_DHV("xDevice("<<mName<<")::Configure(Idx,attr): "); 00286 std::stringstream errstr; 00287 errstr << "Attempt to configure xDevice by event"; 00288 throw Exception("xDevice::Configure(Idx,attr)", errstr.str(), 550); 00289 } 00290 00291 //Configure(rEvents) 00292 void xDevice::Configure(const EventSet& rEvents){ 00293 (void) rEvents; 00294 // cannot do vDevice style configuration of events 00295 00296 FD_DHV("xDevice("<<mName<<")::Configure(rEvents)"); 00297 std::stringstream errstr; 00298 errstr << "Attempt to configure xDevice by events"; 00299 throw Exception("xDevice::Configure", errstr.str(), 550); 00300 } 00301 00302 00303 //CurrentTime(void) 00304 tpTime::Type xDevice::CurrentTime(void) { 00305 00306 FD_DHV("xDevice("<<mName<<"): CurrentTime() "); 00307 // throw exception if there is no device 00308 if(Size()==0) { 00309 std::stringstream errstr; 00310 errstr << "xDevice owns no device!"; 00311 throw Exception("xDevice::CurrentTime", errstr.str(),550); 00312 } 00313 // ask first device 00314 return (*Begin())->CurrentTime(); 00315 } 00316 00317 00318 //CurrentTime(void) 00319 long int xDevice::CurrentTimeMs(void) { 00320 //debug flag: say hello 00321 FD_DHV("xDevice("<<mName<<")::CurrentTimeMs() "); 00322 // throw exception if there is no device 00323 if(Size()==0) { 00324 std::stringstream errstr; 00325 errstr << "xDevice owns no device!"; 00326 throw Exception("xDevice::CurrentTimeMs", errstr.str(),550); 00327 } 00328 // ask first device 00329 return (*Begin())->CurrentTimeMs(); 00330 } 00331 00332 //CurrentTime(now) 00333 void xDevice::CurrentTime(tpTime::Type now) { 00334 //debug flag: say hello 00335 FD_DHV("xDevice("<<mName<<")::CurrentTime("<<now<<") "); 00336 // tell first device if such 00337 if(Size()!=0) (*Begin())->CurrentTime(now); 00338 } 00339 00340 //CurrentTimeMs(now) 00341 void xDevice::CurrentTimeMs(long int nowms) { 00342 //debug flag: say hello 00343 00344 FD_DHV("xDevice("<<mName<<")::CurrentTimeMs("<<nowms<<") "); 00345 // tell first device if such 00346 if(Size()!=0) (*Begin())->CurrentTimeMs(nowms); 00347 } 00348 00349 //DoWrite(rTr,rLabel) 00350 void xDevice::DoWriteConfiguration(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00351 (void) rTw; 00352 00353 FD_DHV("xDevice("<<mName<<")::DoWriteConfiguration()"); 00354 // hard coded begin 00355 rTw.WriteBegin("Devices"); 00356 // define device-iterator 00357 Iterator dit; 00358 //iterate over all devices 00359 for(Idx i=0; i<Size(); i++) { 00360 //if device was read from an extra file 00361 if(mDeviceNames.at(i) != ""){ 00362 //write path to TokenWriter 00363 FD_DHV("xDevice("<<mName<<")::DoWrite(): "<<mDeviceNames.at(i)); 00364 rTw.WriteString(mDeviceNames.at(i)); //TODO: relativ path-names 00365 } 00366 //else device was directly read from base-config-file 00367 else if(mDeviceNames.at(i) == ""){ 00368 //write configuration 00369 FD_DHV("xDevice("<<mName<<")::DoWrite(): "<<mDeviceNames.at(i)); 00370 (mDevices.at(i))->Write(rTw); 00371 } 00372 } 00373 rTw.WriteEnd("Devices"); 00374 } 00375 00376 00377 // ResetRequest() 00378 bool xDevice::ResetRequest(void) { 00379 bool res=false; 00380 Iterator dit; 00381 for(dit=Begin();dit!=End();dit++){ 00382 res = res | (*dit)->ResetRequest(); 00383 } 00384 return res; 00385 } 00386 00387 //DoRead(rTr,rLabel) 00388 void xDevice::DoReadConfiguration(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00389 (void) rLabel; (void) pContext; 00390 00391 FD_DHV("xDevice("<<mName<<")::DoReadConfiguration()"); 00392 //prepare token 00393 Token token; 00394 //prepare string 00395 std::string filename = ""; //to store filename 00396 std::string dirname = ""; //to store directory 00397 std::string path; //to store absolut path 00398 // have default section 00399 std::string label = rLabel; 00400 if(label=="") label = "Devices"; 00401 // test for begin 00402 /* 00403 rTr.Peek(token); 00404 if(!token.IsBegin()) return; 00405 if(token.StringValue()!=label) return; 00406 */ 00407 // read begin 00408 rTr.ReadBegin(label); 00409 // fill mDevices with devices specified in given file 00410 while(!rTr.Eos("Devices")){ 00411 //peek token 00412 rTr.Peek(token); 00413 // if Token is a String we assume its the name of a file containing a device 00414 if(token.Type()==Token::String) { 00415 //read Token 00416 rTr.Get(token); 00417 //import filename 00418 filename = token.StringValue(); 00419 //build up path to base-file 00420 if(rTr.SourceMode()==TokenReader::File) dirname = ExtractDirectory(rTr.FileName()); 00421 //build up path to specified file 00422 path = dirname.append(filename); 00423 //insert device 00424 Insert(path); 00425 continue; 00426 } 00427 // if its not a file it has to be a device 00428 else if(token.Type()==Token::Begin) { 00429 // read device 00430 vDevice* devp = vDevice::FromTokenReader(rTr); 00431 // insert device mDevices 00432 Insert(devp); 00433 //record that this device was read inline 00434 mDeviceNames.push_back(""); 00435 } 00436 } 00437 rTr.ReadEnd(label); 00438 } 00439 00440 00441 // WriteOutput(Idx) 00442 void xDevice::WriteOutput(Idx output){ 00443 00444 FD_DHV("xDevice("<<mName<<")::WriteOutput()"); 00445 // identify corresponding device(if idx is unique) 00446 int didx = mOutputToDevice[output]; 00447 FD_DHV("xDevice("<<mName<<")::WriteOutput(): " << output << " to " << didx); 00448 mDevices.at(didx)->WriteOutput(output); 00449 } 00450 00451 00452 } // name space 00453 00454 |
libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3