$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef _ots_FEVInterface_h_ 00002 #define _ots_FEVInterface_h_ 00003 00004 #define TRACE_NAME "FEVInterface" 00005 #include "artdaq/DAQdata/Globals.hh" 00006 00007 #include "otsdaq-core/Configurable/Configurable.h" 00008 #include "otsdaq-core/FECore/FESlowControlsWorkLoop.h" 00009 #include "otsdaq-core/FiniteStateMachine/VStateMachine.h" 00010 #include "otsdaq-core/WorkLoopManager/WorkLoop.h" 00011 00012 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h" 00013 00014 #include "otsdaq-core/SupervisorInfo/AllSupervisorInfo.h" //to send errors to Gateway, e.g. 00015 00016 #include "otsdaq-core/CoreSupervisors/FESupervisor.h" 00017 00018 #include "otsdaq-core/FECore/FESlowControlsChannel.h" 00019 #include "otsdaq-core/SOAPUtilities/SOAPMessenger.h" //for xdaq::ApplicationDescriptor communication 00020 00021 #include <array> 00022 #include <iostream> 00023 #include <string> 00024 #include <vector> 00025 00026 #include "otsdaq-core/Macros/CoutMacros.h" 00027 00028 #define __ARGS__ \ 00029 const frontEndMacroStruct_t & feMacroStruct, \ 00030 FEVInterface::frontEndMacroConstArgs_t argsIn, \ 00031 FEVInterface::frontEndMacroArgs_t argsOut 00032 00033 #define __GET_ARG_IN__(X, Y) getFEMacroConstArgumentValue<Y>(argsIn, X) 00034 #define __GET_ARG_OUT__(X, Y) getFEMacroArgumentValue<Y>(argsOut, X) 00035 00036 #define __SET_ARG_IN__(X, Y) FEVInterface::emplaceFEMacroArgumentValue(argsIn, X, Y) 00037 #define __SET_ARG_OUT__(X, Y) FEVInterface::setFEMacroArgumentValue(argsOut, X, Y) 00038 00039 namespace ots 00040 { 00041 // class SlowControlsChannelInfo; 00042 class FEVInterfacesManager; 00043 00044 // FEVInterface 00045 // This class is a virtual class defining the features of front-end interface plugin 00046 // class. The features include configuration hooks, finite state machine handlers, 00047 // Front-end Macros for web accessible C++ handlers, slow controls hooks, as well as 00048 // universal write and read for Macro Maker compatibility. 00049 // 00050 // It inherits workloop as 'public virtual' for the case that other classes like 00051 // DataProducer will also be inherited by child class and only one workloop is 00052 // desired. 00053 class FEVInterface : public VStateMachine, public WorkLoop, public Configurable 00054 { 00055 friend class FEVInterfacesManager; 00056 00057 public: 00058 FEVInterface(const std::string& interfaceUID, 00059 const ConfigurationTree& theXDAQContextConfigTree, 00060 const std::string& configurationPath); 00061 00062 virtual ~FEVInterface(void); 00063 00064 FEVInterfacesManager* parentInterfaceManager_; 00065 00066 const std::string& getInterfaceUID(void) const { return interfaceUID_; } 00067 virtual std::string getInterfaceType(void) const 00068 { 00069 return theXDAQContextConfigTree_.getBackNode(theConfigurationPath_) 00070 .getNode("FEInterfacePluginName") 00071 .getValue<std::string>(); 00072 } // interfaceType_;} 00073 00074 virtual void universalRead( 00075 char* address, 00076 char* returnValue) = 0; // throw std::runtime_error exception on error/timeout 00077 virtual void universalWrite(char* address, char* writeValue) = 0; 00078 const unsigned int& getUniversalAddressSize(void) { return universalAddressSize_; } 00079 const unsigned int& getUniversalDataSize(void) { return universalDataSize_; } 00080 00081 void runSequenceOfCommands(const std::string& treeLinkName); 00082 00083 static void sendAsyncErrorToGateway(FEVInterface* fe, 00084 const std::string& errMsg, 00085 bool isSoftError); 00086 00088 // start State Machine handlers 00089 void configure(void) 00090 { 00091 __COUT__ << "\t Configure" << std::endl; 00092 runSequenceOfCommands( 00093 "LinkToConfigureSequence"); /*Run Configure Sequence Commands*/ 00094 } 00095 void start(std::string runNumber) 00096 { 00097 __COUT__ << "\t Start" << std::endl; 00098 runSequenceOfCommands("LinkToStartSequence"); /*Run Start Sequence Commands*/ 00099 } 00100 void stop(void) 00101 { 00102 __COUT__ << "\t Stop" << std::endl; 00103 runSequenceOfCommands("LinkToStopSequence"); /*Run Stop Sequence Commands*/ 00104 } 00105 void halt(void) { stop(); } 00106 void pause(void) { stop(); } 00107 void resume(void) { start(""); } 00108 bool running(void) { /*while(WorkLoop::continueWorkLoop_){;}*/ return false; } 00109 // end State Machine handlers 00111 00113 // start Slow Controls 00114 void configureSlowControls(void); 00115 bool slowControlsRunning(void); // slow controls workloop calls this 00116 void startSlowControlsWorkLooop(void) { slowControlsWorkLoop_.startWorkLoop(); } 00117 void stopSlowControlsWorkLooop(void) { slowControlsWorkLoop_.stopWorkLoop(); } 00118 // end Slow Controls 00120 00122 // start FE Macros 00123 00124 // public types and functions for map of FE macros 00125 using frontEndMacroArg_t = 00126 std::pair<const std::string /* arg name */, std::string /* arg return value */>; 00127 using frontEndMacroArgs_t = std::vector<frontEndMacroArg_t>&; 00128 using frontEndMacroConstArgs_t = const std::vector<frontEndMacroArg_t>&; 00129 struct frontEndMacroStruct_t; // declare name for __ARGS__ 00130 using frontEndMacroFunction_t = void (ots::FEVInterface::*)( 00131 __ARGS__); // void function (vector-of-inputs, vector-of-outputs) 00132 struct frontEndMacroStruct_t // members fully define a front-end macro function 00133 { 00134 frontEndMacroStruct_t( 00135 const std::string& feMacroName, 00136 const frontEndMacroFunction_t& feMacroFunction, 00137 const std::vector<std::string>& namesOfInputArgs, 00138 const std::vector<std::string>& namesOfOutputArgs, 00139 const uint8_t requiredUserPermissions = 1 /*1:=user,255:=admin*/, 00140 const std::string& allowedCallingFrontEnds = 00141 "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/) 00142 : feMacroName_(feMacroName) 00143 , macroFunction_(feMacroFunction) 00144 , namesOfInputArguments_(namesOfInputArgs) 00145 , namesOfOutputArguments_(namesOfOutputArgs) 00146 , requiredUserPermissions_(requiredUserPermissions) 00147 , allowedCallingFrontEnds_(allowedCallingFrontEnds) 00148 { 00149 } 00150 00151 const std::string feMacroName_; 00152 const frontEndMacroFunction_t 00153 macroFunction_; // Note: must be called using this instance 00154 const std::vector<std::string> namesOfInputArguments_, namesOfOutputArguments_; 00155 const uint8_t requiredUserPermissions_; 00156 const std::string allowedCallingFrontEnds_; 00157 }; 00158 const std::map<std::string, frontEndMacroStruct_t>& getMapOfFEMacroFunctions(void) 00159 { 00160 return mapOfFEMacroFunctions_; 00161 } 00162 void runSelfFrontEndMacro( 00163 const std::string& feMacroName, 00164 const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs, 00165 std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs); 00166 // end FE Macros 00168 00170 // start Macros 00171 struct macroStruct_t 00172 { 00173 macroStruct_t(const std::string& macroString); 00174 00175 enum 00176 { 00177 OP_TYPE_READ, 00178 OP_TYPE_WRITE, 00179 OP_TYPE_DELAY, 00180 }; 00181 00182 struct readOp_t 00183 { 00184 uint64_t address_; 00185 bool addressIsVar_; 00186 std::string addressVarName_; 00187 bool dataIsVar_; 00188 std::string dataVarName_; 00189 }; // end macroStruct_t::writeOp_t declaration 00190 00191 struct writeOp_t 00192 { 00193 uint64_t address_; 00194 bool addressIsVar_; 00195 std::string addressVarName_; 00196 uint64_t data_; 00197 bool dataIsVar_; 00198 std::string dataVarName_; 00199 }; // end macroStruct_t::writeOp_t declaration 00200 00201 struct delayOp_t 00202 { 00203 uint64_t delay_; // milliseconds 00204 bool delayIsVar_; 00205 std::string delayVarName_; 00206 }; // end macroStruct_t::writeOp_t declaration 00207 00208 std::string macroName_; 00209 std::vector<std::pair<unsigned int /*op type*/, 00210 unsigned int /*index in specific type vector*/> > 00211 operations_; 00212 std::vector<macroStruct_t::readOp_t> readOps_; 00213 std::vector<macroStruct_t::writeOp_t> writeOps_; 00214 std::vector<macroStruct_t::delayOp_t> delayOps_; 00215 std::set<std::string> namesOfInputArguments_, namesOfOutputArguments_; 00216 bool lsbf_; // least significant byte first 00217 }; // end macroStruct_t declaration 00218 protected: 00219 void runMacro(FEVInterface::macroStruct_t& macro, 00220 std::map<std::string /*name*/, uint64_t /*value*/>& variableMap); 00221 00222 public: 00223 // end FE Macros 00225 00227 // start FE communication helpers 00228 00229 template<class T> 00230 void sendToFrontEnd(const std::string& targetInterfaceID, const T& value) const; 00231 void runFrontEndMacro( 00232 const std::string& targetInterfaceID, 00233 const std::string& feMacroName, 00234 const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs, 00235 std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs) const; 00236 00238 // receiveFromFrontEnd 00239 // * can be used for source interface ID to accept a message from any front-end 00240 // NOTE: can not overload functions based on return type, so T& passed as value 00241 template<class T> 00242 void receiveFromFrontEnd(const std::string& requester, 00243 T& retValue, 00244 unsigned int timeoutInSeconds = 1) const; 00245 // specialized template function for T=std::string 00246 void receiveFromFrontEnd(const std::string& requester, 00247 std::string& retValue, 00248 unsigned int timeoutInSeconds = 1) const; 00249 // NOTE: can not overload functions based on return type, so calls function with T& 00250 // passed as value 00251 template<class T> 00252 T receiveFromFrontEnd(const std::string& requester = "*", 00253 unsigned int timeoutInSeconds = 1) const; 00254 // specialized template function for T=std::string 00255 std::string receiveFromFrontEnd(const std::string& requester = "*", 00256 unsigned int timeoutInSeconds = 1) const; 00257 00258 // end FE Communication helpers 00260 00261 protected: 00262 bool workLoopThread(toolbox::task::WorkLoop* workLoop); 00263 std::string interfaceUID_; 00264 00265 unsigned int universalAddressSize_ = 0; 00266 unsigned int universalDataSize_ = 0; 00267 00268 // Controls members 00269 std::map<std::string, FESlowControlsChannel> mapOfSlowControlsChannels_; 00270 FESlowControlsWorkLoop slowControlsWorkLoop_; 00271 00272 // FE Macro Function members and helper functions: 00273 00274 std::map<std::string, frontEndMacroStruct_t> 00275 mapOfFEMacroFunctions_; // Map of FE Macro functions members 00276 void registerFEMacroFunction( 00277 const std::string& feMacroName, 00278 frontEndMacroFunction_t feMacroFunction, 00279 const std::vector<std::string>& namesOfInputArgs, 00280 const std::vector<std::string>& namesOfOutputArgs, 00281 uint8_t requiredUserPermissions = 1 /*1:=user,255:=admin*/, 00282 const std::string& allowedCallingFEs = 00283 "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/); 00284 00285 public: // for external specialized template access 00286 static const std::string& getFEMacroConstArgument(frontEndMacroConstArgs_t args, 00287 const std::string& argName); 00288 static std::string& getFEMacroArgument(frontEndMacroArgs_t args, 00289 const std::string& argName); 00290 00291 protected: 00292 template<class T> 00293 std::string& setFEMacroArgumentValue(frontEndMacroArgs_t args, 00294 const std::string& argName, 00295 const T& value) const; 00296 // { 00297 // //modify existing pair 00298 // std::string& arg = getFEMacroArgument(args,argName); 00299 // std::stringstream ss; ss << value; 00300 // arg = ss.str(); 00301 // return arg; 00302 // } 00303 template<class T> 00304 std::string& emplaceFEMacroArgumentValue(frontEndMacroArgs_t args, 00305 const std::string& argName, 00306 const T& value) const; 00307 // { 00308 // //insert new pair 00309 // std::stringstream ss; ss << value; 00310 // args.push_back(frontEndMacroArg_t(argName, ss.str())); 00311 // return args.back().second; 00312 // } 00313 00314 }; // end FEVInterface class 00315 00316 template<class T> 00317 T getFEMacroConstArgumentValue(FEVInterface::frontEndMacroConstArgs_t args, 00318 const std::string& argName); 00319 // specialized template version of getFEMacroConstArgumentValue for string 00320 template<> 00321 std::string getFEMacroConstArgumentValue<std::string>( 00322 FEVInterface::frontEndMacroConstArgs_t args, const std::string& argName); 00323 00324 template<class T> 00325 T getFEMacroArgumentValue(FEVInterface::frontEndMacroArgs_t args, 00326 const std::string& argName); 00327 00328 // specialized template version of getFEMacroArgumentValue for string 00329 template<> 00330 std::string getFEMacroArgumentValue<std::string>(FEVInterface::frontEndMacroArgs_t argsIn, 00331 const std::string& argName); 00332 00333 // include template definitions required at include level for compiler 00334 #include "otsdaq-core/FECore/FEVInterface.icc" 00335 00336 } // namespace ots 00337 00338 #endif