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