/* * iocCommDefs.cc * * These functions are defined for using IOC shell commands * to configure the voltage IOCs * * Created on: July 26, 2014 * Author: Hovanes Egiyan */ #include #include #include #include #include #include #include "epicsExport.h" #include "baseDetector.hh" #include "dbCrate.hh" using namespace std; // Global variable to setup the prefix for EPICS records using detector hierarchy names. // This prefix will not show up as a prefix in the hardware hierarchy names since it is // controlled by iocPrefix variables defined in the code below. string detectorRecordPrefix; extern "C" { // -------------------------------------------- // // Definition of the detectorRecordPrefix // static const iocshArg detUsePrefixArg0 = { "Prefix", iocshArgString }; static const iocshArg *detUsePrefixArgs[] = { &detUsePrefixArg0, }; static const iocshFuncDef detUsePrefixFuncDef = { "detUsePrefix", 1, detUsePrefixArgs }; /* Wrapper called by iocsh, selects the argument types that function needs */ static void detUsePrefixCallFunc(const iocshArgBuf *args) { if (args[0].sval == NULL) { detectorRecordPrefix = ""; } else { detectorRecordPrefix = args[0].sval; } return; } /* Registration routine, runs at startup */ static void detUsePrefixRegister(void) { iocshRegister(&detUsePrefixFuncDef, detUsePrefixCallFunc); } //---------------------------------------------------------------------------- // // Crate configuration part for detectors for the IOC shell // static const iocshArg configureDetectorArg0 = { "Detector", iocshArgString }; static const iocshArg configureDetectorArg1 = { "URI", iocshArgString }; static const iocshArg *configureDetectorArgs[] = { &configureDetectorArg0, &configureDetectorArg1 }; static const iocshFuncDef configureDetectorFuncDef = { "configureDetector", 2, configureDetectorArgs }; /* Wrapper called by iocsh, selects the argument types that function needs */ static void configureDetectorCallFunc(const iocshArgBuf *args) { // dbSubsystem::openDB( args[1].sval ); // Crate a new detector. The object will stay until the end of program execution // although the detectors are being tracked by baseDetector object itself. // baseDetector* newDetector = new baseDetector( args[0].sval ); cout << "Will configure a new detector " << args[0].sval << " using DB " << args[1].sval << endl; // new baseDetector( args[0].sval, args[1].sval ); detectorFactory::createDetector( args[0].sval, args[1].sval ); } /* Registration routine, runs at startup */ static void configureDetectorRegister(void) { iocshRegister(&configureDetectorFuncDef, configureDetectorCallFunc); } //----------------------------------------------------------------------------- // // Detector DB loading function call definition part // static const iocshArg detDbLoadRecordsArg0 = { "Crate Name", iocshArgString }; static const iocshArg detDbLoadRecordsArg1 = { "Slot", iocshArgInt }; static const iocshArg detDbLoadRecordsArg2 = { "IOC Prefix", iocshArgString }; static const iocshArg *detDbLoadRecordsArgs[] = { &detDbLoadRecordsArg0, &detDbLoadRecordsArg1, &detDbLoadRecordsArg2 }; static const iocshFuncDef detDbLoadRecordsFuncDef = {"detDbLoadRecords", 3, detDbLoadRecordsArgs}; /* Wrapper called by iocsh, selects the argument types that function needs */ static void detDbLoadRecordsCallFunc(const iocshArgBuf *args) { string crateName = args[0].sval; // Crate name to load. "" means all crates. int slot = args[1].ival; // Slot number to load. -1 means all slots string iocPrefix = args[2].sval; // Prefix to be used for EPICS record names based on geographical address cout << "Loading with prefix " << iocPrefix << " crateName " << crateName << " slot " << slot << endl; if (args[0].sval == NULL) { if( args[1].ival == -1 ) { std::cout << "Will load EPICS DB for all crates" << std::endl; } else { slot = args[1].ival; std::cout << "Will load EPICS DB for all crates" << " and slot #" << slot<< std::endl; } } else { crateName = args[0].sval; if( args[1].ival >= 0 ) { slot = args[1].ival; std::cout << "Will load EPICS DB for crate " << crateName << " and slot #" << slot << std::endl; } else { slot = args[1].ival; std::cout << "Will load EPICS DB for crate " << crateName << std::endl; } } vector allCrates; // Loop through all the registered detectors and load // the EPICS records for the detector channels map detectorMap = baseDetector::getDetectorMap(); for( map::iterator itDet = detectorMap.begin(); itDet != detectorMap.end(); itDet++ ) { string detName = itDet->first; baseDetector* det = itDet->second; det->loadRecords( detectorRecordPrefix, iocPrefix, crateName, slot ); // Get list of crates in this detector and append to the list of all crates try { vector crates4det = det->getCrateVector(); allCrates.insert( allCrates.end(), crates4det.begin(), crates4det.end() ); } catch ( NoCrateException& e ) { cout << e.what() << endl; cout << "There is no crate to match this detector " << detName << endl; continue; } } // cout << "Got the crate vector" << endl; // std::cout << "All crate map is: " << allCrates << std::endl; // std::copy(allCrates.begin(), allCrates.end(), std::ostream_iterator(std::cout, " ")); // std::cout << endl; // Loop over all crates registered during configuration of the detectors // and configure the crates. map crateMap = dbCrate::getCrateMap(); for( map::iterator itCrate = crateMap.begin(); itCrate != crateMap.end(); itCrate++ ){ string hostName = itCrate->first; dbCrate* cratePtr = itCrate->second; // If crate was not specified or crate name was specified and it matches the one of cratePtr // configure that create cout << "Looking at crate " << cratePtr->getName() << " , requested crate is " << crateName << endl; if( crateName == "" || cratePtr->getName() == crateName ) { cout << "Configuring crate " << cratePtr->getName() << " for slot " << slot << endl; cratePtr->configureCrate( slot ); } } // Load the chassis-based EPICS records for all chassis dbCrate::loadRecords( iocPrefix, crateName, slot ); std::cout << "Records for crate called " << crateName << " slot number " << slot << " are loaded. " << std::endl; return; } /* Registration routine, runs at startup */ static void detDbLoadRecordsRegister(void) { iocshRegister(&detDbLoadRecordsFuncDef, detDbLoadRecordsCallFunc); } epicsExportRegistrar(detUsePrefixRegister); epicsExportRegistrar(configureDetectorRegister); epicsExportRegistrar(detDbLoadRecordsRegister); }