| |
libFAUDES
Sections
Index
|
iop_sdevice.cppGo to the documentation of this file.00001 /** @file iop_sdevice.cpp Virtual device for interface definition */ 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_sdevice.h" 00014 #include "sys/time.h" 00015 #include "sp_densityfnct.h" 00016 00017 // fix windows/mingw definition 00018 #ifdef FAUDES_WINEXTRA 00019 #define sleep(sec) Sleep((sec) * 1000) 00020 #define usleep(usec) Sleep((usec) / 1000) 00021 #endif 00022 00023 namespace faudes { 00024 00025 00026 /* 00027 ********************************************** 00028 ********************************************** 00029 ********************************************** 00030 00031 implementation: AttributeSignalActuator 00032 00033 ********************************************** 00034 ********************************************** 00035 ********************************************** 00036 */ 00037 00038 // faudes type std 00039 FAUDES_TYPE_IMPLEMENTATION(AttributeSignalActuator,AttributeVoid,) 00040 00041 //DoAssign(Src) 00042 AttributeSignalActuator& AttributeSignalActuator::DoAssign(const AttributeSignalActuator& rSrcAttr) { 00043 FD_DHV("AttributeSignalActuator(" << this << "):DoAssign(): assignment from " << &rSrcAttr); 00044 mActions=rSrcAttr.mActions; 00045 return *this; 00046 } 00047 00048 //DoWrite(rTw); 00049 void AttributeSignalActuator::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00050 (void) rLabel; (void) pContext; 00051 //dummy for token-io 00052 00053 FD_DHV("AttributeSignalActuator::DoWrite()"); 00054 rTw.WriteBegin("Actuator"); 00055 rTw.WriteBegin("Actions"); 00056 std::vector<Action>::const_iterator ait; 00057 00058 for(ait=mActions.begin(); ait!=mActions.end(); ait++) { 00059 rTw << (Idx) ait->mBit; 00060 if(ait->mValue) rTw.WriteOption("Set"); 00061 else rTw.WriteOption("Clr"); 00062 } 00063 rTw.WriteEnd("Actions"); 00064 rTw.WriteEnd("Actuator "); 00065 } 00066 00067 00068 //DoRead(rTr) 00069 void AttributeSignalActuator::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00070 (void) rLabel; (void) pContext; 00071 //dummy for token-io 00072 00073 FD_DHV("AttributeSignalActuator::DoRead()"); 00074 // clear 00075 mActions.clear(); 00076 // test for actuator section 00077 Token token; 00078 rTr.Peek(token); 00079 if(token.Type()!=Token::Begin) return; 00080 if(token.StringValue()!="Actuator") return; 00081 // read actuator section 00082 rTr.ReadBegin("Actuator"); 00083 bool err=false; 00084 rTr.ReadBegin("Actions"); 00085 while(!rTr.Eos("Actions")) { 00086 // action 00087 Action action; 00088 // 1: bit address 00089 action.mBit=rTr.ReadInteger(); 00090 // 2: value 00091 std::string value=rTr.ReadOption(); 00092 if(value== "Set") { 00093 action.mValue=true; 00094 } else if(value == "Clr") { 00095 action.mValue=false; 00096 } else { 00097 err=true; 00098 break; 00099 } 00100 // 3. record 00101 mActions.push_back(action); 00102 } 00103 // done 00104 rTr.ReadEnd("Actions"); 00105 rTr.ReadEnd("Actuator"); 00106 // report error 00107 if(err) { 00108 std::stringstream errstr; 00109 errstr << "invalid actuator event property" << rTr.FileLine(); 00110 throw Exception("AttributeSignalActuator::Read", errstr.str(), 52); //52 oder 352 00111 } 00112 00113 }//DoRead 00114 00115 00116 /* 00117 ********************************************** 00118 ********************************************** 00119 ********************************************** 00120 00121 implementation: AttributeSignalSensor 00122 00123 ********************************************** 00124 ********************************************** 00125 ********************************************** 00126 */ 00127 00128 00129 // faudes type std 00130 FAUDES_TYPE_IMPLEMENTATION(AttributeSignalSensor,AttributeVoid,) 00131 00132 00133 //DoAssign(Src) 00134 AttributeSignalSensor& AttributeSignalSensor::DoAssign(const AttributeSignalSensor& rSrcAttr) { 00135 FD_DHV("AttributeSignalSensor(" << this << "):DoAssign(): assignment from " << &rSrcAttr); 00136 mTriggers=rSrcAttr.mTriggers; 00137 return *this; 00138 } 00139 00140 00141 //DoWrite(rTw,rLabel,pContext) 00142 void AttributeSignalSensor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00143 (void) rLabel; (void) pContext; 00144 //dummy for token-io 00145 00146 FD_DHV("AttributeSignalSensor()::DoWrite()"); 00147 rTw.WriteBegin("Sensor"); 00148 rTw.WriteBegin("Triggers"); 00149 std::vector<Trigger>::const_iterator ait; 00150 for(ait=mTriggers.begin(); ait!=mTriggers.end(); ait++) { 00151 rTw << ((Idx) ait->mBit); 00152 if(ait->mPos && (!ait->mNeg)) { 00153 rTw.WriteOption("PosEdge"); 00154 } 00155 if((!ait->mPos) && ait->mNeg) { 00156 rTw.WriteOption("NegEdge"); 00157 } 00158 if((ait->mPos) && ait->mNeg) { 00159 rTw.WriteOption("AnyEdge"); 00160 } 00161 } 00162 rTw.WriteEnd("Triggers"); 00163 rTw.WriteEnd("Sensor"); 00164 }//DoWrite(rTw,rLabel,pContext) 00165 00166 00167 //DoRead(rTr,rLabel,pContext) 00168 void AttributeSignalSensor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00169 (void) rLabel; (void) pContext; 00170 //dummy for token-io 00171 00172 FD_DHV("AttributeSignalSensor()::DoRead(tr)"); 00173 // clear 00174 mTriggers.clear(); 00175 // test for sensor section 00176 Token token; 00177 rTr.Peek(token); 00178 if(token.Type()!=Token::Begin) return; 00179 if(token.StringValue()!="Sensor") return; 00180 // read sensor section 00181 rTr.ReadBegin("Sensor"); 00182 bool err=false; 00183 rTr.ReadBegin("Triggers"); 00184 while(!rTr.Eos("Triggers")) { 00185 // trigger 00186 Trigger trigger; 00187 // 1: bit address 00188 trigger.mBit=rTr.ReadInteger(); 00189 // 2: value 00190 std::string value=rTr.ReadOption(); 00191 if (value == "PosEdge") { 00192 trigger.mPos=true; 00193 trigger.mNeg=false; 00194 } else if (value == "NegEdge") { 00195 trigger.mPos=false; 00196 trigger.mNeg=true; 00197 } else if (value == "AnyEdge") { 00198 trigger.mPos=true; 00199 trigger.mNeg=true; 00200 } else { 00201 err=true; 00202 break; 00203 } 00204 // 3. record 00205 mTriggers.push_back(trigger); 00206 } 00207 // done 00208 rTr.ReadEnd("Triggers"); 00209 rTr.ReadEnd("Sensor"); 00210 // report error 00211 if(err) { 00212 std::stringstream errstr; 00213 errstr << "invalid sensor event property" << rTr.FileLine(); 00214 throw Exception("AttributeSignalSensor::Read", errstr.str(), 52); 00215 } 00216 } 00217 00218 00219 00220 /* 00221 ********************************************** 00222 ********************************************** 00223 ********************************************** 00224 00225 implementation: AttributeSignalEvent 00226 00227 ********************************************** 00228 ********************************************** 00229 ********************************************** 00230 */ 00231 00232 00233 // statics 00234 AttributeSignalActuator AttributeSignalEvent::sActuatorPrototype; 00235 AttributeSignalSensor AttributeSignalEvent::sSensorPrototype; 00236 00237 // std faudes type 00238 FAUDES_TYPE_IMPLEMENTATION(AttributeSignalEvent,AttributeDeviceEvent,) 00239 00240 // Default constructor, set my prototypes 00241 AttributeSignalEvent::AttributeSignalEvent(void) : AttributeDeviceEvent() { 00242 FD_DHV("AttributeSignalEvent::AttributeSignalEvent(" << this << ")"); 00243 pActuatorPrototype=&sActuatorPrototype; 00244 pSensorPrototype=&sSensorPrototype; 00245 } 00246 00247 // Copy constructor 00248 AttributeSignalEvent::AttributeSignalEvent(const AttributeSignalEvent& rOtherAttr) : 00249 AttributeDeviceEvent() 00250 { 00251 FD_DHV("AttributeSimplenetEvent(" << this << "): form other attr " << &rOtherAttr); 00252 pActuatorPrototype=&sActuatorPrototype; 00253 pSensorPrototype=&sSensorPrototype; 00254 DoAssign(rOtherAttr); 00255 } 00256 00257 00258 /* 00259 ********************************************** 00260 ********************************************** 00261 ********************************************** 00262 00263 implementation: sDevice 00264 00265 ********************************************** 00266 ********************************************** 00267 ********************************************** 00268 */ 00269 00270 00271 //////////////////////////////////////////////// 00272 // construction and destruction 00273 00274 //sDevice() 00275 sDevice::sDevice(void) : vDevice() { 00276 // constructor 00277 00278 FD_DHV("sDevice(" << mName << ")::sDevice()"); 00279 // have event set with appropriate attributes 00280 mpConfiguration = new TaNameSet<AttributeSignalEvent>; 00281 pConfiguration = dynamic_cast< TaNameSet<AttributeSignalEvent>* >(mpConfiguration); 00282 // have appropriate default label for token io 00283 mDefaultLabel ="SignalDevice"; 00284 // my signal data 00285 mMaxBitAddress=0; 00286 mpSensorEdges=0; 00287 mpRecentSensorEdges=0; 00288 // background thread: 00289 // install mutex 00290 pthread_mutex_init(&mMutex, NULL); 00291 // configuration defaults 00292 mName="SignalDevice"; 00293 mCycleTime=1000; // 1ms 00294 mTimeScale=500; // 500ms is one faudes time unit 00295 } 00296 00297 00298 //~sDevice() 00299 sDevice::~sDevice(void) { 00300 // destructor 00301 00302 FD_DHV("sDevice(" << mName << ")::~sDevice()"); 00303 //cancel background thread: destroy mutex 00304 pthread_mutex_destroy(&mMutex); 00305 // invalidate data 00306 if(mpSensorEdges) delete mpSensorEdges; 00307 if(mpRecentSensorEdges) delete mpRecentSensorEdges; 00308 } 00309 00310 00311 //DoWritePreface(rTw,rLabel,pContext) 00312 void sDevice::DoWritePreface(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00313 00314 FD_DHV("sDevice("<<mName<<")::DoWritePreface()"); 00315 //call base 00316 vDevice::DoWritePreface(rTw,rLabel,pContext); 00317 //write max bitaddress and cycle-time of background task 00318 rTw.WriteInteger(mMaxBitAddress); 00319 rTw.WriteInteger(mCycleTime); 00320 } 00321 00322 //DoReadPreface(rTr,rLabel,pContext) 00323 void sDevice::DoReadPreface(TokenReader& rTr,const std::string& rLabel, const Type* pContext){ 00324 00325 FD_DHV("sDevice("<<mName<<")::DoReadPreface()"); 00326 //call base 00327 vDevice::DoReadPreface(rTr,rLabel,pContext); 00328 //read max bitaddress and cycle-time of background task 00329 //TODO: sollte man doch eigentlich ausrechnen k�nen 00330 mMaxBitAddress = rTr.ReadInteger(); 00331 mCycleTime = rTr.ReadInteger(); 00332 } 00333 00334 00335 00336 00337 00338 // lock - unlock shortcuts; 00339 #define LOCK_E {int rc = pthread_mutex_lock(&mMutex); \ 00340 if(rc) {FD_ERR("sDevice("<<mName<<")::LOCK_E: lock mutex error\n"); exit(1); }} 00341 #define UNLOCK_E {int rc = pthread_mutex_unlock(&mMutex); \ 00342 if(rc) {FD_ERR("sDevice("<<mName<<")::LOCK_E: unlock mutex error\n"); exit(1); }} 00343 00344 00345 #define TLOCK_E {int rc = pthread_mutex_lock(&sdevice->mMutex); \ 00346 if(rc) {FD_ERR("sDevice::TLOCK_E: lock mutex error\n"); exit(1); }} 00347 00348 #define TUNLOCK_E {int rc = pthread_mutex_unlock(&sdevice->mMutex); \ 00349 if(rc) {FD_ERR("sDevice::TLOCK_E: unlock mutex error\n"); exit(1); }} 00350 00351 00352 00353 00354 00355 // Start(void) 00356 void sDevice::Start(void) { 00357 //set device state and create thread 00358 00359 //return if device was allready started 00360 if( (mState == Up)||(mState == StartUp) ) return; 00361 FD_DHV("sDevice("<<mName<<")::Start()"); 00362 //call base 00363 vDevice::Start(); 00364 //dont create thread if device-purpose is not to handle input-signals 00365 if(!Sensors().Empty()){ 00366 mCancelRequest = false; 00367 //setup thread attribute 00368 pthread_attr_t attr; 00369 pthread_attr_init(&attr); 00370 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 00371 //create thread 00372 int rc = pthread_create(&mThreadSynchro, &attr, SDeviceSynchro, this); 00373 if (rc) { 00374 FD_ERR("sDevice("<<mName<<")::Start(): cannot creat thread\n"); 00375 exit(1); 00376 } 00377 //destroy thread-attribute 00378 pthread_attr_destroy(&attr); 00379 } 00380 } 00381 00382 // Stop() 00383 void sDevice::Stop(void) { 00384 //set device state and kill thread 00385 00386 //return if device allready got the command to shut down 00387 if(mState != Up && mState !=StartUp) return; 00388 FD_DHV("sDevice("<<mName<<")::Stop()"); 00389 //dont kill thread if no thread was created 00390 if(!Sensors().Empty()) { 00391 //cancle thread 00392 LOCK_E; 00393 mCancelRequest=true; 00394 UNLOCK_E; 00395 int pc = pthread_join(mThreadSynchro,NULL); 00396 if (pc) { 00397 FD_ERR("sDevice("<<mName<<")::Stop(): cannot join thread??\n"); 00398 } 00399 } 00400 // call base 00401 vDevice::Stop(); 00402 }//end Stop() 00403 00404 00405 //Reset() 00406 void sDevice::Reset(){ 00407 //delete dynamic data 00408 00409 FD_DHV("sDevice("<<mName<<")::Reset()"); 00410 // call base (resets time) 00411 vDevice::Reset(); 00412 //delete dynamic data 00413 ClrSensorSignals(); 00414 ClrActuatorSignals(); 00415 } 00416 00417 // Clear() 00418 void sDevice::Clear(void) { 00419 //delete static data 00420 00421 FD_DHV("sDevice(" << mName << ")::Clear()"); 00422 // call base; note: clear implies stop 00423 vDevice::Clear(); 00424 // clear compiled data 00425 mSensorPosEdgeIndexMap.clear(); 00426 mSensorNegEdgeIndexMap.clear(); 00427 mMaxBitAddress=0; 00428 } 00429 00430 //Compile(void) 00431 void sDevice::Compile(void){ 00432 //setup up internal data structure 00433 00434 FD_DHV("sDevice(" << mName << ")::Compile()"); 00435 // call base 00436 vDevice::Compile(); 00437 // clear my internal data 00438 mSensorPosEdgeIndexMap.clear(); 00439 mSensorNegEdgeIndexMap.clear(); 00440 mMaxBitAddress=0; 00441 // setup my internal data 00442 for(EventSet::Iterator eit=pConfiguration->Begin(); eit!=pConfiguration->End(); eit++) { 00443 AttributeSignalEvent attr = pConfiguration->Attribute(*eit); 00444 if(attr.IsSensor()) { 00445 // fill in reverse maps 00446 std::vector<AttributeSignalSensor::Trigger>::const_iterator ait; 00447 const AttributeSignalSensor* sattr = attr.Sensorp(); 00448 for(ait=sattr->mTriggers.begin(); ait!=sattr->mTriggers.end(); ait++) { 00449 if(ait->mPos) mSensorPosEdgeIndexMap[ait->mBit].Insert(*eit); 00450 if(ait->mNeg) mSensorNegEdgeIndexMap[ait->mBit].Insert(*eit); 00451 if(ait->mBit > mMaxBitAddress) mMaxBitAddress=ait->mBit; 00452 } 00453 } 00454 // check max address 00455 if(attr.IsActuator()) { 00456 std::vector<AttributeSignalActuator::Action>::const_iterator ait; 00457 const AttributeSignalActuator* aattr = attr.Actuatorp(); 00458 for(ait=aattr->mActions.begin(); ait!=aattr->mActions.end(); ait++) { 00459 if(ait->mBit > mMaxBitAddress) mMaxBitAddress=ait->mBit; 00460 } 00461 } 00462 } 00463 // prep state data 00464 if(mpSensorEdges) delete mpSensorEdges; 00465 if(mpRecentSensorEdges) delete mpRecentSensorEdges; 00466 mpSensorEdges = new Edges[mMaxBitAddress+1]; 00467 mpRecentSensorEdges = new Edges[mMaxBitAddress+1]; 00468 } 00469 00470 //CycleTime(void) 00471 int sDevice::CycleTime(void) const { 00472 //Report current cycle time 00473 00474 FD_DHV("sDevice(" << mName << ")::CycleTime()"); 00475 return mCycleTime; 00476 } 00477 00478 //CycleTime(int) 00479 void sDevice::CycleTime(int cycleTime) { 00480 //Set cycle time 00481 FD_DHV("sDevice(" << mName << ")::CycleTime(int)"); 00482 if( mState==Up || mState==StartUp){ 00483 std::stringstream errstr; 00484 errstr << "Changing cycle-time not possible while background thread is still running "; 00485 throw Exception("sDevice::CycleTime: ", errstr.str(), 100); 00486 } 00487 mCycleTime = cycleTime; 00488 } 00489 00490 00491 //ReadSignal(int) 00492 bool sDevice::ReadSignal(int bit){ 00493 FD_DH("sDevice(" << mName << ")::ReadSignal(int)"); 00494 00495 // make sure device is able to read signals 00496 if(Sensors().Empty()){ 00497 std::stringstream errstr; 00498 errstr << "(" << mName << ") is not able to read signals"; 00499 throw Exception("sDevice::ReadSignal():", errstr.str(), 552); //TODO: number! 00500 } 00501 00502 // run with hooks 00503 bool res=false; 00504 if(DoReadSignalsPre()) 00505 res=DoReadSignal(bit); 00506 DoReadSignalsPost(); 00507 00508 return res; 00509 } 00510 00511 //WriteSignal(int,int) 00512 void sDevice::WriteSignal(int bit, bool value){ 00513 // write one actor value, adressed by bit number (0 to 63); 00514 00515 FD_DHV("sDevice(" << mName << ")::WriteSignal(int)"); 00516 // make sure device is able to read signals 00517 if(Actuators().Empty()){ 00518 std::stringstream errstr; 00519 errstr << "(" << mName << ") is not able to write signals"; 00520 throw Exception("sDevice::WriteSignal():", errstr.str(), 552); //TODO: number! 00521 } 00522 00523 // run with hooks 00524 if(DoWriteSignalsPre()) 00525 DoWriteSignal(bit,value); 00526 DoWriteSignalsPost(); 00527 } 00528 00529 00530 //SDeviceSynchro(void*) 00531 void* SDeviceSynchro(void* arg){ 00532 //background-thread main-routine 00533 00534 // cast this object 00535 sDevice* sdevice = static_cast<sDevice*>(arg); 00536 00537 FD_DHV("sDevice(" << sdevice->mName << ")::Synchro(" << sdevice << "): with ct " << sdevice->mCycleTime); 00538 00539 ///////////////////////////////////////////////////// 00540 // cyletime-measurement 00541 // timeA: time consumed for a hole cycle 00542 // timeB: time consumed by computation 00543 // timeC: real time consumed by usleep 00544 //////////////////////////////////////////////////// 00545 #ifdef FAUDES_DEBUG_IOTIMING_X 00546 //arrays to store measured time in 00547 timeval* timeA = new timeval[MAX_SAMPLES]; 00548 timeval* timeB = new timeval[MAX_SAMPLES]; 00549 timeval* timeC = new timeval[MAX_SAMPLES]; 00550 // define local itterator 00551 int itime=0; 00552 // take time 00553 gettimeofday(timeA+itime,0); 00554 #endif 00555 00556 bool running=true; 00557 00558 while(running){ 00559 // lock global variables 00560 TLOCK_E; 00561 if(sdevice->DoReadSignalsPre()) { 00562 // edge detection, accumulative 00563 for(int bit = 0; bit<=sdevice->mMaxBitAddress; bit++) { 00564 // define pointer to Sensoredges 00565 sDevice::Edges* edge= &sdevice->mpSensorEdges[bit]; 00566 // pass edge-info about edge in last cycle 00567 edge->past = edge->current; 00568 // and get corresponding sensor-value 00569 edge->current = sdevice->ReadSignal(bit); 00570 if(edge->posrel) 00571 if( edge->current && (!edge->past) ) { 00572 /* 00573 if(edge->pos && (!edge->lost)) { 00574 FD_DH("sDevice::synchro: lost positive edge at bit address " << bit); 00575 edge->lost=true; 00576 } 00577 */ 00578 FD_DH("sDevice::synchro: sensed positive edge at bit address " << bit); 00579 edge->pos = true; 00580 // queue events to buffer 00581 pthread_mutex_lock(sdevice->pBufferMutex); 00582 EventSet::Iterator eit=sdevice->mSensorPosEdgeIndexMap[bit].Begin(); 00583 EventSet::Iterator eit_end=sdevice->mSensorPosEdgeIndexMap[bit].End(); 00584 for(; eit!=eit_end; eit++) { 00585 sdevice->pSensorBuffer->push_back(*eit); 00586 } 00587 pthread_mutex_unlock(sdevice->pBufferMutex); 00588 //send signal to function "WaitSenosrs()" 00589 FD_DH("sDevice::synchro: send signal " ); 00590 pthread_cond_broadcast(sdevice->pWaitCondition); 00591 } 00592 if(edge->negrel) 00593 if( (!edge->current) && edge->past ) { 00594 FD_DH("sDevice::synchro: sensed negative edge at bit address " << bit); 00595 edge->neg = true; 00596 sdevice->mSensorReady = true; 00597 // queue events to buffer 00598 pthread_mutex_lock(sdevice->pBufferMutex); 00599 EventSet::Iterator eit=sdevice->mSensorNegEdgeIndexMap[bit].Begin(); 00600 EventSet::Iterator eit_end=sdevice->mSensorNegEdgeIndexMap[bit].End(); 00601 for(; eit!=eit_end; eit++) { 00602 sdevice->pSensorBuffer->push_back(*eit); 00603 } 00604 pthread_mutex_unlock(sdevice->pBufferMutex); 00605 //send signal to function "WaitSenosrs" 00606 FD_DH("sDevice::synchro: send signal " ); 00607 pthread_cond_broadcast(sdevice->pWaitCondition); 00608 } 00609 } // loop bits 00610 } // if device ok 00611 sdevice->DoReadSignalsPost(); 00612 // check for cancel request 00613 if(sdevice->mCancelRequest) running=false; 00614 // unlock global variables 00615 TUNLOCK_E; 00616 00617 ////////////////////////////////////// 00618 //cycletime measurement 00619 //measure time to perform computation 00620 #ifdef FAUDES_DEBUG_IOTIMING_X 00621 if(itime < MAX_SAMPLES) gettimeofday(timeB+itime,0); 00622 #endif 00623 00624 // let time pass; todo: use proper timer 00625 usleep(sdevice->mCycleTime); 00626 00627 #ifdef FAUDES_DEBUG_IOTIMING_X 00628 ////////////////////////////////////// 00629 // cycletime measurement 00630 00631 // measure time consumed by wait 00632 if(itime < MAX_SAMPLES) gettimeofday(timeC+itime,0); 00633 // measure time needed for a hole cyle 00634 // increase iterator 00635 itime++; 00636 if(itime < MAX_SAMPLES) gettimeofday(timeA+itime,0); 00637 00638 #endif 00639 // count cycles 00640 sdevice->mCycleCount++; 00641 } // loop while running 00642 00643 00644 #ifdef FAUDES_DEBUG_IOTIMING_X 00645 00646 ///////////////////////////////////////////// 00647 // cycletime measurement 00648 // analysis using SampleDensityFunction 00649 FD_DHT("sDevice::synchro: performance analysis"); 00650 00651 SampledDensityFunction SamplesA; 00652 SamplesA.Clear(); 00653 SamplesA.Dim(100); 00654 SamplesA.Name("time stamp AA: overall period"); 00655 00656 SampledDensityFunction SamplesB; 00657 SamplesB.Clear(); 00658 SamplesB.Dim(100); 00659 SamplesB.Name("time stamp AB: process time"); 00660 00661 SampledDensityFunction SamplesC; 00662 SamplesC.Clear(); 00663 SamplesC.Dim(100); 00664 SamplesC.Name("time stamp CB: waited time"); 00665 00666 SampledDensityFunction SamplesWS; 00667 SamplesWS.Clear(); 00668 SamplesWS.Dim(100); 00669 SamplesWS.Name("time passed till the next call of WaitSensors"); 00670 00671 // timeval-structures needed for further computations 00672 timeval dAA,dBA,dCB,dER; 00673 00674 // perform analysis 00675 // time for a hole cycle 00676 for(int ind = 0; ind < itime-2; ind++){ 00677 // compute time needed 00678 // for a hole cycle 00679 dAA = vDevice::DiffTime(timeA[ind+1],timeA[ind]); 00680 // for coputing sensor-state 00681 dBA = vDevice::DiffTime(timeB[ind],timeA[ind]); 00682 // by usleep(mCyleTime) 00683 dCB = vDevice::DiffTime(timeC[ind],timeB[ind]); 00684 // time passed by until the next call of WaitSensors 00685 dER = vDevice::DiffTime(sdevice->mptimeBegin[ind+1],sdevice->mptimeEnd[ind]); 00686 // add computed samples to corresponding 00687 // SampleDensityFunction classes 00688 SamplesA.Sample(dAA.tv_sec*1000000 + dAA.tv_usec); 00689 SamplesB.Sample(dBA.tv_sec*1000000 + dBA.tv_usec); 00690 SamplesC.Sample(dCB.tv_sec*1000000 + dCB.tv_usec); 00691 SamplesWS.Sample(1000000*dER.tv_sec + dER.tv_usec); 00692 } 00693 00694 // perform statistic computation 00695 SamplesA.Compile(); 00696 SamplesB.Compile(); 00697 SamplesC.Compile(); 00698 SamplesWS.Compile(); 00699 00700 // token output 00701 // SamplesA.Write(); 00702 // SamplesB.Write(); 00703 // SamplesC.Write(); 00704 // SamplesWS.Write(); 00705 00706 // pretty output 00707 std::cout << SamplesA.Str() << std::endl; 00708 std::cout << SamplesB.Str() << std::endl; 00709 std::cout << SamplesC.Str() << std::endl; 00710 std::cout << SamplesWS.Str() << std::endl; 00711 #endif 00712 FD_DH("sDevice(" << sdevice->mName << ")::synchro: terminate background thread"); 00713 pthread_exit(NULL); 00714 // never happens, prevent gcc warning 00715 return NULL; 00716 } 00717 00718 // Write Actuator(Idx) 00719 void sDevice::WriteActuator(Idx actuator) { 00720 00721 FD_DHV("sDevice("<<mName<<")::WriteActuator"); 00722 //return if device is running 00723 if(mState!=Up && mState!=StartUp) return; 00724 //make sure event is part of devices eventset 00725 if(!mActuators.Exists(actuator)) { 00726 std::stringstream errstr; 00727 errstr << "Unknown actuator event " << actuator; 00728 throw Exception("sDevice::WriteActuator", errstr.str(), 65); 00729 } 00730 // find properties 00731 const AttributeSignalActuator* aattr = pConfiguration->Attribute(actuator).Actuatorp(); 00732 if(!aattr) { 00733 std::stringstream errstr; 00734 errstr << "Invalid actuator attribute " << actuator; 00735 throw Exception("sDevice::WriteActuator", errstr.str(), 65); 00736 } 00737 //debug-flag 00738 FD_DH("sDevice("<<mName<<")::WriteActuator: properties found"); 00739 //execute command 00740 std::vector<AttributeSignalActuator::Action>::const_iterator eit; 00741 // run with hooks 00742 if(DoWriteSignalsPre()) { 00743 for(eit=aattr->mActions.begin(); eit!=aattr->mActions.end(); eit++){ 00744 FD_DH("sDevice("<<mName<<")::WriteActuator: mBit "<<eit->mBit<< " mValue "<<eit->mValue); 00745 DoWriteSignal(eit->mBit,eit->mValue); 00746 } 00747 } 00748 DoWriteSignalsPost(); 00749 FD_DHV("sDevice("<<mName<<")::WriteActuator: done"); 00750 } 00751 00752 //ClrSensorSignals() 00753 void sDevice::ClrSensorSignals(void) { 00754 //helper: clear all sensor state 00755 00756 FD_DHV("sDevice("<<mName<<")::ClrSensorSignals(): MaxBitAddress: " << mMaxBitAddress); 00757 //return if device is not running or device is not able to read sensors 00758 if(!(mState!=Up||Sensors().Empty())) { 00759 // lock global variables 00760 FD_DHV("sDevice("<<mName<<")::ClrSensorSignals(): lock mutex "); 00761 LOCK_E; 00762 FD_DHV("sDevice("<<mName<<")::ClrSensorSignals(): edge detection "); 00763 // initialise edge detection 00764 for(int bit = 0;bit<=mMaxBitAddress;bit++) { 00765 Edges* edge= &mpSensorEdges[bit]; 00766 FD_DHV("sDevice("<<mName<<")::ClrSensorSignals(): edge detetion ReadSignal bit " << bit); 00767 edge->current=ReadSignal(bit); 00768 edge->past = edge->current; 00769 edge->pos = false; 00770 edge->neg = false; 00771 edge->posrel = (!mSensorPosEdgeIndexMap[bit].Empty()); 00772 edge->negrel = (!mSensorNegEdgeIndexMap[bit].Empty()); 00773 edge->lost = false; 00774 } 00775 // initialize recent edges 00776 FD_DHV("sDevice("<<mName<<")::ClrSensorSignals(): initialize recent edges "); 00777 for(int bit = 0;bit<=mMaxBitAddress;bit++) { 00778 Edges* redge= &mpRecentSensorEdges[bit]; 00779 redge->pos = false; 00780 redge->neg = false; 00781 redge->posrel = false; 00782 redge->negrel = false; 00783 redge->lost = false; 00784 } 00785 // reset cyclecount 00786 mCycleCount=0; 00787 mRecentCycleCount=0; 00788 mSensorReady=false; 00789 // unlock global variables 00790 UNLOCK_E; 00791 } 00792 FD_DHV("sDevice("<<mName<<")::ClrSensorSignals(): done"); 00793 } 00794 00795 //ClrActuatorSignals() 00796 void sDevice::ClrActuatorSignals(void) { 00797 //clear all actuator lines 00798 FD_DHV("sDevice("<<mName<<")::ClrActuatorSignals"); 00799 //return if device is running or not abel to set actuator signals 00800 if(!(mState!=Up||Actuators().Empty())){ 00801 //stop all actuators 00802 for(int bit=0; bit<=mMaxBitAddress; bit++) WriteSignal(bit, false); 00803 } 00804 } 00805 00806 }//end namespace faudes 00807 00808 |
libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6