Timing.cpp
Go to the documentation of this file.00001
00002 #include <fesa-core/Synchronization/Timing.h>
00003 #include <fesa-core-gsi/Exception/GSIException.h>
00004 #include <fesa-core/Synchronization/MultiplexingContext.h>
00005 #include <fesa-core/Synchronization/SynchronizationLabObjectFactory.h>
00006 #include <fesa-core-gsi/Synchronization/GSICycleDescriptor.h>
00007 #include <fesa-core-gsi/Exception/GSIException.h>
00008 extern "C"
00009 {
00010 #include <tim/TimLib.h>
00011 }
00012
00013 #include <sys/time.h>
00014
00015 #include <math.h>
00016 #include <string>
00017 #include <iostream>
00018 #include <sstream>
00019
00020 namespace fesa
00021 {
00022
00023 void parseCycleSelector(const std::string& cycleSelector,
00024 fesa::CycleSelector& cycleSelectorStructure) {
00025
00026 std::size_t sep1 = cycleSelector.find('.');
00027 if (sep1 == std::string::npos) {
00028 throw fesaGSI::GSIException(__FILE__, __LINE__, FESAGSIErrorParsingTimingDescriptor.c_str(),
00029 cycleSelector.c_str());
00030 }
00031 cycleSelectorStructure.domain_ = cycleSelector.substr(0, sep1);
00032
00033 std::size_t sep2 = cycleSelector.find('.', sep1 + 1);
00034
00035
00036 if (sep2 == std::string::npos) {
00037 sep2 = cycleSelector.size();
00038 }
00039
00040 cycleSelectorStructure.criterion_ = cycleSelector.substr(sep1 + 1, sep2
00041 - sep1 - 1);
00042 cycleSelectorStructure.value_ = cycleSelector;
00043
00044 }
00045
00046 void validateCycleSelector(fesa::CycleSelector& cycleSelector,
00047 fesa::RequestType requestType) {
00048 if (requestType == fesa::SUBSCRIBE) {
00049
00050
00051
00052
00053
00054
00055 }
00056 }
00057
00058 bool match(const std::string& cycleSelector, fesa::MultiplexingContext* context) {
00059 if (cycleSelector.empty()) {
00060 return true;
00061 }
00062
00063 size_t sep1 = cycleSelector.find('.');
00064 size_t sep2 = cycleSelector.rfind('.');
00065 if ((sep1 == std::string::npos) || (sep2 == std::string::npos)) {
00066 return false;
00067 }
00068
00069 std::string machineName = cycleSelector.substr(0, sep1 - 1);
00070 std::string groupName = cycleSelector.substr(sep1 + 1, sep2 - sep1 - 1);
00071 std::string lineName = cycleSelector.substr(sep2 + 1,
00072 cycleSelector.length() - sep2 - 1);
00073
00074 if (groupName == "USER") {
00075 if (!(context->getCycleName().empty())) {
00076 if ((cycleSelector != context->getCycleName())) {
00077 return false;
00078 }
00079 }
00080 } else {
00081
00082 if (machineName.compare(context->getTimingDomainName()) != 0) {
00083 return false;
00084 }
00085
00086
00087 fesa::SynchronizationLabObjectFactory* syncFactory = fesa::SynchronizationLabObjectFactory::getInstance();
00088 fesaGSI::GSICycleDescriptor* pCd = static_cast<fesaGSI::GSICycleDescriptor*>(syncFactory->getCycleDescriptor(machineName, groupName));
00089
00090 unsigned long groupNumber = (unsigned long) pCd->getTgmGroupId();
00091 unsigned long lineNumber = (unsigned long) pCd->getCycleSelectorId(
00092 lineName);
00093
00094
00095 unsigned long lineValueFromTiming;
00096 unsigned long next = 0;
00097 TimLibError err;
00098 TimLibTime time;
00099 time.Second = (long long) (round(context->getCycleStamp()
00100 / (long long) 1000000000));
00101 time.Nano = context->getCycleStamp() - time.Second;
00102
00103 if ((err = TimLibGetGroupValueFromStamp(time, groupNumber, next,
00104 &lineValueFromTiming)) == TimLibErrorSUCCESS) {
00105 if (lineNumber != lineValueFromTiming) {
00106 return false;
00107 }
00108 } else
00109 {
00110
00111 throw fesaGSI::GSIException(__FILE__, __LINE__, FesaErrorTimingLibAccessFailed.c_str());
00112 return false;
00113 }
00114 }
00115 return true;
00116 }
00117
00118 long long getActualTime(bool& isHwTime) {
00119 TimLibTime hwtime;
00120 TimLibError err = TimLibGetTime(0, &hwtime);
00121
00122 if (!err) {
00123 isHwTime = true;
00124 return (hwtime.Second * (long long) 1000000000 + hwtime.Nano);
00125 } else {
00126 isHwTime = false;
00127 struct timeval now;
00128 gettimeofday(&now, 0);
00129 return (now.tv_sec * (long long) 1000000000 + now.tv_usec
00130 * (long long) 1000);
00131 }
00132 }
00133
00134 std::string getTimeString(long long time, char* format) {
00135
00136 if (time == 0) {
00137 bool isHwTime;
00138 time = getActualTime(isHwTime);
00139 }
00140
00141 int seconds = time / (long long) 1000000000;
00142 int nanos = time - (long long) 1000000000 * seconds;
00143
00144 char timestring[32];
00145 strftime(timestring, sizeof(timestring), format, localtime(
00146 (time_t *) &seconds));
00147
00148
00149 std::stringbuf stb("", std::ios::out);
00150 std::ostream ost(&stb);
00151
00152 ost << timestring << ".";
00153 ost.width(6);
00154 ost.fill('0');
00155 ost << nanos / 1000;
00156
00157 return stb.str();
00158 }
00159
00160 int getCycleTime() {
00161
00162
00163 TimLibError err = TimLibInitialize(TimLibDevice_ANY);
00164 if (err != 0) {
00165 std::cout << "Timing::getCycleTime() error: " << TimLibErrorToString(err)
00166 << std::endl;
00167 return -1;
00168 }
00169 TimLibTime hwtime;
00170 err = TimLibGetTime(0, &hwtime);
00171
00172 if (!err)
00173 return hwtime.CTrain;
00174 return -1;
00175 }
00176 }
00177