00001
00002 #include <fesa-core-gsi/RealTime/TimingSimulationEventSource.h>
00003 #include <fesa-core-gsi/Synchronization/TimingSimulationContext.h>
00004
00005 #include <vector>
00006 #include <fesa-core/Utilities/XMLParser.h>
00007 #include <fesa-core/Diagnostic/FesaLogger.h>
00008 #include <fesa-core/Utilities/ParserElements/EventElement.h>
00009 #include <fesa-core/Utilities/ParserElements/ParserElementDefs.h>
00010 #include <fesa-core/Diagnostic/Diagnostics.h>
00011
00012 #include <cmw-log/Logger.h>
00013
00014
00015 namespace
00016 {
00017
00018 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core-gsi.RealTime.TimingEventSource");
00019 const std::string diagTopic = fesa::DiagnosticUtils::eventTrackingStr;
00020
00021 }
00022
00023 namespace fesaGSI
00024 {
00025 TimingSimulationEventSource::SimulationEvent::SimulationEvent(std::string& className, CycleConfig& cycle, DomainConfig* domain, long absOff,long relativEventTimeInCycle, EventConfig* eventConfig) :
00026 delay_(0), absOffset_(absOff), nextEvent_(NULL),eventConfig_(eventConfig)
00027 {
00028
00029 className_ = className;
00030 cycleID_ = cycle.cycleID_;
00031 cycleName_ = cycle.cycleName_;
00032 domainName_ = domain->name_;
00033 relativEventTimeInCycle_ = relativEventTimeInCycle;
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 }
00055
00056 TimingSimulationEventSource::TimingSimulationEventSource(const std::string& name,const std::string& timingSimulationConfigFile,fesa::EventSourceType type) : fesa::AbstractEventSource(name,type)
00057 {
00058 timingConfiguration_ = new TimingSimulationConfig(timingSimulationConfigFile);
00059 simulationEventSequence_ = NULL;
00060 eventSequenceBuild_ = false;
00061 fillEventCollection();
00062 }
00063
00064 TimingSimulationEventSource::~TimingSimulationEventSource()
00065 {
00066
00067 SimulationEvent * pEventSequence = simulationEventSequence_;
00068 while (pEventSequence)
00069 {
00070 SimulationEvent * pTmp = pEventSequence;
00071 pEventSequence = pEventSequence->nextEvent_;
00072 delete pTmp;
00073 }
00074 delete timingConfiguration_;
00075 }
00076
00077 fesa::RTEvent* TimingSimulationEventSource::wait()
00078 {
00079 if (!eventSequenceBuild_)
00080 {
00081 buildEventSequence();
00082 currentEvent_ = simulationEventSequence_;
00083 superCycleCount_ = timingConfiguration_->superCycleRepetition_;
00084 }
00085
00086 while (superCycleCount_ != 0)
00087 {
00088 if (currentEvent_->delay_)
00089 {
00090 time_t sec = currentEvent_->delay_ / 1000;
00091 long long nsec = (currentEvent_->delay_ - sec * 1000) * 1000000;
00092
00093
00094
00095 nsec -= 10000000;
00096 if (nsec < 0)
00097 nsec = 0;
00098 struct timespec delay = { sec, nsec };
00099 nanosleep(&delay, 0);
00100 }
00101
00102 if (currentEvent_->nextEvent_ == NULL)
00103 {
00104 if(superCycleCount_ != -1)
00105 superCycleCount_--;
00106 currentEvent_ = simulationEventSequence_;
00107 }
00108 else
00109 {
00110 currentEvent_ = currentEvent_->nextEvent_;
00111 }
00112
00113 if (currentEvent_->className_ == "")
00114 {
00115 std::stringstream buf;
00116 std::ostringstream errorStrStream;
00117 errorStrStream << "| The execution of the event " << currentEvent_->eventConfig_->eventName_ << " was skipped, since there is no class in this fesa-equipment which is triggered by the event |";
00118 LOG_ERROR_IF(logger, errorStrStream.str());
00119
00120 throw GSIException(__FILE__,__LINE__,FesaGSIUnusedEventSkipped.c_str(),currentEvent_->eventConfig_->eventName_.c_str());
00121 }
00122
00123 std::string fullEventname = currentEvent_->className_+"::"+currentEvent_->eventConfig_->eventName_;
00124
00125
00126 TimingSimulationContext *context = new TimingSimulationContext(currentEvent_->domainName_,currentEvent_->cycleID_, currentEvent_->cycleName_,currentEvent_->relativEventTimeInCycle_);
00127
00128
00129 context->setCycleTimeStamp();
00130
00131 fesa::RTEvent * rtEvent = new fesa::RTEvent(fullEventname, context,this);
00132 return rtEvent;
00133 }
00134
00135
00136 struct timespec delay = { 20, 0 };
00137 std::stringstream buf;
00138 std::ostringstream errorStrStream;
00139 errorStrStream << "|Timing simulation finished. Running infinite sleep-loop now|";
00140 LOG_ERROR_IF(logger, errorStrStream.str());
00141
00142 while(true)
00143 {
00144 nanosleep(&delay, 0);
00145 }
00146 }
00147
00148 void TimingSimulationEventSource::fillEventCollection()
00149 {
00150 std::vector<DomainConfig*>::iterator domainIter;
00151 std::vector<CycleConfig>::iterator cycleIter;
00152 std::vector<EventConfig*>::iterator eventIter;
00153 for (domainIter = timingConfiguration_->timingDomainCol_.begin(); domainIter != timingConfiguration_->timingDomainCol_.end(); domainIter++)
00154 {
00155 for(cycleIter = (*domainIter)->superCycle_.cycleCol_.begin(); cycleIter != (*domainIter)->superCycle_.cycleCol_.end(); cycleIter++)
00156 {
00157 cycleIter->eventSequenceRef_->events_.begin();
00158 for (eventIter = cycleIter->eventSequenceRef_->events_.begin(); eventIter != cycleIter->eventSequenceRef_->events_.end(); eventIter++)
00159 {
00160 std::map<std::string, std::vector<std::string> >::iterator tempIter;
00161 tempIter = eventClassRelationCol_.find((*eventIter)->eventName_);
00162 if (tempIter == eventClassRelationCol_.end())
00163 {
00164 std::vector<std::string> vec;
00165 eventClassRelationCol_.insert(make_pair((*eventIter)->eventName_,vec));
00166 }
00167 }
00168 }
00169 }
00170 }
00171
00172 void TimingSimulationEventSource::connect(boost::shared_ptr<fesa::EventElement>& eventElement)
00173 {
00174 std::string concreteEventName = eventElement->getSourceTypeSpecificData(fesa::TIMING_TAG_CONCRETE_NAME);
00175
00176
00177
00178 size_t pos= concreteEventName.find(':');
00179 std::string className = concreteEventName.substr(0, pos);
00180 std::string eventName = concreteEventName.substr(pos+2);
00181
00182 std::map<std::string, std::vector<std::string> >::iterator iter;
00183 iter = eventClassRelationCol_.find(eventName);
00184 if (iter == eventClassRelationCol_.end())
00185 {
00186 throw GSIException(__FILE__,__LINE__,FesaGSIMissingEventConfiguration.c_str(),eventName.c_str());
00187 }
00188 else
00189 {
00190 (*iter).second.push_back(className);
00191 }
00192 }
00193
00194 void TimingSimulationEventSource::buildEventSequence()
00195 {
00196 long absStartCycleOffset = 0;
00197
00198
00199 computeSuperCycleLength();
00200
00201
00202 checkTimingSimulationConfig();
00203
00204 std::vector<DomainConfig*>::iterator domainIter;
00205 for (domainIter = timingConfiguration_->timingDomainCol_.begin(); domainIter != timingConfiguration_->timingDomainCol_.end(); domainIter++)
00206 {
00207 if(!(*domainIter)->enable_)
00208 continue;
00209
00210 absStartCycleOffset += (*domainIter)->superCycle_.shiftDelay_;
00211
00212 std::vector<CycleConfig>::iterator cycleIter;
00213 for (cycleIter = (*domainIter)->superCycle_.cycleCol_.begin(); cycleIter != (*domainIter)->superCycle_.cycleCol_.end(); cycleIter++)
00214 {
00215 std::vector<EventConfig*>::iterator eventIter;
00216 for (eventIter = cycleIter->eventSequenceRef_->events_.begin(); eventIter != cycleIter->eventSequenceRef_->events_.end(); eventIter++)
00217 {
00218 createSimulationEvent(*eventIter, absStartCycleOffset, *cycleIter, *domainIter);
00219
00220 }
00221
00222 absStartCycleOffset += cycleIter->basicPeriodMultiple_ * timingConfiguration_->basicPeriodLengthMs_;
00223
00224 if (absStartCycleOffset > superCycleLength_)
00225 absStartCycleOffset = absStartCycleOffset - superCycleLength_;
00226 }
00227
00228 computeDelays();
00229 }
00230
00231 eventSequenceBuild_ = true;
00232 }
00233
00234 void TimingSimulationEventSource::insertSorted(SimulationEvent * newEvent)
00235 {
00236 if (simulationEventSequence_ == NULL)
00237 {
00238 simulationEventSequence_ = newEvent;
00239 return;
00240 }
00241
00242 if (newEvent->absOffset_ <= simulationEventSequence_->absOffset_)
00243 {
00244 newEvent->nextEvent_ = simulationEventSequence_;
00245 simulationEventSequence_ = newEvent;
00246 return;
00247 }
00248
00249 SimulationEvent * temp = simulationEventSequence_->nextEvent_;
00250 SimulationEvent * prev = simulationEventSequence_;
00251 while(temp!= NULL)
00252 {
00253 if(newEvent->absOffset_ <= temp->absOffset_)
00254 {
00255 newEvent->nextEvent_ = temp;
00256 prev->nextEvent_ = newEvent;
00257 return;
00258 }
00259 else
00260 {
00261 prev = temp;
00262 temp = temp->nextEvent_;
00263 }
00264 }
00265 prev->nextEvent_ = newEvent;
00266 }
00267
00268
00269 void TimingSimulationEventSource::computeDelays()
00270 {
00271 long prevOffset = 0;
00272 SimulationEvent * pEvent = simulationEventSequence_;
00273 while (pEvent)
00274 {
00275 pEvent->delay_ = pEvent->absOffset_ - prevOffset;
00276 prevOffset = pEvent->absOffset_;
00277 pEvent = pEvent->nextEvent_;
00278 }
00279 }
00280
00281 void TimingSimulationEventSource::computeSuperCycleLength()
00282 {
00283 long maxSuperCycleLenght = 0;
00284
00285 std::vector<DomainConfig*>::iterator timingDomainColIter;
00286 for (timingDomainColIter = timingConfiguration_->timingDomainCol_.begin(); timingDomainColIter != timingConfiguration_->timingDomainCol_.end(); timingDomainColIter++)
00287 {
00288 if(!(*timingDomainColIter)->enable_)
00289 continue;
00290
00291 std::vector<CycleConfig>::iterator cycleColIter;
00292 for (cycleColIter = (*timingDomainColIter)->superCycle_.cycleCol_.begin();cycleColIter!=(*timingDomainColIter)->superCycle_.cycleCol_.end();cycleColIter++)
00293 {
00294 maxSuperCycleLenght += cycleColIter->basicPeriodMultiple_;
00295 }
00296 }
00297 superCycleLength_ = maxSuperCycleLenght * timingConfiguration_->basicPeriodLengthMs_;
00298 }
00299
00300 void TimingSimulationEventSource::checkTimingSimulationConfig()
00301 {
00302 int scShiftDelayFlag = 0;
00303 bool enabledDomainON = false;
00304
00305 std::vector<DomainConfig*>::iterator domainColIter;
00306 for (domainColIter = timingConfiguration_->timingDomainCol_.begin(); domainColIter != timingConfiguration_->timingDomainCol_.end(); domainColIter++)
00307 {
00308 if(!(*domainColIter)->enable_)
00309 continue;
00310
00311 enabledDomainON |= (*domainColIter)->enable_;
00312
00313
00314 if ((*domainColIter)->superCycle_.shiftDelay_ == 0)
00315 scShiftDelayFlag++;
00316
00317 long absStartCycleOffset = (*domainColIter)->superCycle_.shiftDelay_;
00318
00319 std::vector<CycleConfig> cycleCol = (*domainColIter)->superCycle_.cycleCol_;
00320 long lastCycleLength = cycleCol.end()->basicPeriodMultiple_;
00321 long prevStartCycleOffset = (*domainColIter)->superCycle_.shiftDelay_ + superCycleLength_
00322 - lastCycleLength * timingConfiguration_->basicPeriodLengthMs_;
00323 if (prevStartCycleOffset > superCycleLength_)
00324 prevStartCycleOffset = prevStartCycleOffset - superCycleLength_;
00325
00326 std::vector<CycleConfig>::iterator cycleIter;
00327 std::vector<EventConfig*>::iterator eventIter;
00328 for(cycleIter= cycleCol.begin();cycleIter!= cycleCol.end();cycleIter++)
00329 {
00330 for(eventIter=cycleIter->eventSequenceRef_->events_.begin();eventIter!=cycleIter->eventSequenceRef_->events_.end();eventIter++)
00331 {
00332 if((*eventIter)->type_ == EventBurst)
00333 {
00334 EventBurstConfig* burstElement = static_cast<EventBurstConfig*> (*eventIter);
00335
00336 for (unsigned long m = burstElement->occurrences_; m > 0; m--)
00337 {
00338 long eventAbsOffset = absStartCycleOffset + burstElement->delay_
00339 + (burstElement->occurrences_ - m) * burstElement->period_;
00340
00341 if (eventAbsOffset < 0)
00342 eventAbsOffset = eventAbsOffset + superCycleLength_;
00343
00344 long cycleEnd = absStartCycleOffset + cycleIter->basicPeriodMultiple_ * timingConfiguration_->basicPeriodLengthMs_;
00345
00346 if (((burstElement->delay_ > 0) && (eventAbsOffset > cycleEnd)) || ((burstElement->delay_ < 0) && (eventAbsOffset < prevStartCycleOffset)))
00347 {
00348 std::stringstream buf;
00349 buf << burstElement->delay_;
00350 throw GSIException(__FILE__,__LINE__,FESAGSIErrorEventDelayOutOfRange.c_str(),
00351 burstElement->eventName_.c_str(), cycleIter->cycleName_.c_str(),
00352 buf.str().c_str());
00353 }
00354 }
00355 }
00356 }
00357 }
00358
00359 if (enabledDomainON == false)
00360 throw GSIException(__FILE__,__LINE__,FESAGSIErrorNoneDomainEnabled.c_str());
00361
00362 if (scShiftDelayFlag > 1)
00363 throw GSIException(__FILE__,__LINE__,FESAGSIErrorMoreThanOneDomainShift0.c_str());
00364 }
00365 }
00366
00367 void TimingSimulationEventSource::createSimulationEvent(EventConfig *config, long absStartCycleOffset, CycleConfig& cycle, DomainConfig* domain)
00368 {
00369 long eventPeriod = 0;
00370 unsigned long eventOccurence = 1;
00371
00372 EventBurstConfig* burstElement = NULL;
00373 if (config->type_ == EventBurst)
00374 {
00375 burstElement = static_cast<EventBurstConfig*> (config);
00376 eventOccurence = burstElement->occurrences_;
00377 eventPeriod = burstElement->period_;
00378 }
00379
00380 for (unsigned i = eventOccurence; i > 0; i--)
00381 {
00382 long eventAbsOffset = absStartCycleOffset + config->delay_ + (eventOccurence - i) * eventPeriod;
00383 long relativEventTimeInCycle = config->delay_+ (eventOccurence - i) * eventPeriod;
00384
00385 if (eventAbsOffset < 0)
00386 eventAbsOffset = eventAbsOffset + superCycleLength_;
00387 else if (eventAbsOffset > superCycleLength_)
00388 {
00389 eventAbsOffset = eventAbsOffset - superCycleLength_;
00390 }
00391
00392
00393 std::map<std::string, std::vector<std::string> >::iterator iter;
00394 iter = eventClassRelationCol_.find(config->eventName_);
00395 if (iter->second.size() != 0)
00396 {
00397 std::vector<std::string>::iterator classIter;
00398 for(classIter = iter->second.begin();classIter != iter->second.end();classIter++)
00399 {
00400
00401 SimulationEvent * simEvent = new SimulationEvent(*classIter,cycle,domain, eventAbsOffset,relativEventTimeInCycle,config);
00402 insertSorted(simEvent);
00403 }
00404 }
00405 else
00406 {
00407
00408 std::string empty = "";
00409 SimulationEvent * simEvent = new SimulationEvent(empty,cycle,domain, eventAbsOffset,relativEventTimeInCycle,config);
00410 insertSorted(simEvent);
00411 }
00412 }
00413 }
00414 }