From: <ro...@us...> - 2008-07-17 13:57:44
|
Revision: 1918 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1918&view=rev Author: ron-fox Date: 2008-07-17 13:56:13 +0000 (Thu, 17 Jul 2008) Log Message: ----------- Get a bunch of device independent stuff working for the USB readout skeletons. Modified Paths: -------------- trunk/nextgen/base/thread/Synchronizable.h trunk/nextgen/base/thread/dshwrappthreads.h trunk/nextgen/base/thread/dshwrapthreads.h trunk/nextgen/configure.in trunk/nextgen/usb/Makefile.am trunk/nextgen/usb/threadcom/Makefile.am Added Paths: ----------- trunk/nextgen/CRunState.cpp trunk/nextgen/usb/output/COutputThread.cpp trunk/nextgen/usb/output/COutputThread.h trunk/nextgen/usb/output/DataBuffer.cpp trunk/nextgen/usb/output/DataBuffer.h trunk/nextgen/usb/output/Makefile.am trunk/nextgen/usb/tclserver/CControlModule.cpp trunk/nextgen/usb/tclserver/CControlModule.h trunk/nextgen/usb/tclserver/CGetCommand.cpp trunk/nextgen/usb/tclserver/CGetCommand.h trunk/nextgen/usb/tclserver/CModuleCommand.cpp trunk/nextgen/usb/tclserver/CModuleCommand.h trunk/nextgen/usb/tclserver/CSetCommand.cpp trunk/nextgen/usb/tclserver/CSetCommand.h trunk/nextgen/usb/tclserver/CUpdateCommand.cpp trunk/nextgen/usb/tclserver/CUpdateCommand.h trunk/nextgen/usb/tclserver/Makefile.am trunk/nextgen/usb/tclserver/Server.cpp trunk/nextgen/usb/tclserver/TclServer.cpp trunk/nextgen/usb/tclserver/TclServer.h trunk/nextgen/usb/tclserver/server.h trunk/nextgen/usb/tclserver/serverinstance.cpp trunk/nextgen/usb/tclserver/serverinstance.h trunk/nextgen/usb/threadcom/CControlQueues.cpp trunk/nextgen/usb/threadcom/CControlQueues.h trunk/nextgen/usb/threadcom/CRunState.cpp trunk/nextgen/usb/threadcom/CRunState.h Added: trunk/nextgen/CRunState.cpp =================================================================== --- trunk/nextgen/CRunState.cpp (rev 0) +++ trunk/nextgen/CRunState.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,158 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CRunState.h" + +using namespace std; + +// Class level member data: + +CRunState* CRunState::m_pTheInstance(0); + +/*! + Construction For now the default initial state is: + - Title == "Change this title" + - Run NUmber 0 + - State idle. + + \note as befits a singleton pattern, this constructor is private! +*/ +CRunState::CRunState() : + m_title("Change this title"), + m_runNumber(0), + m_state(CRunState::Idle) +{ + m_pTheInstance = this; +} +/*! + Destructor does nothing and, in general should not get called. +*/ +CRunState::~CRunState() +{ +} + +/*! + Get singleton instance: + */ +CRunState* +CRunState::getInstance() +{ + if(!m_pTheInstance) { + m_pTheInstance = new CRunState; + } + return m_pTheInstance; +} + +/*! + Select the currenst state: + \return RunState + \retval current run state value. +*/ +CRunState::RunState +CRunState::getState() +{ + Enter(); + RunState state = m_state; + Leave(); + return state; +} +/*! + Set a new value for the run statel + \param newState : CRunState::RunState + New runstate can be one of CRunState::Idle or CRunState::Active +*/ +void +CRunState::setState(CRunState::RunState state) +{ + Enter(); + m_state = state; + Leave(); +} +/*! + Get the current title. + \return std::string + \retval String containing the run title. +*/ +string +CRunState::getTitle() +{ + Enter(); + string title = m_title; + Leave(); + return title; +} +/*! + Set a new value for the title: + \param newTitle :: std::string + New title string. +*/ +void +CRunState::setTitle(string newTitle) +{ + Enter(); + m_title = newTitle; + Leave(); +} + +/*! + Get the current run number. + \return uint16_t + \retval The current run number. +*/ +uint16_t +CRunState::getRunNumber() +{ + Enter(); + uint16_t run = m_runNumber; + Leave(); + return run; +} +/*! + Set a new run number value: + \param newRunNumber : uint16_t + New value for the run number. +*/ +void +CRunState::setRunNumber(uint16_t newRunNumber) +{ + Enter(); + m_runNumber = newRunNumber; + Leave(); + +} +/*! + Get the number of seconds between scaler readouts: +*/ +uint32_t +CRunState::getScalerPeriod() +{ + uint32_t value; + Enter(); + value = m_scalerPeriod; + Leave(); + return value; +} +/*! + Set the number of seconds between scaler readouts. +*/ +void +CRunState::setScalerPeriod(uint32_t period) +{ + Enter(); + m_scalerPeriod = period; + Leave(); +} Modified: trunk/nextgen/base/thread/Synchronizable.h =================================================================== --- trunk/nextgen/base/thread/Synchronizable.h 2008-07-17 13:46:58 UTC (rev 1917) +++ trunk/nextgen/base/thread/Synchronizable.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -18,9 +18,7 @@ #include <iostream> #include <sstream> -#ifndef DSHWRAPTHREADS_H #include <dshwrapthreads.h> -#endif // forward class references. Modified: trunk/nextgen/base/thread/dshwrappthreads.h =================================================================== --- trunk/nextgen/base/thread/dshwrappthreads.h 2008-07-17 13:46:58 UTC (rev 1917) +++ trunk/nextgen/base/thread/dshwrappthreads.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -12,10 +12,10 @@ -#ifdef USE_PTHREADS + #include <stdlib.h> #include <stdio.h> #include <signal.h> @@ -73,6 +73,6 @@ // How do we display this thing? char *dshwrappthread_tostr(char*,int,dshwrapthread_t); -#endif + #endif Modified: trunk/nextgen/base/thread/dshwrapthreads.h =================================================================== --- trunk/nextgen/base/thread/dshwrapthreads.h 2008-07-17 13:46:58 UTC (rev 1917) +++ trunk/nextgen/base/thread/dshwrapthreads.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -19,7 +19,6 @@ #include <unistd.h> #include <errno.h> -#ifdef USE_PTHREADS #include <dshwrappthreads.h> #define dshwrapthread_create dshwrappthread_create #define dshwrapthread_exit dshwrappthread_exit @@ -39,6 +38,6 @@ #define dshwrapthread_cond_timedwait dshwrappthread_cond_timedwait #define dshwrapthread_tostr dshwrappthread_tostr #define dshwrapthread_mutex_lastmod dshwrappthread_mutex_lastmod -#endif /* USE_PTHREADS */ + #endif Modified: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-07-17 13:46:58 UTC (rev 1917) +++ trunk/nextgen/configure.in 2008-07-17 13:56:13 UTC (rev 1918) @@ -382,6 +382,9 @@ daq/format/Makefile usb/Makefile usb/threadcom/Makefile + usb/tclcommon/Makefile + usb/tclserver/Makefile + usb/output/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/usb/Makefile.am =================================================================== --- trunk/nextgen/usb/Makefile.am 2008-07-17 13:46:58 UTC (rev 1917) +++ trunk/nextgen/usb/Makefile.am 2008-07-17 13:56:13 UTC (rev 1918) @@ -2,4 +2,4 @@ # Builds the VM/CC usb software. It's important to build the common # code first: # -SUBDIRS = threadcom \ No newline at end of file +SUBDIRS = threadcom tclcommon tclserver output \ No newline at end of file Added: trunk/nextgen/usb/output/COutputThread.cpp =================================================================== --- trunk/nextgen/usb/output/COutputThread.cpp (rev 0) +++ trunk/nextgen/usb/output/COutputThread.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,307 @@ + + +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "COutputThread.h" +#include "CRunState.h" +#include "DataBuffer.h" +#include <string> +#include <Exception.h> + + +#include <assert.h> +#include <buftypes.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <iostream> +#include <CRingBuffer.h> +#include <CRingItem.h> +#include <CRingPhysicsEventCountItem.h> +#include <CRingScalerItem.h> +#include <CRingStateChangeItem.h> +#include <DataFormat.h> + + +#include <unistd.h> +#include <pwd.h> +#include <sys/types.h> + + + +using namespace std; + +static DataBuffer* lastBuffer(0); +static const unsigned ReadoutStack(0); +static const unsigned ScalerStack(1); + + +//////////////////////////////////////////////////////////////////////// +///////////////////// Construction and destruction ///////////////////// +//////////////////////////////////////////////////////////////////////// + +/*! + Create an outupt thread. Should only create 1 however if the + following were parameters could create multiple: + - Event buffer queue. + - Free buffer queue. + - Run state. + - Open the ring. + + In future applications this could be done to manage multiple VM-USB + controlled VME crates in 'singles mode'... or with a subsequent chunk of + software on the end of spectrodaq assembling data. + +*/ +COutputThread::COutputThread() : + m_pRing(0) +{ + openRing(); // Open ring named after the user in localhost. + // the ring is created if necessary. +} +/*! + Disconnect from the ring. +*/ +COutputThread::~COutputThread() +{ + delete m_pRing; +} + +//////////////////////////////////////////////////////////////////////// +////////////////////// Thread entry point... /////////////////////////// +//////////////////////////////////////////////////////////////////////// + +/* + Thread entry point. This is just an infinite buffer processing loop. +*/ +void +COutputThread::run() +{ + // Main loop is pretty simple. + try { + while(1) { + + DataBuffer& buffer(getBuffer()); + processBuffer(buffer); + freeBuffer(buffer); + + } + + } + catch (string msg) { + cerr << "COutput thread caught a string exception: " << msg << endl; + throw; + } + catch (char* msg) { + cerr << "COutput thread caught a char* exception: " << msg << endl; + throw; + } + catch (CException& err) { + cerr << "COutputThread thread caught a daq exception: " + << err.ReasonText() << " while " << err.WasDoing() << endl; + throw; + } + catch (...) { + cerr << "COutput thread caught some other exception type.\n"; + throw; + } + +} + + +/* + Get a buffer from the event queue. A reference to the buffer will + be returned. + + Note that this will block if needed to wait for a buffer. + note as well that between runs, we'll wind up blocking in here. + +*/ +DataBuffer& +COutputThread::getBuffer() +{ + DataBuffer* pBuffer = gFilledBuffers.get(); // Will block if needed. + return *pBuffer; + +} +/* + Free a buffer that has been completely processed. + This will return the buffer to the gFreeBuffers queue. + Parameters: + DataBuffer& buffer - Reference to the buffer to return. + +*/ +void +COutputThread::freeBuffer(DataBuffer& buffer) +{ + gFreeBuffers.queue(&buffer); +} +/* + Process a buffer from the reader. At this time we are just going + to figure out what type of buffer we have and dispatch accordingly. + Buffers are as follows: + Begin run is indicated by the type in the DataBuffer, all others look like + data buffers. + End run is indicated by the last bit set in the vmusb header. + scaler is indicated by the scaler bit in the vm usb header. + All others are event data. + Parameters: + DataBuffer& buffer - The buffer from the readout thread. +*/ +void +COutputThread::processBuffer(DataBuffer& buffer) +{ + if (buffer.s_bufferType == 1) { + startRun(buffer.s_timeStamp); + } + else if (buffer.s_bufferType == 2) { + endRun(buffer.s_timeStamp); + } + else { + processUSBData(buffer); // will callback. + } +} + + +/* + Create a begin run item on behalf of the concrete subclass/thread. + \param when - Time the run began. + \note Much of the information about the run is implicit input from the + runstat object. +*/ +void +COutputThread::startRun(time_t when) +{ + // Update our concept of run state, and buffer size: + + CRunState* pState = CRunState::getInstance(); + m_runNumber = pState->getRunNumber(); + m_title = pState->getTitle(); + m_startTimestamp = when; + m_lastStampedBuffer = 0; + m_eventCount = 0; + + CRingStateChangeItem item(BEGIN_RUN, + m_runNumber, + 0, + when, + m_title); + item.commitToRing(*m_pRing); + + +} +/* + Called to emit an end run item for the + caller. + \param when - timestamp of the end run. +*/ +void +COutputThread::endRun(time_t when) +{ + + CRingStateChangeItem item(END_RUN, + m_runNumber, + when - m_startTimestamp, + when, + m_title); + item.commitToRing(*m_pRing); + +} + +/* + Create a scaler item for the caller. + \param when - Absolute time the scaler buffer is being emitted. + \param number- Number of scalers in the item. + \param pScalers - Pointer to the scalers. + +*/ +void +COutputThread::scaler(time_t when, int number, uint32_t* pScalers) +{ + + uint32_t startTime = m_lastStampedBuffer; + uint32_t endTime = when; + m_lastStampedBuffer= when; + + CRingScalerItem item(number); + item.setStartTime(startTime); + item.setEndTime(endTime); + item.setTimestamp(when); + for (int i = 0; i < number; i++) { + item.setScaler(i, *pScalers++); + } + item.commitToRing(*m_pRing); + +} +/*! + Create an event item. + \param size - number of uint16_t's in the event. + \param pData- Pointer to the data words. + +*/ + +void +COutputThread::event(uint32_t size, void* pData) +{ + uint32_t bytes = size*sizeof(uint16_t); + CRingItem item(PHYSICS_EVENT, bytes); + + uint8_t* pDest = reinterpret_cast<uint8_t*>(item.getBodyCursor()); + memcpy(pDest, pData, bytes); + + pDest += bytes; + item.setBodyCursor(pDest); + + item.commitToRing(*m_pRing); + + m_eventCount++; +} +/*! + Produce an event count item on behalf of the client. + We've been maintaining a count of the events in a run for the caller. + \param when -tim3 when this should be emitted. + +*/ +void +COutputThread::eventCount(time_t when) +{ + CRingPhysicsEventCountItem item(m_eventCount, + when - m_startTimestamp, + when); + item.commitToRing(*m_pRing); + +} + +////////////////////////////////////////////////////////////////////////////////// +// +// Utilities. +// + +/* +** Open the ring. The ring name is just the user name. +*/ +void +COutputThread::openRing() +{ + uid_t uid = getuid(); + passwd* pPass = getpwuid(uid); + string name(pPass->pw_name); + + m_pRing = new CRingBuffer(name, CRingBuffer::producer); +} Added: trunk/nextgen/usb/output/COutputThread.h =================================================================== --- trunk/nextgen/usb/output/COutputThread.h (rev 0) +++ trunk/nextgen/usb/output/COutputThread.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,149 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __COUTPUTTHREAD_H +#define __COUTPUTTHREAD_H + +#ifndef __THREAD_H +#include <Thread.h> +#endif + +#ifndef __CRT_STDINT_H +#include <stdint.h> +#ifndef __CRT_STDINT_H +#define __CRT_STDINT_H +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + +// Forward definitions: + +struct DataBuffer; +class CRingBuffer; +/*! + This class bridges the gap between the buffer format of the + USB devices and ring buffers. + + The data + we are using will come from a buffer queue. Elements + of the buffer queue will have the following format: + +\verbatim + +--------------------------------+ + | Buffer size | + +--------------------------------+ + | Buffer Type | + +--------------------------------+ + | Time stamp | + +--------------------------------+ + | Buffer contents as gotten | + | from the device, see the | + | manual | + +- - - - - - -- - - - - - - - - -+ + +\endverbatim + + -# Buffer size is gotten from the read from the device + and indicates the number of bytes of data + in the body and its header word (does not include either itself nor + the buffer type. + -# The buffer type is one of the following: + - 1 Run starting... in this case there will be no VM-USB body. + - 2 USB data note that run end is determined by seeing the + last buffer indicator in the buffer. + -# We will generate only the following sorts of NSCL data buffers: + - 11 Begin run. + - 12 End Run + - 1 Physics data + - 2 Scaler Data. + -# Time stamp is result of time(2) when the buffer was received from + the VMUSB. + + \note This class is a separate thread of execution. + \note This is an abstract base class that captures the common elements + of the output thread for the CC and VM usb devices. + \note A global variable: gFilledBuffers is a CBufferQueue that contains + the data shown above and is used to receive raw data buffers from + the readout thread. + \note There is no need to start/stop thread each run. Once a run is over, + this thread will simply block on the buffer queue until the next run + emits the begin run buffer. +*/ + +class COutputThread : public Thread +{ + // Thread local data: +private: + // These are fetched from the CRun state at start of run. + + uint32_t m_runNumber; // Run number; + std::string m_title; // Run title + + // other data: +private: + time_t m_startTimestamp; //!< Run start time. + time_t m_lastStampedBuffer; //!< Seconds into run of last stamped buffer + uint64_t m_eventCount; //!< Number of events this run. + CRingBuffer* m_pRing; // Where the data goes.. + + // Constuctors and other canonicals. + +public: + COutputThread(); + virtual ~COutputThread(); +private: + COutputThread(const COutputThread& rhs); + COutputThread& operator=(const COutputThread& rhs); + int operator==(const COutputThread& rhs) const; + int operator!=(const COutputThread& rhs) const; +public: + + // Thread operations are all non-public in fact.. don't want to call them + // from outside this class.. only from within the thread.. This includes the + // thread entry point. + +protected: + + virtual void run(); + + DataBuffer& getBuffer(); + void freeBuffer(DataBuffer& buffer); + + void processBuffer(DataBuffer& buffer); + virtual void processUSBData(DataBuffer& buffer); + + void startRun(time_t when); + void endRun(time_t when); + void scaler(time_t when, + int number, + uint32_t* pScalers); + void event(uint32_t size, + void* pData); + void eventCount(time_t when); + + +private: + void openRing(); + +}; + +#endif Added: trunk/nextgen/usb/output/DataBuffer.cpp =================================================================== --- trunk/nextgen/usb/output/DataBuffer.cpp (rev 0) +++ trunk/nextgen/usb/output/DataBuffer.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,61 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + + + +// This file contains the two buffer queues for event data and +// unbound functions that create and destroy event data buffers. +// + +#include <config.h> + +#include "DataBuffer.h" +#include <stdlib.h> +#include <unistd.h> + + +// Buffer queues that communicate between the readout and routing threads: + +CBufferQueue<DataBuffer*> gFilledBuffers; +CBufferQueue<DataBuffer*> gFreeBuffers; + +/*! + Create a new data buffer. + \param bodySize - Number of 16 bit words in the body. + + \return DataBuffer* + \retval A pointer to the newly created data buffer. It is up to the caller + to decide what to do with it (e.g. we don't insert it into the + gFreeBuffers queue +*/ + +DataBuffer* +createDataBuffer(uint32_t bodySize) +{ + size_t bytes = sizeof(struct DataBuffer) + (bodySize-1)*sizeof(uint16_t); + DataBuffer* p = static_cast<DataBuffer*>(malloc(bytes)); + p->s_storageSize = bodySize; + return p; +} +/*! + Free storage that was allocated by a data buffer. It would be a very bad + thing if this data buffer were in one of the buffer queues when destroyed! +*/ +void +destroyDataBuffer(DataBuffer* pBuffer) +{ + free(pBuffer); +} Added: trunk/nextgen/usb/output/DataBuffer.h =================================================================== --- trunk/nextgen/usb/output/DataBuffer.h (rev 0) +++ trunk/nextgen/usb/output/DataBuffer.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,73 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#ifndef __CRT_STDINT_H +#include <stdint.h> +#ifndef __CRT_STDINT_H +#define __CRT_STDINT_H +#endif +#endif + +#ifndef __CRT_UNISTD_H +#include <unistd.h> +#ifndef __CRT_UNISTD_H +#define __CRT_UNISTD_H +#endif +#endif + +#ifndef __CRT_TIME_H +#include <time.h> +#ifndef __CRT_TIME_H +#define __CRT_TIME_H +#endif +#endif + +#ifndef __CBUFFERQUEUE_h +#include <CBufferQueue.h> +#endif + +/*! + \file DataBuffer + Defines the structure of data buffers that will be + passed around from readout thread to output thread. + These are managed in two buffer queues.: + gFilledBuffers is the queue of buffers with data and + gFreeBuffers is a queue of empty buffers available for + use by the readout thread. +*/ +struct DataBuffer { + uint32_t s_bufferSize; //!< Bytes used in the buffer. + uint32_t s_storageSize; //!< bytes in s_rawData[]. + uint32_t s_bufferType; //!< Type of buffer. + time_t s_timeStamp; //!< When the buffer was received. + uint16_t s_rawData[1]; //!< Really larger than that + +}; + + +extern CBufferQueue<DataBuffer*> gFilledBuffers; +extern CBufferQueue<DataBuffer*> gFreeBuffers; + +// A couple of useful unbound functions: + +extern DataBuffer* createDataBuffer(uint32_t bodySize); //!< Create a new data buffer. +extern void destroyDataBuffer(DataBuffer* pBuffer); //!< Free data buffer. + + +// Buffer types; + +static const int TYPE_START(1); +static const int TYPE_STOP(2); +static const int TYPE_EVENTS(3); Added: trunk/nextgen/usb/output/Makefile.am =================================================================== --- trunk/nextgen/usb/output/Makefile.am (rev 0) +++ trunk/nextgen/usb/output/Makefile.am 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,21 @@ +lib_LTLIBRARIES = libOutputStage.la + +libOutputStage_la_SOURCES = DataBuffer.cpp \ + COutputThread.cpp + +noinst_HEADERS = DataBuffer.h \ + COutputThread.h + + +INCLUDES = -I@top_srcdir@/daq/format \ + -I@top_srcdir@/base/dataflow \ + -I@top_srcdir@/base/exception \ + -I@top_srcdir@/base/headers \ + -I@top_srcdir@/base/thread \ + -I@top_srcdir@/usb/threadcom + +libOutputStage_la_LIBADD = @top_srcdir@/daq/format/libdataformat.la \ + @top_srcdir@/base/dataflow/libDataFlow.la \ + @top_srcdir@/base/exception/libException.la \ + @top_srcdir@/base/thread/libdaqthreads.la \ + @top_srcdir@/usb/threadcom/libThreadComm.la \ No newline at end of file Added: trunk/nextgen/usb/tclserver/CControlModule.cpp =================================================================== --- trunk/nextgen/usb/tclserver/CControlModule.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/CControlModule.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,82 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CControlModule.h" +#include <CRunState.h> +#include <CControlQueues.h> + +using namespace std; + +//////////////////////////////////////////////////////////////////////////////////// +// +// Constructors and canonicals. +// + +/*! + Constructing a module is essentially a no-op. + An external entity will need to invoke Attach to attach a + CItemConfiguration to this object. That will in turn + invoke the onAttach function. We can't do that in the + constructor (much as I'd like to), since in constructors, + virtual functions are all confined to the textual class, rather than the + run-time class, and therefore, the wrong onAttach will get called. + +*/ +CControlModule::CControlModule() +{} + +CControlModule::~CControlModule() +{} + +CControlModule::CControlModule(const CControlModule& rhs) : + CConfigurableObject(rhs) +{} + + +CControlModule& +CControlModule::operator=(const CControlModule& rhs) +{ + return dynamic_cast<CControlModule&>(CConfigurableObject::operator=(rhs)); +} + + +int +CControlModule::operator==(const CControlModule& rhs) const +{ + return CConfigurableObject::operator==(rhs); +} + +int +CControlModule::operator!=(const CControlModule& rhs) const +{ + return !(*this == rhs); +} +///////////////////////////////////////////////////////////////////////////////// +// +// Virtual functions: + +/*! + Initialize is called to obtain access to the hardware and + do any one-time device setup. + It is optional. The default implementation here is a no-op. +*/ +void +CControlModule::Initialize() +{} + + + Added: trunk/nextgen/usb/tclserver/CControlModule.h =================================================================== --- trunk/nextgen/usb/tclserver/CControlModule.h (rev 0) +++ trunk/nextgen/usb/tclserver/CControlModule.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,98 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CCONTROLMODULE_H +#define __CCONTROLMODULE_H + +#ifndef __CCONFIGURABLEOBJECT_H +#include <CConfigurableObject.h> +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + + +/*! + This is the base class for programmable electronics that are not read out in events. + Since the USB controllers can only be talked to by a single process, and since they + must be taken out of data taking mode before single shot operations can be performed, + The readout frameworks support a Tcl Server taht can be sent commands to control + specific electronic hardware. + + Each specific framework (e.g. VM-USB or CC-USB) will define a set of supported + control modules. The Tcl server takes care of: + - Initializing the set of objects that get instantiated, and their configuration + (e.g. base addresses or slot numbers) via a configuration script that is analagous + to the daqconfig.tcl (controlconfig.tcl). script. + - If necessary, halting and restarting data taking in order to slip a control function + in in the middle of an active run. + - Dispatching requests received by clients to the appropriate objects. + + This is possible because requests to the server are of one of the following forms: + + - Set objectname parametername value + - Get objectname parametername + - Update objectname + + where the Set command modifes a settable named parameter in the object named + objectname to value, Get returns the value of the named parameter from the named object, + and Update loads the device with any state held internally by the object (e.g. + recovery after power up). + + + CControlModule is an abstract base class. Concrete implementation will have to implement; + - Set - Process the set command on the object. + - Get - Process the get command on the object. + - Update - Process the update command on the object + - onAttach to manage the configuration parameters accepted by the module. + - clone() Create a copy of this object. + - Optionally Initialize. + +*/ +class CControlModule : public CConfigurableObject +{ + +public: + + // Canonicals + + CControlModule(); + virtual ~CControlModule(); + CControlModule(const CControlModule& rhs); + CControlModule& operator=(const CControlModule& rhs); + +private: + int operator==(const CControlModule& rhs) const; + int operator!=(const CControlModule& rhs) const; +public: + // Functions: + + virtual void Initialize(); + virtual void onAttach() = 0; // Attach/init configuration + virtual std::string Update() = 0; // Update hardware + virtual std::string Set(const char* what, + const char* value) = 0; // Set a device parameter. + virtual std::string Get(const char* what) = 0; // Return a device parameter. + virtual CControlModule* clone() = 0; // Virtual copy constructor. +}; + + +#endif Added: trunk/nextgen/usb/tclserver/CGetCommand.cpp =================================================================== --- trunk/nextgen/usb/tclserver/CGetCommand.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/CGetCommand.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,76 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + + +#include <config.h> +#include "CGetCommand.h" + +#include "TclServer.h" +#include <TCLObject.h> +#include <TCLInterpreter.h> +#include "CControlModule.h" +#include <tcl.h> + +using namespace std; + +/*! + Construct the command. +*/ +CGetCommand::CGetCommand(CTCLInterpreter& interp, + TclServer& server) : + CTCLObjectProcessor(interp, "Get"), + m_Server(server) +{} +CGetCommand::~CGetCommand() +{} + +/* + Execute the get command. See the class comments for syntax. +*/ +int +CGetCommand::operator()(CTCLInterpreter& interp, + vector<CTCLObject>& objv) +{ + // Need 3 words on the command line: + + if (objv.size() != 3) { + m_Server.setResult( + "ERROR Get: Incorrect number of command parameters : need Get name point"); + return TCL_ERROR; + } + + // Get the pieces of the command: + + + string name = objv[1]; + string point = objv[2]; + + // Locate the object: + + CControlModule* pModule = m_Server.findModule(name); + if (!pModule) { + string msg("ERROR Get: unable to find module "); + msg += name; + m_Server.setResult( msg); + return TCL_ERROR; + } + + string result = pModule->Get(point.c_str()); + m_Server.setResult( result); + return TCL_OK; + +} + Added: trunk/nextgen/usb/tclserver/CGetCommand.h =================================================================== --- trunk/nextgen/usb/tclserver/CGetCommand.h (rev 0) +++ trunk/nextgen/usb/tclserver/CGetCommand.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,82 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CGETCOMMAND_H +#define __CGETCOMMAND_H + +#ifndef __TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + +class TclServer; +class CTCLObject; +class CTCLInterpreter; +class CVMUSB; + +/*! + CGetCommand implements the Get command this command + retrieves the value of a control point. + The single form is: + + Get name what + + Where: + - name is the name of a control object + - what is the name of a control point within the object. +*/ + +class CGetCommand : public CTCLObjectProcessor +{ + TclServer& m_Server; // Tcl server that is running us. + +public: + CGetCommand(CTCLInterpreter& interp, + TclServer& server); + + virtual ~CGetCommand(); +private: + CGetCommand(const CGetCommand& rhs); + CGetCommand& operator=(const CGetCommand& rhs); + int operator==(const CGetCommand& rhs) const; + int operator!=(const CGetCommand& rhs) const; +public: + + // Command entry point: + +protected: + int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + + +}; + + + +#endif Added: trunk/nextgen/usb/tclserver/CModuleCommand.cpp =================================================================== --- trunk/nextgen/usb/tclserver/CModuleCommand.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/CModuleCommand.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,255 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +using namespace std; + +#include "CModuleCommand.h" +#include <TCLInterpreter.h> +#include <TCLObject.h> +#include <CControlModule.h> +#include <TclServer.h> +#include <CItemConfiguration.h> + + +/*! + Construct the command. + - The base class is created with the command string "Module". + creation is done with registration. + - the member data consists of a reference to the list of currently + defined modules (this is held by the interpreter thread main object + as member data so that it will never go out of scope). + \param interp : CTCLInterpreter& + The interpreter on which this command will be registered. + \param modules : vector<CControlModule*>& + Reference to the list of modules that have been defined already. +*/ +CModuleCommand::CModuleCommand(CTCLInterpreter& interp, + TclServer& server) : + CTCLObjectProcessor(interp, "Module"), + m_Server(server) +{} +//! Destroy the module.. no op provided only as a chain to the base class destructor. +CModuleCommand::~CModuleCommand() +{} + + +/*! + The command executor. The command must have at least 2 object elements: + - the command name ("Module"), + - The subcommand .. which must be either "create", "configure" or cget. + + \param interp : CTCLInterpreter& + Reference to the interpreter that is running this command. + \param vector<TCLObject>& objv + Reference to an array of objectified Tcl_Obj objects that contain the + command line prarameters. + \return int + \retval - TCL_OK - If eveything worked. + \retval - TCL_ERROR - on failures. +*/ +int +CModuleCommand::operator()(CTCLInterpreter& interp, + vector<CTCLObject>& objv) +{ + // validate the parameter count. + + if (objv.size() < 2) { + m_Server.setResult("module: Insufficient parameters need module create | config | cget"); + return TCL_ERROR; + } + + // dispatch to the correct function depending on the command keyword. + + + if (string(objv[1]) == string("create")) { + return create(interp, objv); + } + else if (string(objv[1]) == string("config")) { + return configure(interp, objv); + } + else if (string(objv[1]) == string("cget")) { + return cget(interp, objv); + } + else { + m_Server.setResult("module: Invalid subcommand need module create | config |cget"); + return TCL_ERROR; + } +} +/* + create a new module at present we hardcode the module type to + be jtecgdg. The full form of the command is: + module create jtecgdg name + + This module must later be configured via e.g. + module config name ... + + If module types proliferate a more scalable mechanism like an extensible + object factory might be a better way to do this. +*/ +int +CModuleCommand::create(CTCLInterpreter& interp, + vector<CTCLObject>& objv) +{ + if (objv.size() != 4) { + m_Server.setResult("module create: Wrong number of params need: module create type name"); + return TCL_ERROR; + } + string type = objv[2]; + string name = objv[3]; + + CControlModule* pModule = m_Server.createModule(type); + if (!pModule) { + string result = "No such module type: "; + result += type; + interp.setResult(result); + return TCL_ERROR; + } + + // Create the configuration for the module and attach it: + + CItemConfiguration* pConfiguration = new CItemConfiguration(name); + pModule->Attach(pConfiguration); + m_Server.addModule(pModule); + + + m_Server.setResult(name); + + + return TCL_OK; +} +/*! + Configures a module. The form of the command is: + module config name key1 value1... + + Configuration items are therefore keyword value pairs. + Each pair passed to the configure member of the matching + configuration object. +*/ +int +CModuleCommand::configure(CTCLInterpreter& interp, + vector<CTCLObject>& objv) +{ + // Must be at least 3 command elements and an odd number. + + size_t nelements = objv.size(); + if ((nelements < 3) || ((nelements % 2) == 0)) { + m_Server.setResult("module config : invalid number of command elements."); + return TCL_ERROR; + } + string name = objv[2]; + + CControlModule* pModule = m_Server.findModule(name); + if (!pModule) { + string msg("module config: "); + msg += name; + msg += " not found."; + m_Server.setResult(msg); + return TCL_ERROR; + } + for (int i = 3; i < nelements; i+=2) { + string key = objv[i]; + string value = objv[i+1]; + try { + pModule->configure(key, value); + } + catch (string failmsg) { + string msg("module config: Failed to configure "); + msg += name; + msg += " with: "; + msg += key; + msg += " "; + msg += value; + msg += " because: "; + msg += failmsg; + m_Server.setResult( msg); + return TCL_ERROR; + } + } + + + // Success if we got this far. + + return TCL_OK; // No result string. + +} + +/* + Return a configuration item. There are two forms: + module cget name ?key? + + If key is provided, only that item is returned, as just a simple value. + If key is not provided, the entire configuration is dumped + as a Tcl list of 2 element {key value} sublists. +*/ +int +CModuleCommand::cget(CTCLInterpreter& interp, vector<CTCLObject>& objv) +{ + if ((objv.size() < 3) || (objv.size() > 4)) { + m_Server.setResult("module cget : invalid number of parameters; need module cget name ?key?"); + return TCL_ERROR; + } + + string name = objv[2]; + CControlModule* pModule = m_Server.findModule(name); + if(!pModule) { + string msg("module cget "); + msg += name; + msg += " module not found"; + m_Server.setResult( msg); + return TCL_ERROR; + } + + // The two cases: + + if (objv.size() == 3) { // module cget name - dump the lot. + CItemConfiguration::ConfigurationArray config = pModule->cget(); + Tcl_Obj* result = Tcl_NewListObj(0, NULL); + for (int i =0; i < config.size(); i++) { + string key = config[i].first; + string value = config[i].second; + + Tcl_Obj* keyObj = Tcl_NewStringObj(key.c_str(), -1); + Tcl_Obj* valObj = Tcl_NewStringObj(value.c_str(), -1); + Tcl_Obj* objVector[2] = {keyObj, valObj}; + Tcl_Obj* element = Tcl_NewListObj(2, objVector); + Tcl_ListObjAppendElement(interp, result, element); + + } + Tcl_SetObjResult(interp, result); + return TCL_OK; + } + else { // module cget name key dump the single key. + string key = objv[3]; + string value; + try { + value = pModule->cget(key); + } + catch (string failmsg) { + string msg("module cget: Failed for key: "); + msg += key; + msg += " because: "; + msg += failmsg; + m_Server.setResult( msg); + return TCL_ERROR; + } + m_Server.setResult(value); + return TCL_OK; + + } +} + + Added: trunk/nextgen/usb/tclserver/CModuleCommand.h =================================================================== --- trunk/nextgen/usb/tclserver/CModuleCommand.h (rev 0) +++ trunk/nextgen/usb/tclserver/CModuleCommand.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,86 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CMODULECOMMAND_H +#define __CMODULECOMMAND_H + +#ifndef TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + +class CTCLInterpreter; +class CTCLObject; +class TclServer; +/*! + Implements the module command. This class is subclassed from + CTclObjectProcessor The module command is the command that + each setup script uses to define the set of contrrol modules + that exist. At present, only a single type of control module + is supported: CJTECGDG Jtec/Wiener Gate and Delay generator. +*/ +class CModuleCommand : public CTCLObjectProcessor +{ + // local member data: +private: + TclServer& m_Server; + + // Canonical functions: + +public: + CModuleCommand(CTCLInterpreter& interp, + TclServer& server); + virtual ~CModuleCommand(); + +private: + CModuleCommand(const CModuleCommand& rhs); + CModuleCommand& operator=(const CModuleCommand& rhs); + int operator==(const CModuleCommand& rhs) const; + int operator!=(const CModuleCommand& rhs) const; +public: + + // Virtual function overrides and implementations. +protected: + virtual int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); +private: + int create(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + int configure(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + int cget(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + + + +}; + + +#endif Added: trunk/nextgen/usb/tclserver/CSetCommand.cpp =================================================================== --- trunk/nextgen/usb/tclserver/CSetCommand.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/CSetCommand.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,77 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CSetCommand.h" +#include "TclServer.h" +#include <TCLObject.h> +#include <TCLInterpreter.h> +#include "CControlModule.h" +#include <tcl.h> + +using namespace std; + +/*! + Construct the command. +*/ +CSetCommand::CSetCommand(CTCLInterpreter& interp, + TclServer& server) : + + CTCLObjectProcessor(interp, "Set"), + m_Server(server) +{} +CSetCommand::~CSetCommand() +{} + + + +/* + Execute the set command. Set the class comments for syntax. +*/ +int +CSetCommand::operator()(CTCLInterpreter& interp, + vector<CTCLObject>& objv) +{ + // Must be 4 words in the command: + + if (objv.size() != 4) { + m_Server.setResult("ERROR Set: Incorrect number of command words. Need: Set name point value"); + return TCL_ERROR; + } + // Pull out the values.. All values are strings: + + string name = objv[1]; + string point= objv[2]; + string value= objv[3]; + + // Need to find the module: + + CControlModule* pModule = m_Server.findModule(name); + if (!pModule) { + string msg("ERROR Set: Control module: "); + msg += name; + msg += " cannot be found"; + m_Server.setResult( msg); + + return TCL_ERROR; + } + // Now try the command returning any string error that is thrown: + + string result = pModule->Set(point.c_str(), value.c_str()); + m_Server.setResult( result); + return TCL_OK; + +} Added: trunk/nextgen/usb/tclserver/CSetCommand.h =================================================================== --- trunk/nextgen/usb/tclserver/CSetCommand.h (rev 0) +++ trunk/nextgen/usb/tclserver/CSetCommand.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,87 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CSETCOMMAND_H +#define __CSETCOMMAND_H + +#ifndef __TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + +class TclServer; +class CTCLObject; +class CTCLInterpreter; +class CVMUSB; + +/*! + CSetCommand implements the Set command. + This command sets the value of a control point. + The command has a single form: + + "Set name what value" + + where: + - name is the name of a control object. + - what is the name of a control point within that object. + - value is the new value for that control point. + + Consider for example an 8 channel gate and delay generator named + gdg1 A command like: + + Set gdg1 delay0 10 + + Might set the delay for channel 0 to 10 in that module. +*/ +class CSetCommand : public CTCLObjectProcessor +{ +private: + TclServer& m_Server; // Tcl server that is running us. +public: + CSetCommand(CTCLInterpreter& interp, + TclServer& server); + virtual ~CSetCommand(); +private: + CSetCommand(const CSetCommand& rhs); + CSetCommand& operator=(const CSetCommand& rhs); + int operator==(const CSetCommand& rhs) const; + int operator!=(const CSetCommand& rhs) const; +public: + + // Command entry point: + +protected: + int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + + +}; + +#endif Added: trunk/nextgen/usb/tclserver/CUpdateCommand.cpp =================================================================== --- trunk/nextgen/usb/tclserver/CUpdateCommand.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/CUpdateCommand.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,72 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include <config.h> +#include "CUpdateCommand.h" + +#include "TclServer.h" +#include <TCLObject.h> +#include <TCLInterpreter.h> +#include "CControlModule.h" + +#include <tcl.h> + +using namespace std; + +/*! + Construct the command. +*/ +CUpdateCommand::CUpdateCommand(CTCLInterpreter& interp, + TclServer& server ) : + CTCLObjectProcessor(interp, "Update"), + m_Server(server) +{} +CUpdateCommand::~CUpdateCommand() +{} + +/* + Execute the Update command. See the class comments for syntax. +*/ +int +CUpdateCommand::operator()(CTCLInterpreter& interp, + vector<CTCLObject>& objv) +{ + // Need 2 words on the command line: + + if (objv.size() != 2) { + m_Server.setResult( + "ERROR Update: Incorrect number of command parameters : need Update name"); + return TCL_ERROR; + } + + // Get the pieces of the command: + + + string name = objv[1]; + + // Locate the object: + + CControlModule* pModule = m_Server.findModule(name); + if (!pModule) { + string msg("ERROR Update: unable to find module "); + msg += name; + m_Server.setResult( msg); + return TCL_ERROR; + } + + string result = pModule->Update(); + m_Server.setResult( result); + return TCL_OK; +} Added: trunk/nextgen/usb/tclserver/CUpdateCommand.h =================================================================== --- trunk/nextgen/usb/tclserver/CUpdateCommand.h (rev 0) +++ trunk/nextgen/usb/tclserver/CUpdateCommand.h 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,81 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CUPDATECOMMAND_H +#define __CUPDATECOMMAND_H + +#ifndef __TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + +class TclServer; +class CTCLObject; +class CTCLInterpreter; +class CVMUSB; + +/*! + CUpdateCommand implements the Update command this command + informs a control object to update its values. + The single form is: + + Update name + + Where: + - name is the name of a control object +*/ + +class CUpdateCommand : public CTCLObjectProcessor +{ + TclServer& m_Server; // Tcl server that is running us. + +public: + CUpdateCommand(CTCLInterpreter& interp, + TclServer& server); + virtual ~CUpdateCommand(); +private: + CUpdateCommand(const CUpdateCommand& rhs); + CUpdateCommand& operator=(const CUpdateCommand& rhs); + int operator==(const CUpdateCommand& rhs) const; + int operator!=(const CUpdateCommand& rhs) const; +public: + + // Command entry point: + +protected: + int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + + +}; + + + +#endif Added: trunk/nextgen/usb/tclserver/Makefile.am =================================================================== --- trunk/nextgen/usb/tclserver/Makefile.am (rev 0) +++ trunk/nextgen/usb/tclserver/Makefile.am 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,35 @@ +lib_LTLIBRARIES = libControlServer.la +libControlServer_la_SOURCES = CModuleCommand.cpp \ + TclServer.cpp \ + CControlModule.cpp \ + CSetCommand.cpp \ + serverinstance.cpp \ + CUpdateCommand.cpp \ + CGetCommand.cpp \ + Server.cpp + +include_HEADERS = CSetCommand.h \ + server.h \ + CGetCommand.h \ + CUpdateCommand.h \ + serverinstance.h \ + CControlModule.h \ + CModuleCommand.h \ + TclServer.h + +INCLUDES = -I@top_srcdir@/base/headers \ + -I@top_srcdir@/usb/tclcommon \ + -I@top_srcdir@/usb/threadcom \ + -I@top_srcdir@/base/tclplus \ + -I@top_srcdir@/base/exception \ + -I@top_srcdir@/base/thread \ + @TCL_FLAGS@ + + + +libControlServer_la_LIBADD = @top_srcdir@/usb/tclcommon/libusbtclcommon.la \ + @top_srcdir@/usb/threadcom/libThreadComm.la \ + @top_srcdir@/base/tclplus/libtclPlus.la \ + @top_srcdir@/base/exception/libException.la \ + @top_srcdir@/base/thread/libdaqthreads.la \ + @TCL_LDFLAGS@ \ No newline at end of file Added: trunk/nextgen/usb/tclserver/Server.cpp =================================================================== --- trunk/nextgen/usb/tclserver/Server.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/Server.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,86 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +static const char* Copyright= "(C) Copyright Michigan State University 2002, All rights reserved";/* +** Implementation of Tcl Server connection. +** +*/ +#include <config.h> +#include <tcl.h> +#include <malloc.h> +#include <string.h> +#include <stdio.h> +#include "server.h" +#include "serverinstance.h" +#include <string> +#include <iostream> + +using namespace std; + + + + +static void +Server_Accept(ClientData cd, Tcl_Channel client, char* pHostname, + int nHostport) +{ + + cerr << "Client connection accepted from " << pHostname << endl; + Tcl_Interp* pInterp = (Tcl_Interp*)cd; + + + if (strcmp(pHostname, "127.0.0.1")) { + printf(">>Rejected unauthorized connection from %s on port %d\n", + pHostname, nHostport); + Tcl_Close(pInterp, client); + return; + } + + // Honor the connection + + ServerContext context; + pServerContext pContext = &context; + + + printf("Accepting connection from %s on port %d\n", pHostname, nHostport); + pContext->pInterp = pInterp; + Tcl_DStringInit(&(pContext->RemoteHost)); + Tcl_DStringAppend(&(pContext->RemoteHost), pHostname, -1); + pContext->RemotePort = nHostport; + pContext->DialogChannel = client; + Tcl_DStringInit(&(pContext->command)); + + new CServerInstance(context); + + Tcl_DStringFree(&(context.RemoteHost)); + Tcl_DStringFree(&(context.command)); + +} + +void Server_Init(Tcl_Interp* pInterp, int SERVERPORT) +{ + + // Open the server for business. + + Tcl_OpenTcpServer(pInterp, SERVERPORT, NULL, + Server_Accept, (ClientData)pInterp); + +} + + + + + Property changes on: trunk/nextgen/usb/tclserver/Server.cpp ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/usb/tclserver/TclServer.cpp =================================================================== --- trunk/nextgen/usb/tclserver/TclServer.cpp (rev 0) +++ trunk/nextgen/usb/tclserver/TclServer.cpp 2008-07-17 13:56:13 UTC (rev 1918) @@ -0,0 +1,312 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +using namespace std; + +#include "TclServer.h" +#include "server.h" +#include "serverinstance.h" +#include "CModuleCommand.h" +#include "CSetCommand.h" +#include "CGetCommand.h" +#include "CUpdateCommand.h" + + +#include <tcl.h> +#include <TCLInterpreter.h> +#include "CControlModule.h" +#include <Exception.h> +#include <string> +#include <iostream> + +/*! Constructor is not very interesting 'cause all the action is in + start and operator() +*/ +TclServer::TclServer() : + m_port(-1), + m_configFilename(string("")), + m_pInterpreter(0) +{} +/*! + These threads are built to live 'forever' so the destructor is also +uninteresting. +*/ +TclServer::~TclServer() +{} + +/*! + Start sets up the variables the entry point needs to initialize + and schedules the thread. The thread id is returned to the caller. + Note that while the entry point includes parameters, it's just so much + easier to stuff them into the member data rather than trying to force fit + them to argc,argv formalism in the caller and receiver. + \param port : int + Number of the Tcp/IP port on which we will listen for connections. + \param configFile : const char* + Name of the configuration file that is used to instantiate our controllers. + This is intended to be a Tcl script and is therefore processed by the + interpreter after it has been initialized with all the added commands, + but prior to entering the event loop. + \param vme : CVMUSB& vme + Vme controller that is used to interact with the hardware. + +*/ + +unsigned long +TclServer::start(int port, const char* configFile) +{ + // Set up the member data needed to run the thread... + + m_port = port; + m_configFilename = configFile; + + // Schedule the thread for execution: + + Thread::start(); + m_tid = getId(); + return m_tid; +} + +/*! + Locate a module by name. + \param name : std::string + Name of the module to find. + \return CControlModule* + \retval NULL - not found + \retval Other - Pointer to the found module. +*/ +CControlModule* +TclServer::findModule(string name) +{ + for (int i=0; i < m_Modules.size(); i++) { + CControlModule* pModule = m_Modules[i]; + if (pModule->getName() == name) { + return pModule; + } + } + return static_cast<CControlModule*>(NULL); +} +/*! + Add a new module to the list of modules + \param pNewModule : CControLModule* + Pointer to the new module to add. +*/ +void +TclServer::addModule(CControlModule* pNewModule) +{ + m_Modules.push_back(pNewModule); +} + +/*! + Set the interpreter result to a string value. +*/ +void +TclServer::setResult(string msg) +{ + Tcl_Obj* result = Tcl_NewStringObj(msg.c_str(), -1); + Tcl_SetObjResult(m_pInterpreter->getInterpreter(), result); + + +} +/*! + Add a prototype from which a module can be created. + + This is used by the module command to create the actual modules. + + \param typeName - Type of module. + \param prototype- Pointer to a prototype module, which must have + a lifespan that is the length of the program. + +\note prototypes should not have a... [truncated message content] |
From: <ro...@us...> - 2008-07-17 18:27:22
|
Revision: 1919 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1919&view=rev Author: ron-fox Date: 2008-07-17 18:27:26 +0000 (Thu, 17 Jul 2008) Log Message: ----------- Added the acquisition thread.. with device independent stuff factored out. Modified Paths: -------------- trunk/nextgen/configure.in trunk/nextgen/usb/Makefile.am Added Paths: ----------- trunk/nextgen/usb/acqcommon/ trunk/nextgen/usb/acqcommon/CAcquisitionThread.cpp trunk/nextgen/usb/acqcommon/CAcquisitionThread.h trunk/nextgen/usb/acqcommon/CControlQueues.cpp trunk/nextgen/usb/acqcommon/CControlQueues.h trunk/nextgen/usb/acqcommon/Makefile.am Modified: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-07-17 13:56:13 UTC (rev 1918) +++ trunk/nextgen/configure.in 2008-07-17 18:27:26 UTC (rev 1919) @@ -385,6 +385,7 @@ usb/tclcommon/Makefile usb/tclserver/Makefile usb/output/Makefile + usb/acqcommon/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/usb/Makefile.am =================================================================== --- trunk/nextgen/usb/Makefile.am 2008-07-17 13:56:13 UTC (rev 1918) +++ trunk/nextgen/usb/Makefile.am 2008-07-17 18:27:26 UTC (rev 1919) @@ -2,4 +2,4 @@ # Builds the VM/CC usb software. It's important to build the common # code first: # -SUBDIRS = threadcom tclcommon tclserver output \ No newline at end of file +SUBDIRS = threadcom tclcommon tclserver output acqcommon \ No newline at end of file Added: trunk/nextgen/usb/acqcommon/CAcquisitionThread.cpp =================================================================== --- trunk/nextgen/usb/acqcommon/CAcquisitionThread.cpp (rev 0) +++ trunk/nextgen/usb/acqcommon/CAcquisitionThread.cpp 2008-07-17 18:27:26 UTC (rev 1919) @@ -0,0 +1,514 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CAcquisitionThread.h" +#include <DataBuffer.h> +#include <CControlQueues.h> +#include <CRunState.h> // else pick up the daq one by mistake. +#include <assert.h> +#include <time.h> +#include <string> +#include <Exception.h> +#include <iostream> + +#include <string.h> +#include <errno.h> + +using namespace std; + + +static const unsigned DRAINTIMEOUTS(5); // # consecutive drain read timeouts before giving up. +static const unsigned USBTIMEOUT(10); + + + +// buffer types: +// + + +bool CAcquisitionThread::m_Running(false); +CAcquisitionThread* CAcquisitionThread::m_pTheInstance(0); + +unsigned long CAcquisitionThread::m_tid; // Thread id of the running thread. + + +/*! + Construct the the acquisition thread object. + This is just data initialization its the start member that is + important. +*/ + +CAcquisitionThread::CAcquisitionThread() : + m_pDriver(0) +{ + +} + +/*! + Return the singleton instance of the acquisition thread object: + +*/ +CAcquisitionThread* +CAcquisitionThread::getInstance() +{ + if (!m_pTheInstance) { + m_pTheInstance = new CAcquisitionThread; + } + return m_pTheInstance; +} + +/*! + Start the thread. + - get an instance which, if necessary forces creation. + - Set the adc/scaler lists. + - Initiate the thread which gets the ball rolling. + \param usb :CVMUSB* + Pointer to the vme interface object we use to deal with all this stuff. + \param adcs : std::vector<CReadoutModule*> + A vector consisting of the set of modules that will be read out in the + event mode. This is expected to be hooked to interrupt + 80, IPL 6 and that will be used to fire off the list. + \param scalers : std::vector<CReadoutModule*> + A vector consisting of the set of scaler modules that will be read out + every scalerPeriod seconds. + +*/ +void +CAcquisitionThread::Start() +{ + CRunState* pState = CRunState::getInstance(); + pState->setState(CRunState::Active); + + + CAcquisitionThread* pThread = getInstance(); + + + + + // starting the thread will eventually get operator() called and that + // will do all the rest of the work in thread context. + + pThread->start(); + m_tid = pThread->getId(); + +} + +/*! + Returns true if the thread is running. +*/ +bool +CAcquisitionThread::isRunning() +{ + return m_Running; +} + +/*! + Wait for the thread to exit. +*/ +void +CAcquisitionThread::waitExit() +{ + getInstance()->join(); +} + +/*! + Set the object's device driver: + \param pDriver - Pointer to an instance of a concrete + derivation of CUSBDeviceDriver +*/ +void +CAcquisitionThread::setDriver(CUSBDeviceDriver* pDriver) +{ + m_pDriver = pDriver; +} + + +/*! + Entry point for the thread. +*/ +void +CAcquisitionThread::run() +{ + try { + m_Running = true; // Thread is off and running now. + + beginRun(); // Emit begin run buffer. + + startDaq(); // Setup and start data taking. + try { + + mainLoop(); // Enter the main processing loop. + } + catch (...) { // exceptions are used to exit the main loop.? + } + + endRun(); // Emit end run buffer. + + m_Running = false; // Exiting. + + } + catch (string msg) { + cerr << "CAcquisition thread caught a string exception: " << msg << endl; + throw; + } + catch (char* msg) { + cerr << "CAcquisition thread caught a char* exception: " << msg << endl; + throw; + } + catch (CException& err) { + cerr << "CAcquisitino thread caught a daq exception: " + << err.ReasonText() << " while " << err.WasDoing() << endl; + throw; + } + catch (...) { + cerr << "CAcquisition thread caught some other exception type.\n"; + throw; + } + +} + +/*! + The main loop is simply one that loops: + - Reading a buffer from the vm-usb and processing it if one comes in. + - Checking for control commands and processing them if they come in. +*/ +void +CAcquisitionThread::mainLoop() +{ + DataBuffer* pBuffer = gFreeBuffers.get(); + CControlQueues* pCommands = CControlQueues::getInstance(); + size_t usbBufferSize = usbGetBufferSize(); + try { + while (true) { + + // Event data from the VM-usb. + + size_t bytesRead; + int status = usbReadBuffer(pBuffer->s_rawData, + usbBufferSize, + &bytesRead, + USBTIMEOUT); + + if (status == 0) { + pBuffer->s_bufferSize = bytesRead; + pBuffer->s_bufferType = TYPE_EVENTS; + processBuffer(pBuffer); // Submitted to output thread so... + pBuffer = gFreeBuffers.get(); // need a new one. + } + else { +#ifdef REPORT_ERRORS + cerr << "Bad status from usbread: " << strerror(errno) << endl; +#endif + } + // Commands from our command queue. + + CControlQueues::opCode request; + bool gotOne = pCommands->testRequest(request); + if (gotOne) { + processCommand(request); + } + } + } + catch (...) { + gFreeBuffers.queue(pBuffer); // Don't lose buffers!! + throw; + } +} +/*! + Process a command from our command queue. The command can be one of the + following: + ACQUIRE - The commander wants to acquire the VM-USB we must temporarily + shutdown data taking and drain the VMusb...then ack the message + and wait paitently for a RELEASE before restarting. + PAUSE - Commander wants the run to pause. + END - The commander wants the run to end. +*/ +void +CAcquisitionThread::processCommand(CControlQueues::opCode command) +{ + CControlQueues* queues = CControlQueues::getInstance(); + + if (command == CControlQueues::ACQUIRE) { + stopDaq(); + queues->Acknowledge(); + CControlQueues::opCode release = queues->getRequest(); + assert(release == CControlQueues::RELEASE); + queues->Acknowledge(); + usbToAutonomous(); + } + else if (command == CControlQueues::END) { + stopDaq(); + queues->Acknowledge(); + throw "Run ending"; + } + else if (command == CControlQueues::PAUSE) { + pauseDaq(); + + } + else { + // bad error: + + assert(0); + } +} +/*! + Process a buffer of data from the VM-USB (not artificially generated + buffers. There are only two types of buffers that can come from the + VM-USB: + - Event data + - Scalers + These are distinguishable from the Scaler bit in the header word of the + data from the VM-USB. + \param buffer : DataBuffer* + the buffer of data from the VM-USB. The following fiels have been set: + - s_storageSize : number of bytes of physical storage in a buffer. + - s_bufferType. + - s_buffersSize : number of bytes read from the USB. + - s_rawData : the data read from the USB. + + The disposition of full buffers is done by another thread that is connected + to us by a buffer queue. Once we fill in the buffer type we just have to + submit the buffer to the queue.. which can wake up the output thread and + cause a scheduler pass... or not. + +*/ +void +CAcquisitionThread::processBuffer(DataBuffer* pBuffer) +{ + time_t acquiredTime; // Need to generate our own timestamps. + time(&acquiredTime); + pBuffer->s_timeStamp = acquiredTime; + + // In this version, all stack ids are good. The output thread will ensure that + // stack 1 completions are scalers and all others are events. + + gFilledBuffers.queue(pBuffer); // Send it on to be routed to spectrodaq in another thread. +} +/*! + startDaq start data acquisition from a standing stop. To do this we need to: + - Emit a begin run buffer. + - Create VMUSBReadoutLists from the m_scalers and m_adcs + - Download those lists into the VM-USB, list 2 will be used for event readout. + list 1 for scalers. + - Set the trigger for list 2 to be interrupt number 1 with vmeVector and + vmeIPL as described in the static consts in this module + \bug May want to make this parameterizable, but probably not necessary. + - Set the buffersize to 13k (max). to get optimum throughput. + - Setup scaler readout to happen every 10 seconds. + - Initialize the hardware + - Start USB data acuisition. + +*/ +void +CAcquisitionThread::startDaq() +{ + + // First do a bulk read just to flush any crap that's in the VM-USB + // output fifo..as it appears to sometimes leave crap there. + // ignore any error status, and use a short timeout: + + usbFlushGarbage(); + usbSetup(); + usbToAutonomous(); + + +} +/*! + Stop data taking this involves: + - Forcing a scaler trigger (action register write) + - Setting clearing the DAQ start bit (action register write) + - draining data from the VMUSB: +*/ +void +CAcquisitionThread::stopDaq() +{ + + usbStopAutonomous(); + drainUsb(); +} +/*! + Pause the daq. This means doing a stopDaq() and fielding + requests until resume or stop was sent. + +*/ +void +CAcquisitionThread::pauseDaq() +{ + CControlQueues* queues = CControlQueues::getInstance(); + stopDaq(); + CRunState* pState = CRunState::getInstance(); + pState->setState(CRunState::Paused); + queues->Acknowledge(); + + while (1) { + CControlQueues::opCode req = queues->getRequest(); + + // Acceptable actions are to acquire the USB, + // End the run or resume the run. + // + + if (req == CControlQueues::ACQUIRE) { + queues->Acknowledge(); + CControlQueues::opCode release = queues->getRequest(); + assert (release == CControlQueues::RELEASE); + queues->Acknowledge(); + } + else if (req == CControlQueues::END) { + queues->Acknowledge(); + pState->setState(CRunState::Idle); + throw "Run Ending"; + } + else if (req == CControlQueues::RESUME) { + startDaq(); + queues->Acknowledge(); + pState->setState(CRunState::Active); + return; + } + else { + assert(0); + } + } + +} + +/*! + Drain usb - We read buffers from the DAQ (with an extended timeout) + until the buffer we get indicates it was the last one (data taking turned off). + Each buffer is processed normally. +*/ +void +CAcquisitionThread::drainUsb() +{ + bool done = false; + DataBuffer* pBuffer = gFreeBuffers.get(); + int timeouts(0); + size_t bytesRead; + size_t bufferSize = usbGetBufferSize(); + + cerr << "CAcquisitionThread::drainUsb...\n"; + do { + int status = usbReadBuffer(pBuffer->s_rawData, + bufferSize, + &bytesRead, + DRAINTIMEOUTS); + + if (status == 0) { + pBuffer->s_bufferSize = bytesRead; + pBuffer->s_bufferType = TYPE_EVENTS; + cerr << "Got a buffer, with type header: " << hex << pBuffer->s_rawData[0] << endl; + if (isusbLastBuffer(pBuffer)) { + cerr << "Done\n"; + done = true; + } + processBuffer(pBuffer); + pBuffer = gFreeBuffers.get(); + } + else { + timeouts++; // By the time debugged this is only failure. + cerr << "Read timed out\n"; + if(timeouts >= DRAINTIMEOUTS) { + usbGroinKick(); + done = true; + } + } + } while (!done); + + + gFreeBuffers.queue(pBuffer); + cerr << "Done finished\n"; + +} +/*! + Emit a begin run buffer to the output thread. + the key info in this buffer is just its type and timestamp. + No info at all is in the body, however since the buffer will be returned + to the free list we have to get it from there to begin with: +*/ +void +CAcquisitionThread::beginRun() +{ + DataBuffer* pBuffer = gFreeBuffers.get(); + pBuffer->s_bufferSize = pBuffer->s_storageSize; + pBuffer->s_bufferType = TYPE_START; + processBuffer(pBuffer); // Rest gets taken care of there. +} +/*! + Emit an end of run buffer. + This is just like a begin run buffer except for the buffer type: +*/ +void +CAcquisitionThread::endRun() +{ + DataBuffer* pBuffer = gFreeBuffers.get(); + pBuffer->s_bufferSize = pBuffer->s_storageSize; + pBuffer->s_bufferType = TYPE_STOP; + processBuffer(pBuffer); +} + +// Below are a facade to the member functions of the driver object: + +void +CAcquisitionThread::usbToAutonomous() +{ + m_pDriver->usbToAutonomous(); +} + +int +CAcquisitionThread::usbReadBuffer(void* pBuffer, + size_t bytesToRead, + size_t* pBytesRead, + int timeoutInSeconds) +{ + return m_pDriver->usbReadBuffer(pBuffer, bytesToRead, pBytesRead, timeoutInSeconds); +} + +void +CAcquisitionThread::usbSetup() +{ + m_pDriver->usbSetup(); +} + +size_t +CAcquisitionThread::usbGetBufferSize() +{ + m_pDriver->usbGetBufferSize(); +} + +void +CAcquisitionThread::usbStopAutonomous() +{ + m_pDriver->usbStopAutonomous(); +} + + +bool +CAcquisitionThread::isusbLastBuffer(DataBuffer* pBuffer) +{ + return m_pDriver->isusbLastBuffer(pBuffer); +} + +void +CAcquisitionThread::usbGroinKick() +{ + m_pDriver->usbGroinKick(); +} + +void +CAcquisitionThread::usbFlushGarbage() +{ + m_pDriver->usbFlushGarbage(); +} Added: trunk/nextgen/usb/acqcommon/CAcquisitionThread.h =================================================================== --- trunk/nextgen/usb/acqcommon/CAcquisitionThread.h (rev 0) +++ trunk/nextgen/usb/acqcommon/CAcquisitionThread.h 2008-07-17 18:27:26 UTC (rev 1919) @@ -0,0 +1,147 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CACQUISITIONTHREAD_H +#define __CACQUISITIONTHREAD_H + +using namespace std; + + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + +#ifndef __THREAD_H +#include <Thread.h> +#endif + +#ifndef __CCONTROLQUEUES_H +#include "CControlQueues.h" +#endif + + +// forward class definitions. + +struct DataBuffer; + + +/*! + This is device driver class. Concrete derivations from this class + are attached to the acquisition thread object to provide device specific + functionality. The CAquisitioThread object contains a facade that these + get plugged into: +*/ +class CUSBDeviceDriver +{ +public: + virtual void usbToAutonomous() = 0; // start autonomous data taking. + virtual int usbReadBuffer(void* pBuffer, + size_t bytesToRead, + size_t* bytesRead, + int timeoutInSeconds) = 0; // Read block from usb device. + virtual void usbSetup() = 0; // Load stacks and setup USB device mode. + virtual size_t usbGetBufferSize() = 0; // Get the correct data buffers size for the dev. + virtual void usbStopAutonomous() = 0; // Stop autonomous data taking. + virtual bool isusbLastBuffer(DataBuffer* pBuffer) = 0; // True if last buffer of run. + virtual void usbGroinKick() = 0; // Called if can't get last buffer at stop. + virtual void usbFlushGarbage() = 0; +}; + + + + +/*! + This is the thread that does the data acquisition. + As coded this is a singleton class as well, however as a thread of execution, + it gets started at the beginning of a run and politely requested to stop at + the end of a run. +*/ +class CAcquisitionThread : public Thread +{ + +private: + static bool m_Running; //!< thread is running. + static unsigned long m_tid; //!< ID of thread when running. + + + CUSBDeviceDriver* m_pDriver; // Contains USB device specific functions. + + //Singleton pattern stuff: + + +private: + static CAcquisitionThread* m_pTheInstance; + CAcquisitionThread(); + + +public: + static CAcquisitionThread* getInstance(); + + // Thread functions: + +public: + static void Start(); + static bool isRunning(); + static void waitExit(); /* Wait for this thread to exit (join). */ + +public: + void setDriver(CUSBDeviceDriver* pDriver); + +protected: + virtual void run(); + + + +private: + void mainLoop(); + void processCommand(CControlQueues::opCode command); + void processBuffer(DataBuffer* pBuffer); + void startDaq(); + void stopDaq(); + void pauseDaq(); + void drainUsb(); + void beginRun(); + void endRun(); + + // The following are callouts for interface specific stuff; + // they will call into the device specific object. + +protected: + + void usbToAutonomous() ; // start autonomous data taking. + int usbReadBuffer(void* pBuffer, + size_t bytesToRead, + size_t* bytesRead, + int timeoutInSeconds); // Read block from usb device. + void usbSetup(); // Load stacks and setup USB device mode. + size_t usbGetBufferSize(); // Get the correct data buffers size for the dev. + void usbStopAutonomous() ; // Stop autonomous data taking. + bool isusbLastBuffer(DataBuffer* pBuffer) ; // True if last buffer of run. + void usbGroinKick() ; // Called if can't get last buffer at stop. + void usbFlushGarbage() ; +}; + +#endif Added: trunk/nextgen/usb/acqcommon/CControlQueues.cpp =================================================================== --- trunk/nextgen/usb/acqcommon/CControlQueues.cpp (rev 0) +++ trunk/nextgen/usb/acqcommon/CControlQueues.cpp 2008-07-17 18:27:26 UTC (rev 1919) @@ -0,0 +1,164 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include <CControlQueues.h> +#include <assert.h> +#include <list> + +using namespace std; + +// + +CControlQueues* CControlQueues::m_pTheInstance(0); + +/*! + The constructor does othing since the individueal buffer queues + are quite able to instantiate themselves. + The constructor must be implemented in order to get it to be private. +*/ +CControlQueues::CControlQueues() +{} + +/*! + Get the singleton instance of these queues (lazy instantiation). + Note that while this is not inherently thread-safe, in fact the instance + will be created early in system startup before additional threads have been + created and scheduled, so it's safe enough. To be truly threadsafe, the + body of the if must be protected from threaded execution. +*/ +CControlQueues* +CControlQueues::getInstance() +{ + if(!m_pTheInstance) { + m_pTheInstance = new CControlQueues; + } + return m_pTheInstance; +} + +/*! + Acquire the usb from the readout thread. This sends an + ACQUIRE request to the m_requestQueue and waits for an ACK to + be received from the m_replyQueue. +*/ +void +CControlQueues::AcquireUsb() +{ + Enter(); + blockingTransaction(ACQUIRE); + + // Leave when USB is released. + +} + +/*! + Release the USB.. this sends a RELEASE message to the request queue + and blocks for an ACK response: +*/ +void +CControlQueues::ReleaseUsb() +{ + blockingTransaction(RELEASE); + Leave(); +} +/*! + Request an end run, block until the readout thread is just about to exit + (caller or creator can then join). +*/ +void +CControlQueues::EndRun() +{ + Enter(); + blockingTransaction(END); + Leave(); + +} +/*! + Request to pause a run. +*/ +void +CControlQueues::PauseRun() +{ + Enter(); + blockingTransaction(PAUSE); + Leave(); +} + +/*! + Request to resume a paused run. +*/ +void +CControlQueues::ResumeRun() +{ + Enter(); + blockingTransaction(RESUME); + Leave(); +} + +/*! + Send an acknowledge message to the reply queue. +*/ +void +CControlQueues::Acknowledge() +{ + m_replyQueue.queue(ACK); +} +/*! + Get a command request form the request queue... blocking if needed. + the op code is returned to the caller. +*/ +CControlQueues::opCode +CControlQueues::getRequest() +{ + opCode request = m_requestQueue.get(); + return request; + +} +/*! + Check for a request in the command queue. This is non blocking. + It is used between buffer acquisitions from the readout thread + to see if it needs to back off for the control thread. + \param command : CControlQueues::opCode + Command received if one was received. + \return bool + \retval true - A command message is available. + \retval false - no command message was available. +*/ +bool +CControlQueues::testRequest(CControlQueues::opCode& command) +{ + list<opCode> messages = m_requestQueue.getAll(); + if(messages.empty()) { + return false; + } + else { + assert(messages.size() == 1); // can't stack multiply deep. + command = messages.front(); + return true; + } +} +///////////////////////////////////////////////////////////////////////// + +// Do the common work of a blocking transaction. + +void +CControlQueues::blockingTransaction(CControlQueues::opCode command) +{ + + m_requestQueue.queue(command); + opCode reply = m_replyQueue.get(); + assert(reply == ACK); +} Added: trunk/nextgen/usb/acqcommon/CControlQueues.h =================================================================== --- trunk/nextgen/usb/acqcommon/CControlQueues.h (rev 0) +++ trunk/nextgen/usb/acqcommon/CControlQueues.h 2008-07-17 18:27:26 UTC (rev 1919) @@ -0,0 +1,116 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CCONTROLQUEUES_H +#define __CCONTROLQUEUES_H +#ifndef __CGAURDEDOBJECT_H +#include <CGaurdedObject.h> +#endif + +#ifndef __CBUFFERQUEUE_H +#include <CBufferQueue.h> +#endif + + + + +/*! + + This file contains definitions of queues used to communicate control + requests and responses from the main thread to the readout thread and + back. The idea is that if the main thread needs to do something that + requires the USB, it will do a control request to the readout thread. + The readout thread will then pause data taking and reply to the + main thread, which will then do its USB voodoo, and send another control + request to the readout thread which will restart data taking and + respond with an acknowledge. + + The original design required the main thread to communicate control requests + that would be executed in the readout thread, but this is more complex + than required. The communication protocol is quite simple: + - main thread sends an ACQUIRE string to the readout thread. + - readout thread sends an ACK back indicating that it has halted data taking + and is now waiting. + - main thread performs the USB stuff it needs to do. + - when done with the USB, main thread sends a RELEASE string to the readout + thread which has been waiting for this. + - readout thread sends an ACK back indicating that it is now resuming + data taking. + - When the control thread wants to end a run it sends an ENDRUN message + to the readout thread which ends the run and, as its last act before exiting, + sends an ACK back. + + This is all done via a request and a reply queue which are both + BufferQueues of std::string. + These are bundled together in a CControlQueues class with appropriate + members to manage the communication protocol. + + CControlQueues is a singleton object. + +*/ + +class CControlQueues : public CGaurdedObject +{ + // Public data types (operation codes): +public: + typedef enum _opCode { + ACQUIRE, // Acquire VM-USB for other thread. + RELEASE, // Release VM-USB back to readout thread + END, // End the run. + PAUSE, // Pause the run. + RESUME, // Resume the run. + ACK, // Acknowledge operation (reply). + NAK // Negative acknowledge (reply not yet used). + + } opCode; + // data: +private: + CBufferQueue<opCode> m_requestQueue; + CBufferQueue<opCode> m_replyQueue; + + static CControlQueues* m_pTheInstance; + +private: + CControlQueues(); +public: + static CControlQueues* getInstance(); + + // operations on the queue. + // - Operations used by the control thread; + // These block until the appropriate reply occurs. + // +public: + void AcquireUsb(); //!< Send ACQUIRE to m_requestQueue wait for ACK. + void ReleaseUsb(); //!< Send RELEASE to m_requestQueue wait for ACK. + void EndRun(); //!< Send END to m_requestQueue wait for ACK. + void PauseRun(); + void ResumeRun(); + // + // - Operations used by the readout thread; + // + void Acknowledge(); //!< Send ACK msg to replyQueue. + opCode getRequest(); //!< Blocks until request. + bool testRequest(opCode& code); //!< Returns without blocking. + + // utilities: + +private: + void blockingTransaction(opCode); +}; + + + +#endif Added: trunk/nextgen/usb/acqcommon/Makefile.am =================================================================== --- trunk/nextgen/usb/acqcommon/Makefile.am (rev 0) +++ trunk/nextgen/usb/acqcommon/Makefile.am 2008-07-17 18:27:26 UTC (rev 1919) @@ -0,0 +1,20 @@ +lib_LTLIBRARIES = libusbacqcommon.la + +libusbacqcommon_la_SOURCES = CControlQueues.cpp \ + CAcquisitionThread.cpp + +noinst_HEADERS = CControlQueues.h \ + CAcquisitionThread.h + + +INCLUDES = -I@top_srcdir@/base/thread \ + -I@top_srcdir@/usb/threadcom \ + -I@top_srcdir@/usb/output \ + -I@top_srcdir@/base/exception \ + -I@top_srcdir@/base/headers + +libusbacqcommon_la_LDFLAGS = @top_srcdir@/base/thread/libdaqthreads.la \ + @top_srcdir@/usb/threadcom/libThreadComm.la \ + @top_srcdir@/usb/output/libOutputStage.la \ + @top_srcdir@/base/exception/libException.la + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-14 19:59:11
|
Revision: 1939 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1939&view=rev Author: ron-fox Date: 2008-08-14 19:59:13 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Get the daqconfig part of the VMUSB software built. Modified Paths: -------------- trunk/nextgen/Makefile.am trunk/nextgen/base/dataflow/Makefile.am trunk/nextgen/base/dataflow/ringtostdoutsw.ggo trunk/nextgen/base/dataflow/stdintoringsw.ggo trunk/nextgen/configure.in trunk/nextgen/daq/format/Makefile.am trunk/nextgen/servers/portmanager/cpptest trunk/nextgen/servers/portmanager/makeindex.tcl trunk/nextgen/usb/tclcommon/CConfiguration.cpp trunk/nextgen/usb/tclcommon/CConfiguration.h trunk/nextgen/usb/vmusb/Makefile.am trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am trunk/nextgen/utilities/bufdump/Makefile.am trunk/nextgen/utilities/eventlog/Makefile.am trunk/nextgen/utilities/ringselector/Makefile.am Added Paths: ----------- trunk/nextgen/usb/vmusb/daqconfig/ trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.h trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.cpp trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.h trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.h trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.h trunk/nextgen/usb/vmusb/daqconfig/CVMUSBConfig.cpp trunk/nextgen/usb/vmusb/daqconfig/CVMUSBConfig.h trunk/nextgen/usb/vmusb/daqconfig/Makefile.am Modified: trunk/nextgen/Makefile.am =================================================================== --- trunk/nextgen/Makefile.am 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/Makefile.am 2008-08-14 19:59:13 UTC (rev 1939) @@ -1,5 +1,5 @@ SUBDIRS = base/CopyrightTools base/exception base/tclplus servers base \ - utilities docbuild docconfig usb + daq utilities docbuild docconfig usb install-data-local: Modified: trunk/nextgen/base/dataflow/Makefile.am =================================================================== --- trunk/nextgen/base/dataflow/Makefile.am 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/base/dataflow/Makefile.am 2008-08-14 19:59:13 UTC (rev 1939) @@ -25,7 +25,7 @@ libRingBuffer_la_SOURCES = ringPackage.cpp CRingCommand.cpp -libRingBuffer_la_DEPENDENCIES = libDataFlow.la +libRingBuffer_la_DEPENDENCIES = libDataFlow.la ringtostdoutsw.o stdintoringsw.o libRingBuffer_la_LIBADD = @top_srcdir@/base/tclplus/libtclPlus.la \ @top_srcdir@/base/dataflow/libDataFlow.la \ @@ -42,20 +42,21 @@ ringtostdout_SOURCES = ringtostdout.cpp -ringtostdout_DEPENDENCIES = ringtostdoutsw.o libRingBuffer.la +ringtostdout_DEPENDENCIES = libRingBuffer.la + ringtostdoutsw.o: ringtostdoutsw.ggo $(GENGETOPT) <ringtostdoutsw.ggo --file=ringtostdoutsw --unamed-opts - $(COMPILE) -c ringtostdoutsw.c + $(CC) -c ringtostdoutsw.c ringtostdout_LDADD = ringtostdoutsw.o libRingBuffer.la stdintoring_SOURCES = stdintoring.cpp -stdintoring_DEPENDENCIES = stdintoringsw.o libRingBuffer.la +stdintoring_DEPENDENCIES = libRingBuffer.la stdintoringsw.o: stdintoringsw.ggo $(GENGETOPT) <stdintoringsw.ggo --file=stdintoringsw --unamed-opts - $(COMPILE) -c stdintoringsw.c + $(CC) -c stdintoringsw.c stdintoring_LDADD = stdintoringsw.o libRingBuffer.la @@ -74,9 +75,12 @@ unittests_LDFLAGS = -Wl,"-rpath-link=$(libdir)" + +producer_SOURCES = producer.cpp producer_LDADD = -L@prefix@/lib -lDataFlow producer_LDFLAGS = -Wl,"-rpath-link=$(libdir)" +consumer_SOURCES = consumer.cpp consumer_LDADD = -L@prefix@/lib -lDataFlow consumer_LDFLAGS = -Wl,"-rpath-link=$(libdir)" Modified: trunk/nextgen/base/dataflow/ringtostdoutsw.ggo =================================================================== --- trunk/nextgen/base/dataflow/ringtostdoutsw.ggo 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/base/dataflow/ringtostdoutsw.ggo 2008-08-14 19:59:13 UTC (rev 1939) @@ -1,4 +1,5 @@ package "ringtostdout" +version "1.0" purpose "Output data from an NSCL Ring buffer to stdout." option "mindata" m "Ring get chunking factor" string optional default="1m" Modified: trunk/nextgen/base/dataflow/stdintoringsw.ggo =================================================================== --- trunk/nextgen/base/dataflow/stdintoringsw.ggo 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/base/dataflow/stdintoringsw.ggo 2008-08-14 19:59:13 UTC (rev 1939) @@ -1,4 +1,5 @@ package "ringtostdin" +version "1.0" purpose "Put data from stdin to a ring." option "mindata" m "stdin read chunking factor" string optional default="1m" Modified: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/configure.in 2008-08-14 19:59:13 UTC (rev 1939) @@ -388,6 +388,7 @@ usb/acqcommon/Makefile usb/vmusb/Makefile usb/vmusb/deviceDriver/Makefile + usb/vmusb/daqconfig/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/daq/format/Makefile.am =================================================================== --- trunk/nextgen/daq/format/Makefile.am 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/daq/format/Makefile.am 2008-08-14 19:59:13 UTC (rev 1939) @@ -12,14 +12,15 @@ CRingPhysicsEventCountItem.cpp -include_HEADERS = CRingSelectionPredicate.h \ +include_HEADERS = CRingSelectionPredicate.h \ CDesiredTypesPredicate.h \ CAllButPredicate.h \ CRingItem.h \ CRingStateChangeItem.h \ CRingScalerItem.h \ CRingTextItem.h \ - CRingPhysicsEventCountItem.h + CRingPhysicsEventCountItem.h \ + DataFormat.h INCLUDES = -I@top_srcdir@/base/dataflow \ -I@top_srcdir@/base/exception \ Modified: trunk/nextgen/servers/portmanager/cpptest =================================================================== --- trunk/nextgen/servers/portmanager/cpptest 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/servers/portmanager/cpptest 2008-08-14 19:59:13 UTC (rev 1939) @@ -18,7 +18,7 @@ # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -relink_command="(cd /scratch/fox/daq/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/bin:/usr/bin:/soft/intel/java/bin:/bin:/usr/bin:/soft/intel/java/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.:/var/lib/gems/1.8/bin/:.:/var/lib/gems/1.8/bin/\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/fox/daq/nextgen/servers/portmanager /scratch/fox/daq/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/fox/daq/nextgen/base/exception /scratch/fox/daq/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0/lib)" +relink_command="(cd /scratch/fox/daq/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/bin:/usr/bin:/soft/intel/java/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/user/fox/bin:.:/var/lib/gems/1.8/bin/\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/fox/daq/nextgen/servers/portmanager /scratch/fox/daq/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/fox/daq/nextgen/base/exception /scratch/fox/daq/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0//lib)" # This environment variable determines our operation mode. if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then Modified: trunk/nextgen/servers/portmanager/makeindex.tcl =================================================================== --- trunk/nextgen/servers/portmanager/makeindex.tcl 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/servers/portmanager/makeindex.tcl 2008-08-14 19:59:13 UTC (rev 1939) @@ -1 +1 @@ -pkg_mkIndex /usr/opt/daq/10.0/TclLibs/PortManager *.tcl +pkg_mkIndex /usr/opt/daq/10.0//TclLibs/PortManager *.tcl Modified: trunk/nextgen/usb/tclcommon/CConfiguration.cpp =================================================================== --- trunk/nextgen/usb/tclcommon/CConfiguration.cpp 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/usb/tclcommon/CConfiguration.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -205,21 +205,24 @@ -/////////////////////////////////////////////////////////////////////////// -/////////////////////// Protected utilities /////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/* -** Register a dynamically allocated extension command so that it -** will be automatically deleted when we are destroyed: + +/*! + Register a dynamically allocated extension command so that it + will be automatically deleted when we are destroyed: + + \param processor - reference to the processor to add. + */ void CConfiguration::addCommand(CTCLObjectProcessor& processor) { m_Commands.push_back(&processor); } - +/*! + Clear the configuration. +*/ void CConfiguration::clearConfiguration() { @@ -228,3 +231,12 @@ } m_Objects.clear(); } +/*! + \return CTCLInterpreter* + \retval Pointer to the interpreter that this configuration object runs on. +*/ +CTCLInterpreter* +CConfiguration::getInterpreter() +{ + return m_pInterp; +} Modified: trunk/nextgen/usb/tclcommon/CConfiguration.h =================================================================== --- trunk/nextgen/usb/tclcommon/CConfiguration.h 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/usb/tclcommon/CConfiguration.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -94,11 +94,9 @@ ConfigurationIterator findObjectByName(std::string name); ConfigurationIterator end(); - // For derived classes: - -protected: void addCommand(CTCLObjectProcessor& processor); void clearConfiguration(); + CTCLInterpreter* getInterpreter(); }; Modified: trunk/nextgen/usb/vmusb/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/Makefile.am 2008-08-13 14:47:35 UTC (rev 1938) +++ trunk/nextgen/usb/vmusb/Makefile.am 2008-08-14 19:59:13 UTC (rev 1939) @@ -1 +1 @@ -SUBDIRS = deviceDriver \ No newline at end of file +SUBDIRS = deviceDriver daqconfig Added: trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,56 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CADCCommand.h" +#include <C785.h> + +using std::string; + +/*! + Construction just delegates to the base class: +*/ +CADCCommand::CADCCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName) : + CModuleCommand(interp, config, commandName) +{} + +/*! + Chain to the caller. +*/ +CADCCommand::~CADCCommand() +{ +} + +/*! + The object we need to create is a C785 object +*/ + +CConfigurableObject* +CADCCommand::createObject() +{ + return new C785(); +} + +/*! + The object type is "caen32" +*/ +string +CADCCommand::getType() +{ + return string("caen32"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,101 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CADCCOMMAND_H +#define __CADCCOMMAND_H + +#ifndef __CMODULECOMMAND_H +#include <CModuleCommand.h> +#endif + + + +/*! + This class creates and configures ADCs for the LLNL neutrons daq system. + The command supports the following syntaxes: +\verbatim + adc create module-name base-address + adc config module-name config_params... + adc cget module-name +\verbatim + + The adc create form is used to creat a new adc module. Unlike the 'standard + scripted readout' all adcs are used for data acquisition \em module-name + is a name to be used to refer to the module in other adc subcommands. + \em base-address is the VME base address configured into the module rotary + switches. + + adc config is used to configure a module that has been created. + \em module-name is the name of the module given to the create subcommand. + \em config_params... are a set of keyword value pairs. The keyword defines + what is being configured, and the value is the value of that configuration + item. Configuration keywords supproted are: + - -thresholds The value is a list of 32 values that are the module + thresholds. + - -smallthresholds The value is a boolean (e.g. \em on or \em off). + A true boolean means that the threshold is applied as is + a false boolean means the threshold value is multiplied by 16 + and then applied. + - -ipl The interrupt priority level the module should use. + for the llnl neutron daq this should always be configured to be + 6. + - -vector The interrupt vector the module should use. This is an integer + and should always be configured to be 0x80. + - -highwater The number of events the ADC should accumulate before it fires + an interrupt. This parameter will tune the readout efficiency. + The important thing is to allow sufficient space that the + ADC will not drop (many?) events while it is being emptied by the + VM-USB. + - -fastclear The fast clear window value for the adc (see the hardware docs + for the module. The integer value of this parametr is directly + programmed into the fast clear window register of the module. + - -supressrange Enables zero, overflow and invalid suppression. This is on + by default and should probably only be disabled for test purposes. + + The adc cget command returns the entire module configuration for \em module-name + + example: +\verbatim +adc create adc1 0x800000 +adc config adc1 -ipl 6 -vector 0x80 -supressrange 10 +puts [adc cget adc1] +\endverbatim + +*/ +class CADCCommand : public CModuleCommand +{ +public: + CADCCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("adc")); + virtual ~CADCCommand(); +private: + CADCCommand(const CADCCommand& rhs); + CADCCommand& operator=(const CADCCommand& rhs); + int operator==(const CADCCommand& rhs) const; + int operator!=(const CADCCommand& rhs) const; + + + // These are the member functions that actually + // make this create C785 objects of type "caen32". + +protected: + virtual CConfigurableObject* createObject(); + virtual std::string getType(); + + +}; +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,64 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CCAENChainCommand.h" +#include <CCAENChain.h> + +using namespace std; + + +/*! + Construct the command.. we're going to delegate everything to the + base class constructor. + \param interp CTCLInterpreter& + Reference to the interpreter that will run this command. + \param config CConfiguration& + Reference to the configuration that we will populate. + \param commandName std::string + Name of the command to register. + +*/ +CCAENChainCommand::CCAENChainCommand(CTCLInterpreter& interp, + CConfiguration& config, + string commandName) : + CModuleCommand(interp, config, commandName) +{} + +/*! + There is nothing for us to do for destruction. Let the base classes + deal with that. +*/ +CCAENChainCommand::~CCAENChainCommand() +{} + + +/*! + Create the chain object for the base class: +*/ +CConfigurableObject* +CCAENChainCommand::createObject() +{ + return new CCAENChain(); +} +/*! + Return the module type: "caenchain" +*/ +string +CCAENChainCommand::getType() +{ + return string("caenchain"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,76 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#ifndef __CCAENCHAINCOMMAND_H +#define __CCAENCHAINCOMMAND_H + + +#ifndef __CMODULECOMMAND_H +#include <CModuleCommand.h> +#endif + +/*! + This class creates and configures CAEN Chains for the VM-USB readout software. + The command is derived from the CADCCommand and therefore supports the following + syntaxes: + + \verbatim + caenchain create chain-name + caenchain config chain-name config-params + caenchain cget chain-name + \endverbatim + + The create form is used to create a new caenchain, where caenchain's represent + CBLT readout chains. The chain-name will be used to refer to this chain in other + operations. + + caenchain config configures a chain. At present, the valid configuration options are: + + - -base the value is a uint32_t that represents the MCST/CBLT address that will be + programmed into the modules that make up the chain. + - -modules The value is a properly formatted list of C785 ADC modules that will make up the + chain. The modules must have already been made. The modules must be C785 devices + (you cannot nest chains). There must be at least 2 modules in a chain + (required by the hardware). The modules must occupy a contiguous set of slots + in the backplane (hardware requirement). The first module listed must be the + left most module in the crate. The last module the right most. It is recommmended + therfore that modules be listed left to right. + + The cget command returns the entire module configuration. + +*/ + +class CCAENChainCommand : public CModuleCommand +{ +public: + CCAENChainCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("caenchain")); + virtual ~CCAENChainCommand(); + + // forbidden caonicals. + +private: + CCAENChainCommand(const CCAENChainCommand& rhs); + CCAENChainCommand& operator=(const CCAENChainCommand& rhs); + int operator==(const CCAENChainCommand& rhs) const; + int operator!=(const CCAENChainCommand& rhs) const; + +protected: + virtual CConfigurableObject* createObject(); + virtual std::string getType(); + +}; +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,65 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CCAENV830Command.h" +#include <C830.h> + + +using std::string; + +//////////////////////////////////////////////////////////////////////// +///////////////////////////////// Canonicals /////////////////////////// +//////////////////////////////////////////////////////////////////////// + +/*! + Construct the command. + \param interp : CTCLInterpreter& + Reference to the interpreter on which the command will be registered + \param config : CConfiguration& + Configuration we will be maintaining. +*/ +CCAENV830Command::CCAENV830Command(CTCLInterpreter& interp, CConfiguration& config, + string name) : + CModuleCommand(interp, config, name) +{ +} +/*! + The destructor is just needed to provide a virtual chain back to the + base class destructor. +*/ +CCAENV830Command::~CCAENV830Command() +{ +} + + +/*! + Return a new C830 module. +*/ +CConfigurableObject* +CCAENV830Command::createObject() +{ + return new C830(); +} + +/*! + Return the module type string which is caen830 +*/ +string +CCAENV830Command::getType() +{ + return string("caen830"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,109 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CCAENV830COMMAND_H +#define __CCAENV830COMMAND_H + +#ifndef __CMODULECOMMAND_H +#include <CModuleCommand.h> +#endif + + + + +/*! + This class creates and configures CAEN V830 scaler modules. + The command supports the following syntaxes: +\verbatim + v830 create module-name base-address + v830 config module-name config_params... + v830 cget module-name +\verbatim + + The v830 create form is used to creat a new adc module. + \em base-address is the VME base address configured into the module rotary + switches. + + v830 config is used to configure a module that has been created. + \em module-name is the name of the module given to the create subcommand. + \em config_params... are a set of keyword value pairs. The keyword defines + what is being configured, and the value is the value of that configuration + item. Configuration keywords supported are: + +\verbatim +v830 config name option value ?...? + +where the options/values are: + +Name Type/range Default Purpose +-channels integer 0xffffffff Selectively enable channels. +-dwelltime integer 0 If in periodic trigger mode, the time between triggers +-header bool false If true data will include a header. +-trigger random | vme Specifies how the module triggers an event. random + periodic | means the external latch signal latches the scalers + vme to an event, periodic means the scaler is triggered every + 'dwelltime' * 400ns. vme means the readout list triggers + the scaler. +-wide bool true true - Scalers are 32 bit value, false, 26 bit values. + note that 26 bit wide scaler readout is tagged in the + top bits with the channel number. +-header bool false If true scaler data includes a header as described in + fig 3.1 of the manual. +-autoreset bool true If true, the latch operation also clears the counters. +-geo integer (0-0x1f) 0 The geograhpical address of the module (from PAUX or + as programmed, see below). +-setgeo bool false If true, the geographical address is programmed, + this can only be done for modules without the PAUX + connector...otherwise, the geo address comes from + the PAUX connector. +-ipl integer 0-7 0 If non zero enables the module to interrupt when + the highwater mark is reached. +-vector integer 0-255 0xdd Status/id value to interrupt on. +-highwatermark integer (0-0xffff) 1 How many events need to be in the module to interrupt. + +\endverbatim + + The v830 cget command returns the entire module configuration for \em module-name + + example: +\verbatim +v830 create scaler1 0x800000 +v830 config scaler1 -ipl 6 -vector 0x80 -supressrange 10 +puts [v830 cget scaler1] +\endverbatim + +*/ +class CCAENV830Command : public CModuleCommand +{ + +public: + CCAENV830Command(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("v830")); + virtual ~CCAENV830Command(); +private: + CCAENV830Command(const CCAENV830Command& rhs); + CCAENV830Command& operator=(const CCAENV830Command& rhs); + int operator==(const CCAENV830Command& rhs) const; + int operator!=(const CCAENV830Command& rhs) const; +public: + +protected: + virtual CConfigurableObject* createObject(); + virtual std::string getType(); + +}; +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,61 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include <config.h> +#include <CMADCCommand.h> +#include <CMADC32.h> + + +using std::string; + + +///////////////////////////////////////////////////////////////////// +// Constructors and other implemented canonicals: + +/*! + Construct the madc command and register it. + \param interp - The TCL interpreter on which the command is registered. + \param config - Reference tothe configuration (database of known modules/stacks etc). + \param commandName - Name of the command to register, defaults to "madc" +*/ +CMADCCommand::CMADCCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName) : + CModuleCommand(interp, config, commandName) +{} + +/*! + destructor: +*/ +CMADCCommand::~CMADCCommand() +{} + + +/*! + Create an object for the base class's create method: +*/ +CConfigurableObject* +CMADCCommand::createObject() +{ + return new CMADC32(); +} +/*! + Return the type under which CMADC objects will be registered: +*/ +string +CMADCCommand::getType() +{ + return string("madc"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,71 @@ + +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#ifndef __CMADCCOMMAND_H +#define __CMADCCOMMAND_H + +#ifndef __CMODULECOMMAND_H +#include <CModuleCommand.h> +#endif + + +/*! + The madc command creates and configures Mesytec adc modules. + + The format of this command i: + +\verbatim + madc create module ?config_params? + madc config module ?config_param? + madc cget module +\endverbatim + + + - create is used to create a new module, and optionally configure it. + - config is used to configure an existing module + - cget returns a module's configuration as a property list. + + See the CMADC32.h header for information about the configuration options supported. + +*/ + +class CMADCCommand : public CModuleCommand +{ + +public: + CMADCCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("madc")); + virtual ~CMADCCommand(); + +private: + CMADCCommand(const CMADCCommand& rhs); + CMADCCommand& operator=(const CMADCCommand& rhs); + int operator==(const CMADCCommand& rhs) const; + int operator!=(const CMADCCommand& rhs) const; + + // We need to supply the members below to make the base class work. + +protected: + virtual CConfigurableObject* createObject(); + virtual std::string getType(); + +}; + + + + +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,61 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include <config.h> +#include <CMADCScalerCommand.h> +#include <CMADCScaler.h> + + + +using std::string; + +///////////////////////////////////////////////////////////////////// +// Constructors and other implemented canonicals: + +/*! + Construct the madc command and register it. + \param interp - The TCL interpreter on which the command is registered. + \param config - Reference tothe configuration (database of known modules/stacks etc). + \param commandName - Name of the command to register, defaults to "madc" +*/ +CMADCScalerCommand::CMADCScalerCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName) : + CModuleCommand(interp, config, commandName) + +{} + +/*! + destructor: +*/ +CMADCScalerCommand::~CMADCScalerCommand() +{} + +/*! + Create a new scaler module for the base class: +*/ +CConfigurableObject* +CMADCScalerCommand::createObject() +{ + return new CMADCScaler(); +} +/*! + Return the type under which these modules are registered. +*/ +string +CMADCScalerCommand::getType() +{ + return string("madcscaler"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,75 @@ + +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#ifndef __CMADCSCALERCOMMAND_H +#define __CMADCSCALERCOMMAND_H + + +#ifndef __CMODULECOMMAND_H +#include "CModuleCommand.h" +#endif + +/*! + The madcscaler command creates and configures Mesytec adc modules + so that tht daq time and time couners are read as scalers. + + The format of this command is: + +\verbatim + madcscaler create module ?config_params? + madcscaler config module ?config_param? + madcscaler cget module +\endverbatim + + + - create is used to create a new module, and optionally configure it. + - config is used to configure an existing module + - cget returns a module's configuration as a property list. + + See the CMADCScaler.h header for information about the configuration options supported. + +*/ + +class CMADCScalerCommand : public CModuleCommand +{ + +public: + CMADCScalerCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("madcscaler")); + virtual ~CMADCScalerCommand(); + +private: + CMADCScalerCommand(const CMADCScalerCommand& rhs); + CMADCScalerCommand& operator=(const CMADCScalerCommand& rhs); + int operator==(const CMADCScalerCommand& rhs) const; + int operator!=(const CMADCScalerCommand& rhs) const; + + + + // We need to supply the members below to make the base class work. + +protected: + virtual CConfigurableObject* createObject(); + virtual std::string getType(); + + +}; + + + + +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,71 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CMarkerCommand.h" +#include <CMarker.h> + + +using std::string; + + +////////////////////////////////////////////////////////////////////////////// +///////////////////// Implemented Canonicals ///////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + + +/*! + + Construct the command and register it (base constructor does this + by default. + \param interp : CTCLInterpreter& + Tcl interpreter on which the command will be registered. + \param config : CConfiguration& config + The configuration of ADCs that will be manipulated by this command. + \param commandName std::string + Name of the command to register. +*/ +CMarkerCommand::CMarkerCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName) : + CModuleCommand(interp,config, commandName) +{} + +/*! + Destructor: +*/ +CMarkerCommand::~CMarkerCommand() +{ +} + + +/*! + Create a new marker object and return it to the base class: +*/ +CConfigurableObject* +CMarkerCommand::createObject() +{ + return new CMarker(); +} +/*! + Return the type of module this should be entered into the config with. +*/ +string +CMarkerCommand::getType() +{ + return string("marker"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,71 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CMARKERCOMMAND_H +#define __CMARKERCOMMAND_H + +#ifndef __CMODULECOMMAND_H +#include <CModuleCommand.h> +#endif + + +/*! + This class creates and configure marker stack entries. A marker stack + entry adds a literal 16 bit word to the output buffer for an event. + + The command supports the usual syntaxes for module generating commands: + +\verbatim + marker create name value + marker config name -value new_value + marker cget name + +\endverbatim + + As you can see, the only configuration option supported is + + - -value Sets a new value for the marker. + + Requiring the value on the creation command line is how we ensure that +the value is mandatory +*/ + +class CMarkerCommand : public CModuleCommand +{ + +public: + CMarkerCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName = std::string("marker")); + virtual ~CMarkerCommand(); + +private: + CMarkerCommand(const CMarkerCommand& rhs); + CMarkerCommand& operator=(const CMarkerCommand& rhs); + int operator==(const CMarkerCommand& rhs) const; + int operator!=(const CMarkerCommand& rhs) const; +public: + + // The derived concrete classes must supply implementations for the following + // methods: + +protected: + virtual CConfigurableObject* createObject(); + virtual std::string getType(); + +}; + +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,390 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include <config.h> +#include "CModuleCommand.h" +#include <TCLInterpreter.h> +#include <TCLObject.h> +#include <CConfiguration.h> +#include <CConfigurableObject.h> + +using std::string; +using std::vector; + + +////////////////////////////////////////////////////////////////////////////////////////// + + +/** + * Constructors and canonicals. +**/ + +/*! + \param interp - Reference to the interpreter that will execute this command object. + The object resulting from this construction will be 'hooked up' + so that its operator() is called when the command specified by + name is invoked. + \param config - Reference to the configuration object. This configuration object + is what the command will manipulate when it creates and configures + module objects. + \param name - The name of the command. +*/ +CModuleCommand::CModuleCommand(CTCLInterpreter& interp, CConfiguration& config, string name) : + CTCLObjectProcessor(interp, name), + m_config(config) +{} + +/*! + Chain to the base class destructor which will unregister the command. +*/ +CModuleCommand::~CModuleCommand() +{} + +////////////////////////////////////////////////////////////////////////////////////////////// + +/* + * Implementations of virtual methods that are basic to the operation of the object: +*/ + + +/*! + The command entry just: + - Ensures there is at least 3 parameters, the command, subcommand and + module name. + - Dispatches to the appropriate subcommand processor... or + - Returns an error if the subcommand keyword is not recognized. + + \param interp - Interpreter running the command. + \param objv - Command line words. + + \return int + \retval TCL_OK - Command was successful. + \retval TCL_ERROR - Command failed. + + Side effects: + The interpreter's result will be set in a manner that depends on + success/failure and the subcommand's operation. + +*/ +int +CModuleCommand::operator()(CTCLInterpreter& interp, vector<CTCLObject>& objv) +{ + // require at least 3 parameters. + + if (objv.size() < 3) { + Usage("Insufficient command parameters", objv); + return TCL_ERROR; + } + // Get the subcommand keyword and dispatch or error: + + string subcommand = objv[1]; + if (subcommand == string("create")) { + return create(interp, objv); + } + else if (subcommand == string("config")) { + return config(interp, objv); + } + else if (subcommand == string("cget")) { + return cget(interp, objv); + } + else { + Usage("Invalid subcommand", objv); + return TCL_ERROR; + } +} +/*! + Process the create subcommand: + - ensure we have enough values on the command line. + - If there are 4 command words, insert a -base in front of it. + - ensure we have a valid module name. + - ensure that there is no other module with the same name. + - Create the new module module + - Add it to the configuration. + - If there are additional command words use them to configure the object. + + \param interp - Interpreter that is executing this command. + \param objv - Vector of command words. + + \return int + \retval TCL_OK - Command was successful. + \retval TCL_ERROR - Command failed. + + Side effects: + + The result for the interpreter is set as follows: + - On error this is an error message of the form ERROR: message + - On success, this is the name of the module. allowing e.g. + adc config [adc create adc1 0x80000000] .... +*/ +int +CModuleCommand::create(CTCLInterpreter& interp, vector<CTCLObject>& objv) +{ + if (objv.size() < 3) { + Usage("not enough parameters for the create subcommand", objv); + return TCL_ERROR; + } + // If we have exactly 4 elements, we need to insert a -base in front of the last one. + // after that we must have an odd number of command words so that config works correctly: + + CTCLObject base; + base = string("-base"); + if (objv.size() == 4) { + base.Bind(interp); + vector<CTCLObject>::iterator i = objv.begin(); // [0]. + i++; i++; i++; // [3] + objv.insert(i, base); // I think this pushes the value back. + } + if ((objv.size() % 2) != 1) { + Usage("Incorrect number of parameters for the create subcommand", objv); + return TCL_ERROR; + } + + // Ensure there's not already a module with my type: + + string name = objv[2]; + if (findModule(name)) { + Usage("Duplicate module for the create subcommand", objv); + return TCL_ERROR; + } + // Create configure and insert the module in the configuration. + + CConfigurableObject* pModule = createObject(); + pModule->onAttach(); + + addObjectToConfiguration(m_config, name, getType(), pModule); + + + interp.setResult(name); + if (objv.size() > 3) { + return Configure(interp, // might fail. + objv, + pModule, + 3); + } + return TCL_OK; + + +} +/*! + Configure an existing module. + - Ensure that there are enough command line parameters. These means + at least 5 parameters in order to have at least one configuration + keyword value pair... and that there are an odd number of params + (to ensure that all keywords have values). + - Ensure the module exists, and matches this type. + - Use the Configure utility to configure the object. + + \param interp - Interpreter that is executing this command. + \param objv - Vector of command words. + + \return int + \retval TCL_OK - Command was successful. + \retval TCL_ERROR - Command failed. + + Side effects: + + The interpreter result is set with an error message if the return value + is TCL_ERROR, otherwise it is set with the module name. + Note that all error messages will start with the text "ERROR:" +*/ +int +CModuleCommand::config(CTCLInterpreter& interp, vector<CTCLObject>& objv) +{ + if ((objv.size() < 5) || ((objv.size() % 2) != 1)) { + Usage("Incorrect number of command parameters in ", objv); + return TCL_ERROR; + } + + // Locate the module ensuring it's one of ours: + + string name = objv[2]; + CConfigurableObject* pObject = findModuleOfMyType(name); + if (!pObject) { + Usage("Module specified does not exist or is of the wrong type", objv); + return TCL_ERROR; + } + + + return Configure(interp, objv, pObject); + +} +/*! + Get the configuration of a module and return it as a list of + keyword/value pairs. + - ensure we have enough command line parameters (exactly 3). + - Ensure a module of this type exists and get its pointer. + - Fetch the module's configuration. + - Map the configuration into a list of 2 element lists and set the + result accordingly. + + \param interp - Interpreter that is executing this command. + \param objv - Vector of command words. + + \return int + \retval TCL_OK - Command was successful. + retval TCL_ERROR - Command failed. + + Side effects: + + The interpreter result is set. If the command returned an error, + This is a string that begins with the text ERROR: otherwise it is a + list of 2 element sublists where each sublist is a configuration keyword + value pair...e.g. {-base 0x80000000} ... +*/ +int +CModuleCommand::cget(CTCLInterpreter& interp, vector<CTCLObject>& objv) +{ + if (objv.size() != 3) { + Usage("Invalid command parameter count for cget", objv); + return TCL_ERROR; + } + string name = objv[2]; + CConfigurableObject* pModule = findModuleOfMyType(name); + if (!pModule) { + Usage("No such module", objv); + return TCL_ERROR; + } + CItemConfiguration::ConfigurationArray config = pModule->cget(); + + Tcl_Obj* pResult = Tcl_NewListObj(0, NULL); + + for (int i =0; i < config.size(); i++) { + Tcl_Obj* key = Tcl_NewStringObj(config[i].first.c_str(), -1); + Tcl_Obj* value = Tcl_NewStringObj(config[i].second.c_str(), -1); + + Tcl_Obj* sublist[2] = {key, value}; + Tcl_Obj* sl = Tcl_NewListObj(2, sublist); + Tcl_ListObjAppendElement(interp.getInterpreter(), pResult, sl); + } + Tcl_SetObjResult(interp.getInterpreter(), pResult); + return TCL_OK; +} + +/*! + Create error message text, and set it as the interpreter result. +*/ +void +CModuleCommand::Usage(std::string msg, std::vector<CTCLObject>& objv) +{ + string result("ERROR: "); + result += msg; + result += "\n"; + for (int i = 0; i < objv.size(); i++) { + result += string(objv[i]); + result += ' '; + } + result += "\n"; + result += "Usage\n"; + result += " adc create name base-address\n"; + result += " adc config name config-params...\n"; + result += " adc cget name"; + + getInterpreter()->setResult(result); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// + +/* + * Hook that allows concrete classes to override how modules are added to the configuration. +*/ + +/*! + Add an configurable object to the configuration. + This can be overriden for special needs classes. + + \param config - Reference to the config in which the object should be registered. + \param name - Name to be associated with the object. + \param type - String that defines the type of the object to register. + \param object - Pointer to the object to register. + + \note Implementors can be assured that there is no duplicate module in the configuration + at this time. +*/ +void +CModuleCommand::addObjectToConfiguration(CConfiguration& config, + std::string name, + std::string type, + CConfigurableObject* object) +{ + config.addObject(name, type, object); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// + +/* + * Internal utility functions. +*/ + +/* + Locate a module in the configuration given its name, and not caring about its type. + If found, a pointer to the module is returned, if not a NULL. +*/ +CConfigurableObject* +CModuleCommand::findModule(string name) +{ + CConfiguration::ConfigurationIterator p = m_config.findObjectByName(name); + if (p == m_config.end()) { + return reinterpret_cast<CConfigurableObject*>(0); + } + + return p->s_pObject; +} +/* + Same as above, but also returns null if the module's type is not a match for the + type of module we're managing +*/ +CConfigurableObject* +CModuleCommand::findModuleOfMyType(string name) +{ CConfiguration::ConfigurationIterator p = m_config.findObjectByName(name); + if (p == m_config.end()) { + return reinterpret_cast<CConfigurableObject*>(0); + } + + return (p->s_type == getType()) ? p->s_pObject : reinterpret_cast<CConfigurableObject*>(0); +} +/* + Configure a module using pairs in the objv array starting at some point and + continuing to the end of objv. The assumption is that there are an even number + of remainig elements in objv. + Parameters: + interp - Interpreter doing the config... the result will be set on error. + objv - Command words. + pObject - Pointer to the object being configured. + startAt - which objv to start at. + Returns: + TCL_OK - success. + TCL_ERROR - failure. +*/ +int +CModuleCommand::Configure(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv, + CConfigurableObject* pObject, + unsigned startAt) +{ + try { + for (int i = startAt; i < objv.size(); i += 2) { + string key = objv[i]; + string value = objv[i+1]; + pObject->configure(key, value); + } + } + catch (string msg) { // This may partially configure object... but what else can I do. + Usage(msg, objv); + return TCL_ERROR; + } + return TCL_OK; +} Added: trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,132 @@ +#ifndef __CMODULECOMMAND_H +#define __CMODULECOMMAND_H + +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#ifndef __TCLOBJECTPROCESSOR_H +#include <TCLObjectProcessor.h> +#endif + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + +#ifndef __STL_VECTOR +#include <vector> +#ifndef __STL_VECTOR +#define __STL_VECTOR +#endif +#endif + +class CTCLInterpreter; +class CTCLObject; + +class CConfiguration; +class CConfigurableObject; + +/*! + ABSTRACT BASE CLASS + + This class is a base class for commands that manipulate VM-USB modules. + In most cases the logic for these commands is common. We only need to + delegate to the concrete derived class (we are an ABC): + - createObject creates and returns an actual object (dynamically created). + - getType returns the object type string under which the object will + be entered in the configuration database. + + We supply the following member functions: + - virtual operator() - Dispatches based on subcommand to one of the members below: + - virtual create - Creates a new modules and performs optional partial configuration. + To retain compatibility, this supports a two syntaxes. The first is: + command create name baseAddress, and generates a configure for + the -base attribute. The second is of the form + command create name key value... + and simply uses the part of the command following the object name + as configuration items. + - virtual config - Configures an existing object. + - virtual cget - returns the configuration list of an existing object. + - virtual Usage - Creates a usage string and sets it as the result code. + + The preceding members are also virtual so that module commands with special needs can + override or extend them. +*/ +class CModuleCommand : public CTCLObjectProcessor // >>>ABSTRACT BASE CLASS<<< +{ +protected: + CConfiguration& m_config; +public: + CModuleCommand(CTCLInterpreter& interp, + CConfiguration& config, + std::string name); + virtual ~CModuleCommand(); + +private: + CModuleCommand(const CModuleCommand& rhs); + CModuleCommand& operator=(const CModuleCommand& rhs); + int operator==(const CModuleCommand& rhs) const; + int operator!=(const CModuleCommand& rhs) const; + + + // This class implements the following methods, although they can be + // overridde in concrete sublcasses. + +public: + int operator()(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + +protected: + virtual int create(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + virtual int config(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + virtual int cget(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv); + virtual void Usage(std::string msg, std::vector<CTCLObject>& objv); + + + // The derived concrete classes must supply implementations for the following + // methods: + +protected: + virtual CConfigurableObject* createObject() = 0; + virtual std::string getType() = 0; + + // The following are utility method is also virtual so special requirements can + // override it: + +protected: + virtual void addObjectToConfiguration(CConfiguration& config, + std::string name, + std::string type, + CConfigurableObject* object); + + // Internal utility functions: + +private: + CConfigurableObject* findModule(std::string name); + CConfigurableObject* findModuleOfMyType(std::string name); + int Configure(CTCLInterpreter& interp, + std::vector<CTCLObject>& objv, + CConfigurableObject* pObject, + unsigned startAt = 3); +}; + + + +#endif Added: trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp 2008-08-14 19:59:13 UTC (rev 1939) @@ -0,0 +1,67 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include <config.h> +#include "CNADC2530Command.h" +#include <CNADC2530.h> + +using std::string; + + +//////////////////////////////////////////////////////////////////////////////////// +// Constructors and implemented canonical functions + + +/*! + Construct the command and register it. The base constructor does this by default. + \param interp : CTCLInterpreter& + Tcl interpreter on which the command is registered. + \param config : CConfiguration& + The configuration of ADC's etc. that are manipulated by this command. + \param commandName : std::string + Name of the command to register. This defaults to "hytec" + +*/ +CNADC2530Command::CNADC2530Command(CTCLInterpreter& interp, + CConfiguration& config, + std::string commandName) : + CModuleCommand(interp, config, commandName) +{ +} +/*! + The constructor only exists to maintain a chain of destructors back to the ultimate base class. +*/ +CNADC2530Command::~CNADC2530Command() +{ +} + + +/*! + Return a new CNADC2530 object to the base class. +*/ +CConfigurableObject* +CNADC2530Command::createObject() +{ + return new CNADC2530(); +} + +/*! + Return the device type of the module +*/ +string +CNADC2530Command::getType() +{ + return string("hytec2530"); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.h =================================================================== --- trunk/nextgen/usb/v... [truncated message content] |
From: <ro...@us...> - 2008-08-18 19:39:06
|
Revision: 1942 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1942&view=rev Author: ron-fox Date: 2008-08-18 19:39:08 +0000 (Mon, 18 Aug 2008) Log Message: ----------- Build the application base class for the usb frameworks. Modified Paths: -------------- trunk/nextgen/configure.in trunk/nextgen/usb/Makefile.am Added Paths: ----------- trunk/nextgen/usb/app/ trunk/nextgen/usb/app/CApplication.cpp trunk/nextgen/usb/app/CApplication.h trunk/nextgen/usb/app/Makefile.am trunk/nextgen/usb/app/usbReadout.ggo Modified: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-08-18 12:44:54 UTC (rev 1941) +++ trunk/nextgen/configure.in 2008-08-18 19:39:08 UTC (rev 1942) @@ -386,6 +386,7 @@ usb/tclserver/Makefile usb/output/Makefile usb/acqcommon/Makefile + usb/app/Makefile usb/vmusb/Makefile usb/vmusb/deviceDriver/Makefile usb/vmusb/daqconfig/Makefile Modified: trunk/nextgen/usb/Makefile.am =================================================================== --- trunk/nextgen/usb/Makefile.am 2008-08-18 12:44:54 UTC (rev 1941) +++ trunk/nextgen/usb/Makefile.am 2008-08-18 19:39:08 UTC (rev 1942) @@ -2,4 +2,4 @@ # Builds the VM/CC usb software. It's important to build the common # code first: # -SUBDIRS = threadcom tclcommon tclserver output acqcommon vmusb \ No newline at end of file +SUBDIRS = threadcom tclcommon tclserver output acqcommon app vmusb \ No newline at end of file Added: trunk/nextgen/usb/app/CApplication.cpp =================================================================== --- trunk/nextgen/usb/app/CApplication.cpp (rev 0) +++ trunk/nextgen/usb/app/CApplication.cpp 2008-08-18 19:39:08 UTC (rev 1942) @@ -0,0 +1,290 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "CApplication.h" +#include <CConfiguration.h> +#include <TclServer.h> +#include <Globals.h> +#include "usbReadoutOptions.h" + +#include <TCLInterpreter.h> +#include <CBeginRun.h> +#include <CEndRun.h> +#include <CPauseRun.h> +#include <CResumeRun.h> + +#include <CPortManager.h> + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <iostream> + +//////////////////////////////////////////////////////////////////////////////////////////// +// Canonicals: + +/*! + Destructor just ensures chaining by existing. +*/ +CApplication::~CApplication() +{} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// Implemented member functions. + +/*! + Application entry point. Parse the command lines and start calling the member functions + to stitch together the application: + + \param argc - Count of parameters. + \param argv - Array of pointers to command parameters. +*/ +int +CApplication::main(int argc, char** argv) +{ + gengetopt_args_info parsed; + cmdline_parser(argc, argv, &parsed); + + // fetch the pieces out of the parsed structure. + + std::string daqConfigFile; + std::string ctlConfigFile; + std::string deviceSpecification ; + std::string port; + std::string application; + + if (parsed.daqconfig_given) daqConfigFile = parsed.daqconfig_arg; + if (parsed.ctlconfig_given) ctlConfigFile = parsed.ctlconfig_arg; + if (parsed.device_given) deviceSpecification = parsed.device_arg; + if (parsed.port_given) port = parsed.port_arg; + if (parsed.application_given) application = parsed.application_arg; + + + // Got all we need to get the application put together: + + selectInterface(deviceSpecification); + selectDAQConfigFile(daqConfigFile); + selectControlConfigFile(ctlConfigFile); + createConfiguration(); + createTclServer(port, application); + createMainInterpreter(argc, argv); // MUST BE LAST!!!!!! + + + +} + + +/*! + Figure out the actual daq configuration file. + - If the configuration file has not been given, default it to + $HOME/daqconfig.tcl + - Ensure the configuration file is readable, if not complain before exiting. + - Store the name in the Global variables. + + \param filespec - File name from command line or "" if none provided. +*/ +std::string +CApplication::selectDAQConfigFile(std::string filespec) +{ + std::string finalName = configFile(filespec, "daqconfig.tcl"); + + Globals::configurationFilename = finalName; + + return finalName; +} + +/*! + Select the control configuration file: + - If the user did not specify one onthe command line, default to + $HOME/config/ctlconfig.tcl + - Ensure the configuration file is readable, else complain noisily + - Store the final file in the global variable. + + \param filespec - USer supplied file specification or "" if not supplied. + +*/ +std::string +CApplication::selectControlConfigFile(std::string filespec) +{ + std::string finalName = configFile(filespec, "ctlconfig.tcl"); + Globals::controlConfigFilename = finalName; + return finalName; +} + +/*! + Create the configuration object. The configuration object is responsible + for managing the configuration of the data taking devices. It does + this by having a Tcl interpreter that is enlarged with a set of commands + that allow scripts to create objects that manage specific supported data taking + devices. + + This function invokes the pure virtual function setupConfiguration, implemented by + a concrete sub-class to stock the configuration object's script with the + appropriate set of commands. + + + A pointer to the configuration object is placed in the pConfig global pointer. +*/ +void +CApplication::createConfiguration() +{ + Globals::pConfig = new CConfiguration(); + + setupConfiguration(*Globals::pConfig); + +} + +/*! + Create the main interpreter and register the various commands in it. + Note that this function actually calls Tcl_Main and our static member function + tclAppInit will be where new commands are registered. This function must be the + last thing called in e.g. main as it will not return until the program exits. + This is because the Tcl interpreter main event loop is entered. +*/ +void +CApplication::createMainInterpreter(int argc, char** argv) +{ + Tcl_Main(argc, argv, tclAppInit); +} + +/*! + Create and start the Tcl server application. The server is augmented + by a set of data that control the set of slow control devices that can be + controlled by the clients. These are inserted via a call to the pure virtual + setupTclServer method. + + + \param port - Text string that defines the port on which the server will listen. + If this is blank or "managed" the port manager will be used to + allocate a suitable free port. + + \param application - If the port manager is used, this provides the service + name by which other applications can look us up. This defaults to + "SlowControls" + + It is a bad error for the port to not be empty nor "SlowControls" but not be an integer. +*/ + +void +CApplication::createTclServer(std::string port, std::string application) +{ + int iPort; + + if (application == string("")) application = "SlowControls"; + + // figure out the actual port: + + if ((port == string("managed")) || (port == string(""))) { + iPort = getManagedPort(application); + } + else { + char* pEnd; + iPort = strtoul(port.c_str(), &pEnd, 0); + if (*pEnd) { + std::cerr << "ERROR - Port must be an integer, \"managed\" or empty" << std::endl; + exit(EXIT_FAILURE); + } + } + TclServer* pServer = new TclServer(); + setupTclServer(*pServer); + pServer->start(iPort, Globals::controlConfigFilename.c_str()); + +} + +/* + Figures out the name of a configuration file, and its readability. + + Parameters: + userSupplied - The user supplied path. This can be empty + indicating a default name should be used. + defaultTail - If the userSupplied is blank, the file used is + $HOME/config/<defaultTail> + + An error message and exit results if the final file is not readable. + +*/ + + +std::string +CApplication::configFile(std::string userSupplied, + std::string defaultTail) +{ + // Default the name if not provided. + + if (userSupplied == std::string("") ) { + std::string home = getenv("HOME"); + std::string file = home; + file += "/config/"; + file += defaultTail; + userSupplied = file; + } + + // Ensure that we can actually read this file + + int status = access(userSupplied.c_str(), R_OK); + if (status == -1) { + std::string msg = "Cannot read the configuration script: "; + msg += userSupplied; + perror(msg.c_str()); + exit(EXIT_FAILURE); + } + + return userSupplied; + +} +/* +** Initialize the main interpreter by adding commands to it. +** first we will wrap the interpreter in a CTCLInterpreter object +** so that we can use CTCLObjectprocssor and CTCLProcessor objects +** to extend the interpreter. +** +** Parameters: +** interp - The raw interpreter object pointer. +** Returns: +** TCL_OK if all goes well. +*/ + +int +CApplication::tclAppInit(Tcl_Interp* pInterp) +{ + CTCLInterpreter* pInterpObj = new CTCLInterpreter(pInterp); + CTCLInterpreter& interp(*pInterpObj); + + CBeginRun* pBegin = new CBeginRun(interp); + CEndRun* pEnd = new CEndRun(interp); + CPauseRun* pPause = new CPauseRun(interp); + CResumeRun* pResume = new CResumeRun(interp); + + return TCL_OK; +} + +/* +** Interact with the port manager to obtain a listener port. +** +** Parameters: +** application - Name of the application we will register . +** Returns: +** port on which to listen for connections. +*/ +int +CApplication::getManagedPort(std::string application) +{ + CPortManager* pManager = new CPortManager(); + + return pManager->allocatePort(application); +} Added: trunk/nextgen/usb/app/CApplication.h =================================================================== --- trunk/nextgen/usb/app/CApplication.h (rev 0) +++ trunk/nextgen/usb/app/CApplication.h 2008-08-18 19:39:08 UTC (rev 1942) @@ -0,0 +1,114 @@ +#ifndef __CAPPLICATION_h +#define __CAPPLICATION_H + +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + + +#ifndef __TCL_H +#include <tcl.h> +#ifndef __TCL_H +#define __TCL_H +#endif +#endif + +class CConfiguration; +class TclServer; + +/*! + This file defines the application base class. + The application base class controls the startup flow of the xx-USB readout frameworkds. + It delegates control to some pure virtual methods which capture the device dependencies of + each interface (e.g. VM-USB, CC-USB). + In practice, the main programs of each readout skeleton, will instantiate a subclass + of this base class, and transfer control to it. + + The usage of the software by default is: + + Readout ?options? + + where options are command line options that take parameters: + - --daqconfig=file - specifies the DAQ configuration file, defaults to $HOME/config/daqconfig.tcl + - --ctlconfig=file - specifies the slow control configuration file, defaults to + $HOME/config/ctlconfig.tcl + - --device=specification - specifies which of potentially several xx-USB interfaces the + program should take data on. 'specification' is a device specific specification string. + for VM-USB/CC-USB this is going to be the serial number string of the desired device. + If not specified, again action is up to the specific readout skeleton, but typically, + the first device located on the USB bus is then used. + - --port=n - Specifies the port on which the TCL server will listen for slow control connections. + This defaults to managed which results in using the port manager to allocate + a port. + - --application=appname - Used only if --port=managed, in which case appname is the + name of the application this program will register with the TCL port manager when + requesting a server port. This defaults to "SlowControls". + + The following are pure virtual methods and what they are supposed to do in concrete + subclasses: + - selectInterface Must select the actual interface, create device driver object and + connect it to the acquisition thread object. + - setupConfiguration - Add configuration commands to the daq configuration so that + supported device objects can be created and configured. + - setupTclServer - add device types to the Tcl server so that slow control devices + can be specified and configured. + + + \note All member functions are virtual so that if this callback scheme is + not sufficient for some special applications, specific members can be + overridden. + + */ + +class CApplication +{ + +public: + virtual ~CApplication(); // Ensure that destructor chaining will work. + + // Implemented virtual member functions + +public: + virtual int main(int argc, char** argv); + virtual std::string selectDAQConfigFile(std::string filespec); + virtual std::string selectControlConfigFile(std::string filespec); + virtual void createConfiguration(); + virtual void createMainInterpreter(int argc, char** argv); + virtual void createTclServer(std::string port, std::string application); + + // Pure virtual methods: + +public: + virtual void selectInterface(std::string specification) = 0; + virtual void setupConfiguration(CConfiguration& configuration) = 0; + virtual void setupTclServer(TclServer& server) = 0; + + +private: + + static std::string configFile(std::string userSupplied, + std::string defaultTail); + static int tclAppInit(Tcl_Interp* interp); // Registers interp commands. + int getManagedPort(std::string application); +}; + +#endif Added: trunk/nextgen/usb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/app/Makefile.am (rev 0) +++ trunk/nextgen/usb/app/Makefile.am 2008-08-18 19:39:08 UTC (rev 1942) @@ -0,0 +1,31 @@ +lib_LTLIBRARIES = libusbapplication.la + +libusbapplication_la_SOURCES = CApplication.cpp + +libusbapplication_la_DEPENDENCIES = usbReadoutOptions.o + +noinst_HEADERS = CApplication.h usbReadoutOptions.h + +INCLUDES = -I@top_srcdir@/base/headers \ + -I@top_srcdir@/usb/tclcommon \ + -I@top_srcdir@/usb/tclserver \ + -I@top_srcdir@/usb/acqcommon \ + -I@top_srcdir@/base/tclplus \ + -I@top_srcdir@/servers/portmanager \ + -I@top_srcdir@/base/thread \ + @TCL_FLAGS@ + +libusbapplication_la_LIBADD = usbReadoutOptions.o + +libusbapplication_la_LDFLAGS = @top_srcdir@/usb/tclcommon/libusbtclcommon.la \ + @top_srcdir@//usb/tclserver/libControlServer.la \ + @top_srcdir@/usb/acqcommon/libusbacqcommon.la \ + @top_srcdir@/base/tclplus/libtclPlus.la \ + @top_srcdir@/servers/portmanager/libPortManager.la \ + @top_srcdir@/base/exception/libException.la \ + @top_srcdir@/base/thread/libdaqthreads.la \ + @TCL_LDFLAGS@ + +usbReadoutOptions.h: usbReadout.ggo + $(GENGETOPT) <usbReadout.ggo --file=usbReadoutOptions + $(CC) -c usbReadoutOptions.o usbReadoutOptions.c \ No newline at end of file Added: trunk/nextgen/usb/app/usbReadout.ggo =================================================================== --- trunk/nextgen/usb/app/usbReadout.ggo (rev 0) +++ trunk/nextgen/usb/app/usbReadout.ggo 2008-08-18 19:39:08 UTC (rev 1942) @@ -0,0 +1,11 @@ +package "usbReadout" +version "1.0" +purpose "USB controller readout skeleton" + +option "daqconfig" d "Path to DAQ configuration file" string optional +option "ctlconfig" c "Path to control configuration file" string optional +option "device" u "Specification of USB device to use" string optional +option "port" p "Slow control Tcl server port" string optional +option "application" a "Port Manager application name" string optional + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-18 19:54:58
|
Revision: 1943 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1943&view=rev Author: ron-fox Date: 2008-08-18 19:55:02 +0000 (Mon, 18 Aug 2008) Log Message: ----------- Get the build to really work from a clean state. Modified Paths: -------------- trunk/nextgen/servers/portmanager/cpptest trunk/nextgen/usb/app/Makefile.am Modified: trunk/nextgen/servers/portmanager/cpptest =================================================================== --- trunk/nextgen/servers/portmanager/cpptest 2008-08-18 19:39:08 UTC (rev 1942) +++ trunk/nextgen/servers/portmanager/cpptest 2008-08-18 19:55:02 UTC (rev 1943) @@ -18,7 +18,7 @@ # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -relink_command="(cd /scratch/fox/daq/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/bin:/usr/bin:/soft/intel/java/bin:/opt/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/user/fox/bin:.:/var/lib/gems/1.8/bin/\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/fox/daq/nextgen/servers/portmanager /scratch/fox/daq/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/fox/daq/nextgen/base/exception /scratch/fox/daq/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0//lib)" +relink_command="(cd /scratch/fox/daq/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/bin:/usr/bin:/soft/intel/java/bin:/bin:/usr/bin:/soft/intel/java/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.:/var/lib/gems/1.8/bin/:.:/var/lib/gems/1.8/bin/\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/fox/daq/nextgen/servers/portmanager /scratch/fox/daq/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/fox/daq/nextgen/base/exception /scratch/fox/daq/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0//lib)" # This environment variable determines our operation mode. if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then Modified: trunk/nextgen/usb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/app/Makefile.am 2008-08-18 19:39:08 UTC (rev 1942) +++ trunk/nextgen/usb/app/Makefile.am 2008-08-18 19:55:02 UTC (rev 1943) @@ -28,4 +28,8 @@ usbReadoutOptions.h: usbReadout.ggo $(GENGETOPT) <usbReadout.ggo --file=usbReadoutOptions - $(CC) -c usbReadoutOptions.o usbReadoutOptions.c \ No newline at end of file + $(CC) -c usbReadoutOptions.o usbReadoutOptions.c + +usbReadoutOptions.o: usbReadout.ggo + $(GENGETOPT) <usbReadout.ggo --file=usbReadoutOptions + $(CC) -c usbReadoutOptions.c \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-19 14:26:54
|
Revision: 1946 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1946&view=rev Author: ron-fox Date: 2008-08-19 14:27:01 +0000 (Tue, 19 Aug 2008) Log Message: ----------- initial good compile of the VM-USB readout program..wonder how high it will fly before it crashes. Modified Paths: -------------- trunk/nextgen/configure.in trunk/nextgen/usb/app/CApplication.h trunk/nextgen/usb/output/COutputThread.cpp trunk/nextgen/usb/output/COutputThread.h trunk/nextgen/usb/vmusb/Makefile.am trunk/nextgen/usb/vmusb/daqconfig/Makefile.am trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBControlModule.h Added Paths: ----------- trunk/nextgen/usb/vmusb/app/ trunk/nextgen/usb/vmusb/app/App.cpp trunk/nextgen/usb/vmusb/app/App.h trunk/nextgen/usb/vmusb/app/Makefile.am trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.cpp trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.h Modified: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/configure.in 2008-08-19 14:27:01 UTC (rev 1946) @@ -390,6 +390,7 @@ usb/vmusb/Makefile usb/vmusb/deviceDriver/Makefile usb/vmusb/daqconfig/Makefile + usb/vmusb/app/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/usb/app/CApplication.h =================================================================== --- trunk/nextgen/usb/app/CApplication.h 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/usb/app/CApplication.h 2008-08-19 14:27:01 UTC (rev 1946) @@ -1,4 +1,4 @@ -#ifndef __CAPPLICATION_h +#ifndef __CAPPLICATION_H #define __CAPPLICATION_H /* Modified: trunk/nextgen/usb/output/COutputThread.cpp =================================================================== --- trunk/nextgen/usb/output/COutputThread.cpp 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/usb/output/COutputThread.cpp 2008-08-19 14:27:01 UTC (rev 1946) @@ -50,6 +50,8 @@ static DataBuffer* lastBuffer(0); static const unsigned ReadoutStack(0); static const unsigned ScalerStack(1); +static const unsigned EventCountMask(0xfff); +static const unsigned Continuation(0x1000); //////////////////////////////////////////////////////////////////////// @@ -259,7 +261,7 @@ void COutputThread::event(uint32_t size, void* pData) { - uint32_t bytes = size*sizeof(uint16_t); + uint32_t bytes = size*sizeof(uint16_t); // USB device sizes are not self inclusive. CRingItem item(PHYSICS_EVENT, bytes); uint8_t* pDest = reinterpret_cast<uint8_t*>(item.getBodyCursor()); @@ -288,6 +290,39 @@ } +/*! + Process data from a VM/CC-USB event buffer. We're going to collect + events and pass them on to the event function until we run out of data. + For buffers that don't match, this can be overridden. + \param buffer -Reference to the data buffer struct. + +*/ +void +COutputThread::processUSBData(DataBuffer& buffer) +{ + uint32_t nWordsLeft = buffer.s_bufferSize/sizeof(uint16_t); // Words not yet processed. + uint16_t* pData = buffer.s_rawData; + unsigned nEvents = *pData & EventCountMask; + pData++; + nWordsLeft--; + + while (nWordsLeft && nEvents) { + uint32_t nWords = eventSize(pData); + event(nWords, pData); + + pData += nWords; + nWordsLeft -= nWords; + } + // Note that both nWordsLeft and nEvents should hit zero at the same time!! + + if (nWordsLeft != nEvents) { + cerr << "Words in buffer not consistent with events in buffer:\n"; + cerr << "Both should now be zero but WordsLeft = " << nWordsLeft << endl; + cerr << " EventsLeft= " << nEvents << endl; + cerr << "Continuing with the next buffer\n"; + } +} + ////////////////////////////////////////////////////////////////////////////////// // // Utilities. @@ -305,3 +340,24 @@ m_pRing = new CRingBuffer(name, CRingBuffer::producer); } +/* +** Figure out how many words are in an event. +** note that event word counts are not self inclusive for +** VM/CC-USB devices. +*/ +uint32_t +COutputThread::eventSize(uint16_t* pEvent) +{ + uint32_t size(0); + uint16_t segmentHeader; + do { + segmentHeader = *pEvent; + uint32_t segmentSize = segmentHeader & EventCountMask; + pEvent += segmentSize; + size += segmentSize; + + } while (segmentHeader & Continuation); + + return size; + +} Modified: trunk/nextgen/usb/output/COutputThread.h =================================================================== --- trunk/nextgen/usb/output/COutputThread.h 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/usb/output/COutputThread.h 2008-08-19 14:27:01 UTC (rev 1946) @@ -143,6 +143,7 @@ private: void openRing(); + uint32_t eventSize(uint16_t* pData); }; Modified: trunk/nextgen/usb/vmusb/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/Makefile.am 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/usb/vmusb/Makefile.am 2008-08-19 14:27:01 UTC (rev 1946) @@ -1 +1 @@ -SUBDIRS = deviceDriver daqconfig +SUBDIRS = deviceDriver daqconfig app Added: trunk/nextgen/usb/vmusb/app/App.cpp =================================================================== --- trunk/nextgen/usb/vmusb/app/App.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/app/App.cpp 2008-08-19 14:27:01 UTC (rev 1946) @@ -0,0 +1,128 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> +#include "App.h" + +#include <CVMUSB.h> +#include <CVMUSBDeviceDriver.h> +#include <CAcquisitionThread.h> +#include <CVMUSBConfig.h> +#include <CVMUSBControlConfig.h> + +#include <usb.h> +#include <iostream> +#include <stdlib.h> + + +/*! + - Select which VM-USB to use. + - Create a CVMUSB object that communicates with that interface. + - Create a device driver object. + - Get the acquisition thread singleton object and bind the device driver to it. + + \param specification - specifies the desired interface. If blank, the first + interface enumerated is used. If not, there must be an interface with a + matching serial string, and that one is used. If there is not a matching + serial number, an error is thrown. +*/ + +void +App::selectInterface(std::string specification) +{ + std::vector<struct usb_device*> vmUSBs = CVMUSB::enumerate(); + + // There may not be any of them!!! + + if (vmUSBs.size() == 0) { + cerr << "There are no VM-USBs detected on the system!\n"; + exit(EXIT_FAILURE); + } + + struct usb_device* pDevice = reinterpret_cast<struct usb_device*>(0); + + // Figure out the right usb_device pointer. + + if (specification == std::string("")) { + pDevice = vmUSBs[0]; + } + else { + for (int i=0; i < vmUSBs.size(); i++) { + if (CVMUSB::getSerial(vmUSBs[i]) == specification) { + pDevice = vmUSBs[i]; + break; + } + } + } + // pDevice is null if there is no matching device, or a valid USB pointer + // from which a CVMUSB can be constructed. + + if (!pDevice) { + std::cerr << "None of the VM-USB devices on the system has the serial number " + << specification << std::endl; + std::cerr << "Here is a list of the VM-USB serial numbers I found:\n"; + for (int i=0; i < vmUSBs.size(); i++) { + std::cerr << CVMUSB::getSerial(vmUSBs[i]) << std::endl; + } + exit(EXIT_FAILURE); + } + // Create the device driver: + + CVMUSB* pVMUSB = new CVMUSB(pDevice); + CVMUSBDeviceDriver* pDriver= new CVMUSBDeviceDriver(pVMUSB); + + // Create the acq thread and bind the device driver to it: + + CAcquisitionThread* pReadout = CAcquisitionThread::getInstance(); + pReadout->setDriver(pDriver); + + +} +/*! + Setup a configuration so that it will contain all of the commands needed + to process a DAQ configuration file for the VM-USB supported devices. + \param configuration - reference to the pre-built configuration. +*/ +void +App::setupConfiguration(CConfiguration& config) +{ + CVMUSBConfig::configure(&config); +} +/*! + Set up a Tcl server so that it will be able to process commands in a + control configuration file. + \param server - reference to the server. +*/ +void +App::setupTclServer(TclServer& pServer) +{ + CVMUSBControlConfig::configure(&pServer); +} +///////////////////////////////////////////////////////////////////////////// + +/*! + The program entry point. we simply need to crate an App object and + invoke it's main() entry. +*/ +int +main(int argc, char** argv) +{ + App theApp; + return theApp.main(argc, argv); +} + + +void* gpTCLApplication(0); Added: trunk/nextgen/usb/vmusb/app/App.h =================================================================== --- trunk/nextgen/usb/vmusb/app/App.h (rev 0) +++ trunk/nextgen/usb/vmusb/app/App.h 2008-08-19 14:27:01 UTC (rev 1946) @@ -0,0 +1,47 @@ +#ifndef __APP_H +#define __APP_H +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + + +#ifndef __CAPPLICATION_H +#include <CApplication.h> +#endif + +/*! + This is a concrete subclass of CApplication. This class provides + the pure virtual methods needed to setup a VM-USB readout program. + Specifically, we must provide: + - selectInterface which selects the correct interface, makes + a device driver object and binds it into the acquisition thread object. + - setupConfiguration which takes a configuration object and adds the appropriate + stuff to it so that it can process VM-USB DAQ configuration files. + - setupTclServer which takes a Tcl Server thread object and adds sufficient stuff + to it so that it can read in VM-USB control configuration files. + +\note The implementation file also provides the main, entry point to the program. + +*/ +class App : public CApplication +{ +public: + virtual void selectInterface(std::string specification) ; + virtual void setupConfiguration(CConfiguration& configuration) ; + virtual void setupTclServer(TclServer& server) ; + +}; + +#endif Added: trunk/nextgen/usb/vmusb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/app/Makefile.am (rev 0) +++ trunk/nextgen/usb/vmusb/app/Makefile.am 2008-08-19 14:27:01 UTC (rev 1946) @@ -0,0 +1,32 @@ +bin_PROGRAMS = VMUSBReadout + +VMUSBReadout_SOURCES = App.cpp +noinst_HEADERS = App.h + + +# Assume we need all header dirs and all libs in the usb/vmusb tree. + + +INCLUDES = -I@top_srcdir@/usb/acqcommon \ + -I@top_srcdir@/usb/app \ + -I@top_srcdir@/usb/commands \ + -I@top_srcdir@/usb/tclcommon \ + -I@top_srcdir@/usb/tclserver \ + -I@top_srcdir@/usb/threadcom \ + -I@top_srcdir@/usb/vmusb/daqconfig \ + -I@top_srcdir@/usb/vmusb/deviceDriver \ + -I@top_srcdir@/base/thread \ + @TCL_FLAGS@ + +VMUSBReadout_LDADD = @top_srcdir@/usb/acqcommon/libusbacqcommon.la \ + @top_srcdir@/usb/tclcommon/libusbtclcommon.la \ + @top_srcdir@/usb/threadcom/libThreadComm.la \ + @top_srcdir@/usb/output/libOutputStage.la \ + @top_srcdir@/usb/app/libusbapplication.la \ + @top_srcdir@/usb/tclserver/libControlServer.la \ + @top_srcdir@/usb/vmusb/deviceDriver/libvmUsbDeviceDrivers.la \ + @top_srcdir@/usb/vmusb/daqconfig/libvmUsbConfigCommands.la \ + @top_srcdir@/base/thread/libdaqthreads.la \ + @TCL_LDFLAGS@ -lusb + + Added: trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.cpp 2008-08-19 14:27:01 UTC (rev 1946) @@ -0,0 +1,31 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ +#include <config.h> +#include "CVMUSBControlConfig.h" +#include <TclServer.h> +#include <CGDG.h> + +/*! + Add prototoypes modules for each supported device type to the + Tcl Server. + \param pServer - Pointer to the tcl server object. +*/ +void +CVMUSBControlConfig::configure(TclServer* pServer) +{ + pServer->addPrototype(std::string("gdg"), + new CGDG("gdg")); +} Added: trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.h (rev 0) +++ trunk/nextgen/usb/vmusb/daqconfig/CVMUSBControlConfig.h 2008-08-19 14:27:01 UTC (rev 1946) @@ -0,0 +1,33 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __CVMUSBCONTROLCONFIG_H +#define __CVMUSBCONTROLCONFIG_H + +class TclServer; + +/*! + This file contains some static members that understand how to + setup a TclServer object to understand how to interpret a control + configuration file. +*/ +class CVMUSBControlConfig +{ +public: + static void configure(TclServer* pServer); +}; + +#endif Modified: trunk/nextgen/usb/vmusb/daqconfig/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/Makefile.am 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/usb/vmusb/daqconfig/Makefile.am 2008-08-19 14:27:01 UTC (rev 1946) @@ -10,7 +10,8 @@ CScalerCommand.cpp \ CSIS3804Command.cpp \ CStackCommand.cpp \ - CVMUSBConfig.cpp + CVMUSBConfig.cpp \ + CVMUSBControlConfig.cpp noinst_HEADERS = CADCCommand.h \ CCAENChainCommand.h \ @@ -22,19 +23,26 @@ CNADC2530Command.h \ CScalerCommand.h \ CSIS3804Command.h \ - CStackCommand.h + CStackCommand.h \ + CVMUSBConfig.h \ + CVMUSBControlConfig.h + INCLUDES = -I@top_srcdir@/base/tclplus \ -I@top_srcdir@/usb/tclcommon \ + -I@top_srcdir@/usb/tclserver \ -I@top_srcdir@/base/headers \ -I@top_srcdir@/usb/vmusb/deviceDriver \ -I@top_srcdir@/usb/acqcommon \ + -I@top_srcdir@/base/thread \ @TCL_FLAGS@ libvmUsbConfigCommands_la_LDFLAGS = @top_srcdir@/base/tclplus/libtclPlus.la \ @top_srcdir@/usb/tclcommon/libusbtclcommon.la \ + @top_srcdir@/usb/tclserver/libControlServer.la \ @top_srcdir@/usb/vmusb/deviceDriver/libvmUsbDeviceDrivers.la \ @top_srcdir@/usb/acqcommon/libusbacqcommon.la \ + @top_srcdir@/base/thread/libdaqthreads.la \ @TCL_LDFLAGS@ \ No newline at end of file Modified: trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBControlModule.h =================================================================== --- trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBControlModule.h 2008-08-19 14:25:07 UTC (rev 1945) +++ trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBControlModule.h 2008-08-19 14:27:01 UTC (rev 1946) @@ -71,7 +71,7 @@ // Now here's the thing our facade is in front of: - virtual void Initialize(CVMUSB& vme); + virtual void Initialize(CVMUSB& vme) = 0; virtual std::string Update(CVMUSB& vme) = 0; //!< Update module. virtual std::string Set(CVMUSB& vme, std::string parameter, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-19 21:07:05
|
Revision: 1953 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1953&view=rev Author: ron-fox Date: 2008-08-19 21:07:11 +0000 (Tue, 19 Aug 2008) Log Message: ----------- 1. Fix some build issues. 2. Remove duplication of CModuleCommand class in the USB readout software. Modified Paths: -------------- trunk/nextgen/aclocal.m4 trunk/nextgen/base/CopyrightTools/test trunk/nextgen/servers/portmanager/cpptest trunk/nextgen/servers/portmanager/makeindex.tcl trunk/nextgen/usb/app/Makefile.am trunk/nextgen/usb/tclserver/CModuleCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.h trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.cpp trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.h trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.h trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.cpp trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.h trunk/nextgen/utilities/bufdump/Makefile.am trunk/nextgen/utilities/eventlog/Makefile.am trunk/nextgen/utilities/ringselector/Makefile.am trunk/nextgen/utilities/sclclient/Makefile.am Modified: trunk/nextgen/aclocal.m4 =================================================================== --- trunk/nextgen/aclocal.m4 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/aclocal.m4 2008-08-19 21:07:11 UTC (rev 1953) @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.10 -*- Autoconf -*- +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. +# 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,11 +11,6 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_if(m4_PACKAGE_VERSION, [2.61],, -[m4_fatal([this file was generated for autoconf 2.61. -You have another version of autoconf. If you want to use that, -you should regenerate the build system entirely.], [63])]) - # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # serial 48 Debian 1.5.22-4 AC_PROG_LIBTOOL @@ -6385,7 +6380,7 @@ AC_MSG_RESULT([$SED]) ]) -# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6395,29 +6390,14 @@ # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.10' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.10], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.10])dnl -_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) + [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- @@ -6474,14 +6454,14 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 8 +# serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- @@ -6490,10 +6470,8 @@ [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' @@ -6507,14 +6485,15 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 +# serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -6542,7 +6521,6 @@ ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) @@ -6608,7 +6586,6 @@ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then @@ -6661,8 +6638,7 @@ AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- @@ -6687,9 +6663,8 @@ # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue @@ -6736,8 +6711,8 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6760,20 +6735,16 @@ # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.60])dnl +[AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath @@ -6793,9 +6764,6 @@ AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl @@ -6831,10 +6799,6 @@ [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) @@ -6870,7 +6834,7 @@ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. @@ -6948,14 +6912,14 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 +# serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ @@ -6971,7 +6935,6 @@ # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then @@ -6982,7 +6945,7 @@ fi ]) -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6990,23 +6953,60 @@ # AM_PROG_MKDIR_P # --------------- -# Check for `mkdir -p'. +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- @@ -7118,21 +7118,9 @@ if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. Modified: trunk/nextgen/servers/portmanager/cpptest =================================================================== --- trunk/nextgen/servers/portmanager/cpptest 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/servers/portmanager/cpptest 2008-08-19 21:07:11 UTC (rev 1953) @@ -18,12 +18,12 @@ # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -relink_command="(cd /scratch/fox/daq/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/bin:/usr/bin:/soft/intel/java/bin:/bin:/usr/bin:/soft/intel/java/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.:/var/lib/gems/1.8/bin/:.:/var/lib/gems/1.8/bin/\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/fox/daq/nextgen/servers/portmanager /scratch/fox/daq/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/fox/daq/nextgen/base/exception /scratch/fox/daq/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0//lib)" +relink_command="(cd /scratch/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/bin/mh:/usr/sbin/:/sbin:/usr/bin/mh:/usr/sbin/:/sbin\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/nextgen/servers/portmanager /scratch/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/nextgen/base/exception /scratch/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0/lib)" # This environment variable determines our operation mode. if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then # install mode needs the following variable: - notinst_deplibs=' /scratch/fox/daq/nextgen/servers/portmanager/libPortManager.la /scratch/fox/daq/nextgen/base/exception/libException.la' + notinst_deplibs=' /scratch/nextgen/servers/portmanager/libPortManager.la /scratch/nextgen/base/exception/libException.la' else # When we are sourced in execute mode, $file and $echo are already set. if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then Modified: trunk/nextgen/servers/portmanager/makeindex.tcl =================================================================== --- trunk/nextgen/servers/portmanager/makeindex.tcl 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/servers/portmanager/makeindex.tcl 2008-08-19 21:07:11 UTC (rev 1953) @@ -1 +1 @@ -pkg_mkIndex /usr/opt/daq/10.0//TclLibs/PortManager *.tcl +pkg_mkIndex /usr/opt/daq/10.0/TclLibs/PortManager *.tcl Modified: trunk/nextgen/usb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/app/Makefile.am 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/app/Makefile.am 2008-08-19 21:07:11 UTC (rev 1953) @@ -4,7 +4,7 @@ libusbapplication_la_DEPENDENCIES = usbReadoutOptions.o -noinst_HEADERS = CApplication.h usbReadoutOptions.h +noinst_HEADERS = CApplication.h INCLUDES = -I@top_srcdir@/base/headers \ -I@top_srcdir@/usb/tclcommon \ @@ -26,9 +26,11 @@ @top_srcdir@/base/thread/libdaqthreads.la \ @TCL_LDFLAGS@ +BUILT_SOURCES = usbReadoutOptions.h + usbReadoutOptions.h: usbReadout.ggo $(GENGETOPT) <usbReadout.ggo --file=usbReadoutOptions - $(CC) -c usbReadoutOptions.o usbReadoutOptions.c + $(CC) -c usbReadoutOptions.c usbReadoutOptions.o: usbReadout.ggo $(GENGETOPT) <usbReadout.ggo --file=usbReadoutOptions Modified: trunk/nextgen/usb/tclserver/CModuleCommand.cpp =================================================================== --- trunk/nextgen/usb/tclserver/CModuleCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/tclserver/CModuleCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -68,7 +68,7 @@ // validate the parameter count. if (objv.size() < 2) { - m_Server.setResult("module: Insufficient parameters need module create | config | cget"); + interp.setResult("module: Insufficient parameters need module create | config | cget"); return TCL_ERROR; } @@ -85,7 +85,7 @@ return cget(interp, objv); } else { - m_Server.setResult("module: Invalid subcommand need module create | config |cget"); + interp.setResult("module: Invalid subcommand need module create | config |cget"); return TCL_ERROR; } } @@ -105,7 +105,7 @@ vector<CTCLObject>& objv) { if (objv.size() != 4) { - m_Server.setResult("module create: Wrong number of params need: module create type name"); + interp.setResult("module create: Wrong number of params need: module create type name"); return TCL_ERROR; } string type = objv[2]; @@ -126,7 +126,7 @@ m_Server.addModule(pModule); - m_Server.setResult(name); + interp.setResult(name); return TCL_OK; @@ -147,7 +147,7 @@ size_t nelements = objv.size(); if ((nelements < 3) || ((nelements % 2) == 0)) { - m_Server.setResult("module config : invalid number of command elements."); + interp.setResult("module config : invalid number of command elements."); return TCL_ERROR; } string name = objv[2]; @@ -157,7 +157,7 @@ string msg("module config: "); msg += name; msg += " not found."; - m_Server.setResult(msg); + interp.setResult(msg); return TCL_ERROR; } for (int i = 3; i < nelements; i+=2) { @@ -175,7 +175,7 @@ msg += value; msg += " because: "; msg += failmsg; - m_Server.setResult( msg); + interp.setResult( msg); return TCL_ERROR; } } @@ -199,7 +199,7 @@ CModuleCommand::cget(CTCLInterpreter& interp, vector<CTCLObject>& objv) { if ((objv.size() < 3) || (objv.size() > 4)) { - m_Server.setResult("module cget : invalid number of parameters; need module cget name ?key?"); + interp.setResult("module cget : invalid number of parameters; need module cget name ?key?"); return TCL_ERROR; } @@ -209,7 +209,7 @@ string msg("module cget "); msg += name; msg += " module not found"; - m_Server.setResult( msg); + interp.setResult( msg); return TCL_ERROR; } @@ -243,10 +243,10 @@ msg += key; msg += " because: "; msg += failmsg; - m_Server.setResult( msg); + interp.setResult( msg); return TCL_ERROR; } - m_Server.setResult(value); + interp.setResult(value); return TCL_OK; } Modified: trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -26,7 +26,7 @@ CADCCommand::CADCCommand(CTCLInterpreter& interp, CConfiguration& config, std::string commandName) : - CModuleCommand(interp, config, commandName) + CDAQModuleCommand(interp, config, commandName) {} /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CADCCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -75,7 +75,7 @@ \endverbatim */ -class CADCCommand : public CModuleCommand +class CADCCommand : public CDAQModuleCommand { public: CADCCommand(CTCLInterpreter& interp, Modified: trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -35,7 +35,7 @@ CCAENChainCommand::CCAENChainCommand(CTCLInterpreter& interp, CConfiguration& config, string commandName) : - CModuleCommand(interp, config, commandName) + CDAQModuleCommand(interp, config, commandName) {} /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENChainCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -52,7 +52,7 @@ */ -class CCAENChainCommand : public CModuleCommand +class CCAENChainCommand : public CDAQModuleCommand { public: CCAENChainCommand(CTCLInterpreter& interp, Modified: trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -34,7 +34,7 @@ */ CCAENV830Command::CCAENV830Command(CTCLInterpreter& interp, CConfiguration& config, string name) : - CModuleCommand(interp, config, name) + CDAQModuleCommand(interp, config, name) { } /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CCAENV830Command.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -86,7 +86,7 @@ \endverbatim */ -class CCAENV830Command : public CModuleCommand +class CCAENV830Command : public CDAQModuleCommand { public: Modified: trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -33,7 +33,7 @@ CMADCCommand::CMADCCommand(CTCLInterpreter& interp, CConfiguration& config, std::string commandName) : - CModuleCommand(interp, config, commandName) + CDAQModuleCommand(interp, config, commandName) {} /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -42,7 +42,7 @@ */ -class CMADCCommand : public CModuleCommand +class CMADCCommand : public CDAQModuleCommand { public: Modified: trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -33,7 +33,7 @@ CMADCScalerCommand::CMADCScalerCommand(CTCLInterpreter& interp, CConfiguration& config, std::string commandName) : - CModuleCommand(interp, config, commandName) + CDAQModuleCommand(interp, config, commandName) {} Modified: trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CMADCScalerCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -43,7 +43,7 @@ */ -class CMADCScalerCommand : public CModuleCommand +class CMADCScalerCommand : public CDAQModuleCommand { public: Modified: trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -42,7 +42,7 @@ CMarkerCommand::CMarkerCommand(CTCLInterpreter& interp, CConfiguration& config, std::string commandName) : - CModuleCommand(interp,config, commandName) + CDAQModuleCommand(interp,config, commandName) {} /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CMarkerCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -43,7 +43,7 @@ the value is mandatory */ -class CMarkerCommand : public CModuleCommand +class CMarkerCommand : public CDAQModuleCommand { public: Modified: trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -41,7 +41,7 @@ module objects. \param name - The name of the command. */ -CModuleCommand::CModuleCommand(CTCLInterpreter& interp, CConfiguration& config, string name) : +CDAQModuleCommand::CDAQModuleCommand(CTCLInterpreter& interp, CConfiguration& config, string name) : CTCLObjectProcessor(interp, name), m_config(config) {} @@ -49,7 +49,7 @@ /*! Chain to the base class destructor which will unregister the command. */ -CModuleCommand::~CModuleCommand() +CDAQModuleCommand::~CDAQModuleCommand() {} ////////////////////////////////////////////////////////////////////////////////////////////// @@ -79,7 +79,7 @@ */ int -CModuleCommand::operator()(CTCLInterpreter& interp, vector<CTCLObject>& objv) +CDAQModuleCommand::operator()(CTCLInterpreter& interp, vector<CTCLObject>& objv) { // require at least 3 parameters. @@ -129,7 +129,7 @@ adc config [adc create adc1 0x80000000] .... */ int -CModuleCommand::create(CTCLInterpreter& interp, vector<CTCLObject>& objv) +CDAQModuleCommand::create(CTCLInterpreter& interp, vector<CTCLObject>& objv) { if (objv.size() < 3) { Usage("not enough parameters for the create subcommand", objv); @@ -200,7 +200,7 @@ Note that all error messages will start with the text "ERROR:" */ int -CModuleCommand::config(CTCLInterpreter& interp, vector<CTCLObject>& objv) +CDAQModuleCommand::config(CTCLInterpreter& interp, vector<CTCLObject>& objv) { if ((objv.size() < 5) || ((objv.size() % 2) != 1)) { Usage("Incorrect number of command parameters in ", objv); @@ -244,7 +244,7 @@ value pair...e.g. {-base 0x80000000} ... */ int -CModuleCommand::cget(CTCLInterpreter& interp, vector<CTCLObject>& objv) +CDAQModuleCommand::cget(CTCLInterpreter& interp, vector<CTCLObject>& objv) { if (objv.size() != 3) { Usage("Invalid command parameter count for cget", objv); @@ -276,7 +276,7 @@ Create error message text, and set it as the interpreter result. */ void -CModuleCommand::Usage(std::string msg, std::vector<CTCLObject>& objv) +CDAQModuleCommand::Usage(std::string msg, std::vector<CTCLObject>& objv) { string result("ERROR: "); result += msg; @@ -314,7 +314,7 @@ at this time. */ void -CModuleCommand::addObjectToConfiguration(CConfiguration& config, +CDAQModuleCommand::addObjectToConfiguration(CConfiguration& config, std::string name, std::string type, CConfigurableObject* object) @@ -334,7 +334,7 @@ If found, a pointer to the module is returned, if not a NULL. */ CConfigurableObject* -CModuleCommand::findModule(string name) +CDAQModuleCommand::findModule(string name) { CConfiguration::ConfigurationIterator p = m_config.findObjectByName(name); if (p == m_config.end()) { @@ -348,7 +348,7 @@ type of module we're managing */ CConfigurableObject* -CModuleCommand::findModuleOfMyType(string name) +CDAQModuleCommand::findModuleOfMyType(string name) { CConfiguration::ConfigurationIterator p = m_config.findObjectByName(name); if (p == m_config.end()) { return reinterpret_cast<CConfigurableObject*>(0); @@ -370,7 +370,7 @@ TCL_ERROR - failure. */ int -CModuleCommand::Configure(CTCLInterpreter& interp, +CDAQModuleCommand::Configure(CTCLInterpreter& interp, std::vector<CTCLObject>& objv, CConfigurableObject* pObject, unsigned startAt) Modified: trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -1,5 +1,5 @@ -#ifndef __CMODULECOMMAND_H -#define __CMODULECOMMAND_H +#ifndef __CDAQMODULECOMMAND_H +#define __CDAQMODULECOMMAND_H /* This software is Copyright by the Board of Trustees of Michigan @@ -66,21 +66,21 @@ The preceding members are also virtual so that module commands with special needs can override or extend them. */ -class CModuleCommand : public CTCLObjectProcessor // >>>ABSTRACT BASE CLASS<<< +class CDAQModuleCommand : public CTCLObjectProcessor // >>>ABSTRACT BASE CLASS<<< { protected: CConfiguration& m_config; public: - CModuleCommand(CTCLInterpreter& interp, + CDAQModuleCommand(CTCLInterpreter& interp, CConfiguration& config, std::string name); - virtual ~CModuleCommand(); + virtual ~CDAQModuleCommand(); private: - CModuleCommand(const CModuleCommand& rhs); - CModuleCommand& operator=(const CModuleCommand& rhs); - int operator==(const CModuleCommand& rhs) const; - int operator!=(const CModuleCommand& rhs) const; + CDAQModuleCommand(const CDAQModuleCommand& rhs); + CDAQModuleCommand& operator=(const CDAQModuleCommand& rhs); + int operator==(const CDAQModuleCommand& rhs) const; + int operator!=(const CDAQModuleCommand& rhs) const; // This class implements the following methods, although they can be Modified: trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -37,7 +37,7 @@ CNADC2530Command::CNADC2530Command(CTCLInterpreter& interp, CConfiguration& config, std::string commandName) : - CModuleCommand(interp, config, commandName) + CDAQModuleCommand(interp, config, commandName) { } /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CNADC2530Command.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -56,7 +56,7 @@ */ -class CNADC2530Command : public CModuleCommand +class CNADC2530Command : public CDAQModuleCommand { public: Modified: trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -35,7 +35,7 @@ */ CSIS3804Command::CSIS3804Command(CTCLInterpreter& interp, CConfiguration& config) : - CModuleCommand(interp, config, string("sis3804")) + CDAQModuleCommand(interp, config, string("sis3804")) { } Modified: trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CSIS3804Command.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -35,7 +35,7 @@ are acceptable. */ -class CSIS3804Command : public CModuleCommand +class CSIS3804Command : public CDAQModuleCommand { public: CSIS3804Command(CTCLInterpreter& interp, CConfiguration& config); Modified: trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -34,7 +34,7 @@ Configuration we will be maintaining. */ CScalerCommand:: CScalerCommand(CTCLInterpreter& interp, CConfiguration& config) : - CModuleCommand(interp, config, string("sis3820")) + CDAQModuleCommand(interp, config, string("sis3820")) { } /*! Modified: trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CScalerCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -33,7 +33,7 @@ This module does not require configuration. */ -class CScalerCommand : public CModuleCommand +class CScalerCommand : public CDAQModuleCommand { public: CScalerCommand(CTCLInterpreter& interp, CConfiguration& config); Modified: trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.cpp 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.cpp 2008-08-19 21:07:11 UTC (rev 1953) @@ -38,7 +38,7 @@ CStackCommand::CStackCommand(CTCLInterpreter& interp, CConfiguration& config, std::string commandName) : - CModuleCommand(interp, config, commandName) + CDAQModuleCommand(interp, config, commandName) { } Modified: trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.h =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.h 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/usb/vmusb/daqconfig/CStackCommand.h 2008-08-19 21:07:11 UTC (rev 1953) @@ -77,7 +77,7 @@ programmatically enforced. */ -class CStackCommand : public CModuleCommand +class CStackCommand : public CDAQModuleCommand { Modified: trunk/nextgen/utilities/bufdump/Makefile.am =================================================================== --- trunk/nextgen/utilities/bufdump/Makefile.am 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/utilities/bufdump/Makefile.am 2008-08-19 21:07:11 UTC (rev 1953) @@ -14,9 +14,9 @@ CRingDataSource.h \ CFileDataSource.h \ BufdumpMain.h \ - ../StringsToIntegers.h \ - dumperargs.h + ../StringsToIntegers.h +BUILT_SOURCES = dumperargs.h INCLUDES = -I.. \ Modified: trunk/nextgen/utilities/eventlog/Makefile.am =================================================================== --- trunk/nextgen/utilities/eventlog/Makefile.am 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/utilities/eventlog/Makefile.am 2008-08-19 21:07:11 UTC (rev 1953) @@ -2,10 +2,11 @@ eventlog_SOURCES = eventlog.cpp eventlogMain.cpp -noinst_HEADERS = eventlogargs.h eventlogMain.h +noinst_HEADERS = eventlogMain.h eventlog_DEPENDENCIES = eventlogargs.o +BUILT_SOURCES = eventlogargs.h INCLUDES = -I@top_srcdir@/base/headers \ -I@top_srcdir@/base/exception \ @@ -19,7 +20,7 @@ # Gengetopt stuff. -eventlogsargs.h: eventlogargs.ggo +eventlogargs.h: eventlogargs.ggo $(GENGETOPT) <eventlogargs.ggo --file=eventlogargs $(CC) -c -I. eventlogargs.c Modified: trunk/nextgen/utilities/ringselector/Makefile.am =================================================================== --- trunk/nextgen/utilities/ringselector/Makefile.am 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/utilities/ringselector/Makefile.am 2008-08-19 21:07:11 UTC (rev 1953) @@ -4,8 +4,10 @@ ringselector_DEPENDENCIES = parser.o -noinst_HEADERS = parser.h ../StringsToIntegers.h RingSelectorMain.h +noinst_HEADERS = ../StringsToIntegers.h RingSelectorMain.h +BUILT_SOURCES = parser.h + INCLUDES = -I@top_srcdir@/base/exception \ -I@top_srcdir@/base/headers \ -I@top_srcdir@/daq/format \ Modified: trunk/nextgen/utilities/sclclient/Makefile.am =================================================================== --- trunk/nextgen/utilities/sclclient/Makefile.am 2008-08-19 20:58:39 UTC (rev 1952) +++ trunk/nextgen/utilities/sclclient/Makefile.am 2008-08-19 21:07:11 UTC (rev 1953) @@ -18,6 +18,7 @@ sclclient_DEPENDENCIES = sclclientargs.o +BUILT_SOURCES = sclclientargs.o sclclient_LDADD = sclclientargs.o \ @top_srcdir@/daq/format/libdataformat.la \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-20 19:18:42
|
Revision: 1956 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1956&view=rev Author: ron-fox Date: 2008-08-20 19:18:45 +0000 (Wed, 20 Aug 2008) Log Message: ----------- Looks like a possibly working vmusb readout -> ring buffer. Modified Paths: -------------- trunk/nextgen/usb/acqcommon/CBeginRun.cpp trunk/nextgen/usb/acqcommon/CEndRun.cpp trunk/nextgen/usb/app/CApplication.cpp trunk/nextgen/usb/app/CApplication.h trunk/nextgen/usb/output/COutputThread.cpp trunk/nextgen/usb/output/COutputThread.h trunk/nextgen/usb/vmusb/app/App.cpp trunk/nextgen/usb/vmusb/app/App.h trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am trunk/nextgen/utilities/bufdump/BufdumpMain.cpp Added Paths: ----------- trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.cpp trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.h Modified: trunk/nextgen/usb/acqcommon/CBeginRun.cpp =================================================================== --- trunk/nextgen/usb/acqcommon/CBeginRun.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/acqcommon/CBeginRun.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -120,7 +120,7 @@ } CAcquisitionThread* pReadout = CAcquisitionThread::getInstance(); - pReadout->start(); + pReadout->Start(); interp.setResult("Begin - Run started"); return TCL_OK; Modified: trunk/nextgen/usb/acqcommon/CEndRun.cpp =================================================================== --- trunk/nextgen/usb/acqcommon/CEndRun.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/acqcommon/CEndRun.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -63,7 +63,7 @@ if (objv.size() != 1) { string msg = "end -- incorrect number of command parameters\n"; msg += usage; - interp.setResult(usage); + interp.setResult(msg); return TCL_ERROR; } CRunState* pState = CRunState::getInstance(); @@ -71,7 +71,7 @@ string msg = "end - Invalid state for end run. Must not already be idle\n"; msg += usage; - interp.setResult(usage); + interp.setResult(msg); return TCL_ERROR; } // Now stop the run. Modified: trunk/nextgen/usb/app/CApplication.cpp =================================================================== --- trunk/nextgen/usb/app/CApplication.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/app/CApplication.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -28,7 +28,6 @@ #include <CResumeRun.h> #include <CPortManager.h> -#include <COutputThread.h> #include <stdlib.h> #include <unistd.h> @@ -85,9 +84,8 @@ createConfiguration(); createTclServer(port, application); createBuffers(); - COutputThread* pRouter = new COutputThread(); - pRouter->start(); - createMainInterpreter(argc, argv); // MUST BE LAST!!!!!! + startOutputThread(); + createMainInterpreter(argc, argv); // MUST BE LAST!!!!!! does not return!! Modified: trunk/nextgen/usb/app/CApplication.h =================================================================== --- trunk/nextgen/usb/app/CApplication.h 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/app/CApplication.h 2008-08-20 19:18:45 UTC (rev 1956) @@ -71,6 +71,7 @@ supported device objects can be created and configured. - setupTclServer - add device types to the Tcl server so that slow control devices can be specified and configured. + - startOutputThread - Create/start the output thread (derivation of COutputThread). - createBuffers() - Must set up the buffer pool with sufficient buffers of the correct size for the interface. @@ -103,6 +104,7 @@ virtual void selectInterface(std::string specification) = 0; virtual void setupConfiguration(CConfiguration& configuration) = 0; virtual void setupTclServer(TclServer& server) = 0; + virtual void startOutputThread() = 0; virtual void createBuffers() = 0; Modified: trunk/nextgen/usb/output/COutputThread.cpp =================================================================== --- trunk/nextgen/usb/output/COutputThread.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/output/COutputThread.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -44,14 +44,11 @@ #include <sys/types.h> +static const uint64_t eventCountRate(2000); + using namespace std; -static DataBuffer* lastBuffer(0); -static const unsigned ReadoutStack(0); -static const unsigned ScalerStack(1); -static const unsigned EventCountMask(0xfff); -static const unsigned Continuation(0x1000); //////////////////////////////////////////////////////////////////////// @@ -237,8 +234,8 @@ COutputThread::scaler(time_t when, int number, uint32_t* pScalers) { - uint32_t startTime = m_lastStampedBuffer; - uint32_t endTime = when; + uint32_t startTime = m_lastStampedBuffer - m_startTimestamp; + uint32_t endTime = when - m_startTimestamp;; m_lastStampedBuffer= when; CRingScalerItem item(number); @@ -277,7 +274,7 @@ /*! Produce an event count item on behalf of the client. We've been maintaining a count of the events in a run for the caller. - \param when -tim3 when this should be emitted. + \param when -time when this should be emitted. */ void @@ -300,18 +297,23 @@ void COutputThread::processUSBData(DataBuffer& buffer) { - uint32_t nWordsLeft = buffer.s_bufferSize/sizeof(uint16_t); // Words not yet processed. + uint32_t nWordsLeft = bodySize(buffer); uint16_t* pData = buffer.s_rawData; - unsigned nEvents = *pData & EventCountMask; - pData++; - nWordsLeft--; + unsigned nEvents = eventCount(buffer); + unsigned hWords = headerSize(buffer); + nWordsLeft -= hWords; + pData += hWords; + time_t timestamp = buffer.s_timeStamp; - while (nWordsLeft && nEvents) { + + while (nWordsLeft && nEvents) { // Exit either if out of events or out of data; + uint32_t nWords = eventSize(pData); - event(nWords, pData); + processEvent(timestamp, nWords, pData); pData += nWords; nWordsLeft -= nWords; + nEvents--; } // Note that both nWordsLeft and nEvents should hit zero at the same time!! @@ -321,6 +323,11 @@ cerr << " EventsLeft= " << nEvents << endl; cerr << "Continuing with the next buffer\n"; } + + // After the buffer, put out an event count record: + + eventCount(timestamp); + } ////////////////////////////////////////////////////////////////////////////////// @@ -346,24 +353,3 @@ m_pRing = new CRingBuffer(name, CRingBuffer::producer); } -/* -** Figure out how many words are in an event. -** note that event word counts are not self inclusive for -** VM/CC-USB devices. -*/ -uint32_t -COutputThread::eventSize(uint16_t* pEvent) -{ - uint32_t size(0); - uint16_t segmentHeader; - do { - segmentHeader = *pEvent; - uint32_t segmentSize = segmentHeader & EventCountMask; - pEvent += segmentSize; - size += segmentSize; - - } while (segmentHeader & Continuation); - - return size; - -} Modified: trunk/nextgen/usb/output/COutputThread.h =================================================================== --- trunk/nextgen/usb/output/COutputThread.h 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/output/COutputThread.h 2008-08-20 19:18:45 UTC (rev 1956) @@ -87,6 +87,21 @@ \note There is no need to start/stop thread each run. Once a run is over, this thread will simply block on the buffer queue until the next run emits the begin run buffer. + + This is an abstract base class as there are some elements of the + output thread that are device specific. The device specific elements are + captured in the pure virtual functions: + - bodySize - Returns the number of words in a buffer body. + - eventCount - Given a DataBuffer*, this should return the number of events in + the body part of the buffer. + - headerSize - Given a DataBuffer*, returns the number of words prior to the + first event in the buffer. + - eventSize - Given a pointer to an event within the buffer, returns the number + of words in the event. + - processEvent - Called for each event in the buffer, this is expected to call + back to event or scaler to create/dispose of the appropriate ring item. + + */ class COutputThread : public Thread @@ -136,15 +151,27 @@ void scaler(time_t when, int number, uint32_t* pScalers); - void event(uint32_t size, - void* pData); + void event(uint32_t size, void* pBody); void eventCount(time_t when); + // The concrete interface specific implementation must + // provide the following: + virtual unsigned bodySize(DataBuffer& buffer) = 0; + virtual unsigned eventCount(DataBuffer& buffer) = 0; + virtual unsigned headerSize(DataBuffer& buffer) = 0; + virtual uint32_t eventSize(uint16_t* pEvent) = 0; + virtual void processEvent(time_t when, + uint32_t size, + uint16_t* pEvent) = 0; + + + // utilities. + private: void openRing(); - uint32_t eventSize(uint16_t* pData); + }; #endif Modified: trunk/nextgen/usb/vmusb/app/App.cpp =================================================================== --- trunk/nextgen/usb/vmusb/app/App.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/vmusb/app/App.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -22,6 +22,7 @@ #include <CAcquisitionThread.h> #include <CVMUSBConfig.h> #include <CVMUSBControlConfig.h> +#include <CVMUSBOutputThread.h> #include <DataBuffer.h> #include <CBufferQueue.h> @@ -115,6 +116,15 @@ { CVMUSBControlConfig::configure(&pServer); } +/*! + Create and start the output thread, which is a CVMUSBOutputThread object: +*/ +void +App::startOutputThread() +{ + CVMUSBOutputThread* pOutput = new CVMUSBOutputThread(); + pOutput->start(); +} /*! Create the buffer pool for the system. Modified: trunk/nextgen/usb/vmusb/app/App.h =================================================================== --- trunk/nextgen/usb/vmusb/app/App.h 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/vmusb/app/App.h 2008-08-20 19:18:45 UTC (rev 1956) @@ -41,6 +41,7 @@ virtual void selectInterface(std::string specification) ; virtual void setupConfiguration(CConfiguration& configuration) ; virtual void setupTclServer(TclServer& server) ; + virtual void startOutputThread() ; virtual void createBuffers() ; }; Modified: trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/vmusb/daqconfig/CModuleCommand.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -280,6 +280,7 @@ CDAQModuleCommand::Usage(std::string msg, std::vector<CTCLObject>& objv) { string result("ERROR: "); + string cmd = objv[0]; result += msg; result += "\n"; for (int i = 0; i < objv.size(); i++) { @@ -288,9 +289,15 @@ } result += "\n"; result += "Usage\n"; - result += " adc create name base-address\n"; - result += " adc config name config-params...\n"; - result += " adc cget name"; + result += " "; + result += cmd; + result += " create name base-address\n"; + result += " "; + result += cmd; + result += " config name config-params...\n"; + result += " "; + result += cmd; + result += " cget name"; getInterpreter()->setResult(result); } Added: trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.cpp =================================================================== --- trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.cpp (rev 0) +++ trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -0,0 +1,130 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + + +#include <config.h> +#include "CVMUSBOutputThread.h" +#include <DataBuffer.h> + +// header bit fields. + +static const unsigned EventCountMask(0xfff); +static const unsigned LastBuffer(0x800); + +// Event header bit fields: + +static const unsigned EventLengthMask(0xfff); +static const unsigned Continuation(0x1000); +static const unsigned StackMask(0xe000); +static const unsigned ScalerStack(0x2000); + +static const unsigned HeaderSize(1); + + +/*! + Returns the number of useful data words in the body of the buffer. + In our case we have to remove the end of buffer delimeters from the count + returned by the USB read: + \param buffer - Data buffer struct. + \return unsigned + \retval Numbe of used words in the buffer. + +*/ +unsigned +CVMUSBOutputThread::bodySize(DataBuffer& buffer) +{ + return buffer.s_bufferSize/sizeof(uint16_t) - 2; +} + +/*! + + \param buffer -reference to a data buffer struct. + \return unsigned + \retval number of events in the data buffer. +*/ + +unsigned +CVMUSBOutputThread::eventCount(DataBuffer& buffer) +{ + uint16_t* pRawBuffer = buffer.s_rawData; + return (*pRawBuffer & EventCountMask); +} + +/*! + \param buffer - Refernce to a data buffer struct. + \return unsigned + \retval the size of the buffer header in words (how many words + the caller needs to skip to get to the first event. +*/ +unsigned +CVMUSBOutputThread::headerSize(DataBuffer& buffer) +{ + return HeaderSize; +} +/*! + Returns the size of an event given a pointer to the event itself. + The size returned is the size in words; including any header information. + + \param pEvent - Pointer to the event. + \return uint32_t + \retval Size of the event, including any header. + + \note This size will be passed back without modification to processEvent. +*/ +uint32_t +CVMUSBOutputThread::eventSize(uint16_t* pEvent) +{ + uint32_t size(0); // Size is accumulated here. + uint16_t header; + do { + header = *pEvent++; + uint32_t s = header & EventLengthMask; + pEvent += s; // next chunk if there is one. + size += s+1; // Count the headers in the size. + } while( header & Continuation); + + return size; +} +/*! + Process an event from the buffer: + \param when - Timestamp for when the event occured (really buffer timestamp). + \param size - event size gotten from eventSize() above. + \param pEvent - Pointer to the event (what was passed in to eventSize above). + +*/ +void +CVMUSBOutputThread::processEvent(time_t when, uint32_t size, uint16_t* pEvent) +{ + + // We're going to dispose of this as a scaler or an event: + + if (*pEvent & ScalerStack) { + // For now we assume scalers all live in one fragment. + // if that is ever not true, we need to + // re-marshall the scalers into another bit of storage: + + pEvent++; + size--; // Skip the header. + + int number = size*sizeof(uint16_t)/sizeof(uint32_t); // Scalers are 32 bits wide. + uint32_t* pScalers = reinterpret_cast<uint32_t*>(pEvent); + + scaler(when, number, pScalers); + } + else { + event(size, pEvent); + } +} Added: trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.h =================================================================== --- trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.h (rev 0) +++ trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBOutputThread.h 2008-08-20 19:18:45 UTC (rev 1956) @@ -0,0 +1,40 @@ +#ifndef __CVMUSBOUTPUTTHREAD_H +#define __CVMUSBOUTPUTTHREAD_H +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#ifndef __COUTPUTTHREAD_H +#include <COutputThread.h> +#endif + +/*! + This class implements the pure virtual member functions that are needed + to make an output thread the output thread for a VM-USB module. +*/ +class CVMUSBOutputThread : public COutputThread +{ +public: + virtual unsigned bodySize(DataBuffer& buffer); + virtual unsigned eventCount(DataBuffer& buffer) ; + virtual unsigned headerSize(DataBuffer& buffer) ; + virtual uint32_t eventSize(uint16_t* pEvent) ; + virtual void processEvent(time_t when, + uint32_t size, + uint16_t* pEvent) ; + +}; + +#endif Modified: trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am 2008-08-20 19:18:45 UTC (rev 1956) @@ -3,13 +3,15 @@ libvmUsbDeviceDrivers_la_SOURCES = CVMUSB.cpp CVMUSBReadoutList.cpp CVMUSBDeviceDriver.cpp \ C785.cpp CStack.cpp C3804.cpp C3820.cpp C830.cpp \ CCAENChain.cpp CMADC32.cpp CMADCScaler.cpp CMarker.cpp \ - CNADC2530.cpp CVMUSBControlModule.cpp CGDG.cpp + CNADC2530.cpp CVMUSBControlModule.cpp CGDG.cpp \ + CVMUSBOutputThread.cpp noinst_HEADERS = CVMUSB.h CVMUSBReadoutList.h CVMUSBDeviceDriver.h \ CVMUSBConfigurableObject.h \ C785.h CStack.h C3804.h C3820.h C830.h \ CCAENChain.h CMADC32.h CMADCScaler.h CMarker.h \ - CNADC2530.h CVMUSBControlModule.h CGDG.h + CNADC2530.h CVMUSBControlModule.h CGDG.h \ + CVMUSBOutputThread.h INCLUDES = -I@top_srcdir@/usb/acqcommon \ -I@top_srcdir@/usb/threadcom \ Modified: trunk/nextgen/utilities/bufdump/BufdumpMain.cpp =================================================================== --- trunk/nextgen/utilities/bufdump/BufdumpMain.cpp 2008-08-20 13:59:24 UTC (rev 1955) +++ trunk/nextgen/utilities/bufdump/BufdumpMain.cpp 2008-08-20 19:18:45 UTC (rev 1956) @@ -203,7 +203,7 @@ numToDo--; - if (m_itemCount != 0 && (numToDo == 0)) done = true; + if ((m_itemCount != 0) && (numToDo == 0)) done = true; } else { done = true; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-21 12:59:58
|
Revision: 1957 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1957&view=rev Author: ron-fox Date: 2008-08-21 13:00:07 +0000 (Thu, 21 Aug 2008) Log Message: ----------- Needed to include <stdint.h> in BufdumpMain.h Modified Paths: -------------- trunk/nextgen/base/CopyrightTools/test trunk/nextgen/servers/portmanager/cpptest trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBDeviceDriver.cpp trunk/nextgen/utilities/bufdump/BufdumpMain.h Modified: trunk/nextgen/servers/portmanager/cpptest =================================================================== --- trunk/nextgen/servers/portmanager/cpptest 2008-08-20 19:18:45 UTC (rev 1956) +++ trunk/nextgen/servers/portmanager/cpptest 2008-08-21 13:00:07 UTC (rev 1957) @@ -18,7 +18,7 @@ # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -relink_command="(cd /scratch/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/bin/mh:/usr/sbin/:/sbin:/usr/bin/mh:/usr/sbin/:/sbin\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/nextgen/servers/portmanager /scratch/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/nextgen/base/exception /scratch/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0/lib)" +relink_command="(cd /scratch/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/root/bin:/usr/bin/mh:/usr/sbin/:/sbin\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/nextgen/servers/portmanager /scratch/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/nextgen/base/exception /scratch/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0/lib)" # This environment variable determines our operation mode. if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then Modified: trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBDeviceDriver.cpp =================================================================== --- trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBDeviceDriver.cpp 2008-08-20 19:18:45 UTC (rev 1956) +++ trunk/nextgen/usb/vmusb/deviceDriver/CVMUSBDeviceDriver.cpp 2008-08-21 13:00:07 UTC (rev 1957) @@ -169,7 +169,7 @@ CVMUSBDeviceDriver::usbStopAutonomous() { m_pInterface->writeActionRegister(CVMUSB::ActionRegister::scalerDump); - m_pInterface->writeActionRegister(0); + } /*! Modified: trunk/nextgen/utilities/bufdump/BufdumpMain.h =================================================================== --- trunk/nextgen/utilities/bufdump/BufdumpMain.h 2008-08-20 19:18:45 UTC (rev 1956) +++ trunk/nextgen/utilities/bufdump/BufdumpMain.h 2008-08-21 13:00:07 UTC (rev 1957) @@ -37,7 +37,14 @@ #endif #endif +#ifndef __CRT_STDINT_H +#include <stdint.h> +#ifndef __CRT_STDINT_H +#define __CRT_STDINT_H +#endif +#endif + // Forward definitiosn: class URL; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-08-29 14:05:01
|
Revision: 1964 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1964&view=rev Author: ron-fox Date: 2008-08-29 14:05:10 +0000 (Fri, 29 Aug 2008) Log Message: ----------- Add dcouments for the usb framework. Modified Paths: -------------- trunk/nextgen/aclocal.m4 trunk/nextgen/base/CopyrightTools/test trunk/nextgen/docconfig/config trunk/nextgen/servers/portmanager/cpptest trunk/nextgen/usb/Makefile.am trunk/nextgen/usb/app/Makefile.am trunk/nextgen/usb/vmusb/Makefile.am Added Paths: ----------- trunk/nextgen/usb/usbFramework.xml Modified: trunk/nextgen/aclocal.m4 =================================================================== --- trunk/nextgen/aclocal.m4 2008-08-29 09:41:57 UTC (rev 1963) +++ trunk/nextgen/aclocal.m4 2008-08-29 14:05:10 UTC (rev 1964) @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.9.6 -*- Autoconf -*- +# generated automatically by aclocal 1.10 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005 Free Software Foundation, Inc. +# 2005, 2006 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,6 +11,11 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_if(m4_PACKAGE_VERSION, [2.61],, +[m4_fatal([this file was generated for autoconf 2.61. +You have another version of autoconf. If you want to use that, +you should regenerate the build system entirely.], [63])]) + # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # serial 48 Debian 1.5.22-4 AC_PROG_LIBTOOL @@ -6380,7 +6385,7 @@ AC_MSG_RESULT([$SED]) ]) -# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6390,14 +6395,29 @@ # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- -# Call AM_AUTOMAKE_VERSION so it can be traced. +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.6])]) +[AM_AUTOMAKE_VERSION([1.10])dnl +_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- @@ -6454,14 +6474,14 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 7 +# serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- @@ -6470,8 +6490,10 @@ [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE]) -AC_SUBST([$1_FALSE]) +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl if $2; then $1_TRUE= $1_FALSE='#' @@ -6485,15 +6507,14 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 8 +# serial 9 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -6521,6 +6542,7 @@ ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) @@ -6586,6 +6608,7 @@ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then @@ -6638,7 +6661,8 @@ AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- @@ -6663,8 +6687,9 @@ # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue @@ -6711,8 +6736,8 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6735,16 +6760,20 @@ # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.58])dnl +[AC_PREREQ([2.60])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi fi # test whether we have cygpath @@ -6764,6 +6793,9 @@ AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl @@ -6799,6 +6831,10 @@ [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) @@ -6834,7 +6870,7 @@ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"$am_aux_dir/install-sh"} +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. @@ -6912,14 +6948,14 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 +# serial 5 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ @@ -6935,6 +6971,7 @@ # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then @@ -6945,7 +6982,7 @@ fi ]) -# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6953,60 +6990,23 @@ # AM_PROG_MKDIR_P # --------------- -# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. -# -# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories -# created by `make install' are always world readable, even if the -# installer happens to have an overly restrictive umask (e.g. 077). -# This was a mistake. There are at least two reasons why we must not -# use `-m 0755': -# - it causes special bits like SGID to be ignored, -# - it may be too restrictive (some setups expect 775 directories). -# -# Do not use -m 0755 and let people choose whatever they expect by -# setting umask. -# -# We cannot accept any implementation of `mkdir' that recognizes `-p'. -# Some implementations (such as Solaris 8's) are not thread-safe: if a -# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' -# concurrently, both version can detect that a/ is missing, but only -# one can create it and the other will error out. Consequently we -# restrict ourselves to GNU make (using the --version option ensures -# this.) +# Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], -[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in - # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' -else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - for d in ./-p ./--version; - do - test -d $d && rmdir $d - done - # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. - if test -f "$ac_aux_dir/mkinstalldirs"; then - mkdir_p='$(mkinstalldirs)' - else - mkdir_p='$(install_sh) -d' - fi -fi -AC_SUBST([mkdir_p])]) +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) # Helper functions for option handling. -*- Autoconf -*- @@ -7118,9 +7118,21 @@ if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. Modified: trunk/nextgen/docconfig/config =================================================================== --- trunk/nextgen/docconfig/config 2008-08-29 09:41:57 UTC (rev 1963) +++ trunk/nextgen/docconfig/config 2008-08-29 14:05:10 UTC (rev 1964) @@ -1,2 +1,2 @@ -commands utilities libraries servers -1daq 1epics 1tcl 3daq 3tcl +commands utilities libraries servers frameworks +1daq 1epics 1tcl 1usbReadout 3daq 3tcl 3usbReadout Modified: trunk/nextgen/servers/portmanager/cpptest =================================================================== --- trunk/nextgen/servers/portmanager/cpptest 2008-08-29 09:41:57 UTC (rev 1963) +++ trunk/nextgen/servers/portmanager/cpptest 2008-08-29 14:05:10 UTC (rev 1964) @@ -18,12 +18,12 @@ # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -relink_command="(cd /scratch/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/root/bin:/usr/bin/mh:/usr/sbin/:/sbin\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/nextgen/servers/portmanager /scratch/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/nextgen/base/exception /scratch/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0/lib)" +relink_command="(cd /scratch/fox/daq/nextgen/servers/portmanager; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/bin:/usr/bin:/soft/intel/java/bin:/bin:/usr/bin:/soft/intel/java/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.:/var/lib/gems/1.8/bin/:.:/var/lib/gems/1.8/bin/\"; export PATH; g++ -g -O2 -o \$progdir/\$file cpptest.o -L/scratch/fox/daq/nextgen/servers/portmanager /scratch/fox/daq/nextgen/servers/portmanager/.libs/libPortManager.so -L/scratch/fox/daq/nextgen/base/exception /scratch/fox/daq/nextgen/base/exception/.libs/libException.so -lpub /usr/lib/libcppunit.so -lX11 -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/servers/portmanager/.libs -Wl,--rpath -Wl,/scratch/fox/daq/nextgen/base/exception/.libs -Wl,--rpath -Wl,/usr/opt/daq/10.0/lib)" # This environment variable determines our operation mode. if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then # install mode needs the following variable: - notinst_deplibs=' /scratch/nextgen/servers/portmanager/libPortManager.la /scratch/nextgen/base/exception/libException.la' + notinst_deplibs=' /scratch/fox/daq/nextgen/servers/portmanager/libPortManager.la /scratch/fox/daq/nextgen/base/exception/libException.la' else # When we are sourced in execute mode, $file and $echo are already set. if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then Modified: trunk/nextgen/usb/Makefile.am =================================================================== --- trunk/nextgen/usb/Makefile.am 2008-08-29 09:41:57 UTC (rev 1963) +++ trunk/nextgen/usb/Makefile.am 2008-08-29 14:05:10 UTC (rev 1964) @@ -2,4 +2,6 @@ # Builds the VM/CC usb software. It's important to build the common # code first: # -SUBDIRS = threadcom tclcommon tclserver output acqcommon app vmusb \ No newline at end of file +SUBDIRS = threadcom tclcommon tclserver output acqcommon app vmusb + +EXTRA_DIST = usbFramework.xml \ No newline at end of file Modified: trunk/nextgen/usb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/app/Makefile.am 2008-08-29 09:41:57 UTC (rev 1963) +++ trunk/nextgen/usb/app/Makefile.am 2008-08-29 14:05:10 UTC (rev 1964) @@ -36,4 +36,6 @@ usbReadoutOptions.o: usbReadout.ggo $(GENGETOPT) <usbReadout.ggo --file=usbReadoutOptions - $(CC) -c usbReadoutOptions.c \ No newline at end of file + $(CC) -c usbReadoutOptions.c + +EXTRA_DIST = usbReadout.ggo Added: trunk/nextgen/usb/usbFramework.xml =================================================================== --- trunk/nextgen/usb/usbFramework.xml (rev 0) +++ trunk/nextgen/usb/usbFramework.xml 2008-08-29 14:05:10 UTC (rev 1964) @@ -0,0 +1,4511 @@ +<!-- chapter frameworks --> + +<chapter id="ch.usbframework"> + <title>Framework for xx-USB readout software</title> + <para> + This software provides a framework that can be specialized + to produce readout software for the Wiener/JTEC USB controller modules. + Specific implementations of readout programs for the + <link linkend="ch.vmusbReadout">VM-USB (USB VME + interface)</link>, and the CC-USB (USB CAMAC interface) have been written. + </para> + <para id="ch.vmusbReadout"></para> + <para> + This chapter consists of the following sections: + <itemizedlist> + <listitem> + <para> + <link linkend="ch.usbframework.introduction">Introduction</link>, + an introduction to the framework, the devices it intended to + support and how it works. Much of this can be skimmed by most + people as it contains information intended for developers. + </para> + </listitem> + <listitem> + <para> + <link linkend="ch.usbframework.linking">Libraries and Linking</link>, + Describes the + set of libraries that make up the framework and how + to compile and link against them. + </para> + </listitem> + <listitem> + <para> + <link linkend="ch.usbframework.using">Using the Framework</link>, + Describes how to invoke specialized versions of the framework. + </para> + </listitem> + </itemizedlist> + </para> + <section id="ch.usbframework.introduction"> + <title>Introduction</title> + <para> + Weiner/Jtec provide a pair of USB interfaces with similar capabilities. + The VM-USB is a USB to VME interface, while the CC-USB is a USB + to CAMAC interface. Both interfaces provide support for + autonomous mode data taking. + </para> + <para> + While the VM-USB and CC-USB are quite similar programmatically, + they are different enough that separate readout programs are required + for each interface. The commmon code has been extracted into this + framework. The framework makes it possible to add capability to both + programs in a central place, while providing better maintainability + than a pair of completely separate programs would allow. + </para> + <para> + The programs that result from building on this framework can + be used with the Readout GUI, and provide data to the + ring buffer based data distribution system of the NSCL DAQ. + The remainder of this section describes the architecture of the framework. + If you are not building support for an xx-USB like controller you can + probably ignore much of the remainder of this section. + </para> + <para> + For information about specific specializations of this software, see + the chapters that describe that specialization. + </para> + <section> + <title>Active Software Structure</title> + <para> + The running framework must solve the following set of problems: + <itemizedlist> + <listitem> + <para> + When data taking is active, the VM-USB works + best if there is always a read pending on its event + data pipe. + </para> + </listitem> + <listitem> + <para> + The user interface, must always be live to allow an + active data taking run to be stopped. + </para> + </listitem> + <listitem> + <para> + The format of the data from the xx-USB devices requires + a bit of device dependent massaging before it can + be inserted into ring buffers. + </para> + </listitem> + <listitem> + <para> + Only one program can interact with the xx-USB device, + though external programs may wish to interact with + slow control devices that can only be contacted via + the USB interface...even while data taking is active. + </para> + </listitem> + </itemizedlist> + </para> + <para> + All of these concerns have led to a multithreaded programming framework. + Each thread has a distinct set of functions it fulfills: + <variablelist> + <varlistentry> + <term>Main</term> + <listitem> + <para>The main thread is an extended Tcl interpreter. + It is responsible for starting all of the other + threads that are persistent (see below), and + adding commands to the interpreter so that + runs can be started, paused, resumed and stopped. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>Readout</term> + <listitem> + <para> + This thread is started by the main thread when a + run begins. It sets up the USB device for + data taking and processes buffers from that + device. + </para> + <para> + Per buffer processing is quite limited. Buffers + are simply placed in an output queue for processing + by the Output thread (see below). + </para> + <para> + Between buffer arrivals and when buffer reads time out, + the readout program examines a request queue. + The request queue can have entries from the + main thread requesting it to pause or end data taking. + A Server thread (see below), and also request a + pause in data taking so that slow control devices + can be accessed. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>Output</term> + <listitem> + <para> + This thread takes buffer from the Readout thread's + output queue and turns events in them them into + the appropriate items in a ring buffer. + The ring buffer name is the same as the name of the user + running the program. This allows several users to + take data on the same system simultaneously (but not one user to take + data from multiple sources on the same system). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>Server</term> + <listitem> + <para> + This thread listens on a TCP/IP port. Connecting + clients are then allowed to send commands that + perform slow control. The server interacts, + if needed with Readout to halt data taking + while it plays with devices. + </para> + <para> + The + Server is actually an extended Tcl interpreter, + with the extensions providing the commands for + slow control + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </section> + <section> + <title>Logical Software Structure</title> + <para> + The logical software structure must solve the following set of + problems: + </para> + <itemizedlist> + <listitem> + <para> + Each USB device must be controlled slightly differently + by the Readout thread, and the software should only + be allowed to connect with the correct type of + interface. + </para> + </listitem> + <listitem> + <para> + The format of data in the output buffers may be + different from device to device. + </para> + </listitem> + <listitem> + <para> + Each interface will have support for a different set + of acquisition and control modules, and how they + set up their lists is an interface specific + thing. + </para> + </listitem> + + </itemizedlist> + <para> + We will next describe the base classes that can be extended to provide + device specific functionality and, in general terms, the how to + do these extensions. The reference material will provide + detailed descriptions of these classes. The source code + in the <filename>usb/vmusb</filename> and + <filename>usb/ccusb</filename> directories serves as example + code that you can look at by downloading the source code distribution + of the NSCL DAQ software. + </para> + <section> + <title>Configurable Objects and Data taking modules</title> + <para> + Objects which take data usually must be configured. + This is done by interpreting a configuration script + in a slave, extended interpreter. The USB Readout + framework provides support to make the creation + of configurable device support relatively simple. + </para> + <para> + The core of this is the <classname>CConfiguration</classname> + object. This is created by the framework. Device specific code + provides commands for the configuration object, and devices + themselves, provide configuration options they understand. + Configuration options are name value pairs. By convention names + start with a <literal>-</literal>. For example + <literal>-base</literal> is usually the name of the configuration + option that specifies a VME module's base address in the + VM-USB specialization of this software. + </para> + <para> + Let's take this a bit at a time starting with the actual device + support modules. + </para> + <para> + Each device is a class that is derived (usually indirectly) + from <classname>CConfigurableObject</classname>. + <classname>CConfigurableObject</classname> objects have + a protected member data; <varname>m_pConfiguration</varname>. + That member points to a <classname>CItemConfiguration</classname> + object that holds the configuration for the module as well as + definitions of the configurable parameters of the module. + </para> + <para> + Key member functions of the <classname>CItemConfiguration</classname> + are shown below. See the reference material for more: + </para> + <variablelist> + <varlistentry> + <term><function>addParameter</function></term> + <listitem> + <para> + Allows you to define a configuration parameter. + Configuration parameters can have + <firstterm>validator</firstterm> functions + attached to them. Validators allow the + object to determine if an attempt to + provide a specific value for a configuration + parameter is legal. For example, the + <literal>-base</literal> configuration + parameter should not be able to accept + <literal>george</literal>, but might be able to accept + <literal>0xdead0000</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><function>configure</function></term> + <listitem> + <para> + Allows a caller to attempt to provide a value for + a configuration item. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><function>cget</function></term> + <listitem> + <para> + Allows you to retrieve the string value of a + configuration parameter. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><function>getIntegerParameter</function>, + <function>getUnsignedParameter</function>, + <function>getBoolParameter</function>, + <function>getFloatparameter</function> + <function>getIntegerList</function> + </term> + <listitem> + <para> + Provide ways to fetch a configuration item + and interpret it as a type other than a string. + If you use these, you should supply a validator + with the configuration item that ensures + the item will have strings of the correct type. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>validators</term> + <listitem> + <para> + The class provides several static functions that + perform common validations. For example, + <function>CItemConfiguration::isInteger</function> + ensures that a value is an integer, optionally + checking it against range constraints. + </para> + </listitem> + </varlistentry> + </variablelist> + <para> + <classname>CConfigurableObject</classname> objects therefore, + are what the name implies. Objects that have a configuration. + <classname>CConfigurableObject</classname> objects use a + two stage construction. The object is constructed, and then + a <classname>CItemConfiguration</classname> is attached to the + object via the <methodname>Attach</methodname> member. + This allows for objects to have configurations that are + subclasses of <classname>CItemConfiguration</classname>. + </para> + <para> + <classname>CConfigurableObject</classname> is an abstract + base class. It uses the <methodname>onAttache</methodname> + pure virtual member function, supplied by your derived + classes to define the configuration parameters an object + supports. + </para> + <para> + Other member functions of interest (see the reference material + for more information): + </para> + <variablelist> + <varlistentry> + <term><methodname>Attach</methodname></term> + <listitem> + <para> + Call this to attach a configuration to an object. + The function will establish this as the new + configuration and call <methodname>onAttache</methodname> + which is expected to define accepted configuration + parameters, their validity checkers and constraints. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>configure</methodname></term> + <listitem> + <para> + Delegates to the configuration's + <methodname>configure</methodname> method. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>cget</methodname></term> + <listitem> + <para> + Delegates to the configuration's + <methodname>cget</methodname> method. + </para> + </listitem> + </varlistentry> + </variablelist> + <para> + Typically each xx-USB specific program will want to + add a set of methods that know how to initialize + a module and how to contribute a module's readout instructions + to a list. + </para> + <para> + When the Readout thread starts, it runs a configuration Tcl + script. That script is supposed to have commands that + create modules and organize them into lists that + can be associated with legal xx-USB triggers. + </para> + <para> + The object that runs that script is the <classname>CConfiguration</classname> + object. A pointer to that object is stored in <varname>::Globals::pConfig</varname> + </para> + <para> + The <classname>CConfiguration</classname> maintains modules as a collection of + named <classname>CConfigurableObject</classname> pointers. In addition, each + object can have a type associated with it (types are strings). + </para> + <para> + The <classname>CConfiguration</classname> + also maintains the interpreter used to process the + configuration script. The interpreter can have + additional command registered on it. + These command are typically commands that + allow the script to create module support objects. + </para> + <para> + When constructing an object, these commands must + create an appropriate <classname>CConfigurableObject</classname>, + attach an item configuration to it and make it known to the configuration. + </para> + <para> + <classname>CConfiguration</classname> has the following key member functions: + For more information see the reference pages. + </para> + <variablelist> + <varlistentry> + <term><methodname>addObject</methodname></term> + <listitem> + <para> + Adds an object to the configuration. The object + must have an item configuration attached to it + as it will probably be configured later on + during program execution. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>getObjectsOfType</methodname></term> + <listitem> + <para> + Returns a vector of the objects that match + a specific type. This would typically be called + by the xx-USB specific setup code. For example, + the VM-USB defines a <literal>stack</literal> + type to represent the readout lists. + It requests a list of all the <literal>stack</literal> + objects, asks each to initialize its modules, + create its list and then loads each list into + the interface. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>findObjectByName</methodname></term> + <listitem> + <para> + Locates an object given a name. This is often used + by container objects and by command objects to + ensure the existence of objects or to + ensure that a new object will not clash in name + with an existing object. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>addCommand</methodname></term> + <listitem> + <para> + Adds a new command object to the interpreter that + processes configuration files. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>clearConfiguration</methodname></term> + <listitem> + <para> + Clears the set of modules from the configuration. + </para> + </listitem> + </varlistentry> + + </variablelist> + </section> + <section> + <title>The Device Driver and the Readout Thread</title> + <para> + The Readout thread makes use of a pair of software + design patterns. <classname>CAcquisitionThread</classname> + is a singleton object, having a <methodname>getInstance</methodname> + member function that returns a pointer to the object, creating it + if necessary. The object itself uses a strategy pattern to + encapsulate the code that is interface dependent. The + <methodname>setDriver</methodname> provides a pointer to a + <classname>CUSBDeviceDriver</classname> derived object + that has methods that handle the device specific requests. + </para> + <para> + Each specific reealization of the code must implement + code that calls <methodname>setDriver</methodname> passing + the appropriate device driver object. The driver must + implement the following interface: + </para> + <variablelist> + <varlistentry> + <term><methodname>usbToAutonomous</methodname></term> + <listitem> + <para> + Starts the device taking data autonomously. + Once started, typically these devices cannnot do + anything other than send you data until stopped. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>usbReadBuffer</methodname></term> + <listitem> + <para> + Read a block of data from the device. This is intended + to read a block of data acquired in autonomous mode. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>usbSetup</methodname></term> + <listitem> + <para> + Prepares the device for data taking. + This includes figuring out the lists to load + loading and enabling them. This will be called + prior to <methodname>usbToAutonomous</methodname>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>usbGetBufferSize</methodname></term> + <listitem> + <para> + Returns the size of a data taking buffer. This + size will be used in buffer allocation and + future calls to <methodname>usbReadBuffer</methodname>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>usbStopAutonomous</methodname></term> + <listitem> + <para> + Halts autonomous data taking mode in the device. + Following a call to this, you can expect several + more calls to <methodname>usbReadBuffer</methodname> + to flush data in the USB FIFOs. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>isusbLastBuffer</methodname></term> + <listitem> + <para> + Returns <literal>true</literal> when given a + buffer if the buffer is the last one + from a data taking run. This is used by the + data flush methods to determine when the flush + is complete. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>usbGroinKick</methodname></term> + <listitem> + <para> + This aptly named method is called by the + readout code when it thinks the controller has + hung. It is supposed to take drastic action + to attempt to unhang the controller. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>usbFlushGarbage</methodname></term> + <listitem> + <para> + Intended to throw away any trash that might be + lingering in a usb controler FIFO. This + function should read and discard data + until it believes the usb FIFO's are empty. + </para> + </listitem> + </varlistentry> + </variablelist> + </section> + <section> + <title>Configuring supported slow control modules</title> + <para> + The framework supports a Tcl server that performs slow + control operations on the behalf of client software. + Typically, client software is a GUI that connects to the + Tcl server in the Readout engine to perform slow control + operations. This implies that the Readout software must + be running for these applications to work. + </para> + <para> + The framework is open with respect to control devices. + Control devices are described in a configuration file. + The configuration file is a Tcl script like all other + configuration files in the usb Readout framework. + It is processed by a slave interpreter at program start-time. + A control configuration file must exist, even if it is empty. + </para> + <para> + Prior to that time, the set of device driver modules for + control modules must be described to the Tcl Server framework + so that it knows how to interact with these devices as well + as how to interpret the control configuration script. + </para> + <para> + The prototype pattern is used to describe to the Tcl server + the types of modules that can be created. The prototype + pattern creates objects by duplicating existing objects. + For each control module type that is supported, a driver + module must be registered with the Tcl server and given + a device module type name. + </para> + <para> + When a module of that type is created, the Tcl server + duplicates the prototype driver and associates it with + the module name so that it can be used to control the + module. + </para> + <para> + The <classname>TclServer</classname> class contains + a method named <methodname>addPrototype</methodname> + which is used to add a prototype driver to the + Tcl server. + </para> + <para> + Device drivers themselves are derived from the + <classname>CControlModule</classname> abstract base + class. device drivers for slow control objects are assumed + to have some set of named parameters that can be set + or retrieved. Furthermore, device drivers are derived + from <classname>CConfigurableObject</classname> so they + include a <classname>CItemConfiguration</classname> and + can therefore support configuration options. + Drivers must implement + the following members (see the reference material for full + documentation): + </para> + <variablelist> + <varlistentry> + <term><methodname>Initialize</methodname></term> + <listitem> + <para> + Called when a device is specified in the + configuration file. This method is intended + to connect the device to the driver, and optionally + set it to a known state. This is an optional + method, as a no-op default is provided. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>onAttach</methodname></term> + <listitem> + <para> + Called when the object is connected to + its configuration object. The driver + should define the set of configuration + options supported by the device. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>Update</methodname></term> + <listitem> + <para> + Some devices are write only. This is called + to allow drivers to massively update their + internal copy of the device state back to the + device. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>Set</methodname></term> + <listitem> + <para> + Sets a named parameter in the module to a specific + value. The name and value are not interpreted + or validated by the caller in any way. See the + reference pages for more information about that, + and how drivers should report errors. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>Get</methodname></term> + <listitem> + <para> + Return the current value of a named parameter. + The name is not validated by the caller. + See the reference pages for more information + about how to handle and report error + conditions. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><methodname>clone</methodname></term> + <listitem> + <para> + Produces a copy of the object. This is called + by the Tcl server to turn the prototype instance + of a device driver into an instance of the device + driver that is bound to a device. + </para> + </listitem> + </varlistentry> + </variablelist> + <para> + Usually, a two-level derivation scheme is used to make + controller specific device drivers. The first level creates + a device driver that is still asbstract, but implements the + methods above that interact with the hardware in such a way + that they delegate to identical methods that also get passed + a controller object. The second level implements specific + device support by using the controller arguments to interact + with the hardware. + </para> + </section> + <section> + <title>The Application object, and the entry point.</title> + <para> + When the system is being started up, the pieces and parts + of the system must be created and knit together. Furthermore, + threads objects must be created and started. + </para> + <para> + While this process is mostly device independent, there are + points in the process where device dependent configuration + must be performed. A template method pattern is used to + implement this. + </para> + <para> + The <classname>CApplication</classname> class contains the + controller independent implementation sections of code. + These invoke pure virtual methods that are expected to implement + the device dependent pieces of the startup process. + </para> + <para> + The following are key methods for the <classname>CApplication</classname> + class and its subclasses. + </para> + <variablelist> + <varlistentry> + <term><methodname>main</methodname></term> + <listitem> + <para> + This is the entry point for the initialization. + Typically, the program main will create + the specialized application object and then + invoke its main entry. See the example + below; which is code taken from the + <application>VMUSBReadout</application> + specialization of this fram... [truncated message content] |
From: <ro...@us...> - 2008-09-25 21:06:57
|
Revision: 1983 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1983&view=rev Author: ron-fox Date: 2008-09-25 21:06:35 +0000 (Thu, 25 Sep 2008) Log Message: ----------- Debugging threading issues with the vmusb readout.. specific big change is the need to not use gethostbyname but gethostbyname_r in threaded apps, even if care is taken to serialize requests. Perhaps this is due to something with h_errno that's odd? a Modified Paths: -------------- trunk/nextgen/base/CopyrightTools/Makefile.am trunk/nextgen/base/cvt/Makefile.am trunk/nextgen/base/dataflow/CRemoteAccess.cpp trunk/nextgen/base/dataflow/CRingMaster.cpp trunk/nextgen/base/dataflow/Makefile.am trunk/nextgen/base/dataflow/RingMaster.tcl trunk/nextgen/base/exception/Makefile.am trunk/nextgen/base/security/HostListCheck.cpp trunk/nextgen/base/security/Makefile.am trunk/nextgen/base/tclplus/Makefile.am trunk/nextgen/base/thread/Makefile.am trunk/nextgen/base/uri/Makefile.am trunk/nextgen/base/uri/URL.cpp trunk/nextgen/configure.in trunk/nextgen/daq/format/Makefile.am trunk/nextgen/servers/portmanager/CPortManager.cpp trunk/nextgen/servers/portmanager/CPortManager.h trunk/nextgen/servers/portmanager/Makefile.am trunk/nextgen/servers/tclserver/Makefile.am trunk/nextgen/servers/tclserver/TclAuthorizer.cpp trunk/nextgen/usb/acqcommon/Makefile.am trunk/nextgen/usb/app/CApplication.cpp trunk/nextgen/usb/app/Makefile.am trunk/nextgen/usb/output/COutputThread.cpp trunk/nextgen/usb/output/COutputThread.h trunk/nextgen/usb/output/Makefile.am trunk/nextgen/usb/tclcommon/Makefile.am trunk/nextgen/usb/tclserver/Makefile.am trunk/nextgen/usb/tclserver/TclServer.cpp trunk/nextgen/usb/tclserver/TclServer.h trunk/nextgen/usb/threadcom/Makefile.am trunk/nextgen/usb/vmusb/app/App.cpp trunk/nextgen/usb/vmusb/app/Makefile.am trunk/nextgen/usb/vmusb/daqconfig/Makefile.am trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am trunk/nextgen/utilities/bufdump/Makefile.am trunk/nextgen/utilities/chanlog/Makefile.am trunk/nextgen/utilities/controlpush/CSocket.cpp trunk/nextgen/utilities/controlpush/Makefile.am trunk/nextgen/utilities/daqstart/Makefile.am trunk/nextgen/utilities/eventlog/Makefile.am trunk/nextgen/utilities/ringselector/Makefile.am trunk/nextgen/utilities/sclclient/Makefile.am trunk/nextgen/utilities/sclclient/TcpClient.cpp Modified: trunk/nextgen/base/CopyrightTools/Makefile.am =================================================================== --- trunk/nextgen/base/CopyrightTools/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/CopyrightTools/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -7,7 +7,9 @@ include_HEADERS = CopyrightNotice.h libLicense_la_LDFLAGS = -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" + -Wl,"-rpath-link=$(libdir)" \ + $(THREADLD_FLAGS) +libLicense_la_CXXLFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) TESTS = ./test Modified: trunk/nextgen/base/cvt/Makefile.am =================================================================== --- trunk/nextgen/base/cvt/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/cvt/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -2,4 +2,6 @@ libcvt_la_SOURCES = daqcvt.c include_HEADERS = daqcvt.h libcvt_MANS = libcvt.ps -libcvt_la_LDFLAGS = -version-info @SOVERSION@ -Wl,"-rpath-link=$(libdir)" \ No newline at end of file +libcvt_la_LDFLAGS = -version-info @SOVERSION@ -Wl,"-rpath-link=$(libdir)" \ + $(THREADLD_FLAGS) +libcvt_la_CXXFLAGS= $(THREADCXX_FLAGS) $(AM_CXXFLAGS) Modified: trunk/nextgen/base/dataflow/CRemoteAccess.cpp =================================================================== --- trunk/nextgen/base/dataflow/CRemoteAccess.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/dataflow/CRemoteAccess.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -269,7 +269,6 @@ // Take care of our standard files... - cerr << "In subprocess\n"; int status = dup2(socket, STDIN_FILENO); status = close(STDOUT_FILENO); Modified: trunk/nextgen/base/dataflow/CRingMaster.cpp =================================================================== --- trunk/nextgen/base/dataflow/CRingMaster.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/dataflow/CRingMaster.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -401,8 +401,13 @@ string CRingMaster::ipAddress(string host) { - struct hostent* pEntry = gethostbyname(host.c_str()); - if (pEntry) { + struct hostent* pEntry; + struct hostent entry; + char buffer[1024]; + int errno; + if (!gethostbyname_r(host.c_str(), + &entry, buffer, sizeof(buffer), + &pEntry, &errno)) { // pEntry->h_addr_list[0] has a longword IP address in network byte order: // Modified: trunk/nextgen/base/dataflow/Makefile.am =================================================================== --- trunk/nextgen/base/dataflow/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/dataflow/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -17,13 +17,16 @@ -DBINDIR='"@prefix@/bin"' libDataFlow_la_LDFLAGS = -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" -lrt + -Wl,"-rpath-link=$(libdir)" -lrt \ + $(THREADLD_FLAGS) + libDataFlow_la_LIBADD = @top_srcdir@/base/exception/libException.la \ @top_srcdir@/servers/portmanager/libPortManager.la \ - @top_srcdir@/base/uri/liburl.la + @top_srcdir@/base/uri/liburl.la \ + $(THREADLD_FLAGS) +libDataFlow_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) - libRingBuffer_la_SOURCES = ringPackage.cpp CRingCommand.cpp libRingBuffer_la_DEPENDENCIES = libDataFlow.la ringtostdoutsw.o stdintoringsw.o @@ -33,9 +36,15 @@ libRingBuffer_la_LDFLAGS = $(TCL_LDFLAGS) \ -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" + -Wl,"-rpath-link=$(libdir)" \ + $(THREADLD_FLAGS) +libRingBuffer_la_CXXFLAGS = $(THREADCXX_FLAGS) \ + $(AM_CXXFLAGS) + + + #---------------- Compiled programs. bin_PROGRAMS = ringtostdout stdintoring @@ -47,21 +56,27 @@ ringtostdoutsw.o: ringtostdoutsw.ggo $(GENGETOPT) <ringtostdoutsw.ggo --file=ringtostdoutsw --unamed-opts - $(CC) -c ringtostdoutsw.c + $(CC) -c ringtostdoutsw.c $(THREADC_FLAGS) -ringtostdout_LDADD = ringtostdoutsw.o libRingBuffer.la +ringtostdout_LDADD = ringtostdoutsw.o libRingBuffer.la \ + $(THREADLD_FLAGS) +ringtostdout_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + stdintoring_SOURCES = stdintoring.cpp stdintoring_DEPENDENCIES = libRingBuffer.la stdintoringsw.o: stdintoringsw.ggo $(GENGETOPT) <stdintoringsw.ggo --file=stdintoringsw --unamed-opts - $(CC) -c stdintoringsw.c + $(CC) -c stdintoringsw.c $(THREADC_FLAGS) -stdintoring_LDADD = stdintoringsw.o libRingBuffer.la +stdintoring_LDADD = stdintoringsw.o libRingBuffer.la \ + $(THREADLD_FLAGS) +stdintoring_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + #---------------- Tests Modified: trunk/nextgen/base/dataflow/RingMaster.tcl =================================================================== --- trunk/nextgen/base/dataflow/RingMaster.tcl 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/dataflow/RingMaster.tcl 2008-09-25 21:06:35 UTC (rev 1983) @@ -234,7 +234,6 @@ ::log::log info "Attempted remove of nonexistent $ring" puts $socket "ERROR $ring does not exist" } - } #------------------------------------------------------------------------------- @@ -382,7 +381,7 @@ # Pull out the pieces of the message: - set name [lindex $message 1] + set name [lindex [lindex $message 1] 0];# Strips the {}'s sent in. set type [lindex $message 2] set pid [lindex $message 3] set comment [lindex $message 4] @@ -510,6 +509,10 @@ Unregister $socket $client $message } elseif {$command eq "REMOTE"} { RemoteHoist $socket $client $message + } elseif {$command eq "DEBUG"} { + # Enable/disable debug logging. + set state [lindex $message 1] + ::log::lvSuppress debug $state } else { # Bad command means close the socket: Modified: trunk/nextgen/base/exception/Makefile.am =================================================================== --- trunk/nextgen/base/exception/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/exception/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -9,8 +9,11 @@ MonitorException.h CInvalidArgumentException.h libException_la_LDFLAGS = -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" + -Wl,"-rpath-link=$(libdir)" $(THREADLD_FLAGS) +libException_la_CXXFLAGS = $(THREADCXX_FLAGS) \ + $(AM_CXXFLAGS) + INCLUDES = -I@top_srcdir@/base/headers install-data-local: Modified: trunk/nextgen/base/security/HostListCheck.cpp =================================================================== --- trunk/nextgen/base/security/HostListCheck.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/security/HostListCheck.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -59,9 +59,17 @@ CHostListCheck::Authenticate(const std::string& rHostname) { in_addr Address; - struct hostent* pEntry = gethostbyname(rHostname.c_str()); - if(!pEntry) return kfFALSE; - Address.s_addr = ((struct in_addr*)pEntry->h_addr)->s_addr; + struct hostent* pEntry; + struct hostent entry; + char buffer[1024]; + int error; + + int status = gethostbyname_r(rHostname.c_str(), + &entry, buffer, sizeof(buffer), + &pEntry, &error); + if (status) return kfFALSE; + Address.s_addr = ((struct in_addr*)(entry.h_addr))->s_addr; + return Authenticate(Address); } ////////////////////////////////////////////////////////////////////////////// Modified: trunk/nextgen/base/security/Makefile.am =================================================================== --- trunk/nextgen/base/security/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/security/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -7,8 +7,11 @@ FdInteractor.h HostListCheck.h \ IOInteractor.h Interactor.h PasswordCheck.h StringInteractor.h \ TclAccessListCheck.h UnixUserCheck.h -libSecurity_la_LDFLAGS = -version-info $(SOVERSION) -Wl,"-rpath=$(libdir)" +libSecurity_la_LDFLAGS = -version-info $(SOVERSION) -Wl,"-rpath=$(libdir)" \ + $(THREADLD_FLAGS) +libSecurity_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/tclplus $(TCL_FLAGS) $(SPECTRODAQ_FLAGS) EXTRA_DIS= security.xml Modified: trunk/nextgen/base/tclplus/Makefile.am =================================================================== --- trunk/nextgen/base/tclplus/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/tclplus/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -6,8 +6,10 @@ lib_LTLIBRARIES = libtclPlus.la libtclPlus_la_LDFLAGS = -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" + -Wl,"-rpath-link=$(libdir)" $(THREADLD_FLAGS) +libtclPlus_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + testableSources = TCLInterpreter.cpp TCLProcessor.cpp \ TCLVariable.cpp TCLString.cpp \ TCLResult.cpp TCLTimer.cpp TCLFileHandler.cpp \ Modified: trunk/nextgen/base/thread/Makefile.am =================================================================== --- trunk/nextgen/base/thread/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/thread/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -11,7 +11,10 @@ INCLUDES = -I$(top_srcdir)/base/headers -I$(top_srcdir)/base/exception -DUSE_PTHREADS libdaqthreads_la_LDFLAGS = -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" + -Wl,"-rpath-link=$(libdir)" \ + $(THREADLD_FLAGS) +libdaqthreads_la_CXXFLAGS=$(THREADCXX_FLAGS) + EXTRA_DIST=thread.xml \ No newline at end of file Modified: trunk/nextgen/base/uri/Makefile.am =================================================================== --- trunk/nextgen/base/uri/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/uri/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -5,6 +5,9 @@ liburl_la_SOURCES = URL.cpp include_HEADERS = URL.h -INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/exception +INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/exception +liburl_la_LDFLAGS = $(THREADLD_FLAGS) +liburl_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + EXTRA_DIST = URL.xml Modified: trunk/nextgen/base/uri/URL.cpp =================================================================== --- trunk/nextgen/base/uri/URL.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/base/uri/URL.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -343,7 +343,14 @@ // Host is a DNS or bad: - if (!(gethostbyname(host.c_str()))) { + struct hostent entry; + struct hostent *pEntry; + char buffer[1024]; + int error; + int status = gethostbyname_r(host.c_str(), + &entry, buffer, sizeof(buffer), + &pEntry, &error); + if (status) { throw CURIFormatException(rStr, host.c_str(), __FILE__, __LINE__); Modified: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/configure.in 2008-09-25 21:06:35 UTC (rev 1983) @@ -344,6 +344,19 @@ AM_CONDITIONAL([PDFDOCS], [test x$HAVE_DOCBOOK2PDF = xtrue]) AM_CONDITIONAL([XMLMANS], [test x$HAVE_XMLTO = xtrue]) +# +# Threading is hard coded to -pthread now. +# +THREADCXX_FLAGS="-pthread" +THREADC_FLAGS="-pthread" +THREADLD_FLAGS="-lpthread" + +AC_SUBST(THREADCXX_FLAGS) +AC_SUBST(THREADC_FLAGS) +AC_SUBST(THREADLD_FLAGS) + + + #--------------------------------------------------------------------------- # Generate the following from their .in's (note that Automake takes # *.am -> *.in. Modified: trunk/nextgen/daq/format/Makefile.am =================================================================== --- trunk/nextgen/daq/format/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/daq/format/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -27,12 +27,15 @@ -I@top_srcdir@/base/headers libdataformat_la_LDFLAGS = -version-info $(SOVERSION) \ - -Wl,"-rpath-link=$(libdir)" -lrt + -Wl,"-rpath-link=$(libdir)" -lrt \ + $(THREADLD_FLAGS) libdataformat_la_LIBADD = @top_srcdir@/base/dataflow/libDataFlow.la \ @top_srcdir@/base/exception/ +libdataformat_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + #------------------- Tests: noinst_PROGRAMS = unittests Modified: trunk/nextgen/servers/portmanager/CPortManager.cpp =================================================================== --- trunk/nextgen/servers/portmanager/CPortManager.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/servers/portmanager/CPortManager.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -35,6 +35,10 @@ #include <pwd.h> #include <regex.h> #include <stdlib.h> + +#include <tcl.h> + + // #include <publib.h> #include <ctype.h> @@ -141,7 +145,9 @@ int CPortManager::allocatePort(string application) { + Connect(); + // Build up the command and send it. @@ -171,6 +177,7 @@ // Get the reply: string reply = GetLine(); + // Simplest decode is with an istringstream: @@ -257,7 +264,8 @@ vector<portInfo> result; for(int i =0; i < nlines; i++) { portInfo info; - GetPortInfo(info, GetLine()); + string data = GetLine(); + info = GetPortInfo(data); result.push_back(info); } Disconnect(); @@ -295,9 +303,11 @@ // Translate the host and port to a sockaddr_in structure: sockaddr_in remoteAddress; + memset(&remoteAddress, 0, sizeof(remoteAddress)); try { GetNetworkAddress(remoteAddress); // Throws on error. + } catch (...) { close(m_nSocket); // prevent socket leaks. @@ -400,25 +410,38 @@ result.sin_port = htons(m_nPort); // Attempt to translate the hostname: + + + + struct hostent entry; + struct hostent *pEntry; + char otherData[1024]; + int herrno; + if(!gethostbyname_r(m_sHost.c_str(), + &entry, + otherData, sizeof(otherData), + &pEntry, &herrno)) { + - struct hostent* pEntry = gethostbyname(m_sHost.c_str()); - if(pEntry) { - if(pEntry->h_addrtype != AF_INET) { + if(entry.h_addrtype != AF_INET) { throw CPortManagerException(m_sHost, CPortManagerException::ConnectionFailed, " Host is not AF_INET "); } - memcpy(&(result.sin_addr), pEntry->h_addr, pEntry->h_length); - return; + + memcpy(&(result.sin_addr.s_addr), entry.h_addr_list[0], entry.h_length); + return; } - // For whatever reason, we could not translate the host by name. - // try by number: - - if(!inet_aton(m_sHost.c_str(), &(result.sin_addr))) { - throw CPortManagerException(m_sHost, - CPortManagerException::ConnectionFailed, - "Host lookup failed"); - } + else { + // For whatever reason, we could not translate the host by name. + // try by number: + + if(!inet_aton(m_sHost.c_str(), &(result.sin_addr))) { + throw CPortManagerException(m_sHost, + CPortManagerException::ConnectionFailed, + "Host lookup failed"); + } + } } /*! * Get a line of text from the socket. Unfortunately, the only way to do this @@ -476,63 +499,45 @@ The third chunk is the stuff in the middle with leading and trailing whitespace stripped off. */ -void -CPortManager::GetPortInfo(CPortManager::portInfo& result, string l) +CPortManager::portInfo +CPortManager::GetPortInfo(string l) { - string line(l); + + portInfo result; + + // Ok I tried to do this with regular expressions, but on debian + // etch I caught regcomp in the act of smashing the heap + // so we'll decode the line as a Tcl list which, in fact, it is. + + + int argc; + const char **argv; + + string copy; + copy.assign(l); + const char* list = copy.c_str(); + - // Regular expressions we will use: - - string leadingnumber("^[0-9]+"); - string trailingusername("([a-z])([a-z,0-9]*)$"); - - regex_t lnumber; - regex_t tusername; - - assert(regcomp(&lnumber, leadingnumber.c_str(), REG_EXTENDED) == 0); - assert(regcomp(&tusername, trailingusername.c_str(), REG_EXTENDED) == 0); - - // Get the port number extent and convert the substring to the port. - - regmatch_t portextent; - assert(regexec(&lnumber, line.c_str(), 1, &portextent,0) == 0); - string port; - port.assign(line, portextent.rm_so, - portextent.rm_eo - portextent.rm_so); - result.s_Port = atoi(port.c_str()); - - // Get the username extent and convert the substring into a username. - // we assume usernames are of the form [a-z][a-z,0-9]* - // and are butted right up to the end of the string. - - regmatch_t userextent; - assert(regexec(&tusername, line.c_str(), 1, &userextent, 0) == 0); - result.s_User.assign(line, userextent.rm_so, - userextent.rm_eo - userextent.rm_so); - - - regfree(&lnumber); - regfree(&tusername); - // The string between the two starts is most of the application name. - // we need to trim whitespace off the front and back of this. - - int start = portextent.rm_eo + 1; // string starts earliest here. - int end = userextent.rm_so - 1; // and ends earliest here. - - while(start <= end) { - if(!isspace(line[start])) { - break; - } - start++; + int ok = Tcl_SplitList(reinterpret_cast<Tcl_Interp*>(NULL), + list, + &argc, &argv); + + if (ok != TCL_OK) { + throw std::string("CPortManager::GetPortInfo - string is not a good list"); } - while(end >= start) { - if(!isspace(line[end])) { - break; - } - end--; + if (argc != 3) { + throw std::string("CPortManager::GetPortInfo - list does not have 3 elements"); } - result.s_Application.assign(line, start, end-start+1); - + + result.s_Port = atoi(argv[0]); + result.s_Application = argv[1]; + result.s_User = argv[2]; + + Tcl_Free((char*)argv); + + + return result; + } /*! Get and return the name of the user that corresponds to the current effective userid. Modified: trunk/nextgen/servers/portmanager/CPortManager.h =================================================================== --- trunk/nextgen/servers/portmanager/CPortManager.h 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/servers/portmanager/CPortManager.h 2008-09-25 21:06:35 UTC (rev 1983) @@ -89,7 +89,7 @@ static int DetermineDefaultPort(); void GetNetworkAddress(sockaddr_in& addr) const; std::string GetLine() const; - void GetPortInfo(portInfo& info, std::string line); + portInfo GetPortInfo(std::string line); static int tcp(); }; Modified: trunk/nextgen/servers/portmanager/Makefile.am =================================================================== --- trunk/nextgen/servers/portmanager/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/servers/portmanager/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -11,8 +11,14 @@ libPortManager_la_LDFLAGS = -L@top_srcdir@/base/exception \ -lException \ -version-info $(SOVERSION) \ - -Wl,"-rpath=$(libdir)" + -Wl,"-rpath=$(libdir)" \ + $(TCL_LDFLAGS) \ + $(THREADLD_FLAGS) +libPortManager_la_CXXFLAGS = $(THREADCXX_FLAGS) \ + $(TCL_FLAGS) \ + $(AM_CXXFLAGS) + INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/exception \ -DHOME=\"$(prefix)\" Modified: trunk/nextgen/servers/tclserver/Makefile.am =================================================================== --- trunk/nextgen/servers/tclserver/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/servers/tclserver/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -4,8 +4,13 @@ tclserver_LDADD = -L@top_srcdir@/base/tclplus -ltclPlus -L@top_srcdir@/base/exception \ -L@top_srcdir@/servers/portmanager \ - -L@top_srcdir@/base/CopyrightTools -lPortManager -lLicense -lException $(TCL_LDFLAGS) \ - $(X11LIBS) + -L@top_srcdir@/base/CopyrightTools -lPortManager -lLicense -lException \ + $(TCL_LDFLAGS) \ + $(X11LIBS) \ + $(THREADLD_FLAGS) + +tclserver_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + tclserver_LDFLAGS=-Wl,"-rpath=$(libdir)" INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/exception \ Modified: trunk/nextgen/servers/tclserver/TclAuthorizer.cpp =================================================================== --- trunk/nextgen/servers/tclserver/TclAuthorizer.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/servers/tclserver/TclAuthorizer.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -324,12 +324,18 @@ // First the string is treated as a hostname for the resolver to // turn into an IP address: - struct hostent* pHostInfo = gethostbyname(rName.c_str()); - if(! pHostInfo) { // Try as dotted ip + struct hostent* pHostInfo; + struct hostent entry; + char buffer[1024]; + int error; + if (gethostbyname_r(rName.c_str(), + &entry, buffer, sizeof(buffer), + &pHostInfo, &error)) { + IpAddress.s_addr = inet_addr(rName.c_str()); } else { - memcpy(&IpAddress, pHostInfo->h_addr,4); + memcpy(&IpAddress, entry.h_addr, sizeof(IpAddress)); } union { uint32_t along; @@ -395,8 +401,18 @@ rCanonicalIP = rInName; if(!HostToIp(rCanonicalIP)) return kfFALSE; - struct hostent* pEntry = gethostbyname(myname.c_str()); - rOutname = pEntry ? myname : string(">unresolved<"); + struct hostent* pEntry; + struct hostent entry; + char data[1024]; + int error; + int status = gethostbyname_r(myname.c_str(), + &entry, data, sizeof(data), + &pEntry, &error); + + + + + rOutname = status ? string(">unresolved<") : myname; return kfTRUE; } ///////////////////////////////////////////////////////////////////// Modified: trunk/nextgen/usb/acqcommon/Makefile.am =================================================================== --- trunk/nextgen/usb/acqcommon/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/acqcommon/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -32,5 +32,7 @@ @top_srcdir@/base/exception/libException.la \ @top_srcdir@/base/tclplus/libtclPlus.la \ @top_srcdir@/usb/tclcommon/libusbtclcommon.la \ - @TCL_LDFLAGS@ + @TCL_LDFLAGS@ $(THREADLD_FLAGS) +libusbacqcommon_la_CXXFLAGS = $(THREADCXX_FLAGS) + Modified: trunk/nextgen/usb/app/CApplication.cpp =================================================================== --- trunk/nextgen/usb/app/CApplication.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/app/CApplication.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -83,11 +83,8 @@ selectControlConfigFile(ctlConfigFile); createConfiguration(); createTclServer(port, application); - usleep(500); // Give it time to start and settle. createBuffers(); startOutputThread(); - usleep(500); // Give it time to start and settle. - createMainInterpreter(argc, argv); // MUST BE LAST!!!!!! does not return!! Modified: trunk/nextgen/usb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/app/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/app/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -26,7 +26,8 @@ @top_srcdir@/servers/portmanager/libPortManager.la \ @top_srcdir@/base/exception/libException.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @TCL_LDFLAGS@ + @TCL_LDFLAGS@ $(THREADLD_FLAGS) +libusbapplication_la_CXXFLAGS = $(THREADCXX_FLAGS) BUILT_SOURCES = usbReadoutOptions.h Modified: trunk/nextgen/usb/output/COutputThread.cpp =================================================================== --- trunk/nextgen/usb/output/COutputThread.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/output/COutputThread.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -36,6 +36,8 @@ #include <CRingStateChangeItem.h> #include <DataFormat.h> +#include <CMutex.h> +#include <CCondition.h> #include <unistd.h> #include <pwd.h> @@ -78,6 +80,27 @@ delete m_pRing; } +/*! + Start the thread. We block until the main loop is entered + using the condition variables in the member data: +*/ +void +COutputThread::Start() +{ + + m_pInitMutex = new CMutex(); + m_pInitialized = new CConditionVariable(); + + m_pInitMutex->lock(); // Need to hold this when waiting on condition... + start(); // start the output thread. + + m_pInitialized->wait(*m_pInitMutex); // Wait for initialization to be complete. + m_pInitMutex->unlock(); // We're in the main loop now. + + +} + + //////////////////////////////////////////////////////////////////////// ////////////////////// Thread entry point... /////////////////////////// //////////////////////////////////////////////////////////////////////// @@ -89,13 +112,15 @@ COutputThread::run() { + + try { // the ring is created if necessary. + openRing(); // Open ring named after the user in localhost. + m_pInitialized->signal(); - openRing(); // Open ring named after the user in localhost. + // Main loop is pretty simple. - // Main loop is pretty simple. - try { while(1) { DataBuffer& buffer(getBuffer()); Modified: trunk/nextgen/usb/output/COutputThread.h =================================================================== --- trunk/nextgen/usb/output/COutputThread.h 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/output/COutputThread.h 2008-09-25 21:06:35 UTC (rev 1983) @@ -39,6 +39,10 @@ struct DataBuffer; class CRingBuffer; +class CMutex; +class CConditionVariable; + + /*! This class bridges the gap between the buffer format of the USB devices and ring buffers. @@ -119,6 +123,8 @@ time_t m_lastStampedBuffer; //!< Seconds into run of last stamped buffer uint64_t m_eventCount; //!< Number of events this run. CRingBuffer* m_pRing; // Where the data goes.. + CMutex *m_pInitMutex; + CConditionVariable *m_pInitialized; // Constuctors and other canonicals. @@ -131,13 +137,13 @@ int operator==(const COutputThread& rhs) const; int operator!=(const COutputThread& rhs) const; public: + void Start(); /* Start the application. */ // Thread operations are all non-public in fact.. don't want to call them // from outside this class.. only from within the thread.. This includes the // thread entry point. protected: - virtual void run(); DataBuffer& getBuffer(); Modified: trunk/nextgen/usb/output/Makefile.am =================================================================== --- trunk/nextgen/usb/output/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/output/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -18,4 +18,6 @@ @top_srcdir@/base/dataflow/libDataFlow.la \ @top_srcdir@/base/exception/libException.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @top_srcdir@/usb/threadcom/libThreadComm.la \ No newline at end of file + @top_srcdir@/usb/threadcom/libThreadComm.la \ + $(THREADLD_FLAGS) +libOutputSTage_la_CXXFLAGS = $(THREADCXX_FLAGS) \ No newline at end of file Modified: trunk/nextgen/usb/tclcommon/Makefile.am =================================================================== --- trunk/nextgen/usb/tclcommon/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/tclcommon/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -20,4 +20,6 @@ @top_srcdir@/base/exception/libException.la \ @top_srcdir@/usb/threadcom/libThreadComm.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @TCL_LDFLAGS@ \ No newline at end of file + @TCL_LDFLAGS@ $(THREADLD_LFAGS) + +libusbtclcommon_la_CXXFLAGS = $(THREADCXX_FLAGS) \ No newline at end of file Modified: trunk/nextgen/usb/tclserver/Makefile.am =================================================================== --- trunk/nextgen/usb/tclserver/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/tclserver/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -20,6 +20,7 @@ INCLUDES = -I@top_srcdir@/base/headers \ -I@top_srcdir@/usb/tclcommon \ -I@top_srcdir@/usb/threadcom \ + -I@top_srcdir@/base/thread \ -I@top_srcdir@/base/tclplus \ -I@top_srcdir@/base/exception \ -I@top_srcdir@/base/thread \ @@ -32,4 +33,6 @@ @top_srcdir@/base/tclplus/libtclPlus.la \ @top_srcdir@/base/exception/libException.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @TCL_LDFLAGS@ \ No newline at end of file + @TCL_LDFLAGS@ $(THREADLD_FLAGS) + +libControlServer_la_CXXFLAGS = $(THREAD_CXXFLAGS) $(AM_CXXFLAGS) \ No newline at end of file Modified: trunk/nextgen/usb/tclserver/TclServer.cpp =================================================================== --- trunk/nextgen/usb/tclserver/TclServer.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/tclserver/TclServer.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -25,6 +25,8 @@ #include "CGetCommand.h" #include "CUpdateCommand.h" +#include <CMutex.h> +#include <CCondition.h> #include <tcl.h> #include <TCLInterpreter.h> @@ -69,6 +71,10 @@ unsigned long TclServer::start(int port, const char* configFile) { + m_pMutex = new CMutex; + m_pInitialized = new CConditionVariable; + m_pMutex->lock(); + // Set up the member data needed to run the thread... m_port = port; @@ -77,6 +83,8 @@ // Schedule the thread for execution: Thread::start(); + m_pInitialized->wait(*m_pMutex); + m_pMutex->unlock(); m_tid = getId(); return m_tid; } @@ -175,6 +183,7 @@ readConfigFile(); // Initialize the modules. initModules(); // Initialize the fully configured modules. startTcpServer(); // Set up the Tcp/Ip listener event. + m_pInitialized->signal(); EventLoop(); // Run the Tcl event loop forever. } catch (string msg) { Modified: trunk/nextgen/usb/tclserver/TclServer.h =================================================================== --- trunk/nextgen/usb/tclserver/TclServer.h 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/tclserver/TclServer.h 2008-09-25 21:06:35 UTC (rev 1983) @@ -47,7 +47,8 @@ class CControlModule; class CTCLInterpreter; - +class CConditionVariable; +class CMutex; /*! The TclServer class implements a little Tcl server for our readout software. The server is intended to allow external software to perform control operations @@ -86,6 +87,8 @@ Prototypes m_modulePrototypes; CTCLInterpreter* m_pInterpreter; unsigned long m_tid; + CMutex* m_pMutex; + CConditionVariable* m_pInitialized; public: TclServer(); Modified: trunk/nextgen/usb/threadcom/Makefile.am =================================================================== --- trunk/nextgen/usb/threadcom/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/threadcom/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -10,8 +10,11 @@ INCLUDES = -I@top_srcdir@/base/thread libThreadComm_la_LIBADD = @top_srcdir@/base/thread/libdaqthreads.la \ - @top_srcdir@/base/exception/libException.la + @top_srcdir@/base/exception/libException.la \ + $(THREADLD_FLAGS) +libThreadComm_la_CXXLFAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + install-data: $(INSTALL_DATA) @srcdir@/CBufferQueue.cpp @prefix@/include \ No newline at end of file Modified: trunk/nextgen/usb/vmusb/app/App.cpp =================================================================== --- trunk/nextgen/usb/vmusb/app/App.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/vmusb/app/App.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -123,7 +123,7 @@ App::startOutputThread() { CVMUSBOutputThread* pOutput = new CVMUSBOutputThread(); - pOutput->start(); + pOutput->Start(); } /*! Modified: trunk/nextgen/usb/vmusb/app/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/app/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/vmusb/app/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -29,6 +29,8 @@ @top_srcdir@/usb/vmusb/deviceDriver/libvmUsbDeviceDrivers.la \ @top_srcdir@/usb/vmusb/daqconfig/libvmUsbConfigCommands.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @TCL_LDFLAGS@ -lusb + @TCL_LDFLAGS@ -lusb $(THREADLD_FLAGS) +VMUSBReadout_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + Modified: trunk/nextgen/usb/vmusb/daqconfig/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/daqconfig/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/vmusb/daqconfig/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -45,4 +45,6 @@ @top_srcdir@/usb/vmusb/deviceDriver/libvmUsbDeviceDrivers.la \ @top_srcdir@/usb/acqcommon/libusbacqcommon.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @TCL_LDFLAGS@ \ No newline at end of file + @TCL_LDFLAGS@ $(THREADLD_FLAGS) + +libvmUsbConfigCommands_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) \ No newline at end of file Modified: trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am =================================================================== --- trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/usb/vmusb/deviceDriver/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -27,4 +27,6 @@ @top_srcdir@/usb/threadcom/libThreadComm.la \ @top_srcdir@/usb/output/libOutputStage.la \ @top_srcdir@/base/thread/libdaqthreads.la \ - @TCL_LDFLAGS@ \ No newline at end of file + @TCL_LDFLAGS@ $(THREADLD_FLAGS) + +libvmUsbDeviceDrivers_la_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) \ No newline at end of file Modified: trunk/nextgen/utilities/bufdump/Makefile.am =================================================================== --- trunk/nextgen/utilities/bufdump/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/bufdump/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -29,17 +29,19 @@ dumper_LDADD = dumperargs.o \ @top_srcdir@/daq/format/libdataformat.la \ @top_srcdir@/base/dataflow/libDataFlow.la \ - @top_srcdir@/base/exception/libException.la + @top_srcdir@/base/exception/libException.la \ + $(THREADLD_FLAGS) +dumper_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) dumperargs.h: dumperargs.ggo $(GENGETOPT) <dumperargs.ggo --file=dumperargs - $(CC) -c -I. dumperargs.c + $(CC) -c -I. dumperargs.c $(THREADCFLAGS) dumperargs.o: dumperargs.ggo $(GENGETOPT) <dumperargs.ggo --file=dumperargs - $(CC) -c -I. dumperargs.c + $(CC) -c -I. dumperargs.c $(THREADCFLAGS) EXTRA_DIST=dumperargs.ggo \ No newline at end of file Modified: trunk/nextgen/utilities/chanlog/Makefile.am =================================================================== --- trunk/nextgen/utilities/chanlog/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/chanlog/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -7,7 +7,10 @@ chanlog_SOURCES = chanlog.cpp getinfo.cpp noinst_HEADERS = getinfo.h -chanlog_LDADD = $(EPICS_LDFLAGS) +chanlog_LDADD = $(EPICS_LDFLAGS) $(THREADLD_FLAGS) +chanlog_CXXFLAGS= $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + + INCLUDES = $(EPICS_BIN) $(EPICS_INCLUDES) -I@top_srcdir@/Headers EXTRA_DIST = chanlog.xml Modified: trunk/nextgen/utilities/controlpush/CSocket.cpp =================================================================== --- trunk/nextgen/utilities/controlpush/CSocket.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/controlpush/CSocket.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -213,8 +213,18 @@ { // (3) calls not threadsafe. ipaddr = inet_addr(host.c_str()); if(ipaddr == INADDR_NONE) { // Need to translate the name... - pEntry = gethostbyname(host.c_str()); - if(pEntry) memcpy(&ipaddr, pEntry->h_addr, 4); + + struct hostent entry; + char buffer [1024]; + int error; + if (!gethostbyname_r(host.c_str(), + &entry, buffer, sizeof(buffer), + &pEntry, &error)) { + memcpy(&ipaddr, &(entry.h_addr), 4); + } + else { + pEntry = reinterpret_cast<struct hostent*>(NULL); + } } // <-- End Critical region CApplicationSerializer::Unlock(); if(!pEntry) throw CTCPNoSuchHost(host, Modified: trunk/nextgen/utilities/controlpush/Makefile.am =================================================================== --- trunk/nextgen/utilities/controlpush/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/controlpush/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -41,7 +41,7 @@ controlpush_LDADD = -L@top_srcdir@/base/exception -lException \ -L@top_srcdir@/base/CopyrightTools -lLicense \ - $(EPICS_LDFLAGS) + $(EPICS_LDFLAGS) $(THREADLD_FLAGS) controlpush_LDFLAGS= -Wl,"-rpath=$(libdir)" INCLUDES = -I@top_srcdir@/base/exception \ @@ -49,7 +49,9 @@ -I@top_srcdir@/base/headers \ $(EPICS_BIN) $(EPICS_INCLUDES) +controlpush_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + cmdline.c: options.ggo $(GENGETOPT) --unamed-opts <options.ggo Modified: trunk/nextgen/utilities/daqstart/Makefile.am =================================================================== --- trunk/nextgen/utilities/daqstart/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/daqstart/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -10,11 +10,13 @@ INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/exception -I. -daqstart_LDADD = -L@top_srcdir@/base/exception -lException +daqstart_LDADD = -L@top_srcdir@/base/exception -lException \ + $(THREADLD_FLAGS) -AM_CXXFLAGS = -D_GNU_SOURCE +daqstart_CXXFLAGS=$(THREADCXX_FLAGS) -D_GNU_SOURCE $(AM_CXXFLAGS) + cmdline.c: daqstart.ggo $(GENGETOPT) --unamed-opts <daqstart.ggo Modified: trunk/nextgen/utilities/eventlog/Makefile.am =================================================================== --- trunk/nextgen/utilities/eventlog/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/eventlog/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -16,8 +16,11 @@ eventlog_LDADD = eventlogargs.o \ @top_srcdir@/daq/format/libdataformat.la \ @top_srcdir@/base/dataflow/libDataFlow.la \ - @top_srcdir@/base/exception/libException.la + @top_srcdir@/base/exception/libException.la \ + $(THREADLD_FLAGS) +eventlog_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + # Gengetopt stuff. eventlogargs.h: eventlogargs.ggo Modified: trunk/nextgen/utilities/ringselector/Makefile.am =================================================================== --- trunk/nextgen/utilities/ringselector/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/ringselector/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -16,10 +16,13 @@ ringselector_LDADD = parser.o \ @top_srcdir@/daq/format/libdataformat.la \ @top_srcdir@/base/dataflow/libDataFlow.la \ - @top_srcdir@/base/exception/libException.la + @top_srcdir@/base/exception/libException.la \ + $(THREADLD_FLAGS) +ringselector_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + #----------------------- Gengetopt stuff: parser.h: parser.ggo Modified: trunk/nextgen/utilities/sclclient/Makefile.am =================================================================== --- trunk/nextgen/utilities/sclclient/Makefile.am 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/sclclient/Makefile.am 2008-09-25 21:06:35 UTC (rev 1983) @@ -23,9 +23,12 @@ sclclient_LDADD = sclclientargs.o \ @top_srcdir@/daq/format/libdataformat.la \ @top_srcdir@/base/dataflow/libDataFlow.la \ - @top_srcdir@/base/exception/libException.la + @top_srcdir@/base/exception/libException.la \ + $(THREADLD_FLAGS) +sclclient_CXXFLAGS = $(THREADCXX_FLAGS) $(AM_CXXFLAGS) + sclclientargs.o: sclclientargs.ggo $(GENGETOPT) <sclclientargs.ggo --file sclclientargs $(CC) -c -I. sclclientargs.c Modified: trunk/nextgen/utilities/sclclient/TcpClient.cpp =================================================================== --- trunk/nextgen/utilities/sclclient/TcpClient.cpp 2008-09-24 10:19:45 UTC (rev 1982) +++ trunk/nextgen/utilities/sclclient/TcpClient.cpp 2008-09-25 21:06:35 UTC (rev 1983) @@ -348,9 +348,18 @@ // If that doesn't work use DNS to resolve as a hostname, or throw // no such host exception. - struct hostent* pHostEntry = gethostbyname(m_sRemoteHost.c_str()); - if(!pHostEntry) throw (string("No such host: ") + m_sRemoteHost) ; - memcpy(&result.sin_addr.s_addr, pHostEntry->h_addr, sizeof (in_addr)); + + + struct hostent* pHostEntry; + struct hostent entry; + char data[1024]; + int error; + if (gethostbyname_r(m_sRemoteHost.c_str(), + &entry, data, sizeof(data), + &pHostEntry, &error)) { + throw (string("No such host: ") + m_sRemoteHost) ; + } + memcpy(&result.sin_addr.s_addr, entry.h_addr, sizeof (in_addr)); } result.sin_port = htons(m_nRemotePort); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-10-06 14:33:37
|
Revision: 1989 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1989&view=rev Author: ron-fox Date: 2008-10-06 14:29:15 +0000 (Mon, 06 Oct 2008) Log Message: ----------- Misc commits. Modified Paths: -------------- trunk/nextgen/Makefile.am trunk/nextgen/base/dataflow/CRingBuffer.cpp trunk/nextgen/base/dataflow/ringlib.xml trunk/nextgen/base/dataflow/ringprimitives.xml trunk/nextgen/config.h.in Modified: trunk/nextgen/Makefile.am =================================================================== --- trunk/nextgen/Makefile.am 2008-10-06 14:22:55 UTC (rev 1988) +++ trunk/nextgen/Makefile.am 2008-10-06 14:29:15 UTC (rev 1989) @@ -1,5 +1,5 @@ SUBDIRS = base/CopyrightTools base/exception base/tclplus servers base \ - daq utilities docbuild docconfig usb + daq utilities docbuild docconfig usb sbs install-data-local: Modified: trunk/nextgen/base/dataflow/CRingBuffer.cpp =================================================================== --- trunk/nextgen/base/dataflow/CRingBuffer.cpp 2008-10-06 14:22:55 UTC (rev 1988) +++ trunk/nextgen/base/dataflow/CRingBuffer.cpp 2008-10-06 14:29:15 UTC (rev 1989) @@ -157,6 +157,7 @@ close(fd); format(name, maxConsumer); CRingMaster* pOld = m_pMaster; + m_pMaster = 0; connectToRingMaster(); m_pMaster->notifyCreate(name); Modified: trunk/nextgen/base/dataflow/ringlib.xml =================================================================== --- trunk/nextgen/base/dataflow/ringlib.xml 2008-10-06 14:22:55 UTC (rev 1988) +++ trunk/nextgen/base/dataflow/ringlib.xml 2008-10-06 14:29:15 UTC (rev 1989) @@ -739,7 +739,7 @@ #include <CRemoteAccess> ... -CRingBuffer* pRing = CRingAccess::daqConsmeFrom("tcp://localhost/daqring"); +CRingBuffer* pRing = CRingAccess::daqConsumeFrom("tcp://localhost/daqring"); ... </programlisting> </example> Modified: trunk/nextgen/base/dataflow/ringprimitives.xml =================================================================== --- trunk/nextgen/base/dataflow/ringprimitives.xml 2008-10-06 14:22:55 UTC (rev 1988) +++ trunk/nextgen/base/dataflow/ringprimitives.xml 2008-10-06 14:29:15 UTC (rev 1989) @@ -345,7 +345,7 @@ <!-- manpage 3daq --> <refentry id="manpage.cringbuffer"> <refmeta> - <refentrytitle>CRingBufer</refentrytitle> + <refentrytitle>CRingBuffer</refentrytitle> <manvolnum>3daq</manvolnum> </refmeta> <refnamediv> @@ -372,6 +372,10 @@ <methodparam> <type>size_t</type> <parameter>maxConsumer</parameter> <initializer>m_defaultMaxConsumers</initializer> </methodparam> + <methodparam> + <type>bool</type> + <parameter>tempConnection</parameter><initializer>false</initializer> + </methodparam> </methodsynopsis> <methodsynopsis> <modifier>static</modifier> @@ -583,6 +587,10 @@ <methodparam> <type>size_t</type> <parameter>maxConsumer</parameter> <initializer>m_defaultMaxConsumers</initializer> </methodparam> + <methodparam> + <type>bool</type> <parameter>tempConnection</parameter> + <initializer>false</initializer> + </methodparam> </methodsynopsis> <para> Creates a new ring buffer. Each ring buffer has a distinct name. @@ -635,6 +643,19 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term><type>bool</type> + <parameter>tempConnection</parameter></term> + <listitem> + <para> + If this is true, the ring buffer is registered with the + Ring master using a temporary, one-time connection which is + closed down immediately after registration. This allows + children to be created that don't inherit an open socket if done + early enough in the game. + </para> + </listitem> + </varlistentry> </variablelist> <para> Note that no restrictions are imposed on which users can @@ -1352,7 +1373,7 @@ <classname>CRingBuffer::CRingPRedicate</classname> base class. Objects that are <classname>CMessageFilterPredicate</classname> objects can therefore be passed as predicates to the - <methodname>CRingBufer::blockWhile</methodname> method. + <methodname>CRingBuffer::blockWhile</methodname> method. </para> </callout> <callout arearefs="ringman.filter.savetype"> Modified: trunk/nextgen/config.h.in =================================================================== --- trunk/nextgen/config.h.in 2008-10-06 14:22:55 UTC (rev 1988) +++ trunk/nextgen/config.h.in 2008-10-06 14:29:15 UTC (rev 1989) @@ -1,4 +1,4 @@ -/* config.h.in. Generated from configure.in by autoheader. */ +/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the <arpa/inet.h> header file. */ #undef HAVE_ARPA_INET_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-10-06 15:24:43
|
Revision: 1988 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1988&view=rev Author: ron-fox Date: 2008-10-06 14:22:55 +0000 (Mon, 06 Oct 2008) Log Message: ----------- Changing the name of configure.in -> configure.ac seems to make AM conditionals work. Added Paths: ----------- trunk/nextgen/configure.ac Removed Paths: ------------- trunk/nextgen/configure.in Added: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac (rev 0) +++ trunk/nextgen/configure.ac 2008-10-06 14:22:55 UTC (rev 1988) @@ -0,0 +1,445 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT(nscldaq, 10.0, fo...@ns...) +AC_CONFIG_SRCDIR([utilities/controlpush/CSocket.cpp]) +AC_CONFIG_HEADER([config.h]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LIBTOOL + + +AC_CHECK_PROG(HAVE_GENGETOPT, [gengetopt], true, false) +AC_CHECK_PROG(HAVE_DOCBOOK2PDF, [docbook2pdf], true, false) +AC_CHECK_PROG(HAVE_XMLTO, [xmlto], true, false) + +AC_CHECK_LIB([X11], [XSetWindowBackground]) +AC_CHECK_LIB([Xt], [XtManage]) +AC_CHECK_LIB([cppunit], [_ZN7CppUnit12XmlOutputterD1Ev], []) +AC_CHECK_LIB([pub], [xrealloc], []) + + + + + +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. + +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM +AC_TYPE_UID_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + +# Checks for library functions. + +AC_FUNC_ERROR_AT_LINE +AC_FUNC_FORK +AC_FUNC_MALLOC +AC_CHECK_FUNCS([dup2 gethostbyaddr gethostbyname gettimeofday inet_ntoa memmove memset regcomp socket strchr strcspn strdup strerror strspn strtol]) + +AC_CHECK_FUNCS([ftruncate munmap]) +AC_FUNC_MMAP +AC_FUNC_STAT + +# Automake: + +AM_INIT_AUTOMAKE([]) + +# Makefile exports: + +SOVERSION="10:0:0" + + + + + +#--------------------------------------------------------------------- +# +# Local tests: +# + +# We use gengetopt in a few places. Ideally it's been found by now in the +# path if not we'll need to do the withval thing.. or prompt the user to +# give us a --with-gengetopt-path +# + +if test x$HAVE_GENGETOPT == xtrue +then + GENGETOPT=gengetopt +else + AC_ARG_WITH(gengetopt-path, + [ --with-gengetopt-path=directory that has gengetopt], + [GENGETOPT=$withval], + GENGETOPT="") + if test x$GENGETOPT == x + then + AC_MSG_ERROR([Can't find gengetop in path, install it or help me out with --with-gengetopt-path]) + fi +fi + + + +# Locate Tcl/Tk and setup compile/link switches for them too: +# The list below is the set of versions we will look for. At this +# time, 8.4 is pretty standard and 8.5 is impending which means that +# soon some redhat systems will have it I suppose. +# This list must be updated as time goes by. +# +tcl_versions="8.5 8.4 8.3 8.2 8.1 8.0" # First match; so order new -> old. + +# The TCL Shell - used to run tests... must be in path. +# First check for a version qualified command: +# + +AC_MSG_CHECKING([for tcl shell command...]) +for version in $tcl_versions +do + name=tclsh${version} + AC_CHECK_PROG(TCLSH_CMD, $name, $name) +done +# +# Could be unqualified by version: +# +AC_CHECK_PROG(TCLSH_CMD, tclsh, tclsh) + +if test "$TCLSH_CMD" == "" +then + AC_MSG_ERROR([Can't find a tcl shell]) +else + AC_MSG_RESULT([found: $TCLSH_CMD]) +fi + +# TCL headers: +# We know of a few places the headers can live: +# /usr/include redhat linux. +# /usr/include/tcl debian dude that made link to default tcl. +# /usr/include/tcl<version> debian linux +# /usr/local/include default for source based install. +# Whatever the user specifies. +# For now, the versions we look for are determined by the +# variable tcl_versions that variable is a list of version +# number specifiers. +# + + +tcl_header_dir="" +AC_MSG_CHECKING([for tcl headers]) + +AC_ARG_WITH(tcl-header-dir, + [ --with-tcl-header-dir=path Path to tcl headers], + [tcl_header_dir="$withval" + tcl_headers_found="yes"],[tcl_headers_found="no"]) + + + # /usr/include + +if test $tcl_headers_found == "no"; then + AC_CHECK_FILE([/usr/include/tcl.h], + [tcl_header_dir="/usr/include" + tcl_headers_found="yes"]) +fi + + # /usr/include/tcl + +if test $tcl_headers_found == "no"; then + AC_CHECK_FILE([/usr/include/tcl/tcl.h], + [tcl_header_dir="/usr/include/tcl" + tcl_headers_found="yes"]) +fi + + # /usr/include/tcl<version> + +if test $tcl_headers_found == "no" ; then + for version in $tcl_versions; do + if test $tcl_headers_found == "no" ; then # stop at first match + testdir=/usr/include/tcl$version + AC_CHECK_FILE([${testdir}/tcl.h], + [tcl_header_dir=${testdir} + tcl_headers_found="yes"]) + fi + done +fi + + # /usr/local/include +if test $tcl_headers_found == "no"; then + AC_CHECK_FILE([/usr/local/include/tcl.h], + [tcl_header_dir="/usr/local/include/tcl" + tcl_headers_found="yes"]) +fi + + +if test $tcl_headers_found == "yes"; then + TCL_FLAGS="-I${tcl_header_dir}" + AC_MSG_RESULT([found in $tcl_header_dir]) +else + AC_MSG_ERROR([can't find tcl.h try using --with-tcl-header-dir to help me]) +fi + +# Tcl libraries: +# We look for the following: +# /usr/lib/libtcl.a - Usually a link to a default lib. +# /usr/lib/libtcl<version>.a - version of tcl from tcl_versions +# /usr/local/lib/libtcl.a - As above but installed from source. +# /usr/local/lib<version>.a - As Above but installed from source. +# If --with-tcl-libdir=dir is supplied, that directory is +# searched first. +# ASSUMPTIONS: libtcl and libtk will have the same naming conventions. +# + +tcl_libsearchpath="" +tcl_libfound="no" +AC_MSG_CHECKING([Tcl/Tk library to use]) + + # Does the user want us to look somewhere in particular: + +AC_ARG_WITH(tcl-libdir, + [ --with-tcl-libdir=dir Specify where the tcl libraries live.], + [tcl_libsearchpath=$withval]) + +tcl_libsearchpath="$tcl_libsearchpath /usr/lib /usr/local/lib" + +tcl_libfiles=libtcl.a + +for v in ${tcl_versions} +do + tcl_libfiles="$tcl_libfiles libtcl${v}.a" + tcl_libfiles="$tcl_libfiles libtcl${v}.so" +done + + +for dir in ${tcl_libsearchpath} +do + for file in ${tcl_libfiles} + do + fname=$dir/$file + if test $tcl_libfound == "no" + then + AC_CHECK_FILE($fname, + [tcl_libdir=$dir + tcl_libname=$file + tcl_libfound="yes" + ]) + fi + done +done + +if test $tcl_libfound == "yes" +then + # Find the lib basename: + + tcl_libname=$(echo $tcl_libname|cut -c 4- ) # trim off lib + # + # Use basename to trim of the .a or .so: + # + + tcl_libname=$(basename $(basename $tcl_libname .a) .so) + echo tcl libname $tcl_libname + + + + tk_libname=tk$(echo $tcl_libname|cut -c 4-) # trim off tc...and use tk + + TCL_LDFLAGS="-L${tcl_libdir} -l${tk_libname} -l${tcl_libname}" + +else + AC_MSG_ERROR([Unable to find the tcl library, help me out with --with-tcl-libdir]) +fi + + +# Epics: + +# +# Look for epics in: +# /usr/local/epics +# /opt/epics +# /soft/intel/epics [nscl]. +# --with-epics-rootdir= +# Underneath that we have (we require intel linux remember): +# include - the include directory +# include/os/linux-x86 - os specific includes. +# lib/linux-x86 - libs +# bin/linux-x86/caRepeater - The caRepeater program. +# + +epicstestdirs="/usr/local/epics /opt/epics /soft/intel/epics" +haveepics="no" + + +AC_MSG_CHECKING([ for epics includes, libs and binaries]) + +# Check for --with-epics-rootdir.... + +AC_ARG_WITH(epics-rootdir, + [ --with-epics-rootdir=top level directory of EPICS install], + [haveepics="yes" + epicsroot="$withval"], + [haveepics="no"]) + + + +if test $haveepics == "no" +then + for dir in $epicstestdirs + do + if test $haveepics == "no" + then + AC_CHECK_FILE([${dir}/include/cadef.h], + [haveepics="yes" + epicsroot=$dir]) + fi + done +fi + +# If we found epics we can build the software that needs it. +# otherwise it's optional. + +if test $haveepics == "yes" +then + # Have epics: + + epics=true + EPICS_INCLUDES="-I$epicsroot/include -I$epicsroot/include/os/Linux" + EPICS_LDFLAGS="-L$epicsroot/lib/linux-x86 -lca -Wl,\"-rpath=$epicsroot/lib/linux-x86\"" + EPICS_BIN="-DEPICS_BIN=\"\\\"$epicsroot/bin/linux-x86\\\"\"" +else + epics=false +fi + + +# +# The SBS software will only be built if +# --enable-sbs=kernel-source-dir was supplied. +# In that case, the configured kernel source is assumed to be in +# kernel-source-dir and that will be used to compile the device driver +# as well. +# The default is to _not_ build the sbs stuff. +# + +BUILD_SBS="no" + +AC_ARG_ENABLE([sbs], + AS_HELP_STRING([--enable-sbs=kernel-source-dir], [Build SBS software using kernel-source-dir as directory with configured kernel source]), + [BUILD_SBS="yes" + KERNEL_SOURCE_DIR="$enableval"]) + + +if test "$BUILD_SBS" == "yes" +then + echo Building SBS software with kernel source at: $KERNEL_SOURCE_DIR +else + echo SBS software support not selected! +fi + + + + +#---------------------------------------------------------------------------- + +# Exports to the makefiles: + +AC_SUBST(SOVERSION) + + +AC_SUBST(TCL_FLAGS) +AC_SUBST(TCL_LDFLAGS) +AC_SUBST(TCLSH_CMD) + +AM_CONDITIONAL([EPICS], [test x$epics = xtrue]) + +AC_SUBST(EPICS_INCLUDES) +AC_SUBST(EPICS_LDFLAGS) +AC_SUBST(EPICS_BIN) + + +AC_SUBST(GENGETOPT) + +AM_CONDITIONAL([PDFDOCS], [test x$HAVE_DOCBOOK2PDF = xtrue]) +AM_CONDITIONAL([XMLMANS], [test x$HAVE_XMLTO = xtrue]) + +# +# Threading is hard coded to -pthread now. +# +THREADCXX_FLAGS="-pthread" +THREADC_FLAGS="-pthread" +THREADLD_FLAGS="-lpthread" + +AC_SUBST(THREADCXX_FLAGS) +AC_SUBST(THREADC_FLAGS) +AC_SUBST(THREADLD_FLAGS) + +# SBS stuff: + +AC_SUBST(KERNEL_SOURCE_DIR) +AM_CONDITIONAL([BUILD_SBS_DRIVER], [test "$BUILD_SBS" == "yes"]) + + + + +#--------------------------------------------------------------------------- +# Generate the following from their .in's (note that Automake takes +# *.am -> *.in. +# + +AC_CONFIG_FILES([Makefile + base/Makefile + base/CopyrightTools/Makefile + base/cvt/Makefile + base/exception/Makefile + base/thread/Makefile + base/headers/Makefile + base/security/Makefile + base/tclplus/Makefile + base/tclwidgets/Makefile + base/uri/Makefile + base/dataflow/Makefile + servers/Makefile + servers/tclserver/Makefile + servers/portmanager/Makefile + utilities/Makefile + utilities/chanlog/Makefile + utilities/controlpush/Makefile + utilities/daqstart/Makefile + utilities/dvdburn/Makefile + utilities/epicsdisplay/Makefile + utilities/epicsdisplay/epicsdisplay + utilities/scalerdisplay/Makefile + utilities/scalerdisplay/ScalerDisplay + utilities/sequencer/Makefile + utilities/ringselector/Makefile + utilities/bufdump/Makefile + utilities/eventlog/Makefile + utilities/sclclient/Makefile + daq/Makefile + daq/format/Makefile + usb/Makefile + usb/threadcom/Makefile + usb/tclcommon/Makefile + usb/tclserver/Makefile + usb/output/Makefile + usb/acqcommon/Makefile + usb/app/Makefile + usb/vmusb/Makefile + usb/vmusb/deviceDriver/Makefile + usb/vmusb/daqconfig/Makefile + usb/vmusb/app/Makefile + docbuild/Makefile + docconfig/Makefile]) + +AC_OUTPUT + Deleted: trunk/nextgen/configure.in =================================================================== --- trunk/nextgen/configure.in 2008-10-02 17:12:31 UTC (rev 1987) +++ trunk/nextgen/configure.in 2008-10-06 14:22:55 UTC (rev 1988) @@ -1,411 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.61) -AC_INIT(nscldaq, 10.0, fo...@ns...) -AC_CONFIG_SRCDIR([utilities/controlpush/CSocket.cpp]) -AC_CONFIG_HEADER([config.h]) - -# Checks for programs. -AC_PROG_CXX -AC_PROG_CC -AC_PROG_CPP -AC_PROG_INSTALL -AC_PROG_LIBTOOL - - -AC_CHECK_PROG(HAVE_GENGETOPT, [gengetopt], true, false) -AC_CHECK_PROG(HAVE_DOCBOOK2PDF, [docbook2pdf], true, false) -AC_CHECK_PROG(HAVE_XMLTO, [xmlto], true, false) - -AC_CHECK_LIB([X11], [XSetWindowBackground]) -AC_CHECK_LIB([Xt], [XtManage]) -AC_CHECK_LIB([cppunit], [_ZN7CppUnit12XmlOutputterD1Ev], []) -AC_CHECK_LIB([pub], [xrealloc], []) - - - - - -AC_HEADER_STDC -AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. - -AC_HEADER_STDBOOL -AC_C_CONST -AC_C_INLINE -AC_TYPE_OFF_T -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_HEADER_TIME -AC_STRUCT_TM -AC_TYPE_UID_T -AC_TYPE_UINT16_T -AC_TYPE_UINT32_T -AC_TYPE_UINT8_T - -# Checks for library functions. - -AC_FUNC_ERROR_AT_LINE -AC_FUNC_FORK -AC_FUNC_MALLOC -AC_CHECK_FUNCS([dup2 gethostbyaddr gethostbyname gettimeofday inet_ntoa memmove memset regcomp socket strchr strcspn strdup strerror strspn strtol]) - -AC_CHECK_FUNCS([ftruncate munmap]) -AC_FUNC_MMAP -AC_FUNC_STAT - -# Automake: - -AM_INIT_AUTOMAKE([]) - -# Makefile exports: - -SOVERSION="10:0:0" - - - - - -#--------------------------------------------------------------------- -# -# Local tests: -# - -# We use gengetopt in a few places. Ideally it's been found by now in the -# path if not we'll need to do the withval thing.. or prompt the user to -# give us a --with-gengetopt-path -# - -if test x$HAVE_GENGETOPT == xtrue -then - GENGETOPT=gengetopt -else - AC_ARG_WITH(gengetopt-path, - [ --with-gengetopt-path=directory that has gengetopt], - [GENGETOPT=$withval], - GENGETOPT="") - if test x$GENGETOPT == x - then - AC_MSG_ERROR([Can't find gengetop in path, install it or help me out with --with-gengetopt-path]) - fi -fi - - - -# Locate Tcl/Tk and setup compile/link switches for them too: -# The list below is the set of versions we will look for. At this -# time, 8.4 is pretty standard and 8.5 is impending which means that -# soon some redhat systems will have it I suppose. -# This list must be updated as time goes by. -# -tcl_versions="8.5 8.4 8.3 8.2 8.1 8.0" # First match; so order new -> old. - -# The TCL Shell - used to run tests... must be in path. -# First check for a version qualified command: -# - -AC_MSG_CHECKING([for tcl shell command...]) -for version in $tcl_versions -do - name=tclsh${version} - AC_CHECK_PROG(TCLSH_CMD, $name, $name) -done -# -# Could be unqualified by version: -# -AC_CHECK_PROG(TCLSH_CMD, tclsh, tclsh) - -if test "$TCLSH_CMD" == "" -then - AC_MSG_ERROR([Can't find a tcl shell]) -else - AC_MSG_RESULT([found: $TCLSH_CMD]) -fi - -# TCL headers: -# We know of a few places the headers can live: -# /usr/include redhat linux. -# /usr/include/tcl debian dude that made link to default tcl. -# /usr/include/tcl<version> debian linux -# /usr/local/include default for source based install. -# Whatever the user specifies. -# For now, the versions we look for are determined by the -# variable tcl_versions that variable is a list of version -# number specifiers. -# - - -tcl_header_dir="" -AC_MSG_CHECKING([for tcl headers]) - -AC_ARG_WITH(tcl-header-dir, - [ --with-tcl-header-dir=path Path to tcl headers], - [tcl_header_dir="$withval" - tcl_headers_found="yes"],[tcl_headers_found="no"]) - - - # /usr/include - -if test $tcl_headers_found == "no"; then - AC_CHECK_FILE([/usr/include/tcl.h], - [tcl_header_dir="/usr/include" - tcl_headers_found="yes"]) -fi - - # /usr/include/tcl - -if test $tcl_headers_found == "no"; then - AC_CHECK_FILE([/usr/include/tcl/tcl.h], - [tcl_header_dir="/usr/include/tcl" - tcl_headers_found="yes"]) -fi - - # /usr/include/tcl<version> - -if test $tcl_headers_found == "no" ; then - for version in $tcl_versions; do - if test $tcl_headers_found == "no" ; then # stop at first match - testdir=/usr/include/tcl$version - AC_CHECK_FILE([${testdir}/tcl.h], - [tcl_header_dir=${testdir} - tcl_headers_found="yes"]) - fi - done -fi - - # /usr/local/include -if test $tcl_headers_found == "no"; then - AC_CHECK_FILE([/usr/local/include/tcl.h], - [tcl_header_dir="/usr/local/include/tcl" - tcl_headers_found="yes"]) -fi - - -if test $tcl_headers_found == "yes"; then - TCL_FLAGS="-I${tcl_header_dir}" - AC_MSG_RESULT([found in $tcl_header_dir]) -else - AC_MSG_ERROR([can't find tcl.h try using --with-tcl-header-dir to help me]) -fi - -# Tcl libraries: -# We look for the following: -# /usr/lib/libtcl.a - Usually a link to a default lib. -# /usr/lib/libtcl<version>.a - version of tcl from tcl_versions -# /usr/local/lib/libtcl.a - As above but installed from source. -# /usr/local/lib<version>.a - As Above but installed from source. -# If --with-tcl-libdir=dir is supplied, that directory is -# searched first. -# ASSUMPTIONS: libtcl and libtk will have the same naming conventions. -# - -tcl_libsearchpath="" -tcl_libfound="no" -AC_MSG_CHECKING([Tcl/Tk library to use]) - - # Does the user want us to look somewhere in particular: - -AC_ARG_WITH(tcl-libdir, - [ --with-tcl-libdir=dir Specify where the tcl libraries live.], - [tcl_libsearchpath=$withval]) - -tcl_libsearchpath="$tcl_libsearchpath /usr/lib /usr/local/lib" - -tcl_libfiles=libtcl.a - -for v in ${tcl_versions} -do - tcl_libfiles="$tcl_libfiles libtcl${v}.a" - tcl_libfiles="$tcl_libfiles libtcl${v}.so" -done - - -for dir in ${tcl_libsearchpath} -do - for file in ${tcl_libfiles} - do - fname=$dir/$file - if test $tcl_libfound == "no" - then - AC_CHECK_FILE($fname, - [tcl_libdir=$dir - tcl_libname=$file - tcl_libfound="yes" - ]) - fi - done -done - -if test $tcl_libfound == "yes" -then - # Find the lib basename: - - tcl_libname=$(echo $tcl_libname|cut -c 4- ) # trim off lib - # - # Use basename to trim of the .a or .so: - # - - tcl_libname=$(basename $(basename $tcl_libname .a) .so) - echo tcl libname $tcl_libname - - - - tk_libname=tk$(echo $tcl_libname|cut -c 4-) # trim off tc...and use tk - - TCL_LDFLAGS="-L${tcl_libdir} -l${tk_libname} -l${tcl_libname}" - -else - AC_MSG_ERROR([Unable to find the tcl library, help me out with --with-tcl-libdir]) -fi - - -# Epics: - -# -# Look for epics in: -# /usr/local/epics -# /opt/epics -# /soft/intel/epics [nscl]. -# --with-epics-rootdir= -# Underneath that we have (we require intel linux remember): -# include - the include directory -# include/os/linux-x86 - os specific includes. -# lib/linux-x86 - libs -# bin/linux-x86/caRepeater - The caRepeater program. -# - -epicstestdirs="/usr/local/epics /opt/epics /soft/intel/epics" -haveepics="no" - -AC_MSG_CHECKING([ for epics includes, libs and binaries]) - -# Check for --with-epics-rootdir.... - -AC_ARG_WITH(epics-rootdir, - [ --with-epics-rootdir=top level directory of EPICS install], - [haveepics="yes" - epicsroot="$withval"], - [haveepics="no"]) - - - -if test $haveepics == "no" -then - for dir in $epicstestdirs - do - if test $haveepics == "no" - then - AC_CHECK_FILE([${dir}/include/cadef.h], - [haveepics="yes" - epicsroot=$dir]) - fi - done -fi - -# If we found epics we can build the software that needs it. -# otherwise it's optional. - -if test $haveepics == "yes" -then - # Have epics: - - epics=true - EPICS_INCLUDES="-I$epicsroot/include -I$epicsroot/include/os/Linux" - EPICS_LDFLAGS="-L$epicsroot/lib/linux-x86 -lca -Wl,\"-rpath=$epicsroot/lib/linux-x86\"" - EPICS_BIN="-DEPICS_BIN=\"\\\"$epicsroot/bin/linux-x86\\\"\"" -else - epics=false -fi - - -#---------------------------------------------------------------------------- - -# Exports to the makefiles: - -AC_SUBST(SOVERSION) - - -AC_SUBST(TCL_FLAGS) -AC_SUBST(TCL_LDFLAGS) -AC_SUBST(TCLSH_CMD) - -AM_CONDITIONAL([EPICS], [test x$epics = xtrue]) - -AC_SUBST(EPICS_INCLUDES) -AC_SUBST(EPICS_LDFLAGS) -AC_SUBST(EPICS_BIN) - - -AC_SUBST(GENGETOPT) - -AM_CONDITIONAL([PDFDOCS], [test x$HAVE_DOCBOOK2PDF = xtrue]) -AM_CONDITIONAL([XMLMANS], [test x$HAVE_XMLTO = xtrue]) - -# -# Threading is hard coded to -pthread now. -# -THREADCXX_FLAGS="-pthread" -THREADC_FLAGS="-pthread" -THREADLD_FLAGS="-lpthread" - -AC_SUBST(THREADCXX_FLAGS) -AC_SUBST(THREADC_FLAGS) -AC_SUBST(THREADLD_FLAGS) - - - -#--------------------------------------------------------------------------- -# Generate the following from their .in's (note that Automake takes -# *.am -> *.in. -# - -AC_CONFIG_FILES([Makefile - base/Makefile - base/CopyrightTools/Makefile - base/cvt/Makefile - base/exception/Makefile - base/thread/Makefile - base/headers/Makefile - base/security/Makefile - base/tclplus/Makefile - base/tclwidgets/Makefile - base/uri/Makefile - base/dataflow/Makefile - servers/Makefile - servers/tclserver/Makefile - servers/portmanager/Makefile - utilities/Makefile - utilities/chanlog/Makefile - utilities/controlpush/Makefile - utilities/daqstart/Makefile - utilities/dvdburn/Makefile - utilities/epicsdisplay/Makefile - utilities/epicsdisplay/epicsdisplay - utilities/scalerdisplay/Makefile - utilities/scalerdisplay/ScalerDisplay - utilities/sequencer/Makefile - utilities/ringselector/Makefile - utilities/bufdump/Makefile - utilities/eventlog/Makefile - utilities/sclclient/Makefile - daq/Makefile - daq/format/Makefile - usb/Makefile - usb/threadcom/Makefile - usb/tclcommon/Makefile - usb/tclserver/Makefile - usb/output/Makefile - usb/acqcommon/Makefile - usb/app/Makefile - usb/vmusb/Makefile - usb/vmusb/deviceDriver/Makefile - usb/vmusb/daqconfig/Makefile - usb/vmusb/app/Makefile - docbuild/Makefile - docconfig/Makefile]) - -AC_OUTPUT - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-10-07 11:42:01
|
Revision: 1993 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1993&view=rev Author: ron-fox Date: 2008-10-07 11:41:55 +0000 (Tue, 07 Oct 2008) Log Message: ----------- Add the base SBS API (C not C++) to the build. Modified Paths: -------------- trunk/nextgen/configure.ac Added Paths: ----------- trunk/nextgen/sbs/driver/Makefile.am trunk/nextgen/sbs/driver/dd/ trunk/nextgen/sbs/driver/src/ trunk/nextgen/sbs/driver/src/Makefile.am trunk/nextgen/sbs/driver/src/bt_bind.c trunk/nextgen/sbs/driver/src/bt_cas.c trunk/nextgen/sbs/driver/src/bt_chke.c trunk/nextgen/sbs/driver/src/bt_clre.c trunk/nextgen/sbs/driver/src/bt_ctrl.c trunk/nextgen/sbs/driver/src/bt_hw_diag.c trunk/nextgen/sbs/driver/src/bt_icbr.c trunk/nextgen/sbs/driver/src/bt_info.c trunk/nextgen/sbs/driver/src/bt_init.c trunk/nextgen/sbs/driver/src/bt_ior.c trunk/nextgen/sbs/driver/src/bt_iow.c trunk/nextgen/sbs/driver/src/bt_locking.c trunk/nextgen/sbs/driver/src/bt_mmap.c trunk/nextgen/sbs/driver/src/bt_name.c trunk/nextgen/sbs/driver/src/bt_open.c trunk/nextgen/sbs/driver/src/bt_or_io.c trunk/nextgen/sbs/driver/src/bt_perr.c trunk/nextgen/sbs/driver/src/bt_rdwr.c trunk/nextgen/sbs/driver/src/bt_reset.c trunk/nextgen/sbs/driver/src/bt_sema.c trunk/nextgen/sbs/driver/src/bt_send_irq.c trunk/nextgen/sbs/driver/src/bt_serr.c trunk/nextgen/sbs/driver/src/bt_stat.c trunk/nextgen/sbs/driver/src/bt_string.c trunk/nextgen/sbs/driver/src/bt_tas.c trunk/nextgen/sbs/driver/src/btpiflib.h Removed Paths: ------------- trunk/nextgen/configure.in.old Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2008-10-07 11:29:25 UTC (rev 1992) +++ trunk/nextgen/configure.ac 2008-10-07 11:41:55 UTC (rev 1993) @@ -438,6 +438,11 @@ usb/vmusb/deviceDriver/Makefile usb/vmusb/daqconfig/Makefile usb/vmusb/app/Makefile + sbs/Makefile + sbs/driver/Makefile + sbs/driver/src/Makefile + sbs/driver/include/Makefile + sbs/driver/dd/Makefile docbuild/Makefile docconfig/Makefile]) Deleted: trunk/nextgen/configure.in.old =================================================================== --- trunk/nextgen/configure.in.old 2008-10-07 11:29:25 UTC (rev 1992) +++ trunk/nextgen/configure.in.old 2008-10-07 11:41:55 UTC (rev 1993) @@ -1,686 +0,0 @@ - -# Process this file with autoconf to produce a configure script. -AC_INIT(LICENSE) -AC_CONFIG_AUX_DIR(config) -AM_CONFIG_HEADER(config.h) - -# Separate device libraries. - -AM_INIT_AUTOMAKE(nscldaq, 10.0) - -# -# The variable below should track the -# version number above to ensure that -# all the .so's get appropriately versioned: -# -SOVERSION="10:0:0" - - -# Checks for parameters: - -# Compute the system type: -# We can only build on linux-gnu -# We also have restrictions on the versions for the drivers. -# - - -AC_MSG_CHECKING([operating system ]) - -AC_CANONICAL_HOST - -if test "$host_os" == "linux-gnu" -then - kernel_full_version="$(uname -r)" - kernel_version="$(echo $kernel_full_version | cut -f1,2 -d.)" - AC_MSG_RESULT([Building on $host_os kernel $kernel_version]) -else - AC_MSG_ERROR([This software can only be built on linux-gnu not $host_os]) -fi - - - -# Checks for programs. -AC_PROG_AWK -AC_PROG_CXX -AC_PROG_CC -AC_PROG_CPP -AC_PROG_INSTALL -AC_PROG_LN_S -AC_PROG_LIBTOOL - -# Documentation tools: - -AC_PROG_LN_S -AC_PATH_PROG(HCDOCBOOK, docbook2dvi, echo) -AC_PATH_PROG(HTMLDOCBOOK, docbook2html, echo) -AC_PATH_PROG(DVIPDF, dvipdf, echo) -AC_PATH_PROG(MANDOCBOOK, xmlto, echo) - -# - -AC_PROG_GCC_TRADITIONAL - -# Checks for libraries. - - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS(string.h) -AC_CHECK_HEADERS(malloc.h) -AC_CHECK_HEADERS(netdb.h) -AC_CHECK_HEADERS(netinet/in.h) -AC_CHECK_HEADERS(fcntl.h) -AC_CHECK_HEADERS(sys/ioctl.h) -AC_CHECK_HEADERS(sys/time.h) -AC_CHECK_HEADERS(arpa/inet.h) -AC_CHECK_HEADERS(sys/socket.h) -AC_CHECK_HEADERS(gdbm.h, AC_DEFINE([HAVE_GDBM_H], 1, [<gdbm.h> exists]), AC_MSG_ERROR("Can't find gdbm.h needed to build nscldaq")) -AC_CHECK_HEADERS(limits.h) -AC_CHECK_HEADERS(stddef.h) - - -AC_HEADER_MAJOR -AC_HEADER_SYS_WAIT -AC_HEADER_TIME -AC_HEADER_STAT -AC_PATH_XTRA - -# Checks for typedefs, structures, and compiler characteristics. - -AC_STRUCT_TM -AC_TYPE_SIZE_T -AC_TYPE_PID_T -AC_TYPE_OFF_T -AC_C_CONST -AC_C_INLINE - - - -# Checks for library functions. - -AC_CHECK_LIB(gdbm, gdbm_open, [], [AC_MSG_ERROR("Can't fine libgdm needed tobuild nscldaq")]) -AC_FUNC_MMAP -AC_CHECK_FUNCS(stat) -AC_CHECK_FUNCS(malloc) -AC_CHECK_FUNCS(munmap) -AC_CHECK_FUNCS(getpagesize) -AC_CHECK_FUNCS(memset) -AC_CHECK_FUNCS(strerror) -AC_CHECK_FUNCS(gethostbyname) -AC_CHECK_FUNCS(gethostbyaddr) -AC_CHECK_FUNCS(inet_ntoa) -AC_CHECK_FUNCS(gettimeofday) -AC_CHECK_FUNCS(select) -AC_CHECK_FUNCS(strchr) -AC_CHECK_FUNCS(gethostname) -AC_CHECK_FUNCS(getpass) -AC_CHECK_FUNCS(socket) -AC_CHECK_FUNCS(strdup) -AC_CHECK_FUNCS(strstr) -AC_CHECK_FUNCS(fork) -AC_CHECK_FUNCS(clock_gettime) -AC_CHECK_FUNCS(strtol) -AC_CHECK_FUNCS(strtoul) - - -# See if the C runtime libs have .h's on them or -# if h-less versions can be used for what we need: -# - -AC_LANG_PUSH(C++) -AC_CHECK_HEADER(iostream, [AC_DEFINE([HAVE_HLESS_IOSTREAM],1,[<iostream> exists])],[]) -AC_CHECK_HEADER(istream, [AC_DEFINE([HAVE_HLESS_ISTREAM],1,[<istream> exists])],[]) -AC_CHECK_HEADER(ostream, [AC_DEFINE([HAVE_HLESS_OSTREAM],1,[<ostream> exists])],[]) -AC_CHECK_HEADER(streambuf,[AC_DEFINE([HAVE_HLESS_STREAMBUF],1,[<streambuf> exists])],[]) -AC_CHECK_HEADER(fstream, [AC_DEFINE([HAVE_HLESS_FSTREAM],1,[<fstream> exists])],[]) -AC_CHECK_HEADER(iomanip, [AC_DEFINE([HAVE_HLESS_IOMANIP],1,[<iomanip> exists])],[]) -AC_CHECK_HEADER(sstream, [AC_DEFINE([HAVE_HLESS_SSTREAM],1,[<sstream> exists])],[]) -AC_CHECK_HEADER(typeinfo, [AC_DEFINE([HAVE_HLESS_TYPEINFO],1,[<typeinfo> exists])],[]) - - - -# Is there an std namespace to import from? - -AC_COMPILE_IFELSE([using namespace std;], [AC_DEFINE([HAVE_STD_NAMESPACE],[1],[1 if std namespace defined])]) -AH_VERBATIM([VHAVE_STD_NAMESPACE],[ -/* Define STD macro according to HAVE_STD_NAMESPACE value */ -#ifdef HAVE_STD_NAMESPACE -#define STD(name) std::name -#else -#define STD(name) name -#endif]) - - - -AC_LANG_POP(C++) - -# NSCL DAQ specific checks: - -# We need to locate Spectrodaq most of all: -# -# We look in the following order: -# 1. In /opt/spectrodaq/bin -# 2. In /usr/opt/spectrodaq/bin -# 3. In the location suggested by --with-spectrodaq-home - -spectrodaq_conf_dir="" - -AC_MSG_CHECKING([ for spectrodaq-conf ]) - - - AC_ARG_WITH(spectrodaq-home, - [ --with-spectrodaq-home=top level directory of spectrodaq installation], - [spectrodaq_conf_dir="$withval/bin" - spectrodaq_found="yes"],[spectrodaq_found="no"]) - - -if test $spectrodaq_found == "no"; then - AC_CHECK_FILE(/opt/spectrodaq/bin/spectrodaq-conf, - [spectrodaq_conf_dir=/opt/spectrodaq/bin - spectrodaq_found="yes"]) -fi - -if test $spectrodaq_found == "no"; then - AC_CHECK_FILE(/usr/opt/spectrodaq/bin/spectrodaq-conf, - [spectrodaq_conf_dir=/usr/opt/spectrodaq/bin - spectrodaq_found="yes"]) -fi - -if test $spectrodaq_found == "no"; then - AC_MSG_ERROR([ Cannot locate spectrodaq-conf help me by using --with-spectrodaq-home]) -else -SPECTRODAQ_FLAGS=$($spectrodaq_conf_dir/spectrodaq-conf --cflags) -SPECTRODAQ_LDFLAGS=$($spectrodaq_conf_dir/spectrodaq-conf --libs) -AC_MSG_RESULT([ found in $spectrodaq_conf_dir ]) -fi - -# Now that we have spectrodaq, we need to see if it has a -# spectrodaq_main defined... if so, some of our stuff needs -# to implement main(). -# -AC_LANG_PUSH(C++) -oldcxxflags="$CXXFLAGS" -CXXFLAGS="$CXXFLAGS $SPECTRODAQ_FLAGS" -AC_MSG_CHECKING([spectrodaq has spectrodaq_main() separable]) -AC_COMPILE_IFELSE([ -using namespace std; -#include <spectrodaq.h> -main(int argc, char**argv, char** envp) -{ - return spectrodaq_main(argc, argv, envp); -}], [separate="yes" ], [separate="no"]) - - -if test "$separate" == "yes" -then - AC_DEFINE([HAVE_SPECTRODAQ_MAIN], 1, [spectrodaq has separable main]) -fi -AC_MSG_RESULT([$separate]) -CXXFLAGS="$oldcxxflags" -AC_LANG_POP(C++) - - - -# Figure out SMP flag (needed by the btdriver build). - -AC_MSG_CHECKING([for smp system (btdriver)]) - -if (uname -v |grep -q SMP) -then - SMP_FLAG="-D__SMP__" - AC_MSG_RESULT([System runs the SMP kernel]) -else - SMP_FLAG="" - AC_MSG_RESULT([System is not running an SMP kernel]) -fi - -AC_MSG_CHECKING([ for VME device ]) -# VMEDEVICE - The name of the selected api. -# - -# Default to SBSBit3 but allow -# --with-vme-interface={sbs|wiener|none} -# - -# Default interface is sbs. - -vmeinterface="sbs" - -# Process -with-vme-interface if there. - -AC_ARG_WITH(vme-interface, - [--with-vme-interface=sbs|wiener|wienerusb|none - Choose VME interface], - vmeinterface="$withval") - - -# Figure out where the linux kernel headers are. -# We'll look for $(HEADERS)/linux/module.h in the following spots: -# - /usr/src/kernel-headers-$(uname -r)/include [debian] -# - /usr/src/linux-$(uname-r)/include [redhat] -# - /usr/src/linux/include [old? redhat] -# - Where the user tells us with --with-kernel-headers=value. - - -if test "$kernel_version" == "2.4" -then - -# 2.4 kernels need kernel headers installed: - -AC_MSG_CHECKING([for kernel headers (.../linux/module.h)]) - -AC_ARG_WITH(kernel-headers, - [--with-kernel-headers=location of linux kernel headers], - [KERNEL_INCS="-I$withval"],[KERNEL_INCS="-"]) - -if test $KERNEL_INCS = "-" ; then - AC_CHECK_FILE(/usr/src/kernel-headers-$(uname -r)/include/linux/module.h, - [KERNEL_INCS="-I/usr/src/kernel-headers-$(uname -r)/include"]) -fi - -if test $KERNEL_INCS = "-" ; then - AC_CHECK_FILE(/usr/src/linux-$(uname -r)/include/linux/module.h, - [KERNEL_INCS="-I/usr/src/linux-$(uname -r)/include"]) -fi - -if test $KERNEL_INCS = "-" ; then - AC_CHECK_FILE(/usr/src/linux/include/linux/module.h, - [KERNEL_INCS="-I/usr/src/linux-$(uname -r)/include"]) -fi - -if test $KERNEL_INCS = "-"; then - AC_MSG_ERROR([Could not find kernel headers. Try the --with-kernel-headers switch]) -fi - -else - # More recently we actually need the kernel sources installed. - - - AC_MSG_CHECKING([for kernel sources ]) - AC_ARG_WITH(kernel-sources, - [--with-kernel-sources=location of configured kernel sources], - [KERNEL_SRC="$withval"],[KERNEL_SRC=""]) - - for dir in /usr/src/kernel-source-${kernel_full_version} /usr/src/linux-${kernel_full_version} - do - if test -d $dir -a "$KERNEL_SRC" == "" - then - KERNEL_SRC="$dir" - AC_MSG_RESULT([Found in $KERNEL_SRC]) - fi - done - if test "$KERNEL_SRC" == "" - then - AC_MSG_ERROR([Could not find kernel source dir. help me out using --with-kernel-sources]) - fi -fi - - -# VMEDEVICE - Which device it is. -# VMELIBRARYHEADERS - Where the headers will live for vme lib. -# VMELIBRARY - ld switches neede to use VME. -# DEPENDSON_VME - Space separated list of directories that -# require that specific type of VME interface -# to build (try to keep this number small!!). -# SEPARABLELOCK - Locking if the 'default' locking is good enough -# for this interface. - -case "$vmeinterface" in - sbs) - VMEDEVICE="SBSBIT3" - - # Definitions require to build us: - - # We can support 2.4 and 2.6 kernel builds but they're done - # differently: - # - - - VMELIBRARYHEADERS="-I\$(prefix)/include" - VMELIBRARY="-L\$(prefix)/lib -lbtp -lpthread" - AC_DEFINE(HAVE_SBSVME_INTERFACE,"1",[VME interface is sbs/bit3]) - AC_DEFINE(HAVE_VME_MAPPING, "1",[VME interface capable of mmap(2)]) - DEPENDSON_VME="PowerCheck" - SEPERABLELOCK="Locking" - - case $kernel_version in - 2.4) - - # Definitions require to build us: - - VME_DRIVERDIR="btdriver" - VMEBUILDHEADERS="-I$(pwd)/btdriver/include" - VMEBUILDLIBS="$(pwd)/btdriver/lib/libbtp.la -lpthread" -# VMEBUILDLIBS="-L$(pwd)/btdriver/lib -lbtp -lpthread" - - # Build/install the 2.4 driver (you must be root). - - (cd btdriver; \ - ./configure --prefix=$prefix;\ - make clean; \ - make KERNEL_INCS=${KERNEL_INCS} SMP=${SMP_FLAG}; \ - make install SMP=${SMP_FLAG} KERNEL_INCS=${KERNEL_INCS}) - - ;; - 2.6) - VME_DRIVERDIR="btdriver2.6" - VMEBUILDHEADERS="-I$(pwd)/btdriver2.6/include" - VMEBUILDLIBS="$(pwd)/btdriver2.6/lib/libbtp.la -lpthread" -# VMEBUILDLIBS="-L$(pwd)/btdriver2.6/lib -lbtp -lpthread" - - # build/install the 2.6 driver (you must be root) - - (cd btdriver2.6;./configure --prefix=$prefix;make clean;make; make -k install KERNEL_SRC=$KERNEL_SRC) - ;; - *) - AC_MSG_ERROR([SBS bit3 driver can only be built on 2.4 or 2.6 kernel this is $kernel_version]) - ;; - esac - ;; - wiener) - # Can only build on 2.4 kernel at this time: - - if test "$kernel_version" != "2.4" - then - AC_MSG_ERROR([Wiener support can only be built on the 2.4 kernel this is $kernel_version]) - fi - - VMEDEVICE="WIENER" - # Definitions for the build: Static link and driver has no mmap support. - - VME_DRIVERDIR="wienerdriver" - VMEBUILDHEADERS="-I$(pwd)/wienerdriver/lib" - VMEBUILDLIBS="-L$(pwd)/wienerdriver/lib -lpcivme" - - # Definitions written into the user skeleton makefiles: - - VMELIBRARYHEADERS="-I\$(prefix)/include" - VMELIBRARY="-L\$(prefix)/lib -lpcivme" - DEPENDSON_VME="" - SEPERABLELOCK="Locking" - AC_DEFINE(HAVE_WIENERVME_INTERFACE,"1",[VME Interface is Wiener]) - - ;; - wienerusb) - # lib usb is kernel independent as far as I know. - - VMEDEVICE="WIENERUSB" - VME_DRIVERDIR="" - VMEBUILDHEADERS="" - VMEBUILDLIBS="-lusb" - - # Definitions written to the build skeletons - - VMELIBRARYHEADERS="" - VMELIBRARY="-lusb" - DEPENDSON_VME="" - SEPERABLELOCK="NullLock" - AC_DEFINE(HAVE_WIENERUSBVME_INTERFACE,"1",[VME interfaces is WienerUSB]) - - ;; - none) - VMEDEVICE="NULL" - VME_DRIVERDIR="" - VMEBUILDHEADERS="" - VMEBUILDLIBS="" - - # Definitions written into the user skeleton makefiles: - - VMELIBRARYHEADERS="" - VMELIBRARY="" - DEPENDSON_VME="" - SEPERABLELOCK="NullLock" - - AC_DEFINE(HAVE_NOVME_INTERFACE, "1",[No VME interface selected]) - - ;; - *) - AC_MSG_ERROR([Invalid vme interface type $vmeinterface valid values are sbs, wiener or none]) - ;; -esac - - -AC_MSG_RESULT([$VMEDEVICE]) - -# CAMAC defaults to CESCAMAC but can be overidden via --with-camac=VC32CAMAC - -CAMAC="-DCESCAMAC" -AC_ARG_WITH(camac, - [ --with-camac=interface - specify the camac interfce (e.g. VC32CAMAC)], - CAMAC="-D$withval",[]) - -# X11 libraries - -X11INCS="${X_CFLAGS}" -X11LIBS="${X_LIBS} ${X_EXTRA_LIBS} -lXm -lXt -lX11" - -# To run latex on hyperlatex documentation, we need all of the following: -# Latex, dvips, kpathsea and the existence of hyperlatex.sty findable by -# kpathsea: -# -if test $HAVELATEX = "yes" -a $HAVEDVIPS = "yes" -a \ - $HAVEKPATHSEA = "yes" -a $HYPERLATEX != "echo" -then - stylefile=$(kpsewhich hyperlatex.sty) - if test "$stylefile" != "" - then - AC_PATH_PROG(LATEX, latex) - AC_PATH_PROG(DVIPS, dvips) - else - LATEX="echo" - DVIPS="echo" - fi -fi - - - - - -# -# Look for epics in: -# /usr/local/epics -# /opt/epics -# /soft/intel/epics [nscl]. -# --with-epics-rootdir= -# Underneath that we have (we require intel linux remember): -# include - the include directory -# include/os/linux-x86 - os specific includes. -# lib/linux-x86 - libs -# bin/linux-x86/caRepeater - The caRepeater program. -# - -epicstestdirs="/usr/local/epics /opt/epics /soft/intel/epics" -haveepics="no" - -AC_MSG_CHECKING([ for epics includes, libs and binaries]) - -# Check for --with-epics-rootdir.... - -AC_ARG_WITH(epics-rootdir, - [ --with-epics-rootdir=top level directory of EPICS install], - [haveepics="yes" - epicsroot="$withval"], - [haveepics="no"]) - - - -if test $haveepics == "no" -then - for dir in $epicstestdirs - do - if test $haveepics == "no" - then - AC_CHECK_FILE([${dir}/include/cadef.h], - [haveepics="yes" - epicsroot=$dir]) - fi - done -fi - -# If we found epics we can build the software that needs it. -# otherwise it's optional. - -if test $haveepics == "yes" -then - # Have epics: - - EPICSSOFTWARE="controlpush epicsdisplay chanlog" # Add these directories to build. - EPICS_INCLUDES="-I$epicsroot/include -I$epicsroot/include/os/Linux" - EPICS_LDFLAGS="-L$epicsroot/lib/linux-x86 -lca -Wl,\"-rpath=$epicsroot/lib/linux-x86\"" - EPICS_BIN="-DEPICS_BIN=\"\\\"$epicsroot/bin/linux-x86\\\"\"" -else - # No epics.. provide blank variables: - - EPICSSOFTWARE="" # no directories to add to make. - EPICS_LDFLAGS="" # No ldflags. - EPICS_INCLUDES="" # No includes. - EPICS_BIN="" -fi - - -# We now look for cppunit. This is needed to build c++ tests -# If it is available, we'll define the following: -# CPPUNIT - Indicating to the Makefiles to enable building the tests. -# CPPUNIT_INCLUDES - Any switches needed at compile time for cppunit. -# CPPUNIT_LDFLAGS - Any switches needed at link time for cppunit. -# -# - -AC_ARG_ENABLE(cppunit, - AS_HELP_STRING([--enable-cppunit],[build cppunit based tests]), - [havecppunit="check"], [havecppunit="no"]) - -if test "$havecppunit" != "no" -then - AC_LANG_PUSH(C++) - AC_MSG_CHECKING([for cppunit unit testing framework]) - - AC_CHECK_HEADERS([cppunit/Test.h], [havecppunit="yes"], [havecppunit="no"]) - AC_MSG_RESULT([$havecppunit]) - if test "$havecppunit" == "yes" - then - CPPUNIT_INCLUDES="" - CPPUNIT_LDFLAGS="-lcppunit" - AC_SUBST(CPPUNIT_INCLUDES) - AC_SUBST(CPPUNIT_LDFLAGS) - fi -AC_LANG_POP(C++) -fi - -AM_CONDITIONAL(CPPUNIT, test $havecppunit == "yes") - -# define substitutions: - -# Go for a strict linguistic interpretation: - -# CXXFLAGS="-std=c++98 -pedantic" - -# someday: AC_SUBST(CXXFLAGS) - - # EPICS if it exists. - -AC_SUBST(EPICSSOFTWARE) -AC_SUBST(EPICS_LDFLAGS) -AC_SUBST(EPICS_INCLUDES) -AC_SUBST(EPICS_BIN) - - # Spectrodaq: - -AC_SUBST(spectrodaq_conf_dir) -AC_SUBST(SPECTRODAQ_FLAGS) -AC_SUBST(SPECTRODAQ_LDFLAGS) - - # tcl/tk - -AC_SUBST(TCL_FLAGS) -AC_SUBST(TCL_LDFLAGS) -AC_SUBST(TCLSH_CMD) - - - # VME device: - - -AC_SUBST(VMEDEVICE) -AC_SUBST(VME_DRIVERDIR) -AC_SUBST(VMELIBRARY) -AC_SUBST(VMELIBRARYHEADERS) -AC_SUBST(VMEBUILDHEADERS) -AC_SUBST(VMEBUILDLIBS) -AC_SUBST(DEPENDSON_VME) -AC_SUBST(SEPERABLELOCK) - - # CAMAC device: - -AC_SUBST(CAMAC) - - # X11: - -AC_SUBST(X11LIBS) -AC_SUBST(X11INCS) - - # DOXYGEN - -AC_SUBST(DOXYGEN) - - # Hyperlatex: - -AC_SUBST(HYPERLATEX) -AC_SUBST(LATEX) -AC_SUBST(DVIPS) - -# Linux kernel headers: - -AC_SUBST(KERNEL_INCS) - -# Kernel type (SMP or not) - -AC_SUBST(SMP_FLAG) - - -# The base part of the .so version: - -AC_SUBST(SOVERSION) - -# Documentation tools - -AC_SUBST(HCDOCBOOK) -AC_SUBST(DVIPDF) -AC_SUBST(MANDOCBOOK) -AC_SUBST(HTMLDOCBOOK) - -# Create output files: - -AC_OUTPUT( Makefile tcllib/Makefile \ - Headers/Makefile CopyrightTools/Makefile \ - Exception/Makefile PortManager/Makefile \ - TCL/Makefile Security/Makefile Ftp/Makefile \ - VMEApi/Makefile cvt/Makefile \ - SpecTclOnline/Makefile DeviceSupport/Makefile \ - HPReadout/Makefile \ - Readout/Makefile diskrun/Makefile \ - EventLog/Makefile Scaler/Makefile contrib/Makefile \ - contrib/lecroy/Makefile contrib/whedco/Makefile \ - contrib/caenv812/Makefile contrib/scriptedReadout/Makefile \ - contrib/hpscriptedReadout/Makefile \ - contrib/scalerdisplay/Makefile contrib/N568Panel/Makefile \ - contrib/vhqpanel/Makefile \ - vmetcl/Makefile \ - vmetcl/camactcl/Makefile vmetcl/vhq202m/Makefile bufdump/Makefile \ - TclServer/Makefile bcnaf/Makefile TcpHoister/Makefile \ - Stager/InstallRoot.tcl Stager/Makefile \ - Scripts/Makefile framework/Makefile AlarmDisplay/Makefile \ - LogDisplay/Makefile ProductionReadout/Makefile \ - ProductionReadout/hyperlatex/Makefile \ - ProductionReadout/direct/Makefile \ - ProductionReadout/HP/Makefile \ - btdriver/Makefile btdriver/dd/Makefile btdriver/lib/Makefile \ - btdriver/include/Makefile \ - controlpush/Makefile dvdburn/Makefile epicsdisplay/Makefile \ - epicsdisplay/epicsdisplay chanlog/Makefile \ - daqstart/Makefile ScalerDisplay/Makefile ScalerDisplay/ScalerDisplay \ - wienerdriver/Makefile wienerdriver/driver/Makefile \ - wienerdriver/lib/Makefile PowerCheck/Makefile \ - wienerusbd/Makefile \ - slowControls/Makefile slowControls/caenv812/Makefile \ - slowControls/n568b/Makefile slowControls/vhq/Makefile \ - slowControls/widgets/Makefile sequencer/Makefile \ - spectrodaqStatus/Makefile) Added: trunk/nextgen/sbs/driver/Makefile.am =================================================================== --- trunk/nextgen/sbs/driver/Makefile.am (rev 0) +++ trunk/nextgen/sbs/driver/Makefile.am 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1 @@ +SUBDIRS=include src dd Added: trunk/nextgen/sbs/driver/src/Makefile.am =================================================================== --- trunk/nextgen/sbs/driver/src/Makefile.am (rev 0) +++ trunk/nextgen/sbs/driver/src/Makefile.am 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,34 @@ +lib_LTLIBRARIES = libbtp.la +libbtp_la_SOURCES = bt_rdwr.c \ + bt_ctrl.c \ + bt_mmap.c \ + bt_open.c \ + bt_bind.c \ + bt_chke.c \ + bt_clre.c \ + bt_init.c \ + bt_perr.c \ + bt_locking.c \ + bt_info.c \ + bt_name.c \ + bt_serr.c \ + bt_icbr.c \ + bt_reset.c \ + bt_string.c \ + bt_ior.c \ + bt_iow.c \ + bt_stat.c \ + bt_cas.c \ + bt_tas.c \ + bt_send_irq.c \ + bt_or_io.c + + + +libbtp_la_LDFLAGS = -version-info 1:0:0 +INCLUDES = -I. -I../include \ + -DBT1003 -DNDEBUG -DBT_INLINE \ + -D_POSIX_C_SOURCE -D_POSIX_THREAD_SEMANTICS \ + -O2 -Wall -Wstrict-prototypes + +include_HEADERS = btpiflib.h \ No newline at end of file Added: trunk/nextgen/sbs/driver/src/bt_bind.c =================================================================== --- trunk/nextgen/sbs/driver/src/bt_bind.c (rev 0) +++ trunk/nextgen/sbs/driver/src/bt_bind.c 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,378 @@ +/****************************************************************************** +** +** Filename: bt_bind.c +** +** Purpose: IRIX, Solaris & Linux implementation of bind +** for NanoBus hardware +** +** Functions: bt_bind(), bt_unbind(), bt_hw_bind(), bt_hw_unbind() +** +** $Revision: 742 $ +** +******************************************************************************/ +/***************************************************************************** +** +** Copyright (c) 2000 by SBS Technologies, Inc. +** All Rights Reserved. +** License governs use and distribution. +** +*****************************************************************************/ + +#ifndef LINT +static const char revcntrl[] = "@(#)"__FILE__" $Revision: 742 $" __DATE__; +#endif /* LINT */ + +#include "btapi.h" +#include "btio.h" + +#include "btpiflib.h" + + +/***************************************************************************** +** +** Name: bt_bind +** +** Purpose: Implement BIOC_BIND function which Maps an application +** supplied buffer onto the remote bus. +** Args: +** btd Device Descriptor +** bind_p Pointer to the bind handle to init. +** offset_p Pointer to offset into remote mem where buf is bound +** buf_p Pointer to buffer to bind +** buf_len Length of buffer +** flags Access rights requested on the bind +** swapping Swapping methond to use on remote accesses to the buffer +** +** Returns: +** BT_ENOSUP Always +** +** Notes: +** Hardware does not require any bind. +** +*****************************************************************************/ + +bt_error_t bt_bind( + bt_desc_t btd, + bt_binddesc_t *bind_p, + bt_devaddr_t *offset_p, + void *buf_p, + size_t buf_len, + bt_accessflag_t flags, + bt_swap_t swapping) +{ + bt_error_t retval = BT_SUCCESS; + bt_bind_t bind; + bt_devdata_t save_swap; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_bind:bad descriptor."); + retval = BT_EDESC; + goto bt_bind_end; + } + + /* + ** Verify parameters + */ + if ((bind_p == NULL) || + (buf_p == NULL) || + (offset_p == NULL)) { + DBG_STR("bt_bind:Null pointer passed in"); + retval = BT_EINVAL; + goto bt_bind_end; + } + + /* + ** verify R/W permissions against the open + */ + if (((flags & BT_WR) && !(btd->access_flags & BT_WR)) || + ((flags & BT_RD) && !(btd->access_flags & BT_RD))) { + DBG_STR("bt_bind:Read/Write permissions missmatch."); + retval = BT_EACCESS; + goto bt_bind_end; + } + + /* + ** Setup ioctl structure + */ + bind.host_addr = (bt_devaddr_t) buf_p; + bind.length = buf_len; + bind.nowait = FALSE; + bind.phys_addr = *offset_p; + + /* + ** Set special swapping if requested + */ + if (swapping != BT_SWAP_DEFAULT) { + retval = bt_get_info(btd, BT_INFO_SWAP, &save_swap); + if (retval != BT_SUCCESS) { + DBG_STR("bt_bind:Couldn't get BT_INFO_SWAP info."); + goto bt_bind_end; + } + retval = bt_set_info(btd, BT_INFO_SWAP, swapping); + if (retval != BT_SUCCESS) { + (void) bt_ctrl(btd, BIOC_UNBIND, &bind); + DBG_STR("bt_bind:Couldn't set swapping to users value."); + goto bt_bind_end; + } + } + + /* + ** Do the actual bind + */ + if ((retval = bt_ctrl(btd, BIOC_BIND, &bind)) != BT_SUCCESS) { + DBG_STR("bt_bind:BIOC_BIND failed."); + goto bt_bind_end; + } + + /* + ** Restore special swapping if required + */ + if (swapping != BT_SWAP_DEFAULT) { + retval = bt_set_info(btd, BT_INFO_SWAP, save_swap); + if (retval != BT_SUCCESS) { + (void) bt_ctrl(btd, BIOC_UNBIND, &bind); + DBG_STR("bt_bind:Couldn't restore swapping info."); + goto bt_bind_end; + } + } + *offset_p = bind.phys_addr; + *bind_p = (bt_binddesc_t) bind.sysinfo_p; + +bt_bind_end: + return (retval); +} + + +/***************************************************************************** +** +** Name: bt_unbind +** +** Purpose: Implement BIOC_UNBIND function +** +** Args: +** btd Device Descriptor +** desc Bind descriptor returned from bt_bind() +** +** Returns: +** BT_ENOSUP Always +** +** Notes: +** Hardware does not require any bind. +** +*****************************************************************************/ + +bt_error_t bt_unbind( + bt_desc_t btd, + bt_binddesc_t desc) +{ + bt_error_t retval = BT_SUCCESS; + bt_bind_t unbind; + + /* + ** Check for bad descriptor + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_unbind:bad descriptor."); + retval = BT_EDESC; + goto bt_unbind_end; + } + + /* + ** Verify parameters + */ + if (desc == (bt_binddesc_t) NULL){ + DBG_STR("bt_unbind:Null bind descriptor passed in"); + retval = BT_EINVAL; + goto bt_unbind_end; + } + + /* + ** Setup ioctl structure + */ + unbind.sysinfo_p = (bt_devaddr_t) desc; + + /* + ** Do the actual unbind + */ + if ((retval = bt_ctrl(btd, BIOC_UNBIND, &unbind)) != BT_SUCCESS) { + DBG_STR("bt_unbind:unbind failed"); + goto bt_unbind_end; + } + +bt_unbind_end: + return (retval); +} + +/***************************************************************************** +** +** Name: bt_hw_bind +** +** Purpose: Implement BIOC_HW_BIND function which Maps a physical +** bus address onto the remote bus. +** Args: +** btd Device Descriptor +** bind_p Pointer to the bind handle to init. +** offset_p Pointer to offset into remote mem where buf is bound +** loc_addr Physical bus address to bind +** buf_len Length of buffer +** flags Access rights requested on the bind +** swapping Swapping methond to use on remote accesses to the buffer +** +** Returns: +** BT_ENOSUP Always +** +** Notes: +** Hardware does not require any bind. +** +*****************************************************************************/ + +bt_error_t bt_hw_bind( + bt_desc_t btd, + bt_binddesc_t *bind_p, + bt_devaddr_t *offset_p, + bt_devaddr_t loc_addr, + size_t buf_len, + bt_accessflag_t flags, + bt_swap_t swapping) +{ + bt_error_t retval = BT_SUCCESS; + bt_bind_t bind; + bt_devdata_t save_swap; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_hw_bind:bad descriptor"); + retval = BT_EDESC; + goto bt_hw_bind_end; + } + + /* + ** Verify parameters + */ + if ((bind_p == NULL) || (offset_p == NULL)) { + DBG_STR("bt_hw_bind:Null pointer passed in."); + retval = BT_EINVAL; + goto bt_hw_bind_end; + } + + /* + ** verify R/W permissions against the open + */ + if (((flags & BT_WR) && !(btd->access_flags & BT_WR)) || + ((flags & BT_RD) && !(btd->access_flags & BT_RD))) { + DBG_STR("bt_hw_bind:Read/Write permissions don't match open."); + retval = BT_EACCESS; + goto bt_hw_bind_end; + } + + /* + ** Setup ioctl structure + */ + bind.host_addr = loc_addr; + bind.length = buf_len; + bind.nowait = FALSE; + bind.phys_addr = *offset_p; + + /* + ** Set special swapping if requested + */ + if (swapping != BT_SWAP_DEFAULT) { + retval = bt_get_info(btd, BT_INFO_SWAP, &save_swap); + if (retval != BT_SUCCESS) { + DBG_STR("bt_hw_bind:Couldn't get default swap info."); + goto bt_hw_bind_end; + } + } + + /* + ** Do the actual bind + */ + if ((retval = bt_ctrl(btd, BIOC_HW_BIND, &bind)) != BT_SUCCESS) { + DBG_STR("bt_hw_bind:hw bind call failed."); + goto bt_hw_bind_end; + } + + /* + ** Restore special swapping if required + */ + if (swapping != BT_SWAP_DEFAULT) { + retval = bt_set_info(btd, BT_INFO_SWAP, save_swap); + if (retval != BT_SUCCESS) { + (void) bt_ctrl(btd, BIOC_HW_UNBIND, &bind); + DBG_STR("bt_hw_bind:Couldn't restore default swapping."); + goto bt_hw_bind_end; + } + } + *offset_p = bind.phys_addr; + *bind_p = (bt_binddesc_t) bind.sysinfo_p; + +bt_hw_bind_end: + return (retval); +} + + +/***************************************************************************** +** +** Name: bt_unbind +** +** Purpose: Implement BIOC_HW_UNBIND function +** +** Args: +** btd Device Descriptor +** desc Bind descriptor returned from bt_bind() +** +** Returns: +** BT_ENOSUP Always +** +** Notes: +** Hardware does not require any bind. +** +*****************************************************************************/ + +bt_error_t bt_hw_unbind( + bt_desc_t btd, + bt_binddesc_t desc) +{ + bt_error_t retval = BT_SUCCESS; + bt_bind_t unbind; + + /* + ** Check for bad descriptor + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_hw_unbind:bad descriptor."); + retval = BT_EDESC; + goto bt_hw_unbind_end; + } + + /* + ** Verify parameters + */ + if (desc == (bt_binddesc_t) NULL){ + DBG_STR("bt_hw_unbind:Null bind descriptor passed in"); + retval = BT_EINVAL; + goto bt_hw_unbind_end; + } + + /* + ** Setup ioctl structure + */ + unbind.sysinfo_p = (bt_devaddr_t) desc; + + /* + ** Do the actual unbind + */ + if ((retval = bt_ctrl(btd, BIOC_HW_UNBIND, &unbind)) != BT_SUCCESS) { + DBG_STR("bt_hw_unbind:hw unbind call failed"); + goto bt_hw_unbind_end; + } + +bt_hw_unbind_end: + return (retval); +} + Property changes on: trunk/nextgen/sbs/driver/src/bt_bind.c ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/driver/src/bt_cas.c =================================================================== --- trunk/nextgen/sbs/driver/src/bt_cas.c (rev 0) +++ trunk/nextgen/sbs/driver/src/bt_cas.c 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,99 @@ +/****************************************************************************** +** +** Filename: bt_cas.c +** +** Purpose: NanBus UNIX Mirror API bt_cas() routine. +** +** Functions: bt_cas.c +** +** $Revision: 742 $ +** +******************************************************************************/ +/***************************************************************************** +** +** Copyright (c) 1999 by SBS Technologies, Inc. +** All Rights Reserved. +** License governs use and distribution. +** +*****************************************************************************/ + +#ifndef LINT +static const char revcntrl[] = "@(#)"__FILE__" $Revision: 742 $" __DATE__; +#endif /* LINT */ + +#include "btio.h" +#include "btapi.h" +#include "btpiflib.h" + +/***************************************************************************** +** +** External routines +** +*****************************************************************************/ + +/***************************************************************************** +** +** Name: bt_cas +** +** Purpose: Does a compare and swap atomic transaction of the +** remote bus. +** +** Args: +** btd Unit descriptor +** rem_off Address of the memory location to check. +** cmpval Compare with memory value, if a match swap_value +** is written to this location. +** Swap_val If cmpval and the memory location match, this value +** is written to the location. +** prevval_p Holds the previous value of the memory location. +** data_size Size of the memory location to look at. +** +** Modifies: +** None +** +** Returns: +** BT_SUCCESS No errors +** BT_ESTATUS If there are still status errors. +** BT_ENOPWR Power is off or cable disconnected +** BT_IO Could not query driver +** +** Notes: +** +*****************************************************************************/ + +bt_error_t bt_cas( + bt_desc_t btd, + bt_devaddr_t rem_off, + bt_data32_t cmpval, + bt_data32_t swapval, + bt_data32_t *prevval_p, + size_t data_size + ) +{ + bt_error_t retvalue; + bt_cas_t param; + + if (BT_DESC_BAD(btd)) { /* Bad Descriptor */ + DBG_STR("bt_cas:bad descriptor."); + retvalue = BT_EDESC; + return retvalue; + } + + param.error = BT_SUCCESS; + param.addr = rem_off; + param.cmp = cmpval; + param.swap = swapval; + param.len = data_size; + + + retvalue = bt_ctrl(btd, BIOC_CAS, ¶m); + if (BT_SUCCESS == retvalue) { + DBG_STR("bt_cas:bt_ctrl BIOC_CAS call failed."); + retvalue = param.error; + } + + /* return to the user the results */ + *prevval_p = param.result; + + return retvalue; +} Property changes on: trunk/nextgen/sbs/driver/src/bt_cas.c ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/driver/src/bt_chke.c =================================================================== --- trunk/nextgen/sbs/driver/src/bt_chke.c (rev 0) +++ trunk/nextgen/sbs/driver/src/bt_chke.c 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,70 @@ +/****************************************************************************** +** +** Filename: bt_chke.c +** +** Purpose: NanoBus UNIX Mirror API bt_chkerr() routine. +** +** Functions: bt_chkerr.c +** +** $Revision: 742 $ +** +******************************************************************************/ +/***************************************************************************** +** +** Copyright (c) 1999 by SBS Technologies, Inc. +** All Rights Reserved. +** License governs use and distribution. +** +*****************************************************************************/ + +#ifndef LINT +static const char revcntrl[] = "@(#)"__FILE__" $Revision: 742 $" __DATE__; +#endif /* LINT */ + +#include "btio.h" +#include "btapi.h" + +/***************************************************************************** +** +** External routines +** +*****************************************************************************/ + +/***************************************************************************** +** +** Name: bt_chkerr +** +** Purpose: Checks for any errors. +** +** Args: +** btd Unit descriptor +** +** Modifies: +** None +** +** Returns: +** BT_SUCCESS No errors +** BT_ESTATUS If there are any status errors. +** BT_ENOPWR Power is off or cable disconnected +** BT_EPWRCYC Power has transitioned from off to on +** BT_IO Could not query driver +** +** Notes: +** +*****************************************************************************/ + +bt_error_t bt_chkerr( + bt_desc_t btd + ) +{ + bt_error_t retvalue; + bt_status_t param; + + retvalue = bt_ctrl(btd, BIOC_STATUS, ¶m); + if (param & BT_INTR_POWER) { + retvalue = BT_ENOPWR; + } else if (param & ((bt_status_t) LSR_ERROR_MASK << BT_INTR_ERR_SHFT) ){ + retvalue = BT_ESTATUS; + } + return retvalue; +} Property changes on: trunk/nextgen/sbs/driver/src/bt_chke.c ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/driver/src/bt_clre.c =================================================================== --- trunk/nextgen/sbs/driver/src/bt_clre.c (rev 0) +++ trunk/nextgen/sbs/driver/src/bt_clre.c 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,70 @@ +/****************************************************************************** +** +** Filename: bt_clre.c +** +** Purpose: NanBus UNIX Mirror API bt_clrerr() routine. +** +** Functions: bt_clrerr.c +** +** $Revision: 742 $ +** +******************************************************************************/ +/***************************************************************************** +** +** Copyright (c) 1999 by SBS Technologies, Inc. +** All Rights Reserved. +** License governs use and distribution. +** +*****************************************************************************/ + +#ifndef LINT +static const char revcntrl[] = "@(#)"__FILE__" $Revision: 742 $" __DATE__; +#endif /* LINT */ + +#include "btio.h" +#include "btapi.h" + +/***************************************************************************** +** +** External routines +** +*****************************************************************************/ + +/***************************************************************************** +** +** Name: bt_clrerr +** +** Purpose: Clears any error status in the device. +** +** Args: +** btd Unit descriptor +** +** Modifies: +** None +** +** Returns: +** BT_SUCCESS No errors +** BT_ESTATUS If there are still status errors. +** BT_ENOPWR Power is off or cable disconnected +** BT_IO Could not query driver +** +** Notes: +** +*****************************************************************************/ + +bt_error_t bt_clrerr( + bt_desc_t btd + ) +{ + bt_error_t retvalue; + bt_status_t param; + + retvalue = bt_ctrl(btd, BIOC_CLR_STATUS, ¶m); + if (param & BT_INTR_POWER) { + retvalue = BT_ENOPWR; + } else if (param & ((bt_status_t) LSR_ERROR_MASK << BT_INTR_ERR_SHFT) ){ + retvalue = BT_ESTATUS; + } + + return retvalue; +} Property changes on: trunk/nextgen/sbs/driver/src/bt_clre.c ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/driver/src/bt_ctrl.c =================================================================== --- trunk/nextgen/sbs/driver/src/bt_ctrl.c (rev 0) +++ trunk/nextgen/sbs/driver/src/bt_ctrl.c 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,123 @@ +/****************************************************************************** +** +** Filename: bt_ctrl.c +** +** Purpose: Mirror API implementation of bt_ctrl(). +** +** Functions: bt_ctrl() +** +** $Revision: 742 $ +** +******************************************************************************/ +/***************************************************************************** +** +** Copyright (c) 2000 by SBS Technologies, Inc. +** All Rights Reserved. +** License governs use and distribution. +** +*****************************************************************************/ + +#ifndef LINT +static const char revcntrl[] = "@(#)"__FILE__" $Revision: 742 $" __DATE__; +#endif /* LINT */ + +#include <stddef.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <errno.h> + +#if defined(__vxworks) +#include <ioLib.h> +#endif /* defined __vxworks */ + +#include "btio.h" +#include "btapi.h" +#include "btpiflib.h" + +/***************************************************************************** +** +** External routines +** +*****************************************************************************/ + +/***************************************************************************** +** +** Name: bt_ctrl +** +** Purpose: Access to miscellaneous device functions. +** +** Args: +** btd Unit descriptor +** ctrl What control function to access +** param_p Function specific parameter +** +** Modifies: +** None +** +** Returns: +** BT_SUCCESS on success +** BT_ENOSUP Legacy ioctl()'s not supported +** otherwise appropriate error number +** +** Notes: +** +*****************************************************************************/ + +bt_error_t bt_ctrl( + bt_desc_t btd, + int ctrl, + void *param_p) +{ + bt_error_t retvalue = BT_SUCCESS; + bt_data32_t *status_val = param_p; /* BIOC_ error value is 32-bit value */ + + bool_t error_member_exists = (0 != (_IOC_NR(ctrl) & BT_IO_ERET_FLAG)); + + /* + ** Check for bad descriptor + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_ctrl:bad descriptor."); + retvalue = BT_EDESC; + goto ctrl_end; + } + + /* + ** Initialize return value + */ + if (error_member_exists) { /* 1 = first member arg holds error value */ + *status_val = BT_SUCCESS; /* Initialize status member */ + } + + /* + ** Do the ioctl + */ + if (-1 == (retvalue = ioctl(btd->fd, ctrl, (void *) param_p))) { + switch (errno) { + case EBADF: + retvalue = BT_EDESC; + break; + case ENOTTY: + retvalue = BT_ENOSUP; + break; + case BT_EINVAL: + case BT_ENXIO: + retvalue = errno; + break; + default: + retvalue = BT_EFAIL; + break; + } + } + + /* + ** Replace return value if ioctl() worked and first member + ** arg holds error value + */ + if ( (error_member_exists) && (BT_SUCCESS == retvalue)) { + retvalue = *status_val; + } + +ctrl_end: + return retvalue; +} Property changes on: trunk/nextgen/sbs/driver/src/bt_ctrl.c ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/driver/src/bt_hw_diag.c =================================================================== --- trunk/nextgen/sbs/driver/src/bt_hw_diag.c (rev 0) +++ trunk/nextgen/sbs/driver/src/bt_hw_diag.c 2008-10-07 11:41:55 UTC (rev 1993) @@ -0,0 +1,585 @@ +/****************************************************************************** +** +** Filename: bt_hw_diag.c +** +** Purpose: IRIX, Solaris & Linux implementation of Hardware +** diagnostic routines for dataBLIZZARD hardware +** +** Functions: bt_lcard_diag(), bt_cable_diag(), bt_rcard_diag(), +** bt_pair_diag(), bt_trace_init() bt_driver_version() +** +** $Revision: 742 $ +** +******************************************************************************/ +/***************************************************************************** +** +** Copyright (c) 2000-2002 by SBS Technologies, Inc. +** All Rights Reserved. +** License governs use and distribution. +** +*****************************************************************************/ + +#ifndef LINT +static const char revcntrl[] = "@(#)"__FILE__" $Revision: 742 $" __DATE__; +#endif /* LINT */ + +#include <stdio.h> + +#include <string.h> /* for strncp call */ +#include "btapi.h" +#include "btio.h" +#include "btpiflib.h" + + + +/***************************************************************************** +** +** Name: bt_driver_version +** +** Purpose: Returns the driver version as a text string +** +** Args: +** btd Device Descriptor +** ver_info_p Text string with file and revision number. +** line_p Pointer to the line number failure was discovered. +** +** Returns: +** BT_ENOSUP Not supported on this hardware. +** BT_EINVAL Illegal parameter passed to function. +** BT_EDESC Illegal descriptor passed to function. +** +** BT_SUCCESS Testing passed, local card appears good. +** +** +** Notes: +** +*****************************************************************************/ + +bt_error_t bt_driver_version( + bt_desc_t btd, + char *ver_info_p, + int *line_p) +{ + bt_error_t retval = BT_SUCCESS; + bt_hw_diag_t diag; + char model_version[BT_DIAG_MAX_REV_INFO]; + int i; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_driver_version:bad descriptor."); + retval = BT_EDESC; + goto bt_driver_version_end; + } + + for (i = 0; i < BT_DIAG_MAX_REV_INFO; i++) { + model_version[i] = '\0'; + } + + /* + ** Verify parameters + */ +#if defined (__vxworks) + ver_info_p[BT_DIAG_MAX_REV_INFO] = NULL; +#endif /* defined (__vxworks) */ + + /* + ** Setup ioctl structure + */ + diag.error = (bt_data32_t) BT_SUCCESS; + + /* + ** Retrieve the driver version number + */ + if ((retval = bt_ctrl(btd, BIOC_DRIVER_VERSION, &diag)) != BT_SUCCESS) { + DBG_STR("bt_lcard_diag:BIOC_DRIVER_VERSION failed."); + if (diag.error != BT_SUCCESS) { + retval = diag.error; + } + goto bt_driver_version_end; + } + +bt_driver_version_end: + /* + ** Report the line number and rev info if requested + */ + if (ver_info_p != NULL) { + sscanf((const char *) &diag.rev_info[0], "$Name: %s ", model_version); + +#if defined (__vxworks) + sprintf(ver_info_p, "%s", model_version); +#else + snprintf(ver_info_p, BT_DIAG_MAX_REV_INFO, "%s", model_version); +#endif /* defined (__vxworks) */ + + } + + if (line_p != NULL) { + *line_p = diag.line_number; + } + + return (retval); +} + +/***************************************************************************** +** +** Name: bt_lcard_diag +** +** Purpose: Determine whether the local card is operating +** properly. +** +** Args: +** btd Device Descriptor +** rev_info_p Text string with file and revision number. +** line_p Pointer to the line number failure was discovered. +** +** Returns: +** BT_ENOSUP Not supported on this hardware. +** BT_ENXIO Local memory device not enabled. +** BT_ENOPWR Pig tail connector not installed. +** BT_EINVAL Illegal parameter passed to function. +** BT_EDESC Illegal descriptor passed to function. +** BT_ELCARD Testing failed, local card needs repair. +** +** BT_SUCCESS Testing passed, local card appears good. +** +** +** Notes: +** If the pig tail connector is installed on the local card +** and any data in local dual port memory or the local memory +** device may be destroyed. +** +** All diagnostics require the local memory device to be present. +** +** Both line_p and rev_info_p can be null and no information will +** be returned. +** +*****************************************************************************/ + +bt_error_t bt_lcard_diag( + bt_desc_t btd, + char *rev_info_p, + int *line_p) +{ + bt_error_t retval = BT_SUCCESS; + bt_hw_diag_t diag; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_lcard_diag:bad descriptor."); + retval = BT_EDESC; + goto bt_lcard_diag_end; + } + + /* + ** Verify parameters + */ + + /* + ** Setup ioctl structure + */ + diag.error = (bt_data32_t) BT_SUCCESS; + + /* + ** Do the actual diagnostics + */ + if ((retval = bt_ctrl(btd, BIOC_LCARD_DIAG, &diag)) != BT_SUCCESS) { + DBG_STR("bt_lcard_diag:BIOC_LCARD_DIAG failed."); + if (diag.error != BT_SUCCESS) { + retval = diag.error; + } + goto bt_lcard_diag_end; + } + +bt_lcard_diag_end: + /* + ** Report the line number and rev info if requested + */ + if (rev_info_p != NULL) { + strncpy(rev_info_p, (const char *) &diag.rev_info[0], BT_DIAG_MAX_REV_INFO); + } + + if (line_p != NULL) { + *line_p = diag.line_number; + } + + return (retval); +} + + +/***************************************************************************** +** +** Name: bt_cable_diag +** +** Purpose: Determine whether the cable is operating +** properly. +**. +** Args: +** btd Device Descriptor +** rev_info_p Text string with file and revision number. +** line_p Pointer to the line number failure was discovered. +** +** Returns: +** BT_ENOSUP Not supported on this hardware. +** BT_ENXIO Local memory device not enabled. +** BT_ENOPWR Pig tail connector not installed. +** BT_EINVAL Illegal parameter passed to function. +** BT_EDESC Illegal descriptor passed to function. +** BT_ECABLE Testing failed, cable needs repair. +** +** BT_SUCCESS Testing passed, cable appears good. +** +** +** Notes: +** If the pig tail connector is installed at the end of the +** cable and any data in local dual port memory or the local +** memory device may be destroyed. +** +** All diagnostics require the local memory device to be present. +** +** Should be done after bt_lcard_diag() passes. +** +*****************************************************************************/ + +bt_error_t bt_cable_diag( + bt_desc_t btd, + char *rev_info_p, + int *line_p) +{ + bt_error_t retval = BT_SUCCESS; + bt_hw_diag_t diag; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_cable_diag:bad descriptor."); + retval = BT_EDESC; + goto bt_cable_diag_end; + } + + /* + ** Verify parameters + */ + + /* + ** Setup ioctl structure + */ + diag.error = (bt_data32_t) BT_SUCCESS; + + /* + ** Do the actual diagnostics + */ + if ((retval = bt_ctrl(btd, BIOC_CABLE_DIAG, &diag)) != BT_SUCCESS) { + DBG_STR("bt_cable_diag:BIOC_CABLE_DIAG failed."); + if (diag.error != BT_SUCCESS) { + retval = diag.error; + } + goto bt_cable_diag_end; + } + +bt_cable_diag_end: + /* + ** Report the line number and rev info if requested + */ + if (rev_info_p != NULL) { + strncpy(rev_info_p, (const char *) &diag.rev_info[0], BT_DIAG_MAX_REV_INFO); + } + if (line_p != NULL) { + *line_p = diag.line_number; + } + + return (retval); +} + + +/***************************************************************************** +** +** Name: bt_rcard_diag +** +** Purpose: Determine whether the remote card is operating +** properly. +**. +** Args: +** btd Device Descriptor +** rldev Remote logical device type to use during testing. +** One of bt_dev_t values, normally BT_DEV_A32. +** raddr Remote device address to use during testing. +** rlen Lenght in bytes of remote resource +** rev_info_p Text string with file and revision number. +** line_p Pointer to the line number failure was discovered. +** +** Returns: +** BT_ENOSUP Not supported on this hardware. +** BT_ENXIO Local memory device not enabled. +** BT_ENOPWR Pig tail connector not installed. +** BT_EINVAL Illegal parameter passed to function. +** BT_EDESC Illegal descriptor passed to function. +** BT_ERCARD Testing failed, remote card needs repair. +** +** BT_SUCCESS Testing passed, remote card appears good. +** +** +** Notes: +** Cable must be attached to remote card. Any data in local dual +** port memory, remote dual port memory, specified remote resource +** and the local memory device may be destroyed. +** +** All diagnostics require the local memory device to be present and +** for the remote resource to be vaild. +** +** Should be done after bt_lcard_diag() and bt_cable_diag() passes. +** +*****************************************************************************/ + +bt_error_t bt_rcard_diag( + bt_desc_t btd, + bt_dev_t rldev, + bt_devaddr_t raddr, + bt_data32_t rlen, + char *rev_info_p, + int *line_p) +{ + bt_error_t retval = BT_SUCCESS; + bt_hw_diag_t diag; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_rcard_diag:bad descriptor."); + retval = BT_EDESC; + goto bt_rcard_diag_end; + } + + /* + ** Verify parameters + */ + if ((rldev != BT_DEV_A32) && + (rldev != BT_DEV_A32) && + (rldev != BT_DEV_A16)) { + DBG_STR("bt_rcard_diag: invalid remote logical device type."); + retval = BT_EINVAL; + goto bt_rcard_diag_end; + } + if (rlen == 0) { + DBG_STR("bt_rcard_diag: zero remote length."); + retval = BT_EINVAL; + goto bt_rcard_diag_end; + } + + /* + ** Setup ioctl structure + */ + diag.error = (bt_data32_t) BT_SUCCESS; + diag.r_ldev = rldev; + diag.r_addr = raddr; + diag.r_len = rlen; + + /* + ** Do the actual diagnostics + */ + if ((retval = bt_ctrl(btd, BIOC_RCARD_DIAG, &diag)) != BT_SUCCESS) { + DBG_STR("bt_rcard_diag:BIOC_RCARD_DIAG failed."); + if (diag.error != BT_SUCCESS) { + retval = diag.error; + } + goto bt_rcard_diag_end; + } + +bt_rcard_diag_end: + + /* + ** Report the line number and rev info if requested + */ + if (rev_info_p != NULL) { + strncpy(rev_info_p, (const char *) &diag.rev_info[0], BT_DIAG_MAX_REV_INFO); + } + + if (line_p != NULL) { + *line_p = diag.line_number; + } + + return (retval); +} + + +/***************************************************************************** +** +** Name: bt_pair_diag +** +** Purpose: Determine whether a pair of cards is operating +** properly. +**. +** Args: +** btd Device Descriptor +** rldev Remote logical device type to use during testing. +** One of bt_dev_t values, normally BT_DEV_A32. +** raddr Remote device address to use during testing. +** rlen Lenght in bytes of remote resource +** rev_info_p Text string with file and revision number. +** line_p Pointer to the line number failure was discovered. +** +** Returns: +** BT_ENOSUP Not supported on this hardware. +** BT_ENXIO Local memory device not enabled. +** BT_ENOPWR Pig tail connector not installed. +** BT_EINVAL Illegal parameter passed to function. +** BT_EDESC Illegal descriptor passed to function. +** BT_EPAIR Testing failed, both cards should be replaced. +** +** BT_SUCCESS Testing passed, adapter set appears good. +** +** +** Notes: +** Cable must be attached to remote card. Any data in local dual +** port memory, remote dual port memory, specified remote resource +** and the local memory device may be destroyed. +** +** All diagnostics require the local memory device to be present and +** for the remote resource to be vaild. +** +** Should be done after bt_lcard_diag(), bt_cable_diag() and +** bt_rcard_diag() passes. +** +*****************************************************************************/ + +bt_error_t bt_pair_diag( + bt_desc_t btd, + bt_dev_t rldev, + bt_devaddr_t raddr, + bt_data32_t rlen, + char *rev_info_p, + int *line_p) +{ + bt_error_t retval = BT_SUCCESS; + bt_hw_diag_t diag; + + /* + ** Check for bad descriptor or invalid pointer value + */ + if (BT_DESC_BAD(btd)) { + DBG_STR("bt_pair_diag:bad descriptor."); + retval = BT_EDESC; + goto bt_pair_diag_end; + } + + /* + ** Verify parameters + */ + if ((rldev != BT_DEV_A32) && + (rldev != BT_DEV_A32) && + (rldev != BT_DEV_A16)) { + DBG_STR("bt_pair_diag: invalid remote logical device type."); + retval = BT_EINVAL; + goto bt_pair_diag_end; + } + if (rlen == 0) { + DBG_STR("bt_pair_diag: zero remote length."); + retval = BT_EINVAL; + goto bt_pair_diag_end; + } + + /* + ** Setup ioctl structure + */ + diag.error = (bt_data32_t) BT_SUCCESS; + diag.r_ldev = rldev; + diag.r_addr = raddr; + diag.r_len = rlen; + + /* + ** Do the actual diagnostics + */ + if ((retval = bt_ctrl(btd, BIOC_PAIR_DIAG, &diag)) != BT_SUCCESS) { + DBG_STR("bt_pair_diag:BIOC_PAIR_DIAG failed."); + if (diag.error != BT_SUCCESS) { + retval = diag.error; + } + goto bt_pair_diag_end; + } + +bt_pair_diag_end: + /* + ** Report the line number and rev info if requested + */ + if (rev_in... [truncated message content] |
From: <ro...@us...> - 2008-10-07 14:31:00
|
Revision: 1998 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1998&view=rev Author: ron-fox Date: 2008-10-07 14:29:59 +0000 (Tue, 07 Oct 2008) Log Message: ----------- - Build the NSCL CVMEInterface class. - add tclpackage directory. (need to stock it etc)> Modified Paths: -------------- trunk/nextgen/configure.ac trunk/nextgen/sbs/Makefile.am Added Paths: ----------- trunk/nextgen/sbs/nsclapi/ trunk/nextgen/sbs/nsclapi/CVMEInterface.h trunk/nextgen/sbs/nsclapi/Locking.cpp trunk/nextgen/sbs/nsclapi/Makefile.am trunk/nextgen/sbs/nsclapi/SBSBIT3API.cpp trunk/nextgen/sbs/nsclapi/SBSBit3API.h trunk/nextgen/sbs/tclpackage/ Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2008-10-07 13:41:24 UTC (rev 1997) +++ trunk/nextgen/configure.ac 2008-10-07 14:29:59 UTC (rev 1998) @@ -443,6 +443,7 @@ sbs/driver/src/Makefile sbs/driver/include/Makefile sbs/driver/dd/GNUmakefile + sbs/nsclapi/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/sbs/Makefile.am =================================================================== --- trunk/nextgen/sbs/Makefile.am 2008-10-07 13:41:24 UTC (rev 1997) +++ trunk/nextgen/sbs/Makefile.am 2008-10-07 14:29:59 UTC (rev 1998) @@ -1 +1 @@ -SUBDIRS = driver \ No newline at end of file +SUBDIRS = driver nsclapi Added: trunk/nextgen/sbs/nsclapi/CVMEInterface.h =================================================================== --- trunk/nextgen/sbs/nsclapi/CVMEInterface.h (rev 0) +++ trunk/nextgen/sbs/nsclapi/CVMEInterface.h 2008-10-07 14:29:59 UTC (rev 1998) @@ -0,0 +1,107 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +/*! + Provides device/driver independent interfaces to the VME bus. + This is implemented as a class with wholey static members for the following + reasons: + - Class provides a namespace context to prevent global namespace polution. + - Class allows for future optimizations that support 'sharing' address space + mappings. + + The basic functions we support are: + - Map an address space. + - Unmap an address space. + - Do a block read + - Do a block write. + + The address modes supported are: + A16/D32 - Short I/O space. + A24/D32 - Standard memory. + A32/D32 - Extended memory. + GEO/D32 - Geographical addressing. + MCST/D32 - Multicast control register access. + CBLT/D32 - Chained block transfer. + + \note Assumptions: + - The goal is simplicity. + - There is only one driver on each system. + - All address spaces are open read/write. + - The goal is simplicity! + + +*/ + +#ifndef __VMEINTERFACE_H +#define __VMEINTERFACE_H + + +class CVMEInterface +{ + public: + // Type definitions: + + typedef enum { // Addressing modes: + A16, + A24, + A32, + GEO, + MCST, + CBLT, + LAST, + ShortIO = A16, + Standard = A24, + Extended = A32, + Geographical = GEO, + Multicast = MCST, + ChainedBlock = CBLT +#ifdef HAVE_WIENERUSBVME_INTERFACE + , + A24SuperBLT, + A24UserBLT, + A32SuperBLT, + A32UserBLT, + +#endif + } AddressMode; + + static const char* m_szDriverName; // Name of driver (e.g. NSCLBiT3). + + static void* Open(AddressMode nMode, + unsigned short crate = 0); //!< Open a logical device. + static void Close(void* pDeviceHandle); //!< Close the logical device. + static void* Map(void* pDeviceHandle, + unsigned long nBase, + unsigned long nBytes); //!< Map a chunk of the bus to pva. + static void Unmap(void* pDeviceHandle, + void* pBase, + unsigned long lBytes); //!< Unmap a previously mapped section. + + static int Read(void* pDeviceHandle, + unsigned long nOffset, + void* pBuffer, + unsigned long nBytes); //!< Block read from VME. + static int Write(void* pDeviceHandle, + unsigned long nOffset, + void* pBuffer, + unsigned long nBytes); //!< Block write to vme. + static void Lock(); + static void Unlock(); + +}; + + +#endif Property changes on: trunk/nextgen/sbs/nsclapi/CVMEInterface.h ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/nsclapi/Locking.cpp =================================================================== --- trunk/nextgen/sbs/nsclapi/Locking.cpp (rev 0) +++ trunk/nextgen/sbs/nsclapi/Locking.cpp 2008-10-07 14:29:59 UTC (rev 1998) @@ -0,0 +1,179 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +#include <config.h> + +#include <CVMEInterface.h> +#include <ErrnoException.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <assert.h> +#include <string> + +using namespace std; + +// In some cases we need to define the semun union: + +#if defined(__GNU_LIBRARY__) && !(defined(_SEM_SEMUN_UNDEFINED)) +#else +union semun { + int val; // SETVAL value. + struct semid_ds *buf; // IPC_STAT, IPC_SET buffer. + unsigned short int *array; // Array for GETALL/SETALL + struct seminfo* _buf; // Buffer for IPC_INFO +}; +#endif + + +/*! + This file implements coarse grained VME locking. + If applications use this, the entire VME subsystem will be controlled + by a single lock. +*/ + +static int semid = -1; // This will be the id of the locking semaphore +static int semkey= 0x564d4520; // "VME " :-). + +/*! + This internal function is used to establish the semaphore: + - If the semaphore exists, it's id is just stored in semid. + - If the semaphore does not exist we try to create it O_EXCL + this is an attempt to deal with any timing holes that may + occur when two programs simultaneously attemp to create the semaphore. + - If the O_EXCL creation succeeds (semaphore does not exist), it is + given in initial value of 1 so that a single process can pass the lock + gate. + - If the O_EXCL creation fails, the process backs off for a while and + then does a semget for an existing semaphore again assuming that on the + second try, all initialization has been complete. + + \throw CErrnoException + If an error occured on any of the system calls. + +*/ +static void +AttachSemaphore() +{ + // Retry loop in case anybody makes and then kills it: + + while(1) { + // Try to get the id of an existing semaphore: + + semid = semget(semkey, 0, 0777); // Try to map: + if(semid >= 0) break; // Previously existing!! + if(errno != ENOENT) { + throw + CErrnoException("AttachSemaphore - semget error unexpected"); + } + // Sempahore does not exist. Try to be the only guy to + // create it: + + semid = semget(semkey, 1, 0777 | IPC_CREAT | IPC_EXCL); + if(semid >= 0) { + // We're the creator... initialize the sempahore, and return. + + union semun data; + data.val = 1; + + int istat = semctl(semid, 0, SETVAL, data); // Allow 1 holder + if(istat < 0) { + throw CErrnoException("AttachSemaphore - semctl error unexpected"); + } + + break; + } + if(errno != EEXIST) { + throw + CErrnoException("AttachSemaphore - semget error unexpected"); + } + // The semaphore popped into being between the initial try + // to just attach it and our try to create it. + // The next semget should work, but we want to give + // the creator a chance to initialize the semaphore so + // we don't try to take out a lock on the semaphore before + // it is completely initialized: + + sleep(1); + } + return; +} +/*! + Lock the semaphore. If the semid is -1, the + semaphore is created first. + + \throw CErrnoException + - Really from AttachSemaphore + - From failures in semop. +*/ +void +CVMEInterface::Lock() +{ + // If necessary, get the semaphore id.. + + if (semid == -1) AttachSemaphore(); + assert(semid >= 0); // Otherwise attach.. throws. + + struct sembuf buf; + buf.sem_num = 0; // Only one semaphore. + buf.sem_op = -1; // Want to take the semaphore. + buf.sem_flg = SEM_UNDO; // For process exit. + + while (1) { // In case of signal... + int stat = semop(semid, &buf, 1); + + if(stat == 0) break; + + if(errno != EINTR) { // Bad errno: + throw CErrnoException("CVMEInterface::Lock semop gave bad status"); + } + // On EINTR try again. + } + return; +} +/*! + Unlock the semaphore. It is a crime to unlock the semaphore if it doesn + not yet exist, since that would be unlocking a semaphore that is not yet + locked. + + \throw CErrnoException + If the semop operation produced an error. + \throw string + If the semaphore did not yet exist. +*/ +void +CVMEInterface::Unlock() +{ + if(semid == -1) { + throw string("Attempt to unlock the semaphore before it was created"); + } + struct sembuf buf; + buf.sem_num = 0; + buf.sem_op = 1; + buf.sem_flg= SEM_UNDO; // Undoes the locking undo. + + while(1) { // IN case of signal though not likely. + int stat = semop(semid, &buf, 1); + if(stat == 0) break; // Got the job done!! + if(errno != EINTR) { + throw CErrnoException("CVMEInterface::Unlock semop gave bad status"); + } + // on EINTR try again. + } + return; +} Added: trunk/nextgen/sbs/nsclapi/Makefile.am =================================================================== --- trunk/nextgen/sbs/nsclapi/Makefile.am (rev 0) +++ trunk/nextgen/sbs/nsclapi/Makefile.am 2008-10-07 14:29:59 UTC (rev 1998) @@ -0,0 +1,21 @@ +lib_LTLIBRARIES = libSBSVmeAPI.la +libSBSVmeAPI_la_SOURCES = SBSBIT3API.cpp Locking.cpp +include_HEADERS = CVMEInterface.h SBSBit3API.h + +# Locking.cpp + + +libSBSVmeAPI_la_LDFLAGS = -version-info 1:0:0 \ + -Wl"-rpath=$(libdir)" + +libSBSVmeAPI_la_LIBADD = @top_srcdir@/base/exception/libException.la \ + @top_srcdir@/sbs/driver/src/libbtp.la + + +INCLUDES = -I@top_srcdir@/base/headers -I@top_srcdir@/base/exception \ + -I@top_srcdir@/sbs/driver/include + +LDFLAGS = -lpthread + + + Property changes on: trunk/nextgen/sbs/nsclapi/Makefile.am ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/nsclapi/SBSBIT3API.cpp =================================================================== --- trunk/nextgen/sbs/nsclapi/SBSBIT3API.cpp (rev 0) +++ trunk/nextgen/sbs/nsclapi/SBSBIT3API.cpp 2008-10-07 14:29:59 UTC (rev 1998) @@ -0,0 +1,1013 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + + +static const char* Copyright= "(C) Copyright Michigan State University 2002, All rights reserved"; + + +#include <config.h> + +#include "CVMEInterface.h" +#include "SBSBit3API.h" // Device specific api. + +#ifndef BT1003 +#define BT1003 +#endif +extern "C" { +#include <btapi.h> +#include <btngpci.h> +} +#include <string> +#include <string.h> + + +using namespace std; + + +const char* CVMEInterface::m_szDriverName="SBSBIT3"; + +/* + Local data structures. + */ + +// Translating address spaces to logical device specifiers: + +struct DeviceEntry { + CVMEInterface::AddressMode s_eModeId; + bt_dev_t s_eLogicalDevice; +}; + +static const DeviceEntry kaDeviceTable[] = { + {CVMEInterface::A16, BT_DEV_IO }, + {CVMEInterface::A24, BT_DEV_A24 }, + {CVMEInterface::A32, BT_DEV_A32 }, + {CVMEInterface::GEO, BT_DEV_GEO }, + {CVMEInterface::MCST, BT_DEV_MCCTL }, + {CVMEInterface::CBLT, BT_DEV_CBLT } +}; + +static const unsigned int knDeviceTableSize = sizeof(kaDeviceTable)/ + sizeof(DeviceEntry); + +static const unsigned int BTERRORLENGTH(100); // Length of an error string. + +// Local private 'static' functions. + +/*! + Translate an address space selector into a logical device + selector. + +Parameters: + +\param eAmode CVMEInterface::AddressMode [in] Addressing mode to + translate. + +Returns: +\return bt_dev_t Logical device specifier for bit 3. + +Exceptions: +\throw string describing why the lookup failed. + +*/ + +static bt_dev_t +AddressModeToDevice(CVMEInterface::AddressMode eMode) +{ + for(int i = 0; i < knDeviceTableSize; i++) { + if(kaDeviceTable[i].s_eModeId == eMode) { + return kaDeviceTable[i].s_eLogicalDevice; + } + } + throw string("[SBSBit3]AddressModeToDevice-no such address mode"); +} + +/*! + If necessary throw an error from the return code generated by a + Bt interface library function. + \param pDevice [bt_desc_t* in]: Pointer to device unit open on b3. + \param nReturnCode [bt_error_t in]: A return code from the bit 3 interface + library. + \param pContextString [const char* in]: A string describing the context + of the potential error condition. + + \return - does if nReturnCode == BT_SUCCESS, otherwise, formats and + throws a string exception. + \throw string if nReturnCode != BT_SUCCESS. + +*/ +static void +CheckError(bt_desc_t* pDevice, + bt_error_t nReturnCode, + const char* pContextString) +{ + if(nReturnCode != BT_SUCCESS) { + int nContextLen = strlen(pContextString); + char ErrorMessage[nContextLen + BTERRORLENGTH]; + bt_strerror(*pDevice, nReturnCode, pContextString, + ErrorMessage, sizeof(ErrorMessage)); + throw string(ErrorMessage); + } +} + +/*! + Open the a device and returns a handle to it: + - The Address space selector is translated to a device name. + - a bt_desc_t is allocated. + - bt_open is called to fill in the handle. + - A Pointer to the handle is returned to the user. + +Parameters: +\param eMode CVMEInterface::AddressMode [in] Specifies the + address mode desired for the device. +\param nCrate Number of the crate to open. This can be a value from 0-15. + +Throws: + \throw string - Text string describing the error. + +\note The assumption is that both read and write access are desired. +\note We assume there's only one VME crate attached to the system. +*/ +void* +CVMEInterface::Open(AddressMode eMode, + unsigned short nCrate) +{ + bt_desc_t* pDevice = new bt_desc_t; + + // Validate the crate number. + + if(nCrate > BT_MAX_UNITS) { + throw string("CVMEInterface::[SBS]Open - vme crate number > BT_MAX_UNITS"); + } + + try { + char Device[BT_MAX_DEV_NAME]; + + bt_dev_t LogicalDevice = AddressModeToDevice(eMode); + if(!bt_gen_name(nCrate, LogicalDevice, Device, sizeof(Device))) { + throw + string("CVMEInterface[SBSBit3]::Open - bt_gen_name failed"); + } + + bt_error_t err = bt_open(pDevice, Device, BT_RDWR); + CheckError(pDevice, err, "CVMEInterface[SBSBit3]::Open - Open failed "); + + // Set the appropriate byte swap mode for block transfers. + + CSBSBit3VmeInterface::SetSwapMode(pDevice, BT_SWAP_NONE); + + } + catch(...) { + delete pDevice; + throw; + } + + return (void*)pDevice; +} +/*! + Closes a previously opened device. Note that the device handle + is a pointer to a bt_desc_t that will be deleted. + +Parameters: + +\param pDevice - void* [modified] Pointer to the device dependent + handle. In our case that represents a bt_desc_t. + +Exceptions: +\throw string - Describing any errors. +*/ +void +CVMEInterface::Close(void* pDeviceHandle) +{ + bt_desc_t *p = (bt_desc_t*)pDeviceHandle; + + bt_error_t err = bt_close(*p); + + CheckError(p, err, "CVMEInterface[SBSBit3]::Close - bt_close failed:"); + delete p; // It's not safe to delete on throw. + + +} + +/*! + Map a region of VME address space into process virtual address + space. Once mapped, accesses to the process adress space will + be modifying or reading the VME addreess space without any driver + intervention. + +Parameters: +\param pDeviceHandle - void* [in] Device dependent handle open on + the VME interface device (bt_desc_t*). + +\param lOffset - unsigned long [in] - base address of the first + VME location to map. + +\param lBytes - unsigned long [in] - Number of bytes of VME space + desired. + +Returns: +\return void* Pointer to the address space mapped. + +\note Additional space may be mapped before and after the requested + range in order to acocmodate the memory mapping granularity + of the underlying operating system. This additional mapping + is transparent to the user software. + +Exceptions: +\throw string - Explains any errors. + +*/ +void* +CVMEInterface::Map(void* pDeviceHandle, + unsigned long nBase, + unsigned long nBytes) +{ + bt_desc_t* p = (bt_desc_t*)pDeviceHandle; + void* pSpace; + + bt_error_t err = bt_mmap(*p, + &pSpace, nBase, nBytes, + BT_RDWR, BT_SWAP_NONE); + CheckError(p, err, "CVMEInterface[SBSBit3]::Map - bt_mmap failed : "); + return pSpace; +} +/*! + Unmap an existing address map from process virtual addres space to + VME address space. Once the unmap is done, accesses to that + virtual address window will fail with a SEGFLT or BUSERR + (OS dependent). + +Parameters: +\param pDeviceHandle - void* [in] Device handle pointer. In our + case, this points to a bt_desc_t. + +\param pBase - void* [i] Points to the base of the map. + lBytes pointed to by this pointer will become + inaccessible to the calling process as a result + of this call. +\param lBytes - unsigned long [in] Number of bytes in the region. + +Exceptions: +\throw - string - describing errors from bt_unmap. + +*/ +void +CVMEInterface::Unmap(void* pDeviceHandle, + void* pBase, + unsigned long lBytes) +{ + bt_desc_t* p = (bt_desc_t*)pDeviceHandle; + + bt_error_t err = bt_unmmap(*p, pBase, lBytes); + + CheckError(p, err, "CVMEInterface[SBSBit3]::Unmap - bt_mmap failed : "); + +} +/*! + Performs a block transfer of data from the VME bus to a local + buffer. This function does not require a map to operate. + +Parameters: +\param pDeviceHandle - void* [in] Pointer to the device handle + open on a PCI<-->VME bus interface. In our case + the handle is a bt_desc_t* + +\param nOffset - unsigned long [in] Address in VME space from which + the transfer will start. + +\param pBuffer - void* [out] Pointer to the buffer into which data + will be transferred. + +\param nBytes - unsigned long [in] Number of bytes to transfer. + +Returns: +\return int - Number of bytes transferred. + +Exceptions: +\throw string - Descriptive error text if there was a problem. +*/ + +int +CVMEInterface::Read(void* pDeviceHandle, + unsigned long nOffset, + void* pBuffer, + unsigned long nBytes) +{ + bt_desc_t* p = (bt_desc_t*)pDeviceHandle; + size_t nTransferred; + + bt_error_t err = bt_read(*p, pBuffer, nOffset, nBytes, + &nTransferred); + + CheckError(p, err, "CVMEInterface[SBSBit3]::Read - bt_read failed : "); + return nTransferred; + + +} +/*! + Write a block of data from a user buffer to addresses on the VME +bus. + +Parameters: +\param pDeviceHandle void* [in] Pointer to the device specific + handle. In our case this is realy a bt_desc_t* + +\param lOffset unsigned long [in] Base address in the VME for the + transfer. + +\param pBuffer void * [in] Pointer to the buffer from which + the data comes. + +\param lBytes unsigned long [in] Number of bytes to write. + +Returns: +\return int - Number of bytes transferred. + +Exceptions: +\throw string - Descriptive error text if there was a problem. +*/ +int +CVMEInterface::Write(void* pDeviceHandle, + unsigned long nOffset, + void* pBuffer, + unsigned long nBytes) +{ + bt_desc_t* p = (bt_desc_t*)pDeviceHandle; + size_t nTransferred; + + bt_error_t err = bt_write(*p, pBuffer, nOffset, nBytes, + &nTransferred); + CheckError(p, err, "CVMEInterface[SBSBit3]::Write - bt_read failed : "); + + return nTransferred; + + +} +// The functions following this comment are all SBSBit3 API specific. +// The header for them is in SBSBit3API.h Users call these functions at +// their peril as they bind them to a specific piece of hardware. +// + +/*! + Set the dma transfer mode to use VME block transfer. VME Block transfer + allows the device to do away with additional address cycles after a single + initial address cycle establishes the transfer base address, and the DS's + establish the transfer width. Subsequent data transfers assume an + appropriate increment in address.. This allows data transfer to be + significantly faster for blocks of contiguous data. + + Older slave interfaces may not implement DMA transfer however. + + \param pHandle (void* [in]): pointer to the device handle gotten via + CVMEInterface::Open. + \param enable (bool [in]): true if block transfer mode is desired, + false otherwise. + +*/ +void +CSBSBit3VmeInterface::SetDMABlockTransfer(void* pHandle, bool enable) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + + bt_error_t err = bt_set_info(*p, BT_INFO_BLOCK, (bt_devdata_t)enable); + CheckError(p, err, "CSBSBit3VmeInterface::SetDMABlockTransfer failed"); +} +/*! + Set the DMA transfer mode to 'pause'. In pause, mode, the device + re-arbitrates the bus more often than required by the block mode + transfer specification. While this allows other bus masters a better + bus access latency in the presence of DMA transfers, it also reduces + the DMA throughput. + + \param pDevice (void* [in]): Pointer to device handle returned from + VMEInterface::Open(). + \param enable (bool [in]): State desired: + - true - turns on pause mode. + - false - turns off pause mode. +*/ +void +CSBSBit3VmeInterface::SetDMAPauseMode(void* pHandle, bool enable) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_PAUSE, (bt_devdata_t)enable); + CheckError(p, err, "CSBSBit3VmeInterface::SetDMAPauseMode failed"); +} +/*! + Set the maximum transfer width of the interface. Valid values of the + bt_width_t parameter can be any of: + - BT_WIDTH_D8 8 bit maximum transfer width + - BT_WIDTH_D16 16 bit maximum transfer width + - BT_WIDTH_D32 32 bit maximum transfer width + - BT_WIDTH_D64 64 bit maximum transfer width + - BT_WIDTH_ANY Let the driver choose the best setting. + + By default, after power up, the driver is set at BT_WIDTH_D32 since + most P's don't support D6 transfers (according to the Bit3 manual, while this + has changed with PCI-64, the SBS/Bit3 -620 is a 32 bit wide PCI module. + + \param pHandle (void* [in]): Handle open on the device, gotten via + a successful call to CVMEInterface::Open + \param width (bt_data_width_t [in]): Requested width. See above for legal + values. +*/ +void +CSBSBit3VmeInterface::SetMaxTransferWidth(void* pHandle, bt_width_t eWidth) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_DATAWIDTH, eWidth); + CheckError(p, err, "CSBSBit3VmeInterface::SetMaxTransferWidth failed"); +} +/*! + Set the DMA address modifier code. It is important that this be selected + from one of the block transfer modes if DMA block mode is on else DMA + with slaves may not work + correctly. The default DMA transfer mode is supervisory d32 block transfer. + + \param pHandle (void* [in]): Handle returned from CVMEInterface::Open. + \param nModifier (int [in]): Address modifier. Symbolic definitions + of these are as follows: + - BT_AMOD_A32_SB (0x0F) A32 Extended Supervisory Block transfer. + - BT_AMOD_A32_SP (0x0E) A32 Extended Supervisory Program. + - BT_AMOD_A32_SD (0x0D) A32 Extended Supervisory Data Access. + - BT_AMOD_A32_NB (0x0B) A32 Extended Non-Privileged Block transfer. + - BT_AMOD_A32_NP (0x0A) A32 Extended Non-Privileged Program. + - BT_AMOD_A32_ND (0x09) A32 Extended Non-Privileged Data. + - BT_AMOD_A32_SMBLT (0x0C) A32 Multiplexed Block Transfer (D64) priv. + - BT_AMOD_A32_NMBLT (0x08) A32 Multiplexed Block Transfer (D64) nonpriv + - BT_AMOD_A32 see BT_AMOD_A32_SD + - BT_AMOD_A32_D64 see BT_AMOD_A32_SMBLT + - BT_AMOD_A24_SB (0x3F) A24 Standard Supervisory Block + - BT_AMOD_A24_SP (0x3E) A24 Standard Supervisory Program + - BT_AMOD_A24_SD (0x3D) A24 Standard Supervisory Data Access + - BT_AMOD_A24_NB (0x3B) A24 Standard Non-Privileged Block + - BT_AMOD_A24_NP (0x3A) A24 Standard Non-Privileged Program + - BT_AMOD_A24_ND (0x39) A24 Standard Non-Privileged Data + - BT_AMOD_A24_SMBLT (0x3C) A24 Multiplexed Block Transfer (D64) privileged + - BT_AMOD_A24_NMBLT (0x38) A24 Multiplexed Block Transfer (D64) nonpriv. + - BT_AMOD_A24 see BT_AMOD_A24_SD + - BT_AMOD_A24_D64 see BT_AMOD_A24_SMBLT + - BT_AMOD_A16_SD (0x2D) A16 Short Supervisory Data Access + - BT_AMOD_A16_ND (0x29) A16 Short Non-Privileged Data Access + - BT_AMOD_A16 see BT_AMOD_A16_SD + - BT_AMOD_GEO (0x2F) Geographical addressing + - BT_AMOD_MCCTL (0X09) Multicast control register writes (CAEN ADCS). + - BT_AMOD_CBLT (0x0B) Chained block transfer (CAEN adcs). + +*/ +void +CSBSBit3VmeInterface::SetDMAAddressModifier(void* pHandle, int Modifier) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_DMA_AMOD, Modifier); + CheckError(p, err, "CSBSBit3VmeInterface::SetDMAAddressModifier failed"); +} +/*! + SetMMAPAddress modifier sets the address modifier used for the mmap call. + note that this is somewhat dangerous. The devices themselves have a + default address modifier. Use that whenever possible, as this setting + does not revert to default on close !!!! + + \param pHandle (void* [in]): Device handle returned from CVMEInterface::Open + \param Modifier (int [in]): Requested address modifier. Legal values are: + - BT_AMOD_A32_SB (0x0F) A32 Extended Supervisory Block transfer. + - BT_AMOD_A32_SP (0x0E) A32 Extended Supervisory Program. + - BT_AMOD_A32_SD (0x0D) A32 Extended Supervisory Data Access. + - BT_AMOD_A32_NB (0x0B) A32 Extended Non-Privileged Block transfer. + - BT_AMOD_A32_NP (0x0A) A32 Extended Non-Privileged Program. + - BT_AMOD_A32_ND (0x09) A32 Extended Non-Privileged Data. + - BT_AMOD_A32_SMBLT (0x0C) A32 Multiplexed Block Transfer (D64) priv. + - BT_AMOD_A32_NMBLT (0x08) A32 Multiplexed Block Transfer (D64) nonpriv + - BT_AMOD_A32 see BT_AMOD_A32_SD + - BT_AMOD_A32_D64 see BT_AMOD_A32_SMBLT + - BT_AMOD_A24_SB (0x3F) A24 Standard Supervisory Block + - BT_AMOD_A24_SP (0x3E) A24 Standard Supervisory Program + - BT_AMOD_A24_SD (0x3D) A24 Standard Supervisory Data Access + - BT_AMOD_A24_NB (0x3B) A24 Standard Non-Privileged Block + - BT_AMOD_A24_NP (0x3A) A24 Standard Non-Privileged Program + - BT_AMOD_A24_ND (0x39) A24 Standard Non-Privileged Data + - BT_AMOD_A24_SMBLT (0x3C) A24 Multiplexed Block Transfer (D64) privileged + - BT_AMOD_A24_NMBLT (0x38) A24 Multiplexed Block Transfer (D64) nonpriv. + - BT_AMOD_A24 see BT_AMOD_A24_SD + - BT_AMOD_A24_D64 see BT_AMOD_A24_SMBLT + - BT_AMOD_A16_SD (0x2D) A16 Short Supervisory Data Access + - BT_AMOD_A16_ND (0x29) A16 Short Non-Privileged Data Access + - BT_AMOD_A16 see BT_AMOD_A16_SD + - BT_AMOD_GEO (0x2F) Geographical addressing + - BT_AMOD_MCCTL (0X09) Multicast control register writes (CAEN ADCS). + - BT_AMOD_CBLT (0x0B) Chained block transfer (CAEN adcs). +*/ +void +CSBSBit3VmeInterface::SetMMAPAddressModifier(void* pHandle, int Modifier) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_MMAP_AMOD, Modifier); + CheckError(p, err, "CSBSBit3VmeInterface::SetMMAPAddressModifier failed"); +} +/*! + Set the data swap mode. The SBS/Bit3 interface has byte swapping hardware + that can be set as needed to acommodate differences in byte order between + the host (linux system ), and slave interface (VME board). + \param pHandle (void* [in]): Handle received from a successful call to + CVMEInterface::Open. + \param SwapMode (bt_swap_t [in]) Swap mode, can be one of the follwoing: + - BT_SWAP_NONE No swapping + - BT_SWAP_BSNBD Byte swap, non byte data + - BT_SWAP_WS Word swap + - BT_SWAP_WS_BSNBD Word swap and byte swap non btye data + - BT_SWAP_BSBD Byte swap btye data + - BT_SWAP_BSBD_BSNBD Btye swap byte data and byte swap non byte data + - BT_SWAP_BSBD_WS Byte swap byte data and word swap + - BT_SWAP_BSBD_WS_BSNBD All possible swapping + - BT_SWAP_DEFAULT Driver default swapping + + BT_SWAP_DEFAULT is set to transparently swap bytes in VME byte order (big + endian) to PC byte ordering (little endian). + Note that this setting only affects DMA transfers. At present, you have no + control over the swap mode for memory mapping, and it is BT_SWAP_DEFAULT. + +*/ +void +CSBSBit3VmeInterface::SetSwapMode(void* pHandle, bt_swap_t SwapMode) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_SWAP, SwapMode); + CheckError(p, err, "CSBSBit3VmeInterface::SetSwapMode failed"); +} +/*! + Sets the dma threshold. The dma theshold defines the minimum length + transfer in CVMEInterface::Read or CVMEInterface::Write that will turn on + the bit3's dma engine. If a Read/Write is issued for a transfer smaller than + the threshold, the driver will perform PIO to satisfy it, otherwise it will + perform the transfer via DMA. + + This is a trade off between the high speed transfer + of the dma engine against the longer setup time requirement compared to + PIO transfers. If a Read/Write is issued for a transfer smaller than + + \param pHandle (void* [in]): Device handle returned from CVMEInterface::Open + \param nTransfers (int [in]): The new threshold. + +*/ +void +CSBSBit3VmeInterface::SetDMAThreshold(void* pHandle, int nTransfers) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_DMA_THRESHOLD, nTransfers); + CheckError(p, err, "CSBSBit3VmeInterface::SetDMAThreshold failed"); +} +/*! + Sets the DMA polling ceiling. This determines how many transfers are + required before the driver decides to use interrupts as opposed to polling + to determine that a DMA transfer has completed. + + This value represents a trade-off between operation completion latency + (better for polling), and overall linux system responsiveness (better + for interrupts). Since any polling will be done in the device driver, + the linux system will be almost completely unresponsive for the duration + of a DMA that polls for completion. + + \param pHandle (void* [in]): Handle on the device from CVMEInterface::Open. + \param nTransfers (int [in]): The new ceiling value. +*/ +void +CSBSBit3VmeInterface::SetDMAPollCeiling(void* pHandle, int nTransfers) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_DMA_POLL_CEILING, nTransfers); + CheckError(p, err, "CSBSBit3VmeInterface::SetDMAPollCeiling failed"); +} +/*! + Sets the trace mask. The trace mask determines how much inforation the + driver logs to the /var/log files. The less information logged, the better + the performance, however the more information logged, the easier + it is to troubleshoot problems. + \param pHandle (void * [in]): The handle returned from CVMEInterface::Open + \param nMask A bitwise or of any of the following bits: + - BT_TRC_ERROR Fatal system errors, shouldn't happen + - BT_TRC_WARN driver errors that may happen due to external conditions + - BT_TRC_INFO Messages for errors returned to the user + - BT_TRC_CFG driver configuration and initialization + - BT_TRC_RD_WR generic read/write (outside of DMA & PIO) + - BT_TRC_MMAP memory mapping and related code/ + - BT_TRC_BIND bt_bind() and related code + - BT_TRC_CTRL All ioctl() functions + - BT_TRC_OPEN Driver open and close + - BT_TRC_ISR Interrupt Service Routine + - BT_TRC_IRQ_DISP Interrupt Request Processing/Dispatch + - BT_TRC_ICBR user ICBR and the vector returned by applicable kernel + interrupt handlers. + - BT_TRC_ISR_ERR ISR errors only + - BT_TRC_DMA DMA, each transfer + - BT_TRC_PIO PIO, each transfer + - BT_TRC_FUNC function entry and exit + - BT_TRC_ALLOC Allocation/release of resources + - BT_TRC_LOCK all locks (user & driver internal) + - BT_TRC_MAPREG details of each map register load + - BT_TRC_RAWIO Raw I/O register access + - BT_TRC_KLIB Misc. shared kernel routines + - BT_TRC_KDDI All 3rd party driver rouitnes KDDI + - BT_TRC_LIO Low level I/O register rd/wr + - BT_TRC_PROFILE enable H/W timing marks for profiling + - BT_TRC_DETAIL Detailed trace of enabled function + - BT_TRC_HW_DEBUG enable HW trace messages instead of console + - BT_TRC_ERROR Fatal system errors, shouldn't happen + - BT_TRC_WARN driver errors that may happen due to external conditions + - BT_TRC_INFO Messages for errors returned to the user + - BT_TRC_CFG driver configuration and initialization + - BT_TRC_RD_WR generic read/write (outside of DMA & PIO) + - BT_TRC_MMAP memory mapping and related code/ + - BT_TRC_BIND bt_bind() and related code + - BT_TRC_CTRL All ioctl() functions + - BT_TRC_OPEN Driver open and close + - BT_TRC_ISR Interrupt Service Routine + - BT_TRC_IRQ_DISP Interrupt Request Processing/Dispatch + - BT_TRC_ICBR user ICBR and the vector returned by applicable kernel + interrupt handlers. + - BT_TRC_ISR_ERR ISR errors only + - BT_TRC_DMA DMA, each transfer + - BT_TRC_PIO PIO, each transfer + - BT_TRC_FUNC function entry and exit + - BT_TRC_ALLOC Allocation/release of resources + - BT_TRC_LOCK all locks (user & driver internal) + - BT_TRC_MAPREG details of each map register load + - BT_TRC_RAWIO Raw I/O register access + - BT_TRC_KLIB Misc. shared kernel routines + - BT_TRC_KDDI All 3rd party driver rouitnes KDDI + - BT_TRC_LIO Low level I/O register rd/wr + - BT_TRC_PROFILE enable H/W timing marks for profiling + - BT_TRC_DETAIL Detailed trace of enabled function + - BT_TRC_HW_DEBUG enable HW trace messages instead of console + + Note that the default, power up state is BT_TRC_ERROR | BT_TRC_WARN. +*/ +void +CSBSBit3VmeInterface::SetTraceMask(void* pHandle, int nMask) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_set_info(*p, BT_INFO_TRACE, nMask); + CheckError(p, err, "CSBSBit3VmeInterface::SetTraceMask failed"); +} + +// Information retrieval functions: +// Retrieve read-only parameters of the driver. +// +/*! + Retrieve the SBS part number of the PCI component of the bus interface. + + \param pHandle (void* [in]): The handle returned from CVMEInterface::Open. + \return part number as an integer. +*/ +int +CSBSBit3VmeInterface::GetLocalCardPartNumber(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_LOC_PN, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetLocalPartNumber failed"); + return Result; +} +/*! + Retrieve the SBS part number of the VME component of the bus bridge. + \param pHandle (void* [in]): The handle returned from CVMEInterface::Open. + \return part number as an integer. +*/ +int +CSBSBit3VmeInterface::GetRemoteCardPartNumber(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_REM_PN, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetRemotePartNumber failed"); + return Result; +} +/*! + Returns the number of bytes of local memory on any daughter board in + the VME interface. Presumably this will be 0 if no memory daughter board + is installed. + \param pHandle (void* [in]): The handle returned from CVMEInterface::Open. + \return memory size as unsigned int. +*/ +unsigned int +CSBSBit3VmeInterface::GetLocalMemorySize(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_LM_SIZE, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetLocalMemorySize failed"); + return Result; +} +/*! + + Returns a bool indicating whether or not the DMA block mode transfer + is enabled. For more information about this see, + CSBSBit3VmeInterface::SetDMABlockTransfer. + + \param pHandle (void* [in]): handle returned from CVMEInterface::Open. + \return true if dma on this unit will be done in block transfer mode. + +*/ +bool +CSBSBit3VmeInterface::IsDMABlockTransfer(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_BLOCK, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::IsDMABlockTransfer failed"); + return Result; +} +/*! + Returns a bool that indicates whether or not DMA block transfers are done + in pause mode. For more information about pause mode, see: + CSBSBit3VmeInterface::SetDMAPauseMode. + \param pHandle (void* [in]) Handle returned from CVMEInterface::Open + \return true if dma will be done in pause mode. +*/ +bool +CSBSBit3VmeInterface::IsDMAPauseMode(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_PAUSE, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::IsDMAPauseMode failed"); + return Result; +} +/*! + Returns the Maximum transfer width. + \param pHandle (void* [in]) Device handle gotten from CVMEInterface::Open. + \return The return value will be one of: + - BT_WIDTH_D8 8 bits. + - BT_WIDTH_D16 16 bits. + - BT_WIDTH_D32 32 bits. + - BT_WIDTH_D64 64 bits. +*/ +bt_width_t +CSBSBit3VmeInterface::GetMaxTransferWidth(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_DATAWIDTH, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetMaxTransferWidth failed"); + return Result; +} +/*! + Return the current dma address modifier. + \param pHandle (void* [in]) Device handle gotten from CVMEInterface::Open. + \return The return value will be one of + - BT_AMOD_A32_SB (0x0F) A32 Extended Supervisory Block transfer. + - BT_AMOD_A32_SP (0x0E) A32 Extended Supervisory Program. + - BT_AMOD_A32_SD (0x0D) A32 Extended Supervisory Data Access. + - BT_AMOD_A32_NB (0x0B) A32 Extended Non-Privileged Block transfer. + - BT_AMOD_A32_NP (0x0A) A32 Extended Non-Privileged Program. + - BT_AMOD_A32_ND (0x09) A32 Extended Non-Privileged Data. + - BT_AMOD_A32_SMBLT (0x0C) A32 Multiplexed Block Transfer (D64) priv. + - BT_AMOD_A32_NMBLT (0x08) A32 Multiplexed Block Transfer (D64) nonpriv + - BT_AMOD_A32 see BT_AMOD_A32_SD + - BT_AMOD_A32_D64 see BT_AMOD_A32_SMBLT + - BT_AMOD_A24_SB (0x3F) A24 Standard Supervisory Block + - BT_AMOD_A24_SP (0x3E) A24 Standard Supervisory Program + - BT_AMOD_A24_SD (0x3D) A24 Standard Supervisory Data Access + - BT_AMOD_A24_NB (0x3B) A24 Standard Non-Privileged Block + - BT_AMOD_A24_NP (0x3A) A24 Standard Non-Privileged Program + - BT_AMOD_A24_ND (0x39) A24 Standard Non-Privileged Data + - BT_AMOD_A24_SMBLT (0x3C) A24 Multiplexed Block Transfer (D64) privileged + - BT_AMOD_A24_NMBLT (0x38) A24 Multiplexed Block Transfer (D64) nonpriv. + - BT_AMOD_A24 see BT_AMOD_A24_SD + - BT_AMOD_A24_D64 see BT_AMOD_A24_SMBLT + - BT_AMOD_A16_SD (0x2D) A16 Short Supervisory Data Access + - BT_AMOD_A16_ND (0x29) A16 Short Non-Privileged Data Access + - BT_AMOD_A16 see BT_AMOD_A16_SD + - BT_AMOD_GEO (0x2F) Geographical addressing + - BT_AMOD_MCCTL (0X09) Multicast control register writes (CAEN ADCS). + - BT_AMOD_CBLT (0x0B) Chained block transfer (CAEN adcs). +*/ +int +CSBSBit3VmeInterface::GetDMAAddressModifier(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_DMA_AMOD, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetDMAAddressModifier failed"); + return Result; +} +/*! + Get the address modifier that will be applied to the mmap function. + \param pHandle (void* [in]) Device handle gotten from CVMEInterface::Open. + \return The return value will be one of + - BT_AMOD_A32_SB (0x0F) A32 Extended Supervisory Block transfer. + - BT_AMOD_A32_SP (0x0E) A32 Extended Supervisory Program. + - BT_AMOD_A32_SD (0x0D) A32 Extended Supervisory Data Access. + - BT_AMOD_A32_NB (0x0B) A32 Extended Non-Privileged Block transfer. + - BT_AMOD_A32_NP (0x0A) A32 Extended Non-Privileged Program. + - BT_AMOD_A32_ND (0x09) A32 Extended Non-Privileged Data. + - BT_AMOD_A32_SMBLT (0x0C) A32 Multiplexed Block Transfer (D64) priv. + - BT_AMOD_A32_NMBLT (0x08) A32 Multiplexed Block Transfer (D64) nonpriv + - BT_AMOD_A32 see BT_AMOD_A32_SD + - BT_AMOD_A32_D64 see BT_AMOD_A32_SMBLT + - BT_AMOD_A24_SB (0x3F) A24 Standard Supervisory Block + - BT_AMOD_A24_SP (0x3E) A24 Standard Supervisory Program + - BT_AMOD_A24_SD (0x3D) A24 Standard Supervisory Data Access + - BT_AMOD_A24_NB (0x3B) A24 Standard Non-Privileged Block + - BT_AMOD_A24_NP (0x3A) A24 Standard Non-Privileged Program + - BT_AMOD_A24_ND (0x39) A24 Standard Non-Privileged Data + - BT_AMOD_A24_SMBLT (0x3C) A24 Multiplexed Block Transfer (D64) privileged + - BT_AMOD_A24_NMBLT (0x38) A24 Multiplexed Block Transfer (D64) nonpriv. + - BT_AMOD_A24 see BT_AMOD_A24_SD + - BT_AMOD_A24_D64 see BT_AMOD_A24_SMBLT + - BT_AMOD_A16_SD (0x2D) A16 Short Supervisory Data Access + - BT_AMOD_A16_ND (0x29) A16 Short Non-Privileged Data Access + - BT_AMOD_A16 see BT_AMOD_A16_SD + - BT_AMOD_GEO (0x2F) Geographical addressing + - BT_AMOD_MCCTL (0X09) Multicast control register writes (CAEN ADCS). + - BT_AMOD_CBLT (0x0B) Chained block transfer (CAEN adcs). + +*/ +int +CSBSBit3VmeInterface::GetMMAPAddressModifier(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_PIO_AMOD, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetMMAPAddressModifier failed"); + return Result; +} +/*! + The SBS/Bit3 interface has hardware support for byte swapping. Ordinarily, + the interface is set up to transparently swap between the VME standard + byte ordering (big endian), and PC (little endian) byte ordering. This + function returns the current byte swapping selection. + \param pHandle (void* [in]): Handle received from a successful call to + CVMEInterface::Open. + \return SwapMode (bt_swap_t [in]) Swap mode, can be one of the follwoing: + - BT_SWAP_NONE No swapping + - BT_SWAP_BSNBD Byte swap, non byte data + - BT_SWAP_WS Word swap + - BT_SWAP_WS_BSNBD Word swap and byte swap non btye data + - BT_SWAP_BSBD Byte swap btye data + - BT_SWAP_BSBD_BSNBD Btye swap byte data and byte swap non byte data + - BT_SWAP_BSBD_WS Byte swap byte data and word swap + - BT_SWAP_BSBD_WS_BSNBD All possible swapping + - BT_SWAP_DEFAULT Driver default swapping + + BT_SWAP_DEFAULT is set to transparently swap bytes in VME byte order (big + endian) to PC byte ordering (little endian). + Note that this setting only affects DMA transfers. At present, you have no + control over the swap mode for memory mapping, and it is BT_SWAP_DEFAULT. + +*/ +int +CSBSBit3VmeInterface::GetSwapMode(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_SWAP, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetSwapMode failed"); + return Result; +} +/*! + Return the current dma threshold. CVMEInterface::Read or + CVMEInterface::Write calls that cause more than this threshold number of + bus transfers will engage the DMA engine on the SBS/Bit3 interface. Fewer + transactions will result in a programmed I/O transfer in the driver. + + Control over this setting allows control over the trade-off between the + higher transfer rates of the DMA engine vs. programmed contrrol against + the higher overhead required to setup a DMA transfer. + + \param pHandle (void* [in]): Handle returned from CVMEInterface::Open + \return The threshold value. +*/ +int +CSBSBit3VmeInterface::GetDMAThreshold(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_DMA_THRESHOLD, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetDMAThreshold failed"); + return Result; +} +/*! + Return the DMA Poll ceiling. This value determines the number of + transfers performed by a CVMEInterface::Read or CVMEInterface::Write + operation before using interrupts to synchronize completion. This + value represents a trade-off between the improved latency of polling for + completion and the worsened system response of doing so. + + \param pHandle (void* [in]): Handle returned from CVMEInterface::Open + \return The threshold value. +*/ +int +CSBSBit3VmeInterface::GetDMAPollCeiling(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_DMA_POLL_CEILING, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetDMAPollCeiling failed"); + return Result; +} +/*! + Gets the current debugging trace mask for the device driver. + The driver is extensively instrumented with debugging trace code. + The amount of information traced to the system log files is controled + by a trace mask. This function returns the current value of that mask. + Bits in this mask represent a trade off between the extent of debug + support and the driver overhead required to provide it. + \param pHandle (void* [in]): Handle returned from CVMEInterface::Open + \return The value of the trace mask. This is a bit mask make up of the + logical or of the following bits: + - BT_TRC_ERROR Fatal system errors, shouldn't happen + - BT_TRC_WARN driver errors that may happen due to external conditions + - BT_TRC_INFO Messages for errors returned to the user + - BT_TRC_CFG driver configuration and initialization + - BT_TRC_RD_WR generic read/write (outside of DMA & PIO) + - BT_TRC_MMAP memory mapping and related code/ + - BT_TRC_BIND bt_bind() and related code + - BT_TRC_CTRL All ioctl() functions + - BT_TRC_OPEN Driver open and close + - BT_TRC_ISR Interrupt Service Routine + - BT_TRC_IRQ_DISP Interrupt Request Processing/Dispatch + - BT_TRC_ICBR user ICBR and the vector returned by applicable kernel + interrupt handlers. + - BT_TRC_ISR_ERR ISR errors only + - BT_TRC_DMA DMA, each transfer + - BT_TRC_PIO PIO, each transfer + - BT_TRC_FUNC function entry and exit + - BT_TRC_ALLOC Allocation/release of resources + - BT_TRC_LOCK all locks (user & driver internal) + - BT_TRC_MAPREG details of each map register load + - BT_TRC_RAWIO Raw I/O register access + - BT_TRC_KLIB Misc. shared kernel routines + - BT_TRC_KDDI All 3rd party driver rouitnes KDDI + - BT_TRC_LIO Low level I/O register rd/wr + - BT_TRC_PROFILE enable H/W timing marks for profiling + - BT_TRC_DETAIL Detailed trace of enabled function + - BT_TRC_HW_DEBUG enable HW trace messages instead of console +*/ +int +CSBSBit3VmeInterface::GetTraceMask(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_devdata_t Result; + bt_error_t err = bt_get_info(*p, BT_INFO_TRACE, &Result); + CheckError(p, err, "CSBSBit3VmeInterface::GetTraceMask Failed"); + return Result; +} +/*! + + Does a sysreset on the VME bus. This can be done to return devices + on the VME bus to a known state. Note that this function has \em very + global effect and should be used with caution. + \param pHandle (void* [in]): Handle returned from CVMEInterface::Open. + +*/ +void +CSBSBit3VmeInterface::ResetVme(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + bt_error_t err = bt_reset(*p); + CheckError(p, err ,"CSBSBit3VmeInterface::ResetVme failed"); +} + +/*! + Check for errors on the Bit3 device. Errors must be reset with a call + to CheckErrors. + + \return bt_error_t + \retval BT_SUCCESS - no errors. + \retval BT_ESTATUS - There are status errors. + \retval BT_ENOPWR - VME crate is off. + \retval BT_EPWRCYC - Power just turned on. + \retval BT_IO - driver could not be queried. + +*/ +bt_error_t +CSBSBit3VmeInterface::CheckErrors(void* pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + return bt_chkerr(*p); +} +/*! + Reset errors on the interface. + \return bt_error_t + \retval BT_SUCCESS - success. + \retval BT_ESTATUS - Status errors persist. + \retval BT_ENOPWR - Power is still off. + \retval BT_IO - I/O failure. + */ +bt_error_t +CSBSBit3VmeInterface::ClearErrors(void*pHandle) +{ + bt_desc_t* p = (bt_desc_t*)pHandle; + return bt_clrerr(*p); +} Property changes on: trunk/nextgen/sbs/nsclapi/SBSBIT3API.cpp ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/nsclapi/SBSBit3API.h =================================================================== --- trunk/nextgen/sbs/nsclapi/SBSBit3API.h (rev 0) +++ trunk/nextgen/sbs/nsclapi/SBSBit3API.h 2008-10-07 14:29:59 UTC (rev 1998) @@ -0,0 +1,98 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +/*! + Device specific extensions to CVMEInterface for SBS's driver for + the SBS/Bit3 PCI - VME bus bridge. Use of these functions will + make your software device specific!!!!!! + + Note as well that the + modifications you make will be global to all users of the same + device (address space), and will not be reset when you close/extit. + So if you change a VMEA32/D32 device into a shortio device you've changed + it for everyone!!!! +*/ + +#ifndef __SBSBIT3API_H +#define __SBSBIT3API_H + +#ifndef BT1003 +#define BT1003 +#endif + +extern "C" { + + +#ifndef __SBS_BTDEF_H +#include <btdef.h> +#define __SBS_BTDEF_H +#endif + +#ifndef __SBS_BTPDEF_H +#include <btpdef.h> +#define __SBS_BTPDEF_H +#endif + +#ifndef __SBS_BTNGPCI_H +#include <btngpci.h> +#define __SBS_BTNGPCI_H +#endif +} +class CSBSBit3VmeInterface { +public: + + // Set parameters... + + static void SetDMABlockTransfer(void* pHandle, bool enable); + static void SetDMAPauseMode(void* pHandle, bool enable); + static void SetMaxTransferWidth(void* pHandle, bt_width_t width); + static void SetDMAAddressModifier(void* pHandle, int Modifier); + static void SetMMAPAddressModifier(void* pHandle, int Modifier); + static void SetSwapMode(void* pHandle, bt_swap_t SwapMode); + static void SetDMAThreshold(void* pHandle, int nTransfers); + static void SetDMAPollCeiling(void* pHandle, int nTransfers); + static void SetTraceMask(void* pHandle, int nMask); + + // Get current value of parameters: + + // Readonly parameters first: + + static int GetLocalCardPartNumber(void* pHandle); + static int GetRemoteCardPartNumber(void* pHandle); + static unsigned int GetLocalMemorySize(void* pHandle); + + static bool IsDMABlockTransfer(void* pHandle); + static bool IsDMAPauseMode(void* pHandle); + static bt_width_t GetMaxTransferWidth(void* pHandle); + static int GetDMAAddressModifier(void* pHandle); + static int GetMMAPAddressModifier(void* pHandle); + static int GetSwapMode(void* pHandle); + static int GetDMAThreshold(void* pHandle); + static int GetDMAPollCeiling(void* pHandle); + static int GetTraceMask(void* pHandle); + + // Direct interfaces to the bt interface: + + static void ResetVme(void* pHandle); //!< Reset VME bus. + + // Get/clear error status: + + static bt_error_t CheckErrors(void* pHandle); + static bt_error_t ClearErrors(void* pHandle); +}; + + +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-10-07 18:38:21
|
Revision: 1999 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=1999&view=rev Author: ron-fox Date: 2008-10-07 18:38:16 +0000 (Tue, 07 Oct 2008) Log Message: ----------- Get the VME Tcl package working. Modified Paths: -------------- trunk/nextgen/configure.ac trunk/nextgen/sbs/Makefile.am trunk/nextgen/sbs/nsclapi/Makefile.am Added Paths: ----------- trunk/nextgen/sbs/nsclapi/CVME.h trunk/nextgen/sbs/nsclapi/CVMEptr.h trunk/nextgen/sbs/nsclapi/MmapError.cpp trunk/nextgen/sbs/nsclapi/MmapError.h trunk/nextgen/sbs/nsclapi/VmeModule.cpp trunk/nextgen/sbs/nsclapi/VmeModule.h trunk/nextgen/sbs/tclpackage/Makefile.am trunk/nextgen/sbs/tclpackage/VMECommand.cpp trunk/nextgen/sbs/tclpackage/VMECommand.h trunk/nextgen/sbs/tclpackage/VMEMapCommand.cpp trunk/nextgen/sbs/tclpackage/VMEMapCommand.h trunk/nextgen/sbs/tclpackage/VMEPackage.cpp Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2008-10-07 14:29:59 UTC (rev 1998) +++ trunk/nextgen/configure.ac 2008-10-07 18:38:16 UTC (rev 1999) @@ -444,6 +444,7 @@ sbs/driver/include/Makefile sbs/driver/dd/GNUmakefile sbs/nsclapi/Makefile + sbs/tclpackage/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/sbs/Makefile.am =================================================================== --- trunk/nextgen/sbs/Makefile.am 2008-10-07 14:29:59 UTC (rev 1998) +++ trunk/nextgen/sbs/Makefile.am 2008-10-07 18:38:16 UTC (rev 1999) @@ -1 +1 @@ -SUBDIRS = driver nsclapi +SUBDIRS = driver nsclapi tclpackage Added: trunk/nextgen/sbs/nsclapi/CVME.h =================================================================== --- trunk/nextgen/sbs/nsclapi/CVME.h (rev 0) +++ trunk/nextgen/sbs/nsclapi/CVME.h 2008-10-07 18:38:16 UTC (rev 1999) @@ -0,0 +1,589 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +/* + \class CVME + \file CVME.h + + Encapsulates a CVME object. CVMEs purpose for existence is so that + CVMEptr's wont cause memory leaks. A CVME contains a reference counted + pointer which points to a CVMEptr object which holds the actual mapped + address and performs the actual reads and writes. When a CVME is + constructed, its reference count is incremented, and when one is + destructed, its reference count is decremented. When the reference count + falls to zero, the object is deleted. This way, the object wont be + deleted before we are done with it. + + Author: + Jason Venema + NSCL + Michigan State University + East Lansing, MI 48824-1321 + mailto: ven...@ms... +*/ + +#ifndef __CVME_H +#define __CVME_H + +#ifndef __CVMEPTR_H +#include <CVMEptr.h> +#endif + +#ifndef __REFPTR_H +#include <Refptr.h> +#endif + +template<class T> +class CVME +{ +private: + CRefcountedPtr<CVMEptr<T> > m_pRCptr; // a reference counted pointer to the + // CVMEptr which holds the mapping. + UInt_t m_nOffset; // We need our own offset to do ++ e.g. + + public: + // Enumeration of possible Vme devices to access + enum VmeSpace { + a16d16, + a24d16, + a24d32, + a32d32, + geo + }; + + // Default constructor + CVME<T>(VmeSpace space, UInt_t base, UInt_t length, UInt_t crate=0); + CVME<T>(); + CVME<T>(CVMEptr<T>* aCVMEptr); + // Copy constructor + CVME<T>(const CVME& aCVME); + // Operator= assignment operator + CVME<T>& operator= (const CVME<T>& aCVME); + + // Operator== equality operator + int operator== (const CVME<T>& aCVME) + { + return (m_pRCptr == aCVME.m_pRCptr); + } + + // Mutator functions + protected: + void setRCptr(CVMEptr<T> aRCptr) { m_pRCptr = aRCptr; } + + // Public accessor functions + public: + UInt_t getOffset() { return m_nOffset; } + UInt_t getLength() { return m_pRCptr.operator*().getLength(); } + Address_t getStart() { return m_pRCptr.operator*().getStart(); } + Address_t getgenptr(UInt_t nOffset); + Address_t getcurrptr(); + + // Public member functions + public: + // Pointer dereference/indexing + T& operator*(); + T* operator->(); + T& operator[] (UInt_t nOffset); + T& operator[] (UInt_t nOffset) const; + + // Pointer addition/subtraction + CVME<T>& operator+(UInt_t nOffset); + CVME<T>& operator-(UInt_t nOffset); + CVME<T>& operator+=(UInt_t nOffset); + CVME<T>& operator-=(UInt_t nOffset); + + // Pointer pre-increment/decrement + CVME<T>& operator++(); + CVME<T>& operator--(); + + // Pointer post-increment/decrement + CVME<T>& operator++(Int_t); + CVME<T>& operator--(Int_t); + + // Type conversion operators + public: + volatile UChar_t* asChar(); + volatile UShort_t* asShort(); + volatile ULong_t* asLong(); +}; + + +/* + \fn CVME<T>::CVME<T>(VmeSpace space, UInt_t base, UInt_t length) + + Operation Type: + Constructor + + Purpose: + Construct a CVME<T> by newing into existence a + CVMEptr<T> and encapsulating it in a RefcountedPtr. + + \param VmeSpace space - indicates the vme device to map + UInt_t base - the base address of the module + UInt_t length - the length of the mapping (bytes) + UInt_t crate - VME Crate number. + */ +template<class T> +CVME<T>::CVME(VmeSpace space, UInt_t base, UInt_t length, UInt_t crate) : + m_nOffset(0) +{ + CRefcountedPtr<CVMEptr<T> > p(new CVMEptr<T>(space, base, length, crate)); + m_pRCptr = p; +} + +/* + \fn CVME<T>::CVME<T>() + + Operation Type: + Constructor + + Purpose: + Construct a CVME<T> which points to nothing. +*/ +template<class T> +CVME<T>::CVME() : + m_nOffset(0) +{ + m_pRCptr = 0; +} + +/* + CVME<T>::CVME<T>(CVMEptr<T>& aCVMEptr) + + Operation Type: + Constructor + + Purpose: + Constructs an object of type CVME<T> given a CVMEptr object. + + \param CVMEptr<T>& aCVMEptr - the CVMEptr from which to construct this +*/ +template<class T> +CVME<T>::CVME(CVMEptr<T>* aCVMEptr) : + m_nOffset(0) +{ + m_pRCptr = CRefcountedPtr<CVMEptr<T> >(aCVMEptr); + +} + +/* + \fn CVME<T>::CVME<T>(const CVME<T>& aCVME) + + Operation Type: + Copy Constructor + + Purpose: + Construct a CVME<T> by copying one. +*/ +template<class T> +CVME<T>::CVME(const CVME<T>& aCVME) : + m_pRCptr(aCVME.m_pRCptr), + m_nOffset(aCVME.m_nOffset) +{ + +} + +/* + \fn CVME<T>& CVME<T>::operator=(const CVME<T>& aCVME) + + Operation Type: + Assignment + + Purpose: + Assign another CVME to this +*/ +template<class T> +CVME<T>& +CVME<T>::operator=(const CVME<T>& aCVME) +{ + if(this != &aCVME) { + + m_nOffset = m_nOffset; + m_pRCptr = aCVME.m_pRCptr; + } + return *this; +} + +/* + \fn T& CVME<T>::operator*() + + Operation Type: + Pointer dereference + + Purpose: + Returns the value stored by the encapsulated CVMEptr at its + current offset. Throws a CRangeError exception if it catches one. +*/ +template<class T> +T& +CVME<T>::operator*() +{ + try { + return (*m_pRCptr)[m_nOffset]; + } + catch(CRangeError& re) { + throw re; + } +} + +/* + \fn T* CVME<T>::operator->() + + Operation Type: + Pointer dereference + + Purpose: + Returns a pointer to the value stored by the encapsulated CVMEptr at + its current offset. Throws a CRangeError exception if it catches one. +*/ +template<class T> +T* +CVME<T>::operator->() +{ + UInt_t nOffset = m_pRCptr->getOffset(); + + try { + m_pRCptr->setOffset(m_nOffset); + T* ptr = m_pRCptr.operator*().operator->(); // Here's where we could throw. + m_pRCptr->setOffset(nOffset); + return ptr; + } + catch(CRangeError& re) { + m_pRCptr->setOffset(nOffset); // Be sure to restore the offset. + throw re; + } +} + +/* + \fn T& CVME<T>::operator[](UInt_t nOffset) + + Operation Type: + Indexing(read/write) + + Purpose: + Returns the value stored in the encapsulated CVMEptr at + index nOffset. Throws a CRangeError exception if it catches one. + + \param UInt_t nOffset - the offset at which the value is stored. +*/ +template<class T> +T& +CVME<T>::operator[](UInt_t nOffset) +{ + try { + return m_pRCptr.operator*().operator[](nOffset + m_nOffset); + } + catch(CRangeError& re) { + throw re; + } +} + +/* + \fn T& CVME<T>::operator[](UInt_t nOffset) const + + Operation Type: + Indexing(read/write) + + Purpose: + Returns the value stored in the encapsulated CVMEptr at + index nOffset. Throws a CRangeError exception if it catches one. + + \param UInt_t nOffset - the offset at which the value is stored. +*/ +template<class T> +T& +CVME<T>::operator[](UInt_t nOffset) const +{ + try { + return m_pRCptr.operator*().operator[](nOffset + m_nOffset); + } + catch(CRangeError& re) { + throw re; + } +} + +/* + \fn CVME<T>& CVME<T>::operator+(UInt_t nOffset) + + Operation Type: + Mutator + + binary + note that this will involve a minimum of 2 copy + constructions/destructions of a CVME<T>.. however this is not + too expensive, since it's just a matter of some reference counting + stuff. + + No attempt is made to ensure that the resulting pointer actually + points into the VME space range originally specified. + + \param UInt_t nOffset - the value to add to the current offset +*/ +template<class T> +CVME<T>& +CVME<T>::operator+(UInt_t nOffset) +{ + CVME<T> result(*this); + result.m_nOffset += nOffset; + return result; + +} + +/* + \fn CVME<T>& CVME<T>::operator-(UInt_t nOffset) + + Operation Type: + Mutator + + Same as operator+ but nOffset is subtracted. + + \param UInt_t nOffset - the value to add to the current offset +*/ +template<class T> +CVME<T>& +CVME<T>::operator-(UInt_t nOffset) +{ + return operator+(-nOffset); + +} + +/* + \fn CVME<T>& CVME<T>::operator+=(UInt_t nOffset) + + Operation Type: + Mutator + + Purpose: + Add a value to the encapsulated CVMEptr<T>'s current + offset. Returns a pointer to self . + exception if it catches one. + + \param UInt_t nOffset - the value to add to the current offset +*/ +template<class T> +CVME<T>& +CVME<T>::operator+=(UInt_t nOffset) +{ + m_nOffset += nOffset; + return *this; + +} + +/* + \fn CVME<T>& CVME<T>::operator-=(UInt_t nOffset) + + Operation Type: + Mutator + + Purpose: + Subtracts a value from the encapsulated CVMEptr<T>'s current + offset. Returns the new 'pointer' or throws a CRangeError + exception if it catches one. + + \param UInt_t nOffset - the value to add to the current offset +*/ +template<class T> +CVME<T>& +CVME<T>::operator-=(UInt_t nOffset) +{ + m_nOffset -= nOffset; + return *this; + +} + +/* + \fn CVME<T>& CVME<T>::operator++() + + Operation Type: + Mutator + + Purpose: + (Pre)Increment the current offset into the encapsulated CVME<T>. + Throws a CRangeError exception if it catches one. +*/ +template<class T> +CVME<T>& +CVME<T>::operator++() +{ + m_nOffset++; + return *this; + +} + +/* + \fn CVME<T>& CVME<T>::operator--() + + Operation Type: + Mutator + + Purpose: + (Pre)Decrement the current offset into the encapsulated CVME<T>. + Throws a CRangeError exception if it catches one. +*/ +template<class T> +CVME<T>& +CVME<T>::operator--() +{ + m_nOffset--; + return *this; + +} + +/* + \fn CVME<T>& CVME<T>::operator++(Int_t n) + + Operation Type: + Mutator + + Purpose: + (Post)Increment the current offset into the encapsulated CVME<T>. + Throws a CRangeError exception if it catches one. + + \param Int_t n - dummy parameter to indicate this is a + post-increment operator. +*/ +template<class T> +CVME<T>& +CVME<T>::operator++(Int_t n) +{ + CVME<T> result(*this); + m_nOffset++; + return result; + +} + +/* + \fn CVME<T>& CVME<T>::operator--(Int_t n) + + Operation Type: + Mutator + + Purpose: + (Post)Decrement the current offset into the encapsulated CVME<T>. + Throws a CRangeError exception if it catches one. + + \param Int_t n - dummy parameter to indicate this is a + post-decrement operator. +*/ +template<class T> +CVME<T>& +CVME<T>::operator--(Int_t n) +{ + CVME<T> result(*this); + m_nOffset--; + return result; + +} + +/* + \fn Address_t CVME<T>::getgenptr(UInt_t nOffset) + + Operation Type: + Selector + + Purpose: + Return a pointer to the current address+offset into the module + (via the encapsulated CVMEptr<T>). + + \param UInt_t nOffset - an offset to use to determine the pointer +*/ +template<class T> +Address_t +CVME<T>::getgenptr(UInt_t nOffset) +{ + Address_t p = m_pRCptr.operator*().getgenptr(nOffset+m_nOffset); + if(p) return p; + else return (Address_t)-1; +} + +/* + \fn Address_t CVME<T>::getcurrptr() + + Operation Type: + Selector + + Purpose: + Return a pointer to the current address+current offset into the + module (via the encapsulated CVMEptr<T>). +*/ +template<class T> +Address_t +CVME<T>::getcurrptr() +{ + Address_t p = m_pRCptr.operator*().getgenptr(m_nOffset); + return p; +} + +/* + \fn CVME<UChar_t> CVME<T>::asChar() + + Operation Type: + Type conversion operator + + Purpose: + Returns this as a CVME which maps m_pStart to an address space + containing data of type UChar_t. +*/ +template<class T> +volatile UChar_t* +CVME<T>::asChar() +{ + volatile UChar_t* p = (UChar_t*)m_pRCptr->getStart(); + p += m_pRCptr->getOffset() * sizeof(T)/sizeof(UChar_t); + + return p; + +} + +/* + \fn CVME<UShort_t> CVME<T>::asShort() + + Operation Type: + Type conversion operator + + Purpose: + Returns this as a CVME which maps m_pStart to an address space + containing data of type UShort_t. +*/ +template<class T> +volatile UShort_t* +CVME<T>::asShort() +{ + volatile UShort_t* p = (UShort_t*)m_pRCptr->getStart(); + p += m_nOffset * sizeof(T)/sizeof(UShort_t); + + return p; +} + +/* + \fn CVME<ULong_t> CVME<T>::asLong() + + Operation Type: + Type conversion operator + + Purpose: + Returns this as a CVME which maps m_pStart to an address space + containing data of type ULong_t. +*/ +template<class T> +volatile ULong_t* +CVME<T>::asLong() +{ + volatile ULong_t* p = (ULong_t*)m_pRCptr->getStart(); + p += m_nOffset * sizeof(T)/sizeof(ULong_t); + + return p; +} +#endif Property changes on: trunk/nextgen/sbs/nsclapi/CVME.h ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/nsclapi/CVMEptr.h =================================================================== --- trunk/nextgen/sbs/nsclapi/CVMEptr.h (rev 0) +++ trunk/nextgen/sbs/nsclapi/CVMEptr.h 2008-10-07 18:38:16 UTC (rev 1999) @@ -0,0 +1,705 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + +/* + \class CVMEptr + \file CVMEptr.h + + Encapsulates a CVMEptr object. CVMEptrs are the lowest level of the + vme module memory mapping hierarchy. They perform the actual mapping + via the CVMEInterface class. They directly manipulate the registers + and scale the pointer offsets. + + Author: + Jason Venema + NSCL + Michigan State University + East Lansing, MI 48824-1321 + mailto: ven...@ms... +*/ + +#ifndef __CVMEPTR_H +#define __CVMEPTR_H + +#ifndef __SYS_MMAN_H +#include <sys/mman.h> +#endif + +#ifndef __UNISTD_H +#include <unistd.h> +#endif + +#ifndef __TYPES_H +#include <sys/types.h> +#endif + + +#ifndef __DAQTYPES_H +#include <daqdatatypes.h> +#endif + +#ifndef __RANGEERROR_H +#include <RangeError.h> +#endif + +#ifndef __CVMEINTERFACE_H +#include <CVMEInterface.h> +#endif + +#ifndef __STRING +#include <string> +#endif + +#ifndef __MMAPERROR_H +#include <MmapError.h> +#endif + +#ifndef __CPP_IOSTREAM +#include <iostream> +#ifndef __CPP_IOSTREAM +#define __CPP_IOSTREAM +#endif +#endif + + +template<class T> +class CVMEptr +{ + UInt_t m_nLength; // the length of the mmap + volatile Address_t m_pStart; // the starting address of the mmap + void* m_pHandle; // Handle to VME interface device. + Int_t m_nOffset; + UInt_t m_nSpace; // The address space of the mapping + UInt_t m_nBase; // The base address in the crate + + public: + typedef enum _Space { + a16 = 0, + a24 = 1, + a32 = 3, + geo = 4 + } Space; + + public: + // Default constructor and Copy Constructor + CVMEptr<T>(UInt_t space, UInt_t base, UInt_t length, UInt_t crate=0); + CVMEptr<T>(Space space, UInt_t base, UInt_t length, UInt_t crate=0); + CVMEptr<T>(const CVMEptr& aCVMEptr); + CVMEptr<T>(); + + // operator= Assignment operator + CVMEptr<T>& operator= (const CVMEptr& aCVMEptr); + + // Operator== equality operator + int operator== (const CVMEptr<T>& aCVMEptr) + { + return ((m_nOffset == aCVMEptr.m_nOffset) && + (m_nLength == aCVMEptr.m_nLength) && + (m_pStart == aCVMEptr.m_pStart)); + } + + // Destructor + ~CVMEptr<T>(); + + protected: + + // Protected function member: + // This does the actual mmapping of the VME module + void CreateMap(UInt_t space, UInt_t base, UInt_t length, + UInt_t crate = 0); + + // Public accessor functions to data members + public: + + UInt_t getOffset() const { + return m_nOffset; + } + UInt_t getLength() const { + return m_nLength; + } + Address_t getStart() const { + return m_pStart; + } + void* getHandle() const { + return m_pHandle; + } + UInt_t getSpace() const { + return m_nSpace; + } + UInt_t getBase() const { + return m_nBase; + } + Address_t getgenptr(UInt_t nOffset); + Address_t getcurrptr(); + + // Protected mutator functions to data members + public: + void setOffset(UInt_t am_nOffset) { + m_nOffset = am_nOffset; + } + void setLength(UInt_t am_nLength) { + m_nLength = am_nLength; + } + void setStart(Address_t pStart) { + m_pStart = pStart; + } + void setHandle(void* am_pHandle) { + m_pHandle = am_pHandle; + } + void setSpace(UInt_t am_nSpace) { + m_nSpace = am_nSpace; + } + void setBase(UInt_t am_nBase) { + m_nBase = am_nBase; + } + + // Public member functions + public: + // Pointer dereference + T& operator*(); + T* operator->(); + + // Indexing + T& operator[] (UInt_t nOffset); + + // Pointer addition/subtraction + CVMEptr<T> operator+(UInt_t nOffset); + CVMEptr<T> operator-(UInt_t nOffset); + CVMEptr<T>& operator+=(UInt_t nOffset); + CVMEptr<T>& operator-=(UInt_t nOffset); + + // Pointer pre-increment/decrement + CVMEptr<T>& operator++(); + CVMEptr<T>& operator--(); + + // Pointer post-increment/decrement + CVMEptr<T> operator++(Int_t); + CVMEptr<T> operator--(Int_t); +}; + +#endif + +/* + \fn CVMEptr(VmeSpace space, UInt_t base, UInt_t length) + + Operation Type: + Construction + + \param VmeSpace space - enumeration indicating which vme address space + to use + UInt_t base - the base (offset) into the mapping + UInt_t length - the length of the mapping +*/ + +template<class T> +CVMEptr<T>::CVMEptr(UInt_t space, UInt_t base, UInt_t length, + UInt_t crate) : + m_nOffset(0), + m_nLength(length), + m_nSpace(space), + m_nBase(base) +{ + CreateMap(space, base, length, crate); +} +/* + Same as above, but use Space instead of int: +*/ +template<class T> +CVMEptr<T>::CVMEptr(Space space, UInt_t base, UInt_t length, + UInt_t crate) : + m_nOffset(0), + m_nLength(length), + m_nSpace(space), + m_nBase(base) +{ + CreateMap((int)space, base, length, crate); +} + + +/* + \fn CVMEptr<T>::CVMEptr<T>() + + Operation Type: + Constructor + + Purpose: + Construct an object of this type. Note that no mapping is + performed, and m_nOffset and m_nLength are both set to 0. +*/ +template<class T> +CVMEptr<T>::CVMEptr() +{ + m_nOffset = 0; + m_nLength = 0; +} + +/* + \fn CVMEptr(const CVMEptr& aCVMEptr) + + Operation Type: + Copy construction + + \param CVMEptr aCVMEptr - the CVMEptr to copy +*/ +template<class T> +CVMEptr<T>::CVMEptr(const CVMEptr& aCVMEptr) +{ + m_nOffset = aCVMEptr.m_nOffset; + m_nLength = aCVMEptr.m_nLength; + m_pStart = aCVMEptr.m_pStart; +} + +/* + \fn CVMEptr& operator= (const CVMEptr& aCVMEptr) + + Operation type: + operator= Assignment operator + + \param CVMEptr& aCVMEptr - reference to the CVMEptr to assign this to +*/ +template<class T> +CVMEptr<T>& +CVMEptr<T>::operator= (const CVMEptr& aCVMEptr) +{ + if(this == &aCVMEptr) return *this; + + m_nOffset = aCVMEptr.m_nOffset; + m_nLength = aCVMEptr.m_nLength; + m_pStart = aCVMEptr.m_pStart; + + return *this; +} + +/* + \fn CVMEptr<T>::~CVMEptr<T>() + + Operation type: + Destructor + + Purpose: Destructor is responsible for munmapping the module +*/ +template<class T> +CVMEptr<T>::~CVMEptr<T>() +{ + + CVMEInterface::Unmap(m_pHandle, m_pStart, m_nLength); + CVMEInterface::Close(m_pHandle); +} + +/* + \fn void CVMEptr<T>::CreateMap(UInt_t space, UInt_t base, UInt_t length) + + Operation Type: + Map + + \param UInt_t space - indicates which vme device to open + (a16d16, a24d32 or a32d32) + UInt_t base - the base address of the module which we're mapping to + UInt_t lenght - the length (bytes) of the map + UInt_t crate - Selects the vme crate. +*/ +template<class T> +void +CVMEptr<T>::CreateMap(UInt_t space, UInt_t base, UInt_t length, UInt_t crate) +{ + + m_nOffset = 0; + + // First open the specified vme device + + try { + switch(space) { + case 0: + m_pHandle = CVMEInterface::Open(CVMEInterface::A16, crate); + break; + case 1: // No difference between d16, d32. + case 2: + m_pHandle = CVMEInterface::Open(CVMEInterface::A24, crate); + break; + case 3: + m_pHandle = CVMEInterface::Open(CVMEInterface::A32, crate); + break; + case 4: + m_pHandle = CVMEInterface::Open(CVMEInterface::GEO , crate); + break; + default: + std::cerr << "Default condition in CVMEptr<T> CreateMap switch " << space + << std::endl; + std::cerr.flush(); + + break; + } + } + catch(std::string& err) { + std::string merr = "CVMEptr<T>::CreateMap - Opening connection to vme device"; + merr += '\n'; + merr += err; + merr += "\n"; + CMmapError me(err.c_str()); + throw me; + } + + + // Determine the page size and page offset + + m_nLength = length; + try { + m_pStart = CVMEInterface::Map(m_pHandle, base, length); + } + catch (std::string& err) { + std::string merr("CVMEptr<T>::CreateMap - Unable to perform CVMEInterface::Map"); + merr += '\n'; + merr += err; + merr += "\n"; + throw CMmapError(merr.c_str()); + + } + + +} + + +/* + \fn T& CVMEptr<T>::operator*() + + Operation Type: + Pointer dereference + + Purpose: + Return the value stored at location m_nOffset in the mapped + address space. Throws an exception if the value is out of range. +*/ +template<class T> +T& +CVMEptr<T>::operator*() +{ + if( (m_nOffset < 0) || (m_nOffset >= m_nLength)) { + throw CRangeError (0, m_nLength, m_nOffset, + "CVMEptr<T>::operator*() - outside of address window"); + + } + + Address_t pVa = (Address_t)(m_nOffset*sizeof(T) + (UInt_t)m_pStart); + return (*(T*)pVa); +} + +/* + \fn T* CVMEptr<T>::operator->() + + Operation Type: + Pointer dereference + + Purpose: + Return a pointer to the value at location m_nOffset + into the mapped address space. Throws an exception if the value is + out of range. +*/ +template<class T> +T* +CVMEptr<T>::operator->() +{ + if((m_nOffset < 0) || (m_nOffset >= m_nLength)) { + throw CRangeError(0, m_nLength, m_nOffset, + "CVMEptr<T>::operator->() - outside of address window"); + } + Address_t pVa = (Address_t)(m_nOffset*sizeof(T) + (UInt_t)m_pStart); + + return (T*)pVa; +} + +/* + \fn T& CVMEptr<T>::operator[] (UInt_t nOffset) + + Operation Type: + Index read/write + + Purpose: + Return the value stored at locaton nOffset into the mapped address + space. Throws an exception if the value is out of range. + + \param UInt_t nOffset - the offset into the address space from which to read. +*/ +template <class T> +T& +CVMEptr<T>::operator[] (UInt_t nOffset) +{ + if((m_nOffset < 0) || (m_nOffset >= m_nLength)) { + throw CRangeError(0, m_nLength, m_nOffset, + "CVMEptr<T>::operator[]() - outside of address window"); + } + Address_t pVa = (Address_t)(nOffset*sizeof(T) + (UInt_t)m_pStart); + + return (*(T*)pVa); +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator+(UInt_t nOffset) + + Operation Type: + Mutator + + Purpose: + Add an offset to the current offset. Throws an exception if this + puts us out of range of the memory map. + + \param UInt_t nOffset - the integer to add to the current offset +*/ +template<class T> +CVMEptr<T> +CVMEptr<T>::operator+(UInt_t nOffset) +{ + if(nOffset+m_nOffset <= m_nLength) { // make sure we're in bounds + CVMEptr<T> temp = *this; + temp += nOffset; + return temp; + } + else { + CRangeError re(0, m_nOffset, nOffset, + "CVMEptr<T>::operator+() - outside of mapped address window"); + throw re; + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator-(UInt_t nOffset) + + Operation Type: + Mutator + + Purpose: + Subtracts an offset to the current offset. Throws an exception if this + puts us out of range of the memory map. + + \param UInt_t nOffset - the integer to subtract from the current offset +*/ +template<class T> +CVMEptr<T> +CVMEptr<T>::operator-(UInt_t nOffset) +{ + if(nOffset <= m_nOffset) { // make sure we're in bounds + CVMEptr<T> temp = *this; + temp -= nOffset; + return temp; + } + else { + CRangeError re(0, m_nOffset, nOffset, + "CVMEptr<T>::operator-() - outside of mapped addressed window"); + throw re; + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator+=(UInt_t nOffset) + + Operation Type: + Mutator + + Purpose: + Add an offset to the current offset. Throws an exception if this + puts us out of range of the memory map. + + \param UInt_t nOffset - the integer to add to the current offset +*/ +template<class T> +CVMEptr<T>& +CVMEptr<T>::operator+=(UInt_t nOffset) +{ + if(m_nOffset+nOffset <= m_nLength) { + m_nOffset += nOffset; + return *this; + } + else { + CRangeError re(0, m_nOffset, nOffset, + "CVMEptr<T>::operator+=() - outside of mapped address window"); + throw re; + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator-=(UInt_t nOffset) + + Operation Type: + Mutator + + Purpose: + Subtract an offset to the current offset. Throws an exception if this + puts us out of range of the memory map. + + \param UInt_t nOffset - the integer to subtract from the current offset +*/ +template<class T> +CVMEptr<T>& +CVMEptr<T>::operator-=(UInt_t nOffset) +{ + if(m_nOffset-nOffset > 0) { + m_nOffset -= nOffset; + return *this; + } + else { + CRangeError re(0, m_nOffset, nOffset, + "CVMEptr<T>::operator-=() - outside of mapped address window"); + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator++() + + Operation Type: + Mutator + + Purpose: + (Pre)Increment the current offset. Throws an exception if this puts + m_nOffset past the length of the memory map. +*/ +template<class T> +CVMEptr<T>& +CVMEptr<T>::operator++() +{ + if(m_nOffset < m_nLength) { + m_nOffset++; + return *this; + } + else { + std::string reason = "CVMEptr<T>::operator++() - reference to address which\n"; + reason += "is greater than map size"; + CRangeError re(0, m_nOffset, m_nOffset+1, reason); + throw re; + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator--() + + Operation Type: + Mutator + + Purpose: + (Pre)Decrement the current offset. Throws an exception if this puts + m_nOffset less than 0. +*/ +template<class T> +CVMEptr<T>& +CVMEptr<T>::operator--() +{ + if(m_nOffset > 0) { + m_nOffset--; + return *this; + } + else { + std::string reason = "CVMEptr<T>::operator--() - reference to address which\n"; + reason += "is less than map size"; + CRangeError re(0, m_nOffset, m_nOffset-1, reason); + throw re; + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator++(Int_t) + + Operation type: + Mutator + + Purpose: + (Post)Increment the current offset. Throws an exception if this puts + us past the length of the map. + + \param Int_t - dummy parameter indicates this is a + post-increment operator +*/ +template<class T> +CVMEptr<T> +CVMEptr<T>::operator++(Int_t) +{ + if(m_nOffset < m_nLength) { + CVMEptr<T> p(*this); + operator++(); + return p; + } + else { + std::string reason = "CVMEptr<T>::operator++() - reference to memory address\n"; + reason += "which is greater than the size of the map"; + CRangeError re(0, m_nOffset, m_nOffset+1, reason); + throw re; + } +} + +/* + \fn CVMEptr<T>& CVMEptr<T>::operator--(Int_t) + + Operation type: + Mutator + + Purpose: + (Post)Decrement the current offset. Throws an exception if this puts + us before the beginning of the memory map. + + \param Int_t - dummy parameter indicates this is a + post-decrement operator +*/ +template<class T> +CVMEptr<T> +CVMEptr<T>::operator--(Int_t) +{ + if(m_nOffset > 0) { + CVMEptr<T> p(*this); + operator--(); + return p; + } + else { + std::string reason = "CVMEptr<T>::operator--() reference to memory address\n"; + reason += "which is less than the start address of the map"; + CRangeError re(0, m_nOffset, m_nOffset-1, reason); + throw re; + } +} + +/* + \fn Address_t CVMEptr<T>::getgenptr(UInt_t nOffset) + + Operation type: + Selector + + Purpose: + Return a pointer to the current address+offset into the module + + \param UInt_t nOffset - an offset to use to determine the pointer +*/ +template<class T> +Address_t +CVMEptr<T>::getgenptr(UInt_t nOffset) +{ + Address_t p = (Address_t)(nOffset*sizeof(T) + (UInt_t)m_pStart); + if(p) return p; + else return (Address_t)kpNULL; +} + +/* + \fn Address_t CVMEptr<T>::getcurrptr(UInt_t nOffset) + + Operation Type: + Selector + + Purpose: + Return a pointer to the current address+current offset into the module +*/ +template<class T> +Address_t +CVMEptr<T>::getcurrptr() +{ + Address_t p = (Address_t)(m_nOffset*sizeof(T) + (UInt_t)m_pStart); + if(p) return p; + else return (Address_t)kpNULL; +} Property changes on: trunk/nextgen/sbs/nsclapi/CVMEptr.h ___________________________________________________________________ Added: svn:executable + * Modified: trunk/nextgen/sbs/nsclapi/Makefile.am =================================================================== --- trunk/nextgen/sbs/nsclapi/Makefile.am 2008-10-07 14:29:59 UTC (rev 1998) +++ trunk/nextgen/sbs/nsclapi/Makefile.am 2008-10-07 18:38:16 UTC (rev 1999) @@ -1,7 +1,10 @@ lib_LTLIBRARIES = libSBSVmeAPI.la -libSBSVmeAPI_la_SOURCES = SBSBIT3API.cpp Locking.cpp -include_HEADERS = CVMEInterface.h SBSBit3API.h +libSBSVmeAPI_la_SOURCES = SBSBIT3API.cpp Locking.cpp \ + VmeModule.cpp MmapError.cpp +include_HEADERS = CVMEInterface.h SBSBit3API.h CVME.h \ + CVMEInterface.h CVMEptr.h VmeModule.h MmapError.h + # Locking.cpp Added: trunk/nextgen/sbs/nsclapi/MmapError.cpp =================================================================== --- trunk/nextgen/sbs/nsclapi/MmapError.cpp (rev 0) +++ trunk/nextgen/sbs/nsclapi/MmapError.cpp 2008-10-07 18:38:16 UTC (rev 1999) @@ -0,0 +1,327 @@ +/* + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of this License, + you may choose any version ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author to +ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make +exceptions for this. Our decision will be guided by the two goals of +preserving the free status of all derivatives of our free software and of +promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE +THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO +LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR +THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS ' +*/ + + +/*! + \file MmapError.cpp + + Encapsulates mmap system service errors of any sort. + + Author: + Jason Venema + NSCL + Michigan State University + East Lansing, MI 48824-1321 + mailto: ven...@ms... +*/ +#include <config.h> +#include "MmapError.h" +#include <stdio.h> + +#ifdef HAVE_STD_NAMESPACE +using namespace std; +#endif + +static const char* Copyright = +"CMmapError.cpp: Copyright 2002 NSCL, All rights reserved\n"; + +/*! + \fn const char* CMmapError::ReasonText() const + + Purpose: + Returns a string which describes the reason for the exception +*/ +const char* +CMmapError::ReasonText() const +{ + return m_ReasonText.c_str(); +} + +/*! + \fn void CMmapError::UpdateReason() + + Purpose: + Updates the ReasonText based on the current exception. +*/ +void +CMmapError::UpdateReason() +{ + m_ReasonText = "Mmap error: Unable to mmap device"; + m_ReasonText += "\nException occurred in: "; + m_ReasonText += CException::WasDoing(); +} Property changes on: trunk/nextgen/sbs/nsclapi/MmapError.cpp ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/sbs/nsclapi/MmapError.h =================================================================== --- trunk/nextgen/sbs/nsclapi/MmapError.h (rev 0) +++ trunk/nextgen/sbs/nsclapi/MmapError.h 2008-10-07 18:38:16 UTC (rev 1999) @@ -0,0 +1,352 @@ +/* + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Pr... [truncated message content] |
From: <ro...@us...> - 2008-10-08 11:51:50
|
Revision: 2002 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2002&view=rev Author: ron-fox Date: 2008-10-08 11:51:40 +0000 (Wed, 08 Oct 2008) Log Message: ----------- Add all the device support modules from 8.1 ported to nextgen, mostly by stripping off the spectrodaq interfaces and fixing up the ANSI C++ kludges that suported g++-2.95 no longer supported. Modified Paths: -------------- trunk/nextgen/configure.ac trunk/nextgen/sbs/Makefile.am trunk/nextgen/sbs/nsclapi/Makefile.am trunk/nextgen/sbs/nsclapi/VmeModule.cpp trunk/nextgen/sbs/nsclapi/VmeModule.h Added Paths: ----------- trunk/nextgen/sbs/vmemodules/ trunk/nextgen/sbs/vmemodules/CADC2530.cpp trunk/nextgen/sbs/vmemodules/CADC2530.h trunk/nextgen/sbs/vmemodules/CAENcard.cpp trunk/nextgen/sbs/vmemodules/CAENcard.h trunk/nextgen/sbs/vmemodules/CAENcard_767.cpp trunk/nextgen/sbs/vmemodules/CAENcard_767.h trunk/nextgen/sbs/vmemodules/CBD8210.cpp trunk/nextgen/sbs/vmemodules/CBD8210.h trunk/nextgen/sbs/vmemodules/CCAENChain.cpp trunk/nextgen/sbs/vmemodules/CCAENChain.h trunk/nextgen/sbs/vmemodules/CCAENV1x90.cpp trunk/nextgen/sbs/vmemodules/CCAENV1x90.h trunk/nextgen/sbs/vmemodules/CCAENV1x90Data.h trunk/nextgen/sbs/vmemodules/CCAENV1x90Opcodes.h trunk/nextgen/sbs/vmemodules/CCAENV1x90Registers.h trunk/nextgen/sbs/vmemodules/CCAENV560.cpp trunk/nextgen/sbs/vmemodules/CCAENV560.h trunk/nextgen/sbs/vmemodules/CCAENV560Registers.h trunk/nextgen/sbs/vmemodules/CCAENV820Registers.h trunk/nextgen/sbs/vmemodules/CCAENV830.cpp trunk/nextgen/sbs/vmemodules/CCAENV830.h trunk/nextgen/sbs/vmemodules/CCAENV977.cpp trunk/nextgen/sbs/vmemodules/CCAENV977.h trunk/nextgen/sbs/vmemodules/CCAMACScalerLRS2551.cpp trunk/nextgen/sbs/vmemodules/CCAMACScalerLRS2551.h trunk/nextgen/sbs/vmemodules/CCAMACScalerLRS4434.cpp trunk/nextgen/sbs/vmemodules/CCAMACScalerLRS4434.h trunk/nextgen/sbs/vmemodules/CCamac.cpp trunk/nextgen/sbs/vmemodules/CCamac.h trunk/nextgen/sbs/vmemodules/CCamacModule.cpp trunk/nextgen/sbs/vmemodules/CCamacModule.h trunk/nextgen/sbs/vmemodules/CCamacNimout.cpp trunk/nextgen/sbs/vmemodules/CCamacNimout.h trunk/nextgen/sbs/vmemodules/CCrateController.cpp trunk/nextgen/sbs/vmemodules/CCrateController.h trunk/nextgen/sbs/vmemodules/CModule32.cpp trunk/nextgen/sbs/vmemodules/CModule32.h trunk/nextgen/sbs/vmemodules/CSIS3600.cpp trunk/nextgen/sbs/vmemodules/CSIS3600.h trunk/nextgen/sbs/vmemodules/CSIS3820.cpp trunk/nextgen/sbs/vmemodules/CSIS3820.h trunk/nextgen/sbs/vmemodules/CScaler.cpp trunk/nextgen/sbs/vmemodules/CScaler.h trunk/nextgen/sbs/vmemodules/CVMEScalerLRS1151.cpp trunk/nextgen/sbs/vmemodules/CVMEScalerLRS1151.h trunk/nextgen/sbs/vmemodules/CaenIO.cpp trunk/nextgen/sbs/vmemodules/CaenIO.h trunk/nextgen/sbs/vmemodules/Makefile.am trunk/nextgen/sbs/vmemodules/Nimout.cpp trunk/nextgen/sbs/vmemodules/Nimout.h trunk/nextgen/sbs/vmemodules/camac.h trunk/nextgen/sbs/vmemodules/camacmap.cpp trunk/nextgen/sbs/vmemodules/camacmap.h trunk/nextgen/sbs/vmemodules/cescamac.h trunk/nextgen/sbs/vmemodules/cesmacros.h trunk/nextgen/sbs/vmemodules/macros.h trunk/nextgen/sbs/vmemodules/sis3300.cpp trunk/nextgen/sbs/vmemodules/sis3300.h trunk/nextgen/sbs/vmemodules/v890.cpp trunk/nextgen/sbs/vmemodules/v890.h trunk/nextgen/sbs/vmemodules/wienercamac.h trunk/nextgen/sbs/vmemodules/wienermacros.h Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2008-10-07 18:54:06 UTC (rev 2001) +++ trunk/nextgen/configure.ac 2008-10-08 11:51:40 UTC (rev 2002) @@ -445,6 +445,8 @@ sbs/driver/dd/GNUmakefile sbs/nsclapi/Makefile sbs/tclpackage/Makefile + sbs/puretcl/Makefile + sbs/vmemodules/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/sbs/Makefile.am =================================================================== --- trunk/nextgen/sbs/Makefile.am 2008-10-07 18:54:06 UTC (rev 2001) +++ trunk/nextgen/sbs/Makefile.am 2008-10-08 11:51:40 UTC (rev 2002) @@ -1 +1 @@ -SUBDIRS = driver nsclapi tclpackage puretcl +SUBDIRS = driver nsclapi tclpackage puretcl vmemodules Modified: trunk/nextgen/sbs/nsclapi/Makefile.am =================================================================== --- trunk/nextgen/sbs/nsclapi/Makefile.am 2008-10-07 18:54:06 UTC (rev 2001) +++ trunk/nextgen/sbs/nsclapi/Makefile.am 2008-10-08 11:51:40 UTC (rev 2002) @@ -8,8 +8,7 @@ # Locking.cpp -libSBSVmeAPI_la_LDFLAGS = -version-info 1:0:0 \ - -Wl"-rpath=$(libdir)" +libSBSVmeAPI_la_LDFLAGS = -version-info 1:0:0 libSBSVmeAPI_la_LIBADD = @top_srcdir@/base/exception/libException.la \ @top_srcdir@/sbs/driver/src/libbtp.la Modified: trunk/nextgen/sbs/nsclapi/VmeModule.cpp =================================================================== --- trunk/nextgen/sbs/nsclapi/VmeModule.cpp 2008-10-07 18:54:06 UTC (rev 2001) +++ trunk/nextgen/sbs/nsclapi/VmeModule.cpp 2008-10-08 11:51:40 UTC (rev 2002) @@ -419,14 +419,9 @@ int CVmeModule::operator== (const CVmeModule& aCVmeModule) { -#if defined(HAVE_WIENERVME_INTERFACE) || defined(HAVE_WIENERUSBVME_INTERFACE) - return ((m_nSpace == aCVmeModule.m_nSpace) && - (m_nBase == aCVmeModule.m_nBase) && - (m_nLength== aCVmeModule.m_nLength) && - (m_nCrate == aCVmeModule.m_nCrate)); -#else + return (m_CVME == aCVmeModule.m_CVME); -#endif + } /* @@ -445,23 +440,9 @@ UChar_t CVmeModule::peekb(UInt_t offset) { -#ifdef HAVE_WIENERVME_INTERFACE - UChar_t byte; - WienerVMEInterface::ReadBytes(m_pDriver, - m_nBase + offset, - &byte, 1); - return byte; -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - UChar_t byte; - WienerUSBVMEInterface::ReadBytes(m_pDriver, - m_nBase + offset, - &byte, 1); - return byte; -#endif -#ifdef HAVE_VME_MAPPING + return (UChar_t)((m_CVME.asChar())[offset]); -#endif + } /* @@ -480,26 +461,10 @@ UShort_t CVmeModule::peekw(UInt_t offset) { -#ifdef HAVE_WIENERVME_INTERFACE - UShort_t word; - WienerVMEInterface::ReadWords(m_pDriver, - m_nBase + offset * sizeof(UShort_t), - &word, 1); - return word; -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - UShort_t word; - WienerUSBVMEInterface::ReadWords(m_pDriver, - m_nBase + offset * sizeof(UShort_t), - &word, 1); - return word; -#endif - -#ifdef HAVE_VME_MAPPING volatile UShort_t* c = (m_CVME.asShort()); return (UShort_t)(c[offset]); -#endif + } /* @@ -518,25 +483,9 @@ ULong_t CVmeModule::peekl(UInt_t offset) { -#ifdef HAVE_WIENERVME_INTERFACE - ULong_t lword; - WienerVMEInterface::ReadLongs(m_pDriver, - m_nBase + offset * sizeof(UInt_t), - &lword, 1); - return lword; -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - ULong_t lword; - WienerUSBVMEInterface::ReadLongs(m_pDriver, - m_nBase + offset * sizeof(UInt_t), - &lword, 1); - return lword; -#endif - -#ifdef HAVE_VME_MAPPING return (ULong_t)((m_CVME.asLong())[offset]); -#endif + } /* @@ -555,19 +504,9 @@ void CVmeModule::pokeb(UChar_t byte, UInt_t nOffset) { -#ifdef HAVE_WIENERVME_INTERFACE - WienerVMEInterface::WriteBytes(m_pDriver, m_nBase + nOffset, - &byte, 1); -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - WienerUSBVMEInterface::WriteBytes(m_pDriver, m_nBase + nOffset, - &byte, 1); -#endif - -#ifdef HAVE_VME_MAPPING (m_CVME.asChar())[nOffset] = byte; -#endif + } /* @@ -586,21 +525,9 @@ void CVmeModule::pokew(UShort_t word, UInt_t nOffset) { -#ifdef HAVE_WIENERVME_INTERFACE - WienerVMEInterface::WriteWords(m_pDriver, - m_nBase + nOffset*sizeof(UShort_t), - &word, 1); -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - WienerUSBVMEInterface::WriteWords(m_pDriver, - m_nBase + nOffset*sizeof(UShort_t), - &word, 1); -#endif - -#ifdef HAVE_VME_MAPPING (m_CVME.asShort())[nOffset] = word; -#endif + } /* @@ -619,21 +546,9 @@ void CVmeModule::pokel(ULong_t lword, UInt_t nOffset) { -#ifdef HAVE_WIENERVME_INTERFACE - WienerVMEInterface::WriteLongs(m_pDriver, - m_nBase + nOffset * sizeof(ULong_t), - &lword, 1); -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - WienerUSBVMEInterface::WriteLongs(m_pDriver, - m_nBase + nOffset * sizeof(ULong_t), - &lword, 1); -#endif - -#ifdef HAVE_VME_MAPPING (m_CVME.asLong())[nOffset] = lword; -#endif + } /*! Utility function to copy an object to me. @@ -641,16 +556,9 @@ void CVmeModule::CopyToMe(const CVmeModule& rModule) { -#if defined(HAVE_WIENERVME_INTERFACE) || defined(HAVE_WIENERUSBVME_INTERFACE) - m_nSpace = rModule.m_nSpace; - m_nBase = rModule.m_nBase; - m_nLength= rModule.m_nLength; - m_nCrate = rModule.m_nCrate; - m_pDriver= (rModule.m_pDriver); -#endif -#ifdef HAVE_VME_MAPPING + m_CVME = rModule.m_CVME; -#endif + } @@ -678,27 +586,14 @@ UInt_t CVmeModule::readl(void* pBuffer, UInt_t nOffset, size_t longs) { -#ifdef HAVE_VME_MAPPING ULong_t* pSource = (ULong_t*)m_CVME.asLong() + nOffset; ULong_t* pDest = (ULong_t*)pBuffer; for(UInt_t i =0; i < longs; i++) { // memcpy is not ensured to be long transfers. *pDest++ = *pSource++; } return longs; -#endif -#ifdef HAVE_WIENERVME_INTERFACE - return WienerVMEInterface::ReadLongs(m_pDriver, - m_nBase + nOffset*sizeof(ULong_t), - pBuffer, longs); -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - return WienerUSBVMEInterface::ReadLongs(m_pDriver, - m_nBase + nOffset*sizeof(ULong_t), - pBuffer, longs); -#endif - } /*! @@ -725,24 +620,14 @@ UInt_t CVmeModule::readw(void* pBuffer, UInt_t nOffset, size_t words) { -#ifdef HAVE_VME_MAPPING + UShort_t* pSource = (UShort_t*)m_CVME.asShort() + nOffset; UShort_t* pDest = (UShort_t*)pBuffer; for(UInt_t i =0; i < words; i++) { // memcpy is not ensured to be word transfers. *pDest++ = *pSource++; } return words; -#endif -#ifdef HAVE_WIENERVME_INTERFACE - return WienerVMEInterface::ReadWords(m_pDriver, - m_nBase + nOffset*sizeof(UShort_t), - pBuffer, words); -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - return WienerUSBVMEInterface::ReadWords(m_pDriver, - m_nBase + nOffset*sizeof(UShort_t), - pBuffer, words); -#endif + } /*! @@ -769,25 +654,14 @@ UInt_t CVmeModule::readb(void* pBuffer, UInt_t nOffset, size_t bytes) { -#ifdef HAVE_VME_MAPPING + UChar_t* pSource = (UChar_t*)m_CVME.asChar() + nOffset; UChar_t* pDest = (UChar_t*)pBuffer; for(UInt_t i =0; i < bytes; i++) { // memcpy is not ensured to be long transfers. *pDest++ = *pSource++; } return bytes; -#endif -#ifdef HAVE_WIENERVME_INTERFACE - return WienerVMEInterface::ReadBytes(m_pDriver, - m_nBase + nOffset, - pBuffer, bytes); -#endif -#ifdef HAVE_WIENERUSBVME_INTERFACE - return WienerUSBVMEInterface::ReadBytes(m_pDriver, - m_nBase + nOffset, - pBuffer, bytes); -#endif } Modified: trunk/nextgen/sbs/nsclapi/VmeModule.h =================================================================== --- trunk/nextgen/sbs/nsclapi/VmeModule.h 2008-10-07 18:54:06 UTC (rev 2001) +++ trunk/nextgen/sbs/nsclapi/VmeModule.h 2008-10-08 11:51:40 UTC (rev 2002) @@ -338,20 +338,8 @@ // Mutator function -#if defined(HAVE_WIENERVME_INTERFACE) || defined(HAVE_WIENERUSBVME_INTERFACE) protected: - void setDriver(void* pDriver) { - m_pDriver = pDriver; - } - public: - void* getDriver() { - return m_pDriver; - } -#endif - -#ifdef HAVE_VME_MAPPING - protected: void setCVME(CVME<UShort_t> aCVME) { m_CVME = aCVME; @@ -363,7 +351,6 @@ return m_CVME; } -#endif // Public member functions public: Added: trunk/nextgen/sbs/vmemodules/CADC2530.cpp =================================================================== --- trunk/nextgen/sbs/vmemodules/CADC2530.cpp (rev 0) +++ trunk/nextgen/sbs/vmemodules/CADC2530.cpp 2008-10-08 11:51:40 UTC (rev 2002) @@ -0,0 +1,2045 @@ +/*=========================================================================*\ +| Copyright (C) 2008 by the Board of Trustees of Michigan State University. | +| You may use this software under the terms of the GNU public license | +| (GPL). The terms of this license are described at: | +| http://www.gnu.org/licenses/gpl.txt | +| | +| Written by: E. Kasten | +\*=========================================================================*/ + +/* + Change Log: +*/ + +static const char* Copyright= "(C) Copyright Michigan State University 2008, All rights reserved"; + +#include <config.h> + +#include <CADC2530.h> +#include <string> +#include <unistd.h> +#include <string.h> +#include <math.h> + +#include <assert.h> + +using namespace std; + + +// Convenience function for longword swapping. +#define swaplong(n) (((n >> 16) & 0xffff) | ((n & 0xffff) << 16)) + +// Byte offset associated with a structure/field. +#define Offset(structname, field) ((unsigned int)&(((structname*)0x0)->field)) + +// Short and Long noffset associated with a struct/field. +#define ShortOffset(structname, field) (Offset(structname,field)/sizeof(short)) +#define LongOffset(structname, field) (Offset(structname,field)/sizeof(long)) + +// VME crate definitions +#define VME_CRATE_SIZE 24 // Slots in a VME crate. + +// ADC2530 register and memory sizes and offsets +#define CADC2530_REGSIZE 0xC0 // Size of register set. +#define CADC2530_MEMSIZE 0x200000 // Size of all histo/list memory. +#define CADC2530_HISTOMEMSIZE 0x40000 // Size of histogram memory. +#define CADC2530_HISTOCHANSIZE 0x2000 // Size of histogram channel in longs. + +// This value masks out (logical AND) the bits returned from a +// CSR read that should not be retained during a CSR set operation. +#define CADC2530_CSRMASK 0x00FF8A + +// This value masks out (logical AND) the bits returned from a +// CTR read that should not be retained during a CTR set operation. +#define CADC2530_CTRMASK 0x00810F + +// Defines for parsing list mode data blocks +#define IS_LIST_HEADER(x) (((((x>>24)&0x07) == 0x2)) ? true : false) +#define IS_LIST_EOB(x) (((((x>>24)&0x07) == 0x4)) ? true : false) +#define IS_LIST_CHANNEL(x) ((((x>>24)&0x07) == 0x0)) ? true : false) +#define GET_LIST_CHANCOUNT(x) (((x>>8)&0x07)+1) +#define GET_LIST_CHANNUM(x) (((x>>16)&0x07)+1) +#define GET_LIST_CHANDATA(x) (x&0x1FFF) +#define GET_LIST_EVENTCOUNT(x) (x&0x00FFFFFF) + +// Definition of the register and configuration memory. +typedef struct ADCregisters_struct { + unsigned short ManufacturerId; // 0x00 (R) + unsigned short DeviceType; // 0x02 (R) + unsigned short CSR; // 0x04 (RW) + unsigned short MemoryOffset; // 0x06 (RW) + unsigned short ListAddressLS; // 0x08 (RW) + unsigned short ListAddressMS; // 0x0A (RW) + unsigned short InterruptVector; // 0x0C (RW) + unsigned short CTR; // 0x0E (RW) + unsigned short FullnessFlag; // 0x10 (RW) + unsigned short InterruptMask; // 0x12 (RW) + unsigned short LowerLevelDisc; // 0x14 (RW) + unsigned short UpperLevelDisc; // 0x16 (RW) + unsigned short EventCounterLS; // 0x18 (RW) + unsigned short EventCounterMS; // 0x1A (RW) + unsigned short Conversion; // 0x1C (R) + unsigned short SlidingScaleTest; // 0x1E (RW) + unsigned short NotUsed2[16]; // 0x20-0x3F + unsigned short SerialNumber; // 0x40 (R) + unsigned short DataInNonVolatileMem[63]; // 0x42-0xBF +} ADCregisters_t; + +// Bit definition for the control and status register (CSR) +typedef union ADCcsr_union { + unsigned short csrval; + struct bit_struct { + unsigned char RSTBSY : 1; // Read->Busy, Write->Reset (RW) + unsigned char SS : 1; // Enable sliding scale (0 is ON) (RW) + unsigned char DR : 1; // Data ready (R) + unsigned char SC : 1; // Set calibration on (RW) + unsigned char FFCLR : 1; // Force fast clear on all channesl (W) + unsigned char ACM : 1; // Auto memory clear (RW) (not completed) + unsigned char IS : 1; // Interrupt status (R) + unsigned char IE : 1; // Interrupt enable (RW) + unsigned char ARM : 1; // Start acquisition (RW) + unsigned char IPL : 3; // Set interrupt priority level (RW) + unsigned char FHE : 1; // Full/Half full or Event interrupt (RW) + unsigned char ZE : 1; // Enable zero conversion (RW) + unsigned char GE : 1; // Enable gate mode (RW) + unsigned char HE : 1; // Enable histogram mode (RW) + } bits; +} ADCcsr_t; + +// Bit definition for the calibration and test register (CTR) +typedef union ADCctr_union { + unsigned short ctrval; + struct bit_struct { + unsigned char M012 : 3; // Channel select bits 0-2 (RW) + unsigned char MEN : 1; // Enable the MUX switch (RW) + unsigned char D04 : 1; // Unused + unsigned char D05 : 1; // Unused + unsigned char D06 : 1; // Unused + unsigned char D07 : 1; // Unused + unsigned char DISC : 1; // Disable compensation (0 -> comp. applied) (RW) + unsigned char D09 : 1; // Unused + unsigned char D10 : 1; // Unused + unsigned char D11 : 1; // Unused + unsigned char D12 : 1; // Unused + unsigned char D13 : 1; // Unused + unsigned char D14 : 1; // Unused + unsigned char DEAC : 1; // Disable auto fast clear + } bits; +} ADCctr_t; + +// Bit definition for the fullness flag register +typedef union ADCfullnessflag_union { + unsigned short flags; + + struct byte_struct { + unsigned char HALFFULL : 8; // Half full flags + unsigned char FULL : 8; // Full flags + } bytes; + + struct bit_struct { + unsigned char F1 : 1; + unsigned char F2 : 1; + unsigned char F3 : 1; + unsigned char F4 : 1; + unsigned char F5 : 1; + unsigned char F6 : 1; + unsigned char F7 : 1; + unsigned char F8 : 1; + unsigned char HF1 : 1; + unsigned char HF2 : 1; + unsigned char HF3 : 1; + unsigned char HF4 : 1; + unsigned char HF5 : 1; + unsigned char HF6 : 1; + unsigned char HF7 : 1; + unsigned char HF8 : 1; + } bits; +} ADCfullnessflag_t; + +/*==============================================================*/ +/** @fn CADC2530::CADC2530(int slotNum,int crateNum,long nBase) +* @brief Constructor. +* +* NOTE: geographic addressing is currently unsupported. +* +* Constructs a Hytec 2530 ADC card. The card can be addressed either +* geographically or via base addres switches. If geographical +* addressing is used, the slot value comes from the card position +* in the crate. Otherwise it is programmed by the slotNum parameter. +* +* @param crateNum The crate number in which the module lives. +* This selects which of the VME crates the module is in. VME +* crate numbers can be determined using the cratelocator utility. +* The crate number is also programmed into the crate register so +* that the module crate field in the data stream is correct. +* +* @param nBase long [in] The base address of the module. +* +* @return this +*/ +CADC2530::CADC2530(int crateNum,long nBase) : + my_nCrate(crateNum), + my_nBase(nBase), + my_nMemOffset(nBase), + my_pModule(NULL), + my_pMemory(NULL), + my_nCardId(0), + my_nCardType(0), + my_nModFd(0), + my_nMemFd(0), + my_eventmode(false), + my_cureventpos(0) +{ + assert(sizeof(ADCregisters_t) == CADC2530_REGSIZE); // Else struct misdefined. + slotInit(); +} + +/*==============================================================*/ +/** @fn CADC2530::CADC2530(const CADC2530& card) +* @brief Copy constructor. +* +* Copy constructor: Constructs a new card from an existing card +* object. A new map is established to the card for this object. +* The card is not re-initialized, but remains in the state defined +* by the existing card. +* +* @param card The card to copy. +* @return this +*/ +CADC2530::CADC2530(const CADC2530& card) : + my_nCrate(card.my_nCrate), + my_nBase(card.my_nBase), + my_nMemOffset(card.my_nMemOffset), + my_nCardId(card.my_nCardId), + my_nCardType(card.my_nCardType), + my_pModule(NULL), + my_pMemory(NULL), + my_nModFd(0), + my_nMemFd(0), + my_eventmode(false), + my_cureventpos(0) +{ + mapCard(); // Map the card. +} + +/*==============================================================*/ +/** @fn CADC2530::CADC2530(const CADC2530& card) +* @brief Copy constructor. +* +* Assignment operator. This card is destroyed, and replaced with +* a copy of the card described by <em>card</em>. this is not +* initialized, but remains in the state defined by the rhs of the +* assignment. +* +* @param card The card to assign to this. +* @return Dereferenced version of this. +*/ +CADC2530& CADC2530::operator=(const CADC2530& card) { + if (this != (&card)) { + if (this->my_pModule != NULL) destroyCard(); // Destroy old memory map. + my_nCrate = card.my_nCrate; + my_nBase = card.my_nBase; + my_nMemOffset = card.my_nMemOffset; + my_eventmode = card.my_eventmode; + my_cureventpos= card.my_cureventpos; + my_nMemFd = 0; + my_nModFd = 0; + my_pModule = NULL; + my_pMemory = NULL; + mapCard(); + } + return *this; +} + +/*==============================================================*/ +/** @fn CADC2530::~CADC2530() +* @brief Unmap and destruct. +* +* Unmap and destruct this card object. +* +* @param None +* @return None +*/ +CADC2530::~CADC2530() { + destroyCard(); +} + +/*==============================================================*/ +/** @fn CADC2530::checkCard(int nCrate,long nBase,unsigned short &rType,unsigned short &rManId) +* @brief Static method to check if a card is a Hyted 2530 ADC. +* +* Static method to check if a card is a Hytec 2530 ADC. Simply maps +* the register set and retrieves the manufacturer id and device type +* from the locations where they are stored for the ADC2530. These +* values are returned in rManId and rType. +* +* Note, this is a static method that does not require the +* instantiation of this class to be called. Also, it should be +* called as: CADC2530::checkCard(). +* +* @param nCrate The crate number to check. +* @param nBase The crate number to check. +* @param rType The device type (output). +* @param rManId The manufactuer id (output). +* @return true If this card appears to be a ADC2530, else false. +*/ +bool CADC2530::checkCard(int nCrate,long nBase,unsigned short &rType, unsigned short &rManId) { + // Ensure that the slot and crate specified stay within bounds. + int crate = nCrate & 0xff; // Not important enough to give an error, + // just discard the extra. + + // The card is not mapped yet, so do it. + void *fd = NULL; + rType = 0; + rManId = 0; + + + fd = CVMEInterface::Open(CVMEInterface::A24,crate); + volatile unsigned short *adcmod = (volatile unsigned short*)CVMEInterface::Map(fd,nBase,CADC2530_REGSIZE); + + + rType = ((volatile ADCregisters_t*)adcmod)->DeviceType; + rManId = ((volatile ADCregisters_t*)adcmod)->ManufacturerId; + CVMEInterface::Unmap(fd,(void*)adcmod,CADC2530_REGSIZE); + CVMEInterface::Close(fd); + + + adcmod = NULL; + fd = NULL; + + if ((rManId != 0x8063)||(rType != 2530)) return false; + else return true; +} + +/*==============================================================*/ +/** @fn CADC2530::volt2lld(double volt) +* @brief Static method to convert a voltage to an LLD setting. +* +* Static method to convert a voltage in the range [0-0.8191] volts +* to a lower level discriminator (LLD) value. All specified values +* greater than 0.8191 will return 0x3FFC (maximum setting), and +* all values less than zero will return 0x0 (minimu setting). +* +* Note, this is a static method that does not require the +* instantiation of this class to be called. Also, it should be +* called as: CADC2530::volt2lld(). +* +* @param volt The voltage to convert. +* @return An LLD setting for the specified voltage. +*/ +unsigned short CADC2530::volt2lld(double volt) { + unsigned short sval = 0; + if (volt < 0) { + sval = 0x0; + } else if (volt > 0.8191) { + sval = 0x3FFC; + } else { + int val = (int)((volt/3.2764)/(0.25/4095)); + sval = (unsigned short)((val << 2)&0x00003FFC); + } + + return sval; +} + +/*==============================================================*/ +/** @fn CADC2530::volt2uld(double volt) +* @brief Static method to convert a voltage to an ULD setting. +* +* Static method to convert a voltage in the range [0-8.191] volts. +* to a upper level discriminator (ULD) value. All values +* greater than 8.191 will be set to 8.191 and all values less than +* zero will be set to 0. +* +* Note, this is a static method that does not require the +* instantiation of this class to be called. Also, it should be +* called as: CADC2530::volt2uld(). +* +* @throw A string exeception on error. +* @param volt The voltage to convert. +* @return An ULD setting for the specified voltage. +*/ +unsigned short CADC2530::volt2uld(double volt) { + unsigned short sval = 0; + + if (volt < 0) { + sval = 0x0; + } else if (volt > 8.191) { + sval = 0x3FFC; + } else { + int val = (unsigned int)trunc(((volt/3.2764)-2)/(0.5/4095)); + sval = (unsigned short)((val << 2)&0x00003FFC); + } + + return sval; +} + +/*==============================================================*/ +/** @fn CADC2530::toString() +* @brief Stringify this card. +* +* Stringify this card as a std::string that describes this +* module. +* +* @throw A string execption if there were any problems. +* @param None +* @return A std::string representation of this module. +*/ +const std::string& CADC2530::toString() { + static string namstr; + static char buffer[256]; + sprintf(buffer,"ADC2530 in crate %d at base 0x%x with memory offset 0x%x",my_nCrate,my_nBase,my_nMemOffset); + namstr = buffer; + return namstr; +} + + + +/*==============================================================*/ +/** @fn CADC2530::readListEvent(void *buf,int lngsLeft) +* @brief Read a single event into a user buffer. +* +* Reads a single list memory event into a user buffer (pointer to +* local memory). The buf parameter is a pointer to local memory +* that has already been alocated. +* +* This method is meant for internal use and assumes that +* list memory boundary checking has already been completed before +* this method was called. +* +* @param buf A pointer to local memory that has already been allocated. +* @param lngsLeft Number of longs left in list memory. +* @return An integer indicating the number of BYTES of data placed in buf. +* @retval >0 indicates the number of BYTES of data placed in buf. +* @retval 0 indicates that no data was placed in the buffer. +*/ +int CADC2530::readListEvent(void* buf,int lngsLeft) { + int lngcnt = 0; + unsigned int *lptr = (unsigned int*)buf; + + // Need at least a header and EOB + if (lngsLeft < 2) return(0); + + + lptr[lngcnt] = ((volatile unsigned long*)my_pMemory)[my_cureventpos]; + + int chans = GET_LIST_CHANCOUNT(lptr[0]); + + // Only read out the last event if there is enough memory + // to contain it. + if ((chans+2) < lngsLeft) { + lngcnt++; + my_cureventpos++; + +#ifdef ADC2530_LOOP_COPY + + for (int i = 0; i < (chans+1); i++) { + lptr[lngcnt] = ((volatile unsigned long*)my_pMemory)[my_cureventpos]; + my_cureventpos++; + lngcnt++; + } +#else + memcpy(lptr, const_cast<const unsigned int*>(my_pMemory+my_cureventpos), + (chans+1)*sizeof(unsigned int)); +#endif + } + + return lngcnt*sizeof(unsigned int); +} + +/*==============================================================*/ +/** @fn CADC2530::readListEvents(void *buf,int& nEvents) +* @brief Read multiple events into a user buffer. +* +* Reads multiple list memory events into a user buffer (pointer to +* local memory). The buf parameter is a pointer to local memory +* that has already been alocated. The size of buf should be +* at least 40*nEvents in size to guarantee sufficient space +* for reading the request number of events. +* +* @param buf A pointer to local memory that has already been allocated. +* @param nEvents (IN) The number of events to read, (OUT) the number of +* events actually read. +* @return An integer indicating the number of BYTES of data placed in buf. +* @retval >0 indicates the number of BYTES of data placed in buf. +* @retval 0 indicates that no data was placed in the buffer. +*/ +int CADC2530::readListEvents(void* buf,int& nEvents) { + int lngcnt = 0; + unsigned int *lptr = (unsigned int*)buf; + + // First check list memory boundaries + unsigned int listaddr = getListAddress(); + if (listaddr == 0) { + if (dataReady()) listaddr = (CADC2530_MEMSIZE/sizeof(unsigned int)); + } + + // Now read the events + int eventsread = 0; + for (int i = 0; i < nEvents; i++) { + int bytes = readListEvent((void*)lptr,listaddr-my_cureventpos); + if (bytes <= 0) break; // No more events + eventsread++; + + lptr += (bytes/sizeof(unsigned int)); + lngcnt += (bytes/sizeof(unsigned int)); + } + + nEvents = eventsread; + return lngcnt*sizeof(unsigned int); +} + +/*==============================================================*/ +/** @fn CADC2530::readHistogramChannel(void *buf,int channum) +* @brief Read a single event into a user buffer. +* +* Reads a single histogram channel into a user buffer (pointer to +* local memory). The buf parameter is a pointer to local memory +* that has already been alocated. This user allocated buffer must +* be sized to contain at least 8192 (0x2000) 32-bit long words +* (32768 bytes). +* +* @throw String exception on error. +* @param buf A pointer to local memory that has already been allocated. +* @param channum The channel number to read in the range [1-8]. +* @return An integer indicating the number of BYTES of data placed in buf. +* @retval >0 indicates the number of BYTES of data placed in buf. +* @retval 0 indicates that no data was placed in the buffer. +*/ +int CADC2530::readHistogramChannel(void* buf,int channum) { + if ((channum < 1)||(channum > 8)) { + char buffer[256]; + sprintf(buffer, "CADC2530::readHistogramChannel(): the channel number specified must be in the range [1-8]. A channel number of %d was specified\n",channum); + throw string(buffer); + } + + int chstart = (channum - 1) * CADC2530_HISTOCHANSIZE; + unsigned int *lptr = (unsigned int*)buf; + + + for (int i = 0; i < CADC2530_HISTOCHANSIZE; i++) { + lptr[i] = ((volatile unsigned long*)my_pMemory)[chstart+i]; + } + + return (CADC2530_HISTOCHANSIZE * sizeof(unsigned int)); +} + +/*==============================================================*/ +/** @fn CADC2530::slotInit() +* @brief Initialize a card to a standard, well defined state. +* +* Maps the card and initializes it to a well defined state. +* The card location is assumed to already have been set up +* as defined by the member variables (except for my_pModule and +* my_pMemory which are filled in by mapCard()). +* +* @throw A string execption if there were any problems. +* @param None +* @return None +*/ +void CADC2530::slotInit() { + mapCard(); + resetCard(); + clearHistogramMemory(); +} + +/*==============================================================*/ +/** @fn CADC2530::cardType() +* @brief Return the device type of this card. +* +* Return the device type of this card. It should 2530(dec) for +* the Hytec 2530 ADC as read from location base+0x02. +* +* @param None +* @return The device type as an unsigned short. +*/ +unsigned short CADC2530::cardType() { + if (!my_nCardType) { + my_nCardType = ((volatile ADCregisters_t*)my_pModule)->DeviceType; + } + return my_nCardType; +} + +/*==============================================================*/ +/** @fn CADC2530::manufacturerId() +* @brief Return the manufacturer id for this card. +* +* Return the manufacturer id for this card. It should 0x8063 for +* the Hytec 2530 ADC as read from location base+0x0. +* +* @param None +* @return The manufacturer id as an unsigned short. +*/ +unsigned short CADC2530::manufacturerId() { + if (!my_nCardId) { + my_nCardId = ((volatile ADCregisters_t*)my_pModule)->ManufacturerId; + } + return my_nCardId; +} + +/*==============================================================*/ +/** @fn CADC2530::setMemoryOffset(unsigned long memoset)) +* @brief Set the memory offset to the specified address. +* +* Set the memory offset to the specified A32 address. +* Note, memoff is right shifted 16 bits and logically ANDed +* with 0xFFE0 before it is written to the register (the A32 return +* value reflects this). +* +* @param memoset The A32 memory offset base. +* @return The value read back from the register as an A32 address. +*/ +unsigned long CADC2530::setMemoryOffset(unsigned long memoset) { + unsigned long lval = (memoset >> 16); + unsigned short sval = (lval & 0xFFE0); + + ((volatile ADCregisters_t*)my_pModule)->MemoryOffset = sval; + lval = ((volatile ADCregisters_t*)my_pModule)->MemoryOffset; + + return (lval << 16); +} + +/*==============================================================*/ +/** @fn CADC2530::calcMemoryOffset(unsigned long base)) +* @brief Calculate the memory offset register setting. +* +* Calculate the memory offset register setting given +* the current A24 base address for this card's registers. +* +* @param base The base address for this card. +* @return A computed memory offset A32 base value. +*/ +unsigned long CADC2530::calcMemoryOffset(unsigned long base) { + unsigned long regset = ((base >> 8) & 0xFFE0); + return (regset << 16); +} + +/*==============================================================*/ +/** @fn CADC2530::mapModule() +* @brief Map this cards registers into memory. +* +* Given the values in +* - my_nCrate - Physical crate number. +* - my_nBase - Base address. +* +* - Creates a map to the registers of the module. +* +* @throw string describing why the method failed. +* @param None +* @return None +*/ +void CADC2530::mapModule() { + // Donot map the register memory more than once. + if (my_pModule != NULL) { + char buffer[256]; + sprintf(buffer, "CADC2530::mapModule(): The Card in crate %d at base 0x%x already has a register memory map.\n",my_nCrate,my_nBase); + throw string(buffer); + } + + // Ensure that the slot and crate specified stay within bounds. + my_nCrate = my_nCrate & 0xff; // Not important enough to give an error, + // just discard the extra. + + // The card is not mapped yet, so do it. + void *fd = NULL; + + fd = CVMEInterface::Open(CVMEInterface::A24, my_nCrate); + my_pModule = (volatile unsigned short*)CVMEInterface::Map(fd,my_nBase, + CADC2530_REGSIZE); + + // Check if the module type is a 2530(dec) and that the manufacturer is + // 0x8063. If not, then issue and error message. + my_nCardId = manufacturerId(); + my_nCardType = cardType(); + + if ((my_nCardId != 0x8063)||(my_nCardType != 2530)) { + + CVMEInterface::Unmap(fd,(void*)my_pModule,CADC2530_REGSIZE); + CVMEInterface::Close(fd); + my_pModule = NULL; + char buffer[256]; + sprintf(buffer, "CADC2530::mapModule(): Card in crate %d at base 0x%x is not a Hytec 2530 ADC or is missing type=%d id=0x%0x\n",my_nCrate,my_nBase,my_nCardType,my_nCardId); + throw string(buffer); + } + + my_nModFd = fd; // Save for destruction. +} + +/*==============================================================*/ +/** @fn CADC2530::mapMemory() +* @brief Map this card's list/histogram memory. +* +* Given the values in +* - my_nCrate - Physical crate number. +* - my_nBase - Base address. +* +* - Creates a map to the list/histogram memory of the module. +* +* @throw string describing why the method failed. +* @param None +* @return None +*/ +void CADC2530::mapMemory() { + // We must have a register memory map first. + if (my_pModule == NULL) { + char buffer[256]; + sprintf(buffer, "CADC2530::mapMemory(): Cannot map list/histogram memory without first mapping the ADC2530 registers for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase); + throw string(buffer); + } + + // Donot map the list/histogram memory more than once. + if (my_pMemory != NULL) { + char buffer[256]; + sprintf(buffer, "CADC2530::mapMemory(): The Card in crate %d at base 0x%x already has a list/histogram memory map.\n",my_nCrate,my_nBase); + throw string(buffer); + } + + // Ensure that the slot and crate specified stay within bounds. + my_nCrate = my_nCrate & 0xff; // Not important enough to give an error, + // just discard the extra. + + // The card is not mapped yet, so do it. + void *fd = NULL; + + // Now can map the list/histogram memory + unsigned long nmemoset = calcMemoryOffset(my_nBase); + my_nMemOffset = setMemoryOffset(nmemoset); + + // If we did this correctly and the card is working correctly, + // we should read back the setting we calculated. + if (nmemoset != my_nMemOffset) { + char buffer[256]; + sprintf(buffer, "CADC2530::mapMemory(): Error setting list/histogram memory offset for ADC2530 card in crate %d at base 0x%x (written=0x%x, read=0x%x)\n",my_nCrate,my_nBase,nmemoset,my_nMemOffset); + throw string(buffer); + } + + // Now map the list/histogram memory. + + fd = CVMEInterface::Open(CVMEInterface::A32, my_nCrate); + my_pMemory = (volatile unsigned int*)CVMEInterface::Map(fd,my_nMemOffset, + CADC2530_MEMSIZE); + + my_nMemFd = fd; // Save for destruction. +} + +/*==============================================================*/ +/** @fn CADC2530::destroyMemory() +* @brief Unmap this card's list/histogram memory. +* +* Destroy the list/histogram memory map for this card. +* +* @param None +* @return None +*/ +void CADC2530::destroyMemory() { + if (my_pMemory == NULL) return; + + + CVMEInterface::Unmap(my_nMemFd,(void*)my_pMemory,CADC2530_MEMSIZE); + CVMEInterface::Close(my_nMemFd); + + my_pMemory = NULL; + my_nMemFd = NULL; +} + +/*==============================================================*/ +/** @fn CADC2530::clearMemory() +* @brief Zero out the histogram/list memory. +* +* Write zeroes to all locations in the histogram/list memory. +* +* @throw string describing why the method failed. +* @param None +* @return None +*/ +void CADC2530::clearMemory() { + // We must have a memory map first. + if (my_pMemory == NULL) { + char buffer[256]; + sprintf(buffer, "CADC2530::clearMemory(): Cannot clear list/histogram memory without first having a memory map for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase); + throw string(buffer); + } + + for (int i = 0x0; i < (CADC2530_MEMSIZE/4); i++) { + + ((volatile unsigned int*)my_pMemory)[i] = (unsigned int)0x0; + } +} + +/*==============================================================*/ +/** @fn CADC2530::clearHistogramMemory() +* @brief Zero out only histogram memory. +* +* Write zeroes to all locations in only the histogram memory. +* Since the memory used for histogramming is significantly +* smaller that that used in list mode, clearing only histogram +* memory is faster than clearing all of the card's memory. +* +* @throw string describing why the method failed. +* @param None +* @return None +*/ +void CADC2530::clearHistogramMemory() { + // We must have a memory map first. + if (my_pMemory == NULL) { + char buffer[256]; + sprintf(buffer, "CADC2530::clearHistogramMemory(): Cannot clear histogram memory without first having a memory map for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase); + throw string(buffer); + } + + for (int i = 0x0; i < (CADC2530_HISTOMEMSIZE/4); i++) { + ((volatile unsigned int*)my_pMemory)[i] = (unsigned int)0x0; + } +} + +/*==============================================================*/ +/** @fn CADC2530::resetCard() +* @brief Reset card to a set of initial settings. +* +* Reset this card to a set of initial settings. This includes +* issuing a CSR clear and FFCLR and setting the CSR to an +* all zero state. This does not clear the list/histogram +* memory (call clearMemory() or clearHistogramMemory() to zero +* all list/histogram memory or just histogram memory respectively). +* +* @throw string describing why the method failed. +* @param None +* @return None +*/ +void CADC2530::resetCard() { + // We must have a memory map first. + if (my_pModule == NULL) { + char buffer[256]; + sprintf(buffer, "CADC2530::resetCard(): Cannot reset this card without first having a memory map for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase); + throw string(buffer); + } + + disarm(); + resetCTR(); + setLLD(0x0); + setULD(0x0); + setInterruptVector(0x0); + setInterruptMask(0x0); + fastClear(); + resetCSR(); + clearEventCounter(); + clearListAddress(); + clearFullnessFlags(); + modeHistogram(false); +} + +/*==============================================================*/ +/** @fn CADC2530::destroyModule() +* @brief Unmap this card's register memory. +* +* Destroy the register memory map for this card. The card +* is also reset (resetCard()). +* +* @param None +* @return None +*/ +void CADC2530::destroyModule() { + if (my_pModule == NULL) return; + + resetCard(); + + CVMEInterface::Unmap(my_nModFd,(void*)my_pModule,CADC2530_REGSIZE); + CVMEInterface::Close(my_nModFd); + + my_pModule = NULL; + my_nModFd = NULL; +} + +/*==============================================================*/ +/** @fn CADC2530::mapCard() +* @brief Map the ADC card into memory. +* +* Given the values in +* - my_nCrate - Physical crate number. +* - my_nBase - Base address. +* +* - Creates a map to the registers of the module. +* - Creates a map to the list/histogram memory of the module. +* +* @throw string describing why the method failed. +* @param None +* @return None +*/ +void CADC2530::mapCard() { + mapModule(); + mapMemory(); +} + +/*==============================================================*/ +/** @fn CADC2530::destroyCard() +* @brief Unmap this card. +* +* Destroy the memory maps for this card. +* +* @param None +* @return None +*/ +void CADC2530::destroyCard() { + destroyMemory(); + destroyModule(); +} + +/*==============================================================*/ +/** @fn CADC2530::arm() +* @brief Start acquisition according to the current mode setting. +* +* Start acquistion according to the current mode (list or +* histogram) setting. +* +* @param None +* @return None +*/ +void CADC2530::arm() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.ARM = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::disarm() +* @brief Stop acquisition. +* +* Stop either histogram or list mode acquistion depending on +* setting. +* +* @param None +* @return None +*/ +void CADC2530::disarm() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.ARM = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::dataReadyOnEvent() +* @brief Data ready when there's at least one event. +* +* The data ready flag will be set when there's at least one +* event. This is the default for gate mode (list memory) +* operation. +* +* @see dataReadOnFullness() +* @param None +* @return None +*/ +void CADC2530::dataReadyOnEvent() { + my_eventmode = true; + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.DR = 1; + csr.bits.FHE = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::dataReadyOnFullness() +* @brief Data ready determined by fullness flags. +* +* The data ready flag will be set based on fullness flag +* register bits. This is the default for histogram mode. +* +* @see dataReadOnEvent() +* @param None +* @return None +*/ +void CADC2530::dataReadyOnFullness() { + my_eventmode = false; + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.DR = 1; + csr.bits.FHE = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::enableGate() +* @brief Enable gate mode. +* +* Enable mode that uses front panel master gate. +* +* @param None +* @return None +*/ +void CADC2530::enableGate() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.GE = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::disableGate() +* @brief Disable gate mode. +* +* Disable mode that uses front panel master gate. +* +* @param None +* @return None +*/ +void CADC2530::disableGate() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.GE = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::enableZeroCnv() +* @brief Enable zero conversion. +* +* Enable zero conversion. +* +* @param None +* @return None +*/ +void CADC2530::enableZeroCnv() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.ZE = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::disableZeroCnv() +* @brief Disable zero conversion. +* +* Disable zero conversion. +* +* @param None +* @return None +*/ +void CADC2530::disableZeroCnv() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.ZE = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::enableCalibration() +* @brief Enable calibration. +* +* Enable calibration. When enabled the calibration and +* test register (CTR) functions are enabled. +* +* @param None +* @return None +*/ +void CADC2530::enableCalibration() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.SC = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::disableCalibration() +* @brief Disable calibration. +* +* Disable calibrarion. When disabled the calibration and +* test register (CTR) functions are disabled. +* +* @param None +* @return None +*/ +void CADC2530::disableCalibration() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.SC = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::enableSlidingScale() +* @brief Enable sliding scale. +* +* Enable sliding scale. Note, when this CSR bit is 0, sliding +* scale is enabled. +* +* @param None +* @return None +*/ +void CADC2530::enableSlidingScale() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.SS = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::disableSlidingScale() +* @brief Disable sliding scale. +* +* Disable sliding scale. Note, when this CSR bit is 1, sliding +* scale is disabled. +* +* @param None +* @return None +*/ +void CADC2530::disableSlidingScale() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.SS = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::enableInterrupt() +* @brief Enable interrupt. +* +* Enable interrupt. An IRQ is generated if the CSR interrupt +* status bit is set and interrupts are enabled. The IRQ number +* is determined by the CSR interrupt priority level. This bit +* is cleared during the interrupt cycle ROAK. +* +* @param None +* @return None +*/ +void CADC2530::enableInterrupt() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.IE = 1; + setCSRbits(csr.csrval,csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::disableInterrupt() +* @brief Disable interrupt. +* +* Disable interrupt. An IRQ is generated if the CSR interrupt +* status bit is set and interrupts are enabled. The IRQ number +* is determined by the CSR interrupt priority level. This bit +* is cleared during the interrupt cycle ROAK. +* +* @param None +* @return None +*/ +void CADC2530::disableInterrupt() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.IE = 1; + resetCSRbits(csr.csrval); +} + +/*==============================================================*/ +/** @fn CADC2530::isArmed() +* @brief Check if acquisition has been started. +* +* Check whether acquisition has been started. +* +* @param None +* @return None +*/ +bool CADC2530::isArmed() { + ADCcsr_t csr; + csr.csrval = getCSR(); + return (csr.bits.ARM == 1); +} + +/*==============================================================*/ +/** @fn CADC2530::modeHistogram(bool indgates) +* @brief Set acquisition to histogram mode. +* +* Set acquisition to histogram mode. If indgates is false, +* then use self gating. If indgates is true, use individual +* gates on front panel. +* +* @param indgates True if individual front panel gates are to be used. +* @return None +*/ +void CADC2530::modeHistogram(bool indgates) { + ADCcsr_t csr; + + csr.csrval = 0; + csr.bits.HE = 1; + setCSRbits(csr.csrval,csr.csrval); + + if (indgates) { + csr.csrval = 0; + csr.bits.GE = 1; + setCSRbits(csr.csrval,csr.csrval); + } else { + csr.csrval = 0; + csr.bits.GE = 1; + resetCSRbits(csr.csrval); + } + + dataReadyOnFullness(); +} + +/*==============================================================*/ +/** @fn CADC2530::modeGate() +* @brief Set acquisition to gate mode. +* +* Set acquisition to gate mode. Gate mode using +* front panel master gate with data stored in list mode. +* +* @param None +* @return None +*/ +void CADC2530::modeGate() { + ADCcsr_t csr; + csr.csrval = 0; + csr.bits.HE = 1; + resetCSRbits(csr.csrval); + csr.csrval = 0; + csr.bits.GE = 1; + setCSRbits(csr.csrval,csr.csrval); + dataReadyOnEvent(); +} + +/*==============================================================*/ +/** @fn CADC2530::getEventCounter() +* @brief Return the event counter. +* +* Return the number of events currently recorded by the +* ADC event counter. +* +* @param None +* @return The number of events. +*/ +unsigned int CADC2530::getEventCounter() { + unsigned short ecls = ((volatile ADCregisters_t*)my_pModule)->EventCounterLS; + unsigned short ecms = ((volatile ADCregisters_t*)my_pModule)->EventCounterMS; + + unsigned int evtcnt = ((ecms&0x00FF)<<16)|(ecls&0x0000FFFF); + return evtcnt; +} + +/*==============================================================*/ +/** @fn CADC2530::clearEventCounter() +* @brief Clear the ADC event counter. +* +* Set the ADC event counter to zero. +* +* @param None +* @return None +*/ +void CADC2530::clearEventCounter() { + my_cureventpos= 0; + + ((volatile ADCregisters_t*)my_pModule)->EventCounterLS = 0x0; + ((volatile ADCregisters_t*)my_pModule)->EventCounterMS = 0x0; + +} + +/*==============================================================*/ +/** @fn CADC2530::getListAddress() +* @brief Return the list address counter. +* +* Return the list address counter. Can be used to determine +* the amount of data has in list memory when in gate mode. +* +* @see clearListAddress() +* @param None +* @return The list address counter. +*/ +unsigned int CADC2530::getListAddress() { + unsigned short lals = ((volatile ADCregisters_t*)my_pModule)->ListAddressLS; + unsigned short lams = ((volatile ADCregisters_t*)my_pModule)->ListAddressMS; + + unsigned int lstaddr = ((lams&0x0000FFFF)<<16)|(lals&0x0000FFFF); + return lstaddr; +} + +/*==============================================================*/ +/** @fn CADC2530::clearListAddress() +* @brief Clear the list address counter. +* +* Set the list address counter to zero. +* +* @see getListAddress() +* @param None +* @return None +*/ +void CADC2530::clearListAddress() { + + ((volatile ADCregisters_t*)my_pModule)->ListAddressLS = 0x0; + ((volatile ADCregisters_t*)my_pModule)->ListAddressMS = 0x0; +} + +/*==============================================================*/ +/** @fn CADC2530::isBusy() +* @brief Check if the module is busy. +* +* Check is the module has accepted input pulses and that they +* are being converted. +* +* @param None +* @return True if the module is busy. +*/ +bool CADC2530::isBusy() { + ADCcsr_t csr; + csr.csrval = getCSR(); + return (csr.bits.RSTBSY == 1); +} + +/*==============================================================*/ +/** @fn CADC2530::clearFullnessFlags() +* @brief Clear the fullness flags to zero. +* +* Clear the fullness flags to zero. +* +* @param None +* @return None +*/ +void CADC2530::clearFullnessFlags() { + + ((volatile ADCregisters_t*)my_pModule)->FullnessFlag = 0x0; + +} + +/*==============================================================*/ +/** @fn CADC2530::getFullnessFlags() +* @brief Get the fullness flags. +* +* Get the fullness flags. Note, the meaning of the +* individual bits is dependent on whether the module is in +* list or histogram mode. +* +* @param None +* @return The current fullness flags. +*/ +unsigned short CADC2530::getFullnessFlags() { + unsigned short flags = 0; + flags = ((volatile ADCregisters_t*)my_pModule)->FullnessFlag; + + return flags; +} + +/*==============================================================*/ +/** @fn CADC2530::isChannelFull(unsigned short aChan) +* @brief Check if a histogram channel is full. +* +* Check if the specified histogram channel is full (overflow). Note, +* no determination is made as whether the module is actually +* operating in histogram mode. Also, histogram mode flags are +* shared with list mode flags. +* +* @throw String exception on error. +* @param aChan The channel to check in the range [1-8]. +* @return If the fullness flag of the specified channel is set. +*/ +bool CADC2530::isChannelFull(unsigned short aChan) { + if ((aChan < 1)||(aChan > 8)) { + char buffer[256]; + sprintf(buffer, "CADC2530::isChannelFull(): When checking channel fullness, the channel specified must be in the range [1-8] (channel == %d).\n",aChan); + throw string(buffer); + } + + ADCfullnessflag_t fflags; + fflags.flags = getFullnessFlags(); + unsigned char mask = 0x1; + mask = (mask << (aChan - 1)); + return ((fflags.bytes.FULL & mask) > 0); +} + +/*==============================================================*/ +/** @fn CADC2530::channelHasData(unsigned short aChan) +* @brief Check if a histogram channel has data. +* +* Check if the specified histogram channel has data. Note, +* no determination is made as whether the module is actually +* operating in histogram mode. Also, histogram mode flags are +* shared with list mode flags. +* +* @throw String exception on error. +* @param aChan The channel to check in the range [1-8]. +* @return If the half-fullness flag of the specified channel is set. +*/ +bool CADC2530::channelHasData(unsigned short aChan) { + if ((aChan < 1)||(aChan > 8)) { + char buffer[256]; + sprintf(buffer, "CADC2530::channelHasData(): When checking channel fullness, the channel specified must be in the range [1-8] (channel == %d).\n",aChan); + throw string(buffer); + } + + ADCfullnessflag_t fflags; + fflags.flags = getFullnessFlags(); + unsigned char mask = 0x1; + mask = (mask << (aChan - 1)); + return ((fflags.bytes.HALFFULL & mask) > 0); +} + +/*==============================================================*/ +/** @fn CADC2530::isListFull() +* @brief Check if list mode memory is full. +* +* Check if list mode memory is full. Note, +* no determination is made as whether the module is actually +* operating in list mode. Also, List mode flags are shared with +* histogram mode flags. +* +* @param None. +* @return If the list mode fullness flag is set. +*/ +bool CADC2530::isListFull() { + ADCfullnessflag_t fflags; + fflags.flags = getFullnessFlags(); + unsigned char mask = 0x1; + return ((fflags.bytes.FULL & mask) > 0); +} + +/*==============================================================*/ +/** @fn CADC2530::isListHalfFull() +* @brief Check if list mode memory is half full. +* +* Check if list mode memory is half full. Note, +* no determination is made as whether the module is actually +* operating in list mode. Also, List mode flags are shared with +* histogram mode flags. +* +* @param None. +* @return If the list mode half-fullness flag is set. +*/ +bool CADC2530::isListHalfFull() { + ADCfullnessflag_t fflags; + fflags.flags = getFullnessFlags(); + unsigned char mask = 0x1; + return ((fflags.bytes.HALFFULL & mask) > 0); +} + +/*==============================================================*/ +/** @fn CADC2530::setSSTR(unsigned short sstrval) +* @brief Set the sliding scale test register. +* +* Set the slid... [truncated message content] |
From: <ro...@us...> - 2008-10-15 19:06:00
|
Revision: 2012 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2012&view=rev Author: ron-fox Date: 2008-10-15 19:05:55 +0000 (Wed, 15 Oct 2008) Log Message: ----------- Mostly just update docs of tclplus to include the new event driven commanders, and tcl server component. Modified Paths: -------------- trunk/nextgen/base/tclplus/tclplus.xml trunk/nextgen/configure.ac trunk/nextgen/sbs/Makefile.am trunk/nextgen/sbs/driver/src/Makefile.am Modified: trunk/nextgen/base/tclplus/tclplus.xml =================================================================== --- trunk/nextgen/base/tclplus/tclplus.xml 2008-10-15 13:40:24 UTC (rev 2011) +++ trunk/nextgen/base/tclplus/tclplus.xml 2008-10-15 19:05:55 UTC (rev 2012) @@ -199,7 +199,7 @@ </para> <methodsynopsis> - <type>void</type> <function>getProgramArgs</function> + <type>void</type> <methodname>getProgramArgs</methodname> <methodparam> <type>int&</type> <parameter>argc</parameter> </methodparam> @@ -4210,7 +4210,7 @@ <refsynopsisdiv> <programlisting> -#include <CTCLLiveEventLoop> +#include <CTCLLiveEventLoop.h> </programlisting> <classsynopsis> <ooclass><classname>CTCLLiveEventLoop</classname></ooclass> @@ -4393,9 +4393,733 @@ </refentry> + <refentry id="manpage.ctclchannelcommander"> + <refmeta> + <refentrytitle>CTCLChannelCommander</refentrytitle> + <manvolnum>3daq</manvolnum> + </refmeta> + <refnamediv> + <refname>CTCLChannelCommander</refname> + <refpurpose>Accept commands on a Tcl channel from the event loop.</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CTCLChannelCommander.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CTCLChannelCommander</classname></ooclass> + <constructorsynopsis> + <methodname>CTCLChannelCommander</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>interp</parameter> + </methodparam> + <methodparam> + <type>Tcl_Channel</type> <parameter>channel</parameter> + </methodparam> + </constructorsynopsis> + <destructorsynopsis> + <modifier>virtual</modifier> <methodname>~CTCLChannelCommander</methodname> + <void /> + </destructorsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>start</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>stop</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <type>Tcl_Channel</type> <methodname>getChannel</methodname> + <void /> <modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>onInput</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> <methodname>onInputException</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> <methodname>onEndFile</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>onCommand</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>returnResult</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> <methodname>prompt1</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>prompt2</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>sendPrompt</methodname> + <methodparam> + <type>std::string</type> <parameter>prompt</parameter> + </methodparam> + </methodsynopsis> + + + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + The <classname>CTCLChannelCommander</classname> is a class that + registers an input event handler for a Tcl channel. When input + is available on the channel, a line of text is read, and appended + to a command under construction. When the command is syntactically + complete, it is dispatched to a Tcl interpreter for execution. + </para> + <para> + The subclass <classname>CTCLStdioCommander</classname> is specifically + tailored to accept commands on stdin. ALong with the server listener + <classname>CTCLServer</classname>, <classname>CTCLTcpServerInstance</classname> + is tailored to accpet commands on a socket. + </para> + <para> + Many aspects of the class are tailorable by overriding the various + methods in derived classes. The class is capable of generating prompts + in case the channel is interactive. The classs can also return the + results of commands to the client over the medium of its choice. + End file and exception handling can be simlarly tailored. + </para> + <para> + When deriving a specific class be sure you understand the default actions + of all of the base class members. You may save a great deal of work by + carefully chosing exactly which members to override, or generate a + great deal of work by making poor choices. + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis> + <methodname>CTCLChannelCommander</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>interp</parameter> + </methodparam> + <methodparam> + <type>Tcl_Channel</type> <parameter>channel</parameter> + </methodparam> + </methodsynopsis> + <para> + Constructs a new channel commander. Activation of the commander is + a two step process. First the commander is constructed, second + it <methodname>start</methodname> method is called to register the + event handlers. + </para> + <para> + <parameter>interp</parameter> is a pointer to the interpreter + channel on to which the commands will be dispatched. + <parameter>channel</parameter> is the channel from which commands + will be accepted. + </para> + <para> + The application must also be visiting the event loop for + commands to be processed from the + <parameter>channel</parameter>. + Tk applications automatically run the event loop. + Pure Tcl applications run the event loop only when + <command>vwait</command> is waiting, while the + special shell or tcl applications based around + <classname>CTCLLiveEventLoop</classname> run the + event loop automatically just like Tk does. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>start</methodname> + <void /> + </methodsynopsis> + <para> + Enables processing of commands from the channel. When + the event loop is entered, if the channel is readable, + control will be to + <methodname>onInput</methodname> in object context. + It is not considered an error to call + <methodname>start</methodname> when event processing + is in progress. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>stop</methodname> + <void /> + </methodsynopsis> + <para> + Requests channel processing be disabled. The event handlers + that arrange for control to be dispatched to the + <methodname>onInput</methodname> + method are disabled. The channel remains open and must + be closed (if desired) by any client software. + </para> + <methodsynopsis> + <type>Tcl_Channel</type> <methodname>getChannel</methodname> + <void /> <modifier>const</modifier> + </methodsynopsis> + <para> + Returns the channel from which commands are being accepted. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>onInput</methodname> + <void /> + </methodsynopsis> + <para> + This member function is called when data can be read from the + input channel. The function attempts to read a line of text. + The text is appended to a command under construction and, + if <function>Tcl_CommandComplete</function> says that + string is a syntactically complete command, + <methodname>onCommand</methodname> is invoked to execute the + command. + </para> + <para> + All of this command acquisition and exection is also mixed up + with prompting. + <methodname>prompt1</methodname> + is called when the object is ready to get a new command, and + <methodname>prompt2</methodname> is called when the + object is ready to accept the next line of a multi-line command. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> <methodname>onInputException</methodname> + <void /> + </methodsynopsis> + <para> + Called when an exception condition is detected on the channel. The default implementation + calls + <methodname>onEndFile</methodname> + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> <methodname>onEndFile</methodname> + <void /> + </methodsynopsis> + <para> + Called when reads of the channel indicate an end file condition. + <methodname>onInputException</methodname>'s default implementation + also calls this. The default behavior is to invoke + <methodname>stop</methodname> so that no additional events will + be posted. This is the normal and reasonable behavior because + a channel with an endfile condition continously generates + readable events. + </para> + <para> + The channel remains open. It is always up to client software to + close the channel. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>onCommand</methodname> + <void /> + </methodsynopsis> + <para> + Called when a complete command has been accepted. Complete in this + case means syntactically complete. It does not imply correctness, + or even proper number of arguments. + </para> + <para> + Default behavior is to submit the command string to the + interpreter. Once the command has been executed, + <methodname>returnResult</methodname> + is executed to allow the command result to be reported + if desired. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>returnResult</methodname> + <void /> + </methodsynopsis> + <para> + By default this does nothing. It is provided to allow subclasses + to tailore what is done with command results. For example, + the + <classname>CTCLStdioCommander</classname> + class reports the result on + <literal>stdout</literal>. + <classname>CTCLTcpServerInstance</classname> on the other hand + reports the result back to the client over the socket. + </para> + <para> + The <methodname>GetResultString</methodname> method of the + interpreter object (the pointer <varname>m_pInterp</varname> + is a pointer to the interpreter object) should be used to + get the result string. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> <methodname>prompt1</methodname> + <void /> + </methodsynopsis> + <para> + Called when its time to prompt for the first line of a command. + This calls + <methodname>prompt1String</methodname> to get the prompt string, + and calls + <methodname>sendPrompt</methodname> to actually emit the prompt. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>prompt2</methodname> + <void /> + </methodsynopsis> + <para> + Called when its time to prompt for additional linesof a command. + This calls + <methodname>prompt2String</methodname> to get the prompt string + and calls + <methodname>sendPrompt</methodname> to actually emit the prompt. + </para> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>sendPrompt</methodname> + <methodparam> + <type>std::string</type> <parameter>prompt</parameter> + </methodparam> + </methodsynopsis> + </refsect1> + <refsect1> + <title>Prompting</title> + <para> + The class provides a framework for prompting interactive channels. + This frameworks is based on two prompt strings that can be gotten + via calls to + <methodname>prompt1String</methodname> and + <methodname>prompt2String</methodname> + respectively. + </para> + <para> + The first of these prompts is emitted when the software is + ready to accept the first line of a new command. + By default it is the text "<literal>% </literal>". Scripts + can customize this prompt by defining the + variable <varname>tcl_prompt1</varname> to be a script + whose returned value is the prompt. + </para> + <para> + The second of these prompts is emitted when the software + is ready to accept continuation lines of multiline commands. + By default it is the text "<literal>%_ </literal>". + Scripts can customize this prompt by defining the + variable <varname>tcl_prompt2</varname> to be a script + whose returned value is the desired prompt. + </para> + </refsect1> + </refentry> + <refentry id="manpage.CTCLStdioCommander"> + <refmeta> + <refentrytitle>CTCLStdioCommander</refentrytitle> + <manvolnum>3daq</manvolnum> + </refmeta> + <refnamediv> + <refname>CTCLStdioCommander</refname> + <refpurpose>Event driven command input on stdin/stdout</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CTCLStdioCommander.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CTCLStdioCommander</classname></ooclass> + <constructorsynopsis> + <methodname>CTCLStdioCommander</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + </methodparam> + </constructorsynopsis> + <destructorsynopsis> + <modifier>virtual</modifier> <methodname>~CTCLStdioCommander</methodname> + <void /> + </destructorsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>sendPrompt</methodname> + <methodparam> + <type>std::string</type> <parameter>prompt</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>returnResult</methodname> + <void /> + </methodsynopsis> + + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + Provides a commander that can be hooked to the event loop to allow + event loop driven applications to continue to process commands on + stdin/stdout as interactive shells do. + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis> + <methodname>CTCLStdioCommander</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + </methodparam> + </methodsynopsis> + <para> + Constructs a commander. <parameter>pInterp</parameter> is the + interpreter to which the complete commands will be submitted. + </para> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>sendPrompt</methodname> + <methodparam> + <type>std::string</type> <parameter>prompt</parameter> + </methodparam> + </methodsynopsis> + <para> + Overrides the base class <methodname>sendPrompt</methodname> + method by sending the requested <parameter>prompt</parameter> + string to the <type>Tcl_Channel</type> Tcl has open on + <literal>stdout</literal>. The channel is also flushed to + ensure that the prompt is made immediately visible. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>returnResult</methodname> + <void /> + </methodsynopsis> + <para> + Overrides the base class member. + Retrieves the result from the interpreter, appends a newline + character and passes the resulting string to + <methodname>sendPrompt</methodname> which makes the result + visible on stdout. + </para> + </refsect1> + </refentry> + + + <refentry id="manpage.CTCLServer"> + <refmeta> + <refentrytitle>CTCLServer</refentrytitle> + <manvolnum>3daq</manvolnum> + </refmeta> + <refnamediv> + <refname>CTCLServer</refname> + <refpurpose>Listener for a Tcl server.</refpurpose> + </refnamediv> + <refsynopsisdiv> + <programlisting> +#include <CTCLServer.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CTCLServer</classname></ooclass> + <constructorsynopsis> + <methodname>CTCLServer</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + </methodparam> + <methodparam> + <type>int</type> <parameter>port</parameter> + </methodparam> + </constructorsynopsis> + <destructorsynopsis> + <modifier>virtual</modifier> <methodname>~CTCLServer</methodname> + <void /> + </destructorsynopsis> + <methodsynopsis> + <type>void</type> + <methodname>instanceExit</methodname> + <methodparam> + <type>CTCLTcpServerInstance*</type> <parameter>pInstance</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <type>void</type> + <methodname>shutdown</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>protected virtual</modifier> + <type>bool</type> <methodname>allowConnection</methodname> + <methodparam> + <type>Tcl_Channel</type> <parameter>connection</parameter> + </methodparam> + <methodparam> + <type>std::string</type> <parameter>hostname</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <modifier>protected virtual</modifier> + <type>CTCLTcpServerInstance*</type> + <methodname>createInstance</methodname> + <methodparam> + <type>Tcl_Channel</type> <parameter>connection</parameter> + </methodparam> + <methodparam> + <type>std::string</type> <parameter>hostname</parameter> + </methodparam> + </methodsynopsis> + + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + Tcl servers allow a Tcp/Ip client to connect to a tcl application + and poke commands at it. While this is a very powerful communications + mechanism, it should be used very cautiously as it can also be quite + dangerous (imagine a client pushing a command like + <command>exec /bin/bash -c rm -rf ~</command> for example). + </para> + <para> + <classname>CTCLServer</classname> is a class that provides the listener + portion of the server. The application that uses this must execute + a Tcl event loop in a timely fashion. + <classname>CTCLServer</classname> processes connections and creates, + where appropriate <classname>CTCLTcpServerInstance</classname> objects + that handle communication with clients. + The server object maintains a directory of server instances so that when + asked to shutdown it can shutdown all server instances as well. + </para> + <para> + The class provides strategy pattern hooks to support arbitrary + authorization models, as well as the production of any subclass + of <classname>CTCLTcpServerInstance</classname> to process + the commands. + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis> + <methodname>CTCLServer</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + </methodparam> + <methodparam> + <type>int</type> <parameter>port</parameter> + </methodparam> + </methodsynopsis> + <para> + Constructs and activates a server object. Activation means that + the Tcl event loop can dispatch events for client connections + to the object for processing. + <parameter>pInterp</parameter> is the interpreter this server + is supposed to be servicing. In the standard scheme, this is + the interpreter to which commands will be dispatched. + <parameter>port</parameter> is the Tcp/IP port on which the + server will listen for connections. + </para> + <methodsynopsis> + <type>void</type> + <methodname>instanceExit</methodname> + <methodparam> + <type>CTCLTcpServerInstance*</type> <parameter>pInstance</parameter> + </methodparam> + </methodsynopsis> + <para> + The server maintains a directory of server instances. When server + instances exit they must call this function in the server listener + passing a pointer to themselves (<varname>this</varname>) as a + parameter. This function locates the instance in the + directory, removes it from the directory and + <emphasis>deletes that object</emphasis>. + </para> + <para> + Having called this, the server instance should return + immediately as its object context has become invalid. + If the server listener object is asked to shutdown, it will + also call <methodname>instanceExit</methodname> on all + instances to shut them down as well. + </para> + <methodsynopsis> + <type>void</type> + <methodname>shutdown</methodname> + <void /> + </methodsynopsis> + <para> + Stops listening for connections on the server port and + shuts down all instances by invoking + <methodname>instanceExit</methodname> on them. + </para> + <methodsynopsis> + <modifier>protected virtual</modifier> + <type>bool</type> <methodname>allowConnection</methodname> + <methodparam> + <type>Tcl_Channel</type> <parameter>connection</parameter> + </methodparam> + <methodparam> + <type>std::string</type> <parameter>hostname</parameter> + </methodparam> + </methodsynopsis> + <para> + Called at connection time to determine if the connection should + be allowed. <parameter>connection</parameter> is the + <type>Tcl_Channel</type> that is open on the client. + overrides of this are perfectly free to do any sort of + communication back and fort with the client to determine + its elligibility to connect. + </para> + <para> + <parameter>hostname</parameter> is the name of the host + that is connecting. This allows a host based authentication + scheme to be developed. + </para> + <para> + The function must return <literal>true</literal> to accept the + connection and <literal>false</literal> to deny it. + </para> + <methodsynopsis> + <modifier>protected virtual</modifier> + <type>CTCLTcpServerInstance*</type> + <methodname>createInstance</methodname> + <methodparam> + <type>Tcl_Channel</type> <parameter>connection</parameter> + </methodparam> + <methodparam> + <type>std::string</type> <parameter>hostname</parameter> + </methodparam> + </methodsynopsis> + <para> + Called to create a client instance. The client instance is responsible + for interacting with the client to do whatever communication is needed. + By making this virtual, any type descended from + <classname>CTCLTcpServerInstance</classname> can be created. + </para> + <para> + <parameter>connection</parameter> is the <type>Tcl_Channel</type> + open on the client. + <parameter>hostname</parameter> is the host that is connecting. + </para> + </refsect1> + + </refentry> + + <refentry id="manpage.CTCLTcpServerInstance"> + <refmeta> + <refentrytitle>CTCLTcpServerInstance</refentrytitle> + <manvolnum>3daq</manvolnum> + </refmeta> + <refnamediv> + <refname>CTCLTcpServerInstance</refname> + <refpurpose>Channel commander that is a server instance for <classname>CTCLServer</classname></refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CTCLTcpServerInstance.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CTCLTcpServerInstance : public CTCLChannelCommander</classname></ooclass> + <constructorsynopsis> + <methodname>CTCLTcpServerInstance</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + </methodparam> + <methodparam> + <type>Tcl_Channel</type> <parameter>connection</parameter> + </methodparam> + <methodparam> + <type>CTCLServer*</type> <parameter>pServer</parameter> + </methodparam> + </constructorsynopsis> + <destructorsynopsis> + <modifier>virtual</modifier> <methodname>~CTCLTcpServerInstance</methodname> + <void /> + </destructorsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>onEndFile</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>returnResult</methodname> + <void /> + </methodsynopsis> + + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + Server instance that takes client commands and submits them to + an interpreter. The results of each command are sent back to the + client. At this point the client can only look at the + result value to determine if there was an error as no error indication + is passed back. + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <constructorsynopsis> + <methodname>CTCLTcpServerInstance</methodname> + <methodparam> + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + </methodparam> + <methodparam> + <type>Tcl_Channel</type> <parameter>connection</parameter> + </methodparam> + <methodparam> + <type>CTCLServer*</type> <parameter>pServer</parameter> + </methodparam> + </constructorsynopsis> + <para> + Constructs a new server instance. + <parameter>pInterp</parameter> is the interpreter to which + commands should be directed. + <parameter>connection</parameter> is the <type>Tcl_Channel</type> + that represents the Tcp/IP connection to the client. + <parameter>pServer</parameter> is the TCL server object + that starts us. That server's + <methodname>instanceExit</methodname> member should be called + to shut down and clean up this object. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>onEndFile</methodname> + <void /> + </methodsynopsis> + <para> + Override to end of file handling. Closes the + channel and invokes the + server listener's <methodname>instanceExit</methodname> + method to get ourselves deleted. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>returnResult</methodname> + <void /> + </methodsynopsis> + <para> + Returns a command result by fetching it from the interpreter + and sending it back to the client on the socket. + </para> + </refsect1> + </refentry> + <!-- /manpage --> - <!-- manpage 1daq --> <refentry id="manpage.evttclsh"> Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2008-10-15 13:40:24 UTC (rev 2011) +++ trunk/nextgen/configure.ac 2008-10-15 19:05:55 UTC (rev 2012) @@ -447,6 +447,7 @@ sbs/tclpackage/Makefile sbs/puretcl/Makefile sbs/vmemodules/Makefile + sbs/readout/Makefile docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/sbs/Makefile.am =================================================================== --- trunk/nextgen/sbs/Makefile.am 2008-10-15 13:40:24 UTC (rev 2011) +++ trunk/nextgen/sbs/Makefile.am 2008-10-15 19:05:55 UTC (rev 2012) @@ -1 +1 @@ -SUBDIRS = driver nsclapi tclpackage puretcl vmemodules +SUBDIRS = driver nsclapi tclpackage puretcl vmemodules readout Modified: trunk/nextgen/sbs/driver/src/Makefile.am =================================================================== --- trunk/nextgen/sbs/driver/src/Makefile.am 2008-10-15 13:40:24 UTC (rev 2011) +++ trunk/nextgen/sbs/driver/src/Makefile.am 2008-10-15 19:05:55 UTC (rev 2012) @@ -29,6 +29,7 @@ INCLUDES = -I. -I../include \ -DBT1003 -DNDEBUG -DBT_INLINE \ -D_POSIX_C_SOURCE -D_POSIX_THREAD_SEMANTICS \ + -D_XOPEN_SOURCE \ -O2 -Wall -Wstrict-prototypes include_HEADERS = btpiflib.h \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2008-11-13 22:40:09
|
Revision: 2048 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2048&view=rev Author: ron-fox Date: 2008-11-13 22:40:07 +0000 (Thu, 13 Nov 2008) Log Message: ----------- Add top level check-TESTS target to test all dirs that have a test. Modified Paths: -------------- trunk/nextgen/Makefile.am Added Paths: ----------- trunk/nextgen/dotests Modified: trunk/nextgen/Makefile.am =================================================================== --- trunk/nextgen/Makefile.am 2008-11-13 21:14:32 UTC (rev 2047) +++ trunk/nextgen/Makefile.am 2008-11-13 22:40:07 UTC (rev 2048) @@ -1,8 +1,16 @@ +if BUILD_SBS_DRIVER + SBSDIRS=sbs +endif + SUBDIRS = base/CopyrightTools base/exception base/tclplus servers base \ - daq utilities docbuild docconfig usb sbs + daq utilities docbuild docconfig usb $(SBSDIRS) install-data-local: $(mkinstalldirs) @prefix@/TclLibs echo "pkg_mkIndex @prefix@/TclLibs *.so" >makeindex.tcl $(TCLSH_CMD) <makeindex.tcl + +EXTRA_DIST=dotests + +TESTS=./dotests Added: trunk/nextgen/dotests =================================================================== --- trunk/nextgen/dotests (rev 0) +++ trunk/nextgen/dotests 2008-11-13 22:40:07 UTC (rev 2048) @@ -0,0 +1,8 @@ + for f in `find . -name Makefile -exec grep -l check-TESTS {} \;` +do + if test $f != ./Makefile + then + echo testing with $f + (cd `dirname $f`; make check-TESTS) + fi +done Property changes on: trunk/nextgen/dotests ___________________________________________________________________ Added: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2009-03-27 18:20:06
|
Revision: 2113 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2113&view=rev Author: ron-fox Date: 2009-03-27 18:19:53 +0000 (Fri, 27 Mar 2009) Log Message: ----------- Not sure what all this is~ Modified Paths: -------------- trunk/nextgen/base/CopyrightTools/test trunk/nextgen/base/exception/Makefile.am trunk/nextgen/configure.ac Added Paths: ----------- trunk/nextgen/base/exception/CInvalidPacketStateException.cpp trunk/nextgen/base/exception/CInvalidPacketStateException.h Modified: trunk/nextgen/base/CopyrightTools/test =================================================================== (Binary files differ) Added: trunk/nextgen/base/exception/CInvalidPacketStateException.cpp =================================================================== --- trunk/nextgen/base/exception/CInvalidPacketStateException.cpp (rev 0) +++ trunk/nextgen/base/exception/CInvalidPacketStateException.cpp 2009-03-27 18:19:53 UTC (rev 2113) @@ -0,0 +1,377 @@ +/* + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of this License, + you may choose any version ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author to +ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make +exceptions for this. Our decision will be guided by the two goals of +preserving the free status of all derivatives of our free software and of +promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE +THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO +LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR +THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS ' +*/ +static const char* Copyright = "(C) Copyright Michigan State University 2002, All rights reserved"; +//////////////////////////CInvalidPacketStateException.cpp file//////////////////////////////////// +#include <config.h> +#include "CInvalidPacketStateException.h" + +#ifdef HAVE_STD_NAMESPACE +using namespace std; +#endif +/*! + Default constructor. This is called when declarations of the form e.g.: + - CInvalidPacketStateException object; + are performed. + \param +*/ +CInvalidPacketStateException::CInvalidPacketStateException (bool WasOpen, + const char* pszAction) : + CReadoutException(pszAction), + m_nWasOpen(WasOpen) +{ + BuildReasonText(); +} +/*! + Copy construction. This is invoked when e.g. an object is passed by value + to a function. The copy constructor makes a clone of the rhs object. + \param rhs - Reference to the objet from which this copy will be + constructed. +*/ +CInvalidPacketStateException::CInvalidPacketStateException(const CInvalidPacketStateException& rhs) : + CReadoutException(rhs), + m_nWasOpen(rhs.m_nWasOpen) +{ + BuildReasonText(); +} +/*! + Assignment operation. This member function supports assignment of + an object of this class to an object of the same class. + \param rhs - The right hand side of the assignment to *this. + \returns - a reference to *this +*/ +CInvalidPacketStateException& +CInvalidPacketStateException::operator= (const CInvalidPacketStateException& rhs) +{ + if (this != &rhs) { + CReadoutException::operator= (rhs); + m_nWasOpen = rhs.m_nWasOpen; + BuildReasonText(); + } + return *this; +} +/*! + Equality comparison. + */ +int +CInvalidPacketStateException::operator==(const CInvalidPacketStateException& rhs) +{ + return ( CReadoutException::operator==(rhs) && + (m_nWasOpen == rhs.m_nWasOpen)); // Note that ReasonText is computed from + // object state variables. +} + +/*! + Returns the state of the open flag in the segment. + cast to integer. + +*/ +Int_t +CInvalidPacketStateException::ReasonCode() const +{ + return (Int_t)m_nWasOpen; +} + +/*! + Returns a text string which describes why the exception + was thrown. + +*/ +const char* +CInvalidPacketStateException::ReasonText() const +{ + + return m_sReasonText.c_str(); +} +/*! + Re-computes the reason text from the object's member variables. The implicit + inputs to this function include: + - m_sWasOpen - True if the state was open. + - getAction() returns the action being performed at the time the exception was + detected. +*/ +void +CInvalidPacketStateException::BuildReasonText() +{ + m_sReasonText = "Incorrect handling of a readout packet: "; + m_sReasonText += getAction(); + m_sReasonText += "requires that the packet be "; + m_sReasonText += (m_nWasOpen ? " closed.\n " : " open.\n "); + m_sReasonText += "The actual state was: "; + m_sReasonText += (m_nWasOpen ? "open.\n" : " closed.\n"); + +} Property changes on: trunk/nextgen/base/exception/CInvalidPacketStateException.cpp ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/base/exception/CInvalidPacketStateException.h =================================================================== --- trunk/nextgen/base/exception/CInvalidPacketStateException.h (rev 0) +++ trunk/nextgen/base/exception/CInvalidPacketStateException.h 2009-03-27 18:19:53 UTC (rev 2113) @@ -0,0 +1,82 @@ +/* + This software is Copyright by the Board of Trustees of Michigan + State University (c) Copyright 2005. + + You may use this software under the terms of the GNU public license + (GPL). The terms of this license are described at: + + http://www.gnu.org/licenses/gpl.txt + + Author: + Ron Fox + NSCL + Michigan State University + East Lansing, MI 48824-1321 +*/ + + +//////////////////////////CInvalidPacketStateException.h file////////////////////////////////// + +#ifndef __CINVALIDPACKETSTATEEXCEPTION_H +#define __CINVALIDPACKETSTATEEXCEPTION_H + + + +#ifndef __CREADOUTEXCEPTION_H +#include "CReadoutException.h" +#endif + + + +#ifndef __STL_STRING +#include <string> +#ifndef __STL_STRING +#define __STL_STRING +#endif +#endif + +/*! + Encapsulates exceptions which are thrown as a result of + mis-manipulating packets. + The ReasonCode function returns nonzero if the packet was open. + */ +class CInvalidPacketStateException : public CReadoutException +{ +private: + bool m_nWasOpen; //!< nonzero if packet was open. + std::string m_sReasonText; //!< Reason for exception is built here. + +public: + + CInvalidPacketStateException (bool WasOpen, const char* pszAction); + CInvalidPacketStateException(const CInvalidPacketStateException& rhs); + ~ CInvalidPacketStateException ( ) { } + + CInvalidPacketStateException& operator= (const CInvalidPacketStateException& rhs); + int operator==(const CInvalidPacketStateException& rhs); + int operator!=(const CInvalidPacketStateException& rhs) { + return !(operator==(rhs)); + } + + // Selectors for class attributes: +public: + + int getWasOpen() const { + return m_nWasOpen; + } + + // Mutators: +protected: + + // Class operations: +public: + + Int_t ReasonCode () const ; + virtual const char* ReasonText () const ; + +protected: + void BuildReasonText(); + +}; + +#endif Property changes on: trunk/nextgen/base/exception/CInvalidPacketStateException.h ___________________________________________________________________ Added: svn:executable + * Modified: trunk/nextgen/base/exception/Makefile.am =================================================================== --- trunk/nextgen/base/exception/Makefile.am 2009-03-27 18:19:34 UTC (rev 2112) +++ trunk/nextgen/base/exception/Makefile.am 2009-03-27 18:19:53 UTC (rev 2113) @@ -3,12 +3,12 @@ RangeError.cpp StreamIOError.cpp \ StateException.cpp URIFormatException.cpp \ MonitorException.cpp CInvalidArgumentException.cpp \ - CDuplicateSingleton.cpp CNoSuchObjectException.cpp + CDuplicateSingleton.cpp CNoSuchObjectException.cpp include_HEADERS = ErrnoException.h Exception.h StreamIOError.h \ RangeError.h StateException.h URIFormatException.h \ MonitorException.h CInvalidArgumentException.h \ - CDuplicateSingleton.h CNoSuchObjectException.h + CDuplicateSingleton.h CNoSuchObjectException.h libException_la_LDFLAGS = -version-info $(SOVERSION) \ -Wl,"-rpath-link=$(libdir)" $(THREADLD_FLAGS) Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2009-03-27 18:19:34 UTC (rev 2112) +++ trunk/nextgen/configure.ac 2009-03-27 18:19:53 UTC (rev 2113) @@ -379,7 +379,7 @@ # THREADCXX_FLAGS="-pthread" THREADC_FLAGS="-pthread" -THREADLD_FLAGS="-lpthread" +THREADLD_FLAGS="-lpthread -lrt" AC_SUBST(THREADCXX_FLAGS) AC_SUBST(THREADC_FLAGS) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2009-03-27 18:45:30
|
Revision: 2114 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2114&view=rev Author: ron-fox Date: 2009-03-27 18:45:11 +0000 (Fri, 27 Mar 2009) Log Message: ----------- Add ReadoutGui to the build. Modified Paths: -------------- trunk/nextgen/configure.ac trunk/nextgen/daq/Makefile.am trunk/nextgen/sbs/readout/Makefile.am Added Paths: ----------- trunk/nextgen/daq/readoutgui/ trunk/nextgen/daq/readoutgui/Configuration.tcl trunk/nextgen/daq/readoutgui/DAQParameters.tcl trunk/nextgen/daq/readoutgui/ExpFileSystemConfig.tcl trunk/nextgen/daq/readoutgui/Experiment.tcl trunk/nextgen/daq/readoutgui/InitializeConfiguration.tcl trunk/nextgen/daq/readoutgui/InstallRoot.tcl trunk/nextgen/daq/readoutgui/InstallRoot.tcl.in trunk/nextgen/daq/readoutgui/KeeplistGui.tcl trunk/nextgen/daq/readoutgui/Makefile.am trunk/nextgen/daq/readoutgui/Makefile.in trunk/nextgen/daq/readoutgui/Monitor.tcl trunk/nextgen/daq/readoutgui/OS.tcl trunk/nextgen/daq/readoutgui/ReadougGUIPanel.tcl trunk/nextgen/daq/readoutgui/ReadougGUIPanel.ui trunk/nextgen/daq/readoutgui/ReadougGUIPanel_ui.tcl trunk/nextgen/daq/readoutgui/ReadoutControl.tcl trunk/nextgen/daq/readoutgui/ReadoutGui.tcl trunk/nextgen/daq/readoutgui/ReadoutShell trunk/nextgen/daq/readoutgui/ReadoutShell.tcl trunk/nextgen/daq/readoutgui/ReadoutState.tcl trunk/nextgen/daq/readoutgui/RemoteInfo.tcl trunk/nextgen/daq/readoutgui/RunReadout.sh trunk/nextgen/daq/readoutgui/RunTime.tcl trunk/nextgen/daq/readoutgui/ScalerParameterGUI.tcl trunk/nextgen/daq/readoutgui/SecretTk.c trunk/nextgen/daq/readoutgui/UniqueInstance.tcl trunk/nextgen/daq/readoutgui/WaitPackage.cpp trunk/nextgen/daq/readoutgui/bells.tcl trunk/nextgen/daq/readoutgui/daqparameters.test trunk/nextgen/daq/readoutgui/directories.tcl trunk/nextgen/daq/readoutgui/directories.test trunk/nextgen/daq/readoutgui/experiment.test trunk/nextgen/daq/readoutgui/filesystem.test trunk/nextgen/daq/readoutgui/initconfig.test trunk/nextgen/daq/readoutgui/installpkg trunk/nextgen/daq/readoutgui/installpkg.tcl trunk/nextgen/daq/readoutgui/installroot.test trunk/nextgen/daq/readoutgui/ostest.test trunk/nextgen/daq/readoutgui/readoutcontrol.test trunk/nextgen/daq/readoutgui/readoutguitest.tk trunk/nextgen/daq/readoutgui/rsh.tcl trunk/nextgen/daq/readoutgui/scalerParameterDialog.tcl trunk/nextgen/daq/readoutgui/scalerParameterDialog.ui trunk/nextgen/daq/readoutgui/scalerParameterDialog_ui.tcl trunk/nextgen/daq/readoutgui/scalerparametergui.tk trunk/nextgen/daq/readoutgui/selectReadout.tcl trunk/nextgen/daq/readoutgui/selectReadout.ui trunk/nextgen/daq/readoutgui/selectReadoutDialog.tcl trunk/nextgen/daq/readoutgui/selectReadout_ui.tcl trunk/nextgen/daq/readoutgui/selectreadoutest.tk trunk/nextgen/daq/readoutgui/system.test trunk/nextgen/daq/readoutgui/testrunner.tk trunk/nextgen/daq/readoutgui/tests.test trunk/nextgen/daq/readoutgui/warning.tcl Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2009-03-27 18:19:53 UTC (rev 2113) +++ trunk/nextgen/configure.ac 2009-03-27 18:45:11 UTC (rev 2114) @@ -429,6 +429,7 @@ utilities/sclclient/Makefile daq/Makefile daq/format/Makefile + daq/readoutgui/Makefile usb/Makefile usb/threadcom/Makefile usb/tclcommon/Makefile Modified: trunk/nextgen/daq/Makefile.am =================================================================== --- trunk/nextgen/daq/Makefile.am 2009-03-27 18:19:53 UTC (rev 2113) +++ trunk/nextgen/daq/Makefile.am 2009-03-27 18:45:11 UTC (rev 2114) @@ -1 +1 @@ -SUBDIRS = format \ No newline at end of file +SUBDIRS = format readoutgui \ No newline at end of file Added: trunk/nextgen/daq/readoutgui/Configuration.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/Configuration.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/Configuration.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,127 @@ +# +# This software is Copyright by the Board of Trustees of Michigan +# State University (c) Copyright 2005. +# +# You may use this software under the terms of the GNU public license +# (GPL). The terms of this license are described at: +# +# http://www.gnu.org/licenses/gpl.txt +# +# Author: +# Ron Fox +# NSCL +# Michigan State University +# East Lansing, MI 48824-1321 +# + +# +# Configuration.tcl +# This file contains code that manages configuration variables. +# Configuration variables will live inthe configuration namespace. +# ::configuration:: is not to be confused with ::Configuration:: +# which is where the procs in this package live. +# They can be loaded from file, read from the environment and handed +# explicit values. +# Once given value, they can be retrieved, or modified, and written. +# We do all this in a way that allows users to just to set commands to +# set configuration values, rather than anything funky. +# +package provide Configuration 1.0 + +namespace eval configuration {}; # Config vars live here. + +namespace eval Configuration { + variable ConfigFile +}; # Procs live here. + +# Configuration::readConfigFile path +# Read a configuration file. The indicated configuration file +# is read in at global level inside a namespace eval ::configuration. +# Parameters: +# path Filesystem path to the configuration file. +# Errors: +# FileNotFound - Nosuch file. +# FileNotReadable - File found but could not be read. +# +proc Configuration::readConfigFile {path} { + if {![file exists $path]} { + error "Configuration::FileNotFound - Attempting to read configurationfile: $path" + } + if {![file readable $path]} { + error "Configuration::FileNotReadable - $path was not readable by this user" + } + set Configuration::ConfigFile $path + uplevel #0 { + namespace eval ::configuration:: { + source $Configuration::ConfigFile + } + } + +} +# Configuration::readEnvironmet confname envname default +# Sets a configuration variable from an environment variable. +# if the environment variable has not been set, a default is applied. +# Parameters: +# confname - Name of the configuration variable. +# envname - Name of the environment variable. +# default - Default value for the configuration variable. +# This defaults to empty. +# +# +proc Configuration::readEnvironment {confname envname {default {}}} { + global env + + if {[array names env $envname] == "" } { + if {$default ne ""} { + set ::configuration::$confname $default + } + } else { + set ::configuration::$confname $env($envname) + } +} +# Configuration::Set confname value +# Provides a value for a configuration variable, +# creating it if needed. +# Parameters: +# confname - Name of configuration valuel +# value - New value. +# +proc Configuration::Set {confname value} { + set ::configuration::$confname $value +} +# Configuration::get confname default +# Retrieve the value of a configuration variable. +# Parameters: +# confname - name of configuration variable. +# default - Defautl value to return if not +# defined. Defaults to empty string. +# +# Returns: +# Value of the config variable after all defaulting. +# +proc Configuration::get {confname {default {}}} { + if {[info var ::configuration::$confname] != ""} { + return [set ::configuration::$confname] + } else { + return $default + } +} +# Configuration::writeConfigFile channel +# Writes all the variables in the configuration namespace +# to the file open on the channel. The file is written +# in such a way that it can be recovered as a configuration file. +# This may seem trivial, but remember we have to get rid of +# the namespace from the configuration variable names. +# Parameters: +# channel - Channel open on the output file. +# +proc Configuration::writeConfigFile channel { + set names [info var ::configuration::*] + foreach var $names { + set value [set $var] + set list [split $var :] + set varname [lrange [split $var :] 4 end] + set varname [join $varname ::] + puts $channel [list set $varname $value] + } +} Added: trunk/nextgen/daq/readoutgui/DAQParameters.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/DAQParameters.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/DAQParameters.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,209 @@ +# +# This software is Copyright by the Board of Trustees of Michigan +# State University (c) Copyright 2005. +# +# You may use this software under the terms of the GNU public license +# (GPL). The terms of this license are described at: +# +# http://www.gnu.org/licenses/gpl.txt +# +# Author: +# Ron Fox +# NSCL +# Michigan State University +# East Lansing, MI 48824-1321 +# + +# This package captures and encapsulates the +# configuration information of the data acquisition subsystem. +# This configuration data controls how Readout is started, what +# it is fed for a first run number, and how data are recorded. +# Configuration parameters are: +# +# Parameter Name Env Name Meaning +# SourceHost DAQHOST Which system runs the readout software +# ReadoutPath RDOFILE Full path to the readout program. +# FtpHost EVTHOST Host on which event recording is done. +# Password PASSWD An encrypted password. The password is +# encrypted via DES with a key you'll just +# have to dig out yourself. Note that +# If supplied in the env var, PASSWD is assumed +# to be cleartext and encrypted here. +# BufferSize BUFFERSIZE Size of buffers on disk. +# + +package provide DAQParameters 1.0 +package require Configuration +package require des + + +namespace eval DAQParameters { +} +# DAQParameters::setDefaults +# Initialize the default values for each of the parameters. +# The following parameters have defaults: +# +# SourceHost - localhost +# BufferSize - 4096 (words) +proc DAQParameters::setDefaults {} { + + Configuration::Set SourceHost localhost + Configuration::Set BufferSize 8192 +} +# DAQParameters::environmentOverrides +# Overrides the defaults with information from the environment +# See the file comment header for information about which +# items support env overrides. +# +proc DAQParameters::environmentOverrides {} { + global env + + + Configuration::readEnvironment SourceHost DAQHOST + Configuration::readEnvironment ReadoutPath RDOFILE + Configuration::readEnvironment FtpHost EVTHOST + Configuration::readEnvironment BufferSize BUFFERSIZE + + + # Passwd is handled strangely since it must be encrypted. + + if {[array names env PASSWD] != ""} { + DAQParameters::passwordIs $env(PASSWD) + } +} +# DAQParameters::getSourceHost +# Returns the name of the host on which Readout should be run +# (DAQHOST). +# +proc DAQParameters::getSourceHost {} { + return [Configuration::get SourceHost localhost] +} +# DAQParameters::sourceHostIs name +# Set a new value for the data source host. +# Parameters: +# name - Name of the host. +# +proc DAQParameters::sourceHostIs {name} { + Configuration::Set SourceHost $name +} +# DAQParameters::getReadoutPath +# Returns the current path to the readout program. +# +proc DAQParameters::getReadoutPath {} { + return [Configuration::get ReadoutPath] +} +# DAQParameters::readoutPathIs path +# Sets a new readout path. +# The path must point to an executable file. +# +# Parameters: +# path - Path to the file. +# Errors: +# NotFound - File is not found. +# NotExecutable - File is not executable. +proc DAQParameters::readoutPathIs path { + + if {![file exists $path]} { + error "DAQParameters::NotFound - There is no readout program at $path" + } + if {![file executable $path]} { + error "DAQParameters::NotExecutable - $path is not executable therefore not a readout program" + } + Configuration::Set ReadoutPath $path +} +# DAQParameters::getFtpHost +# Returns the name of the host to which ftp +# event logging is directed. +# +proc DAQParameters::getFtpHost {} { + return [Configuration::get FtpHost] +} +# DAQParameters::ftpHostIs host +# Sets the name of the ftp host. The host must exist. +# and be running an ftp server. This is checked for +# via attempting to form a connection to it on the ftp +# port. +# Parameters: +# host - the ftp host. Can be either a DNS name or +# dotted ip. +# Errors +# HostNotFTPServer +# +# NOTES: THIS IS OBSOLETE!!! so don't require an ftp host. +# +proc DAQParameters::ftpHostIs {host} { + Configuration::Set FtpHost $host + return + +} +# DAQParameters::passwordIs passwd +# Sets a new password. As this is assumed to come from the +# outside world, we get a plaintext password. This is stored +# des encrypted so that when written to the config file it +# can't be easily read. +# Parameters: +# passwd - new password. +# +proc DAQParameters::passwordIs {passwd {key {}}} { + global tcl_platform + + set o $tcl_platform(user) + set e nscldaq + set f {ron fox} + + + + + set enc [::DES::des -mode encode -key $key$o$key$e$key$f$key $passwd] + Configuration::Set Password $enc +} +# DAQParameters::getPassword key +# Returns the unencrypted password given that you know the encryption key. +# +proc DAQParameters::getPassword {{key {}}} { + global tcl_platform + + set o {ron fox} + set e $tcl_platform(user) + set f nscldaq + + set cipher [Configuration::get Password] + set word [::DES::des -mode decode -key $key$e$key$f$key$o$key $cipher] + set word [string trim $word "\0"] + + + return $word +} +# DAQParameters::setEncryptedPasswd ciphertext +# Set the ciphertext Password +# Parameters: +# ciphertext - encrypted passwd. +proc DAQParameters::setEncryptedPasswd ciphertext { + Configuration::Set Password $ciphertext +} +# DAQParameters::getEncryptedPasswd +# Returns encrypted passwd. +# +proc DAQParameters::getEncryptedPasswd {} { + return [Configuration::get Password] +} + +# DAQParameters::setBufferSize value +# Set a buffersize for daq (used to name event files). +# Parameters: +# value - New buffersize. +# Errors: +# InvalidSize - value < 128. +proc DAQParameters::setBufferSize value { + if {$value < 128} { + "error DAQParameters::InvalidSize - Buffer sizes less than 128 are not allowed value was: $value" + } + Configuration::Set BufferSize $value +} +# DAQParameters::getBuffersize +# Returns the current buffersize. +# +proc DAQParameters::getBufferSize {} { + return [Configuration::get BufferSize 8192] +} + Added: trunk/nextgen/daq/readoutgui/ExpFileSystemConfig.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/ExpFileSystemConfig.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/ExpFileSystemConfig.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,64 @@ +# +# This software is Copyright by the Board of Trustees of Michigan +# State University (c) Copyright 2005. +# +# You may use this software under the terms of the GNU public license +# (GPL). The terms of this license are described at: +# +# http://www.gnu.org/licenses/gpl.txt +# +# Author: +# Ron Fox +# NSCL +# Michigan State University +# East Lansing, MI 48824-1321 +# + +# This file contains the package that maintains the configuration of the +# experimental file system. +# The filesystem hangs off two roots: +# Root ENV Default +# StageArea EVENTS ~/stagearea +# Experiment EXPDIR ~/experiment +# Since it is critical for this configuration to be correct +# and consistent, we don't support programmatic mid-stream +# changes. + +package provide ExpFileSystemConfig 1.0 +package require Configuration + +namespace eval ExpFileSystemConfig { + +} +# ExpFileSystemConfig::setDefaults +# Sets the defaulst for the configuration variables. +# See the file comment header for more information. +# +proc ExpFileSystemConfig::setDefaults {} { + global env + set home $env(HOME) + Configuration::Set StageArea [file join $home stagearea] + Configuration::Set Experiment [file join $home experiment] +} +# ExpFileSystemConfig::environmentOverrides +# Override the default settings with environment vars as +# described in the file header comments. +# +proc ExpFileSystemConfig::environmentOverrides {} { + global env + set home $env(HOME) + Configuration::readEnvironment StageArea EVENTS [file join $home stagearea] + Configuration::readEnvironment Experiment EXPDIR [file join $home experiment] +} +# ExpFileSystemConfig::getStageArea +# Return the value for the stagearea config param. +# +proc ExpFileSystemConfig::getStageArea {} { + return [Configuration::get StageArea] +} +# ExpFileSystemConfig::getExperimentDirectory +# Get the experiment directory configuration parameter. +# +proc ExpFileSystemConfig::getExperimentDirectory {} { + return [Configuration::get Experiment] +} Added: trunk/nextgen/daq/readoutgui/Experiment.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/Experiment.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/Experiment.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,430 @@ +# +# This software is Copyright by the Board of Trustees of Michigan +# State University (c) Copyright 2005. +# +# You may use this software under the terms of the GNU public license +# (GPL). The terms of this license are described at: +# +# http://www.gnu.org/licenses/gpl.txt +# +# Author: +# Ron Fox +# NSCL +# Michigan State University +# East Lansing, MI 48824-1321 +# + + + +package provide Experiment 2.0 +package require ExpFileSystem +package require ReadoutControl +package require InstallRoot +package require DAQParameters +package require Diagnostics + + +namespace eval Experiment { + variable Logrecorder "[InstallRoot::Where]/bin/eventlog" + variable EventlogPid 0 + variable fileWaitTimeout 45 + + + # Define exports: + + namespace export Register + namespace export BiggestRun + namespace export EmergencyEnd + namespace export CleanOrphans + namespace export RunFileExists + + +} +#-------------- The procs below should be considered local to Experiment:: --- + +# Experiment::runcompare +# Compares two run files and determines which +# is the smaller. +proc Experiment::runcompare {r1 r2} { + set r1 [file tail $r1] + set r2 [file tail $r2] + + scan $r1 run%d d1 + scan $r2 run%d d2 + return [expr {($d1 > $d2) ? 1 : -1}] +} +# Experiment::spectrodaqURL system +# Given a system name returns the URL to contact +# the spectrodaq on that system. +# Parameters: +# system - The ip address or dns of the system;. +proc Experiment::spectrodaqURL {system} { + set sfd [open /etc/services r] + set services [read $sfd] + close $sfd + set services [split $services "\n"] + foreach service $services { + set name [lindex $service 0] + set portproto [split [lindex $service 1] /] + set port [lindex $portproto 0] + set proto [lindex $portproto 1] + append name : proto + lappend servicelist $name $port + } + array set servicearray $servicelist + + if {[array names servicearray sdaq-link:tcp] == ""} { + set port 2602 + } else { + set port $servicearray(sdaq-link) + } + + append url tcp:// $system : $port / + return $url +} +# Experiment::waitFile name ?granularity ?timeout?? +# Wait for a file to exist. +# Parameters: +# name - Sufficient path to the file. +# granularity - Polling period (1 sec by default). +# timeout - Limit on passes (infinite by default). +# Returns: +# 1 - File now exists. +# 0 - Timeout. +# NOTE: +# If tk is loaded, then we will run a few update idle +# commands each pass through the loop. +# +proc Experiment::waitFile {name {granularity 1000} {timeout 0}} { + set passes 0 + set done 0 + + while {1} { + if {[file exists $name]} { + return 1 + } + incr passes + if {($passes > $timeout) && ($timeout != 0)} { + return 0 + } + after $granularity + if {[info command tk] != ""} { + update idle + update idle + update idle + update idle + } + } +} +# Experiment::makeEventLink run +# Make a link to the event file in the current directory of the +# metadata tree. +# Parameters: +# run - Number of the run +# NOTE: +# Only segment 0 is linked. +# +proc Experiment::makeEventLink run { + after 1000; # For debugging let eventlog start + set linkpath [ExpFileSystem::WhereisCurrentData] + set filename [ExpFileSystem::GenRunFile $run] + set filepath [file join [ExpFileSystem::GetStage] current] + set linkname [file join $linkpath $filename] + if {[file exists $linkname] || ([catch {file readlink $linkname}] == 0)} { + file delete -force $linkname + } + exec ln -s [file join $filepath $filename] $linkname + +} +# Experiment::callback cbproc arg... +# If cbproc is defined as a procedure it is called +# with the args as a parameter. +# +proc Experiment::callback {cbproc args} { + if {[info proc ::$cbproc] != ""} { + eval ::$cbproc $args + } +} + +# Experiment::BiggestRun +# Returns the next free run number. The next free run +# is determined by discovering the highest run number for +# which there is a data file and incrementing that. +# This is no longer done by relying on a .lastrun file. +# instead we just look at the experiment directory, and figure +# out which run is largest from the names of the directories present. +# If no runs have been taken yet, 0 is returned. +proc Experiment::BiggestRun {} { + set runDirectory [ExpFileSystem::WhereisMetadata] + set runs [glob -nocomplain [file join $runDirectory run*]] + if {[llength $runs] == 0} { + return 0 + } else { + set runs [lsort -decreasing -command Experiment::runcompare $runs] + set biggest [file tail [lindex $runs 0]] + scan $biggest run%d run + + incr run + return $run + } +} +# Experiment::finalizeEventData run +# Does all of the end of run activities on the event data and +# event metadata. This involves: +# - Removing the experiment/current link to the event data. +# - Moving the entire contents of the experiment/current dir +# into a run dir. +# - Moving the event data into the run dir. +# - Creating the compatibility link in stagearea/complete to the +# event data in the run dir. +# Parameters: +# run - The number of the run to finalize. +# +proc Experiment::finalizeEventData run { + set current [ExpFileSystem::WhereisCurrentData] + set stage [ExpFileSystem::GetStage] + set targetdir [file dirname [ExpFileSystem::WhereisRunFile $run]] + set eventdir [ExpFileSystem::WhereisCurrentEventData] + set complete [ExpFileSystem::WhereareCompleteEventFiles] + + # First remove all links in the current dir to the event data. + # These are assumed to constitute a contiguous set of event segments. + + set segment 0 + set name [file join $current [ExpFileSystem::GenRunFile $run $segment]] + while {[file exists $name]} { + file delete -force $name + incr segment + set name [file join $current [ExpFileSystem::GenRunFile $run $segment]] + } + # Now we can create the target dir and tar the contents of experiment current to it. + + file mkdir $targetdir + catch { + exec sh << \ + "(cd $current; tar chf - .) | (cd $targetdir; tar xpf -)" + } + # Move the event segments from stagearea/current -> experiment/runn + # and make a compatibility link in stagarea/complete + + # Ensure the targetdir is writable... + + file attributes $targetdir -permissions 0750; # rwxr-x--- + file attributes $complete -permissions 0750; # Allow me to write the link. + + set segment 0 + while {1} { + set file [ExpFileSystem::GenRunFile $run $segment] + set srcfile [file join $eventdir $file] + if {![file exists $srcfile]} { + break + } + set dstfile [file join $targetdir $file] + set linkfile [file join $complete $file] + file rename -force $srcfile $dstfile + file attributes $dstfile -permissions 0440; # Make the saved file read-only + catch {exec ln -s $dstfile $linkfile};# On overwrite links may exist. + + incr segment + + } + # Remove writability from the target dir so Dirk can't screw up. + + file attributes $targetdir -permissions 0550; # r-xr-x--- + file attributes $complete -permissions 0550; # and the complete directory too. +} + +#------------ The procs below should be considered public ------------- + +# Experiment::RunBeginning +# +# Run is about to begin. +# If taping was enabled the following: +# 1. Start the taper in single shot, ftp mode. +# 2. Make a symbolic link in the current directory to the event log +# file. +# If the proc OnBegin is defined invoke it. +# +proc Experiment::RunBeginning {} { + variable Logrecorder + variable EventlogPid + variable fileWaitTimeout + + + set ::Diagnostics::isTk 1; #Ugly but works... forces tk dialogs from warning + set nrun [ReadoutControl::GetRun] + if {[ReadoutControl::isTapeOn]} { + # + # Start the event logger. + # + set Stagedir [ExpFileSystem::WhereisCurrentEventData] + set currentdata [ExpFileSystem::WhereisCurrentData] + set user $::tcl_platform(user) + set sourceHost [DAQParameters::getSourceHost] + set SourceURL [Experiment::spectrodaqURL $sourceHost] + set ftpLoghost [DAQParameters::getFtpHost] + set ftpLogpasswd [DAQParameters::getPassword] + + cd $Stagedir + + + set EventlogPid [exec $Logrecorder -one -source $SourceURL &] + + Experiment::makeEventLink $nrun + + Experiment::waitFile .ready 1000 $fileWaitTimeout + if {![file exists .ready]} { + Error "The event logger is not yet ready after a very long time" + } + file delete -force .ready + } else { + set EventlogPid 0; # So emergency end won't make abnormal end file. + } + Experiment::callback OnBegin $nrun +} + # Experiment::RunEnded + # Run has ended. + # If taping is on: + # 1. Wait for the taper to end (.done appears in this dir). + # 2. Delete the .done file. + # 3. unlink the current link to the event file. + # 4. Move the event data to the complete dir. + # 5. Copy current to the appropriate run directory (following links) + # 6. Create a new link to the event data in the run directory. + # If OnEnd is defined, call it. + # +proc Experiment::RunEnded {} { + variable EventlogPid + variable fileWaitTimeout + + set nrun [ReadoutControl::GetRun] + # IF OnEnd is defined, call it: + # + Experiment::callback OnEnd $nrun + + if {[ReadoutControl::isTapeOn]} { + # + # Wait for eventlog to finish. + Experiment::waitFile .done 1000 $fileWaitTimeout + if {![file exists .done]} { + Diagnostics::Warning "eventlog may not have finished normally continuing with post run actions" + } + # TODO: Perhaps we should force event log to end if .done is not present yet? + + file delete -force .done + set EventlogPid 0 + + + Experiment::finalizeEventData $nrun + + + } +} +# Experiment::RunPaused +# If the OnPause proc is defined, call it. +# +proc Experiment::RunPaused {} { + + set nrun [ReadoutControl::GetRun] + Experiment::callback OnPause $nrun +} +# Experiment::RunResuming +# If the onResume proc is defined, call it. +# +proc Experiment::RunResuming {} { + set nrun [ReadoutControl::GetRun] + Experiment::callback OnResume $nrun +} +# Experiment::ReadoutStarting +# +# If the OnStart proc is defined call it. +# +proc Experiment::ReadoutStarting {} { + Experiment::callback OnStart +} + # + # Perform an emergency end: If the enentlog program is + # running it is killed, and the .done file created. + # Next the RunEnded process is called. + # +proc Experiment::EmergencyEnd {} { + variable EventlogPid + if {$EventlogPid != 0} { + catch {exec kill -KILL $EventlogPid} + exec touch .done + } + ::Experiment::RunEnded + set nrun [ReadoutControl::GetRun] + set rundir [file dirname [ExpFileSystem::WhereisRunFile $nrun]] + file mkdir $rundir + file attributes $rundir -permissions 0750 + exec touch $rundir/000RunAbnormallyEnded + file attributes $rundir/000RunAbnormallyEnded -permissions 0440 + file attributes $rundir -permissions 0550 +} +#Experiment::CleanOrphans +# Clean up orphaned event files in the stage area's current +# and, manage any dangling links in the experiment current dir. +# If there is a corresponding run directory, complete the link. +# If not, make a link in the orphaned dir. +# +proc Experiment::CleanOrphans {} { + set Eventdir [ExpFileSystem::WhereisCurrentEventData] + set root [ExpFileSystem::GetStage] + file mkdir $root/orphans + + + # If there are event files in the stagearea, + # we finalize their runs. + # and put a file named 000orphaned in their metadata + # directory to let people know where these came from. + + while {1} { + set orphans [glob -nocomplain [file join $Eventdir run*.evt]] + + if {[llength $orphans] == 0} { + break + } + scan [file tail [lindex $orphans 0]] run%d run + finalizeEventData $run + + set target [ExpFileSystem::WhereisRun $run] + file attributes $target -permissions 0750 + + set fd [open [file join $target 000orphaned] w] + close $fd + file attributes $target -permissions 0550 + } + # If current has dangling event data links, they will be destroyed. + + set evts [ExpFileSystem::WhereisCurrentEventData] + foreach filename [glob -nocomplain [file join $evts run*.evt]] { + file delete $filename + } + +} +# +# Register callbacks with runcontrol stuff: +# +proc Experiment::Register {} { + ReadoutControl::SetOnBegin ::Experiment::RunBeginning + ReadoutControl::SetOnEnd ::Experiment::RunEnded + ReadoutControl::SetOnPause ::Experiment::RunPaused + ReadoutControl::SetOnResume ::Experiment::RunResuming + ReadoutControl::SetOnLoad ::Experiment::ReadoutStarting +} + +# Check to see if an event file already exists for a +# specific run. +# Parameters: +# run - Number of the run to check. +# Returns: +# 1 - the file exists. +# 0 - the file does not exist. +# +proc Experiment::RunFileExists {run} { + set name [ExpFileSystem::WhereisRunFile $run] + return [file exists $name] + +} + Property changes on: trunk/nextgen/daq/readoutgui/Experiment.tcl ___________________________________________________________________ Added: svn:executable + * Added: trunk/nextgen/daq/readoutgui/InitializeConfiguration.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/InitializeConfiguration.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/InitializeConfiguration.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,126 @@ +# +# This software is Copyright by the Board of Trustees of Michigan +# State University (c) Copyright 2005. +# +# You may use this software under the terms of the GNU public license +# (GPL). The terms of this license are described at: +# +# http://www.gnu.org/licenses/gpl.txt +# +# Author: +# Ron Fox +# NSCL +# Michigan State University +# East Lansing, MI 48824-1321 +# + + +# Handle initializing configurations of multiple components. +# The idea of this package is that a program may consist of an +# assemblage of several components, each with its own set of +# configuration variables and configuration files/environment +# variables to set them up. Each configuration is represented +# by a package and a namespace in which at least the following +# 2 procs are defined +# +# setDefaults - Sets any default values for configuration +# variables managed by this package. +# environmentOverrides - Reads the environment to override +# any defaults. +# Configuration files are assumed to override env variables. +# +# We support the addition of packages, and configuration files +# and finally the ordered configuration of all of these. +# +package provide InitializeConfiguration 1.0 +package require Configuration + +namespace eval InitializeConfiguration { + variable packageList {} + variable configurationFiles {} +} + +# InitializeConfiguration::addSubsystem name +# Adds a component (subsystem) to the list of configurable +# packages. The name must refer to a package in the +# namespace $name that defines procs like +# setDefaults and environmentOverrides. +# +# Parameters: +# name - Name of the package. +# Errors: +# NoSuchPackage if the package 'name' cannot be loaded. +# +proc InitializeConfiguration::addSubsystem name { + if {[catch {package require $name}]} { + error "InitializeConfiguration::NoSuchPackage - configuration package $name could not be found in tcl library path" + } + lappend InitializeConfiguration::packageList $name +} +# InitializeConfiguration::addConfigFile path +# Adds a configuration file to the list of config files +# sourced in at initialization time. The file +# must exist and be readable. +# Parameter: +# path - path to the configuration File +# Errors: +# InitializeConfiguration::FileNotFound +# InitializeConfiguration::FileNotReadable +# +proc InitializeConfiguration::addConfigFile path { + if {![file exists $path]} { + error "InitializeConfiguration::FileNotFound - Configuration file $path could not be found" + } + if {![file readable $path]} { + error "InitializeConfiguration::FileNotReadable - Configuration file $path is not readable by this user" + } + lappend InitializeConfiguration::configurationFiles $path + +} + +# initialize +# Initialize the configuration system for all packages and +# configuration files. +# +proc InitializeConfiguration::initialize {} { + + + # First bring the configuration namespaces online. + # and set defaults: + foreach pkg $InitializeConfiguration::packageList { + package require $pkg + set def "" + append def $pkg :: setDefaults + $def + } + + + +} + + +# Process the configuration files for each pacakge: + +proc InitializeConfiguration::processConfigFiles {} { + # Read the configuration files. + + foreach f $InitializeConfiguration::configurationFiles { + Configuration::readConfigFile $f + } +} + +# +# Process the env variables for each configuration. +# +proc InitializeConfiguration::processEnv {} { + # Finally process env vars. + + + foreach pkg $InitializeConfiguration::packageList { + + set envo "" + append envo $pkg :: environmentOverrides + $envo + } + +} \ No newline at end of file Added: trunk/nextgen/daq/readoutgui/InstallRoot.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/InstallRoot.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/InstallRoot.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,8 @@ +package provide InstallRoot 1.0 +namespace eval InstallRoot { +variable root /usr/opt/daq/8.2 +proc Where {} { +variable root +return $root +} +} Added: trunk/nextgen/daq/readoutgui/InstallRoot.tcl.in =================================================================== --- trunk/nextgen/daq/readoutgui/InstallRoot.tcl.in (rev 0) +++ trunk/nextgen/daq/readoutgui/InstallRoot.tcl.in 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,8 @@ +package provide InstallRoot 1.0 +namespace eval InstallRoot { +variable root @prefix@ +proc Where {} { +variable root +return $root +} +} Added: trunk/nextgen/daq/readoutgui/KeeplistGui.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/KeeplistGui.tcl (rev 0) +++ trunk/nextgen/daq/readoutgui/KeeplistGui.tcl 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,270 @@ +# +# This software is Copyright by the Board of Trustees of Michigan +# State University (c) Copyright 2005. +# +# You may use this software under the terms of the GNU public license +# (GPL). The terms of this license are described at: +# +# http://www.gnu.org/licenses/gpl.txt +# +# Author: +# Ron Fox +# NSCL +# Michigan State University +# East Lansing, MI 48824-1321 +# + + +package provide KeeplistGUI 2.0 +package require keeplistDialog +package require snit + +# +# This snit widget creates a dialog +# that displays the keep list dialog. +# The dialog is displayed and can be run either +# as a modal or non modal dialog. +# The package provides two helper functions: +# modalKeeplistDialog - Make a modal keeplist dialog +# keeplistDialog - Make a non modal keeplist dialog. +# +# options: +# -eligible - Set/Get the contents of the listbox +# of runs that are elligible for retension. +# -scheduled - Set/Get the contents of the listbox of runs +# that are scheduled for retension. +# -retained - Set/Get the contents of the listbox of runs +# that are already retained. +# -command - Register a script to be called when the Ok button +# is called, The script is given the widget name +# as a parameter. +# -cancelcmd - Register a script to be called when the Cancel button +# is called, the script is given the widget name as a parameter. +# Note that the command callback wrappers will destroy the GUI of the widget +# >after< the callback script is invoked. +# +# Public Methods (other than construction/destruction) +# modal - +# + +snit::widget keeplistGUI { + hulltype toplevel + option -eligible + option -scheduled + option -kept + option -command {} + option -cancelcmd {} + + # Constructor: + + constructor {args} { + keeplistDialog::init $win + $win.ok configure -command [mymethod onOk] + $win.cancel configure -command [mymethod onCancel] + $self configurelist $args + } + # Destructor: + + destructor { + } + + # Public members: + + # modal: + # Make the dialog modal. + # This is done by creating a hidden widget + # doing a grab and then a tkwait on the + # hidden window so that we exit when the + # hidden window is destroyed. + # Doing it this way also allows us to potentially + # de-modalize the dialog as a result of a -command + # (unsupported in this release) + # + method modal {} { + frame $win.hidden + grab $win + tkwait window $win.hidden + catch {grab release $win} + } + # Private members: + + method FillListBox {widget list} { + set newlist [lsort -command keeplistDialog::compareRunFiles $list] + $widget delete 0 end + foreach item $newlist { + $widget insert end $item + } + + } + # EndModalEventLoop + # If the dialog is modal ($win.hidden exists), + # the hidden widget is destroyed exiting the modal + # event loop. + # + method EndModalEventLoop {} { + if {[winfo exists $win.hidden]} { + destroy $win.hidden + } + } + # DispatchScript script parameter + # Dispatches a user script (if it is not empty) + # appending the parameter. + # + method DispatchScript {script parameter} { + if {$script != ""} { + eval $script $parameter + } + } + # Configuration set handlers: + + # Fill the elligible run list of the dialog box + # with the sorted list of runs in the list. + # The list is a set of filenames (with or without + # paths. + # The widget we are filling is $win.unkeptruns + # We use the proc + # keeplistDialog::compareRunFiles + # To help us sort the incoming list + # + onconfigure -eligible {list} { + $self FillListBox $win.unkeptruns $list + } + # Same as for -eligible + # except that the target widget is: + # $win.scheduledforkeep + onconfigure -scheduled {list} { + $self FillListBox $win.scheduledforkeep $list + } + # Same as for -eligible except that the widget + # filled is $win.keptruns + onconfigure -kept {list} { + $self FillListBox $win.keptruns $list + } + + # Configuration get handlers: + + # Retrieve and return the contents of the + # $win.unkeptruns list box. + # + oncget -eligible { + return [$win.unkeptruns get 0 end] + } + # Retrieve and return the contents of the + # $win.scheduledforkeep listbox. + # + oncget -scheduled { + return [$win.scheduledforkeep get 0 end] + } + # Retrieve and return the contents of the + # $win.kept listbox. + # + oncget -kept { + return [$win.keptruns get 0 end] + } + # Event handlers; + + # OK button was hit. + # If the user has registered a -command invoke it with the + # top level widget. + # After that, if the hidden widget exists, destroy it + # to exit the modal event loop, otherwise leave things + # well enough alone. + # + method onOk {} { + $self DispatchScript $options(-command) $win + $self EndModalEventLoop + } + # onCancel + # invokes the user's script and then destroys + # the window. Destroying the event loop ensures + # that the client cannot fetch modified lists. + # + method onCancel {} { + $self DispatchScript $options(-cancelcmd) $win + destroy $win + } +} + +namespace eval KeeplistGUI { + variable KeeplistModified 0 +} + +# KeeplistGui::StuffListBox widget filenames +# Stocks a listbox with run file names +# (not paths). The names are assumed to be +# runfiles and are inserted sorted by run number +# Parameters: +# widget - The name of the list box to stuff. +# filenames - The list of filenames (potentially with +# path information) to stuff into the box. +# +proc KeeplistGUI::StuffListBox {widget filenames} { + # First a new list with no path info: + + set nameonly "" + foreach file $filenames { + lappend nameonly [file tail $file] + } + + set nameonly [lsort -command keeplistDialog::compareRunFiles $nameonly] + + # Stuff the list box: + + foreach name $nameonly { + $widget insert end $name + } + +} + +# KeeplistGUI::KeeplistDialog Elligible Keeplist KeptList +# Let the user manipulate the kept run list. +# Kept runs are not deleted after a stage pass. +# Note that while the parameters are run files, they +# are turned into run names (e.g. run123-4096.evt). +# prior to being put in the list box. +# +# Parameters: +# Elligible - run files that are elligible for staging, but not +# marked for keep. +# KeepList - run files that are elligible for staging, but are +# scheduled to be retained. +# KeptList - Run files that have been staged and kept. +# (readonly). +# Returns the name of the toplevel widget it creates: +# +proc KeeplistGUI::keeplistDialog {topname Elligible KeepList KeptList} { + return [keeplistGUI $topname -eligible $Elligible -scheduled $KeepList -kept $KeptList] + +} +# Same as above, however the dialog is made modal and +# the return value is a 3 element list consisting of +# the contents of the three list boxes (eligible, scheduled and kept) +# on exit. +# If cancel, or destroyed, the original lists are returned. +# +proc KeeplistGUI::modalKeeplistDialog {topname Elligible Keeplist KeptList} { + set widget [KeeplistGUI::keeplistDialog $topname $Elligible $Keeplist $KeptList] + $widget modal + + if {[catch {$widget cget -eligible} values]} { + set values $Elligible + } + lappend result $values + + if {[catch {$widget cget -scheduled} values]} { + set values $Keeplist + } + lappend result $values + + if {[catch {$widget cget -kept} values]} { + set values $KeptList + } + lappend result $values + + catch {destroy $widget }; # Normal exit only destroys hidden. + + return $result + +} + + Added: trunk/nextgen/daq/readoutgui/Makefile.am =================================================================== --- trunk/nextgen/daq/readoutgui/Makefile.am (rev 0) +++ trunk/nextgen/daq/readoutgui/Makefile.am 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,77 @@ +install-exec-local: + $(mkinstalldirs) $(prefix)/bin + $(mkinstalldirs) $(prefix)/TclLibs/Stager + $(INSTALL_SCRIPT) $(TCLPACKAGES) $(prefix)/TclLibs/Stager + $(INSTALL_SCRIPT) InstallRoot.tcl $(prefix)/TclLibs/Stager + for f in $(TCLAPPS); do $(INSTALL_SCRIPT) $$f $(prefix)/bin/`basename $$f .tcl`; done + $(INSTALL_SCRIPT) ReadoutShell.tcl $(prefix)/bin + $(INSTALL_SCRIPT) RunReadout.sh $(prefix)/TclLibs + echo "pkg_mkIndex -verbose $(prefix)/TclLibs/Stager *.tcl" > installpkg.tcl + $(TCLSH_CMD) <installpkg.tcl + echo Adjusting installation location of libWait.so compiled tcl extension. + mv $(prefix)/lib/libWait.* $(prefix)/TclLibs + +TCLPACKAGES=Configuration.tcl \ + DAQParameters.tcl \ + ExpFileSystemConfig.tcl \ + Experiment.tcl \ + InitializeConfiguration.tcl \ + OS.tcl \ + ReadougGUIPanel.tcl ReadougGUIPanel_ui.tcl \ + ReadoutControl.tcl \ + ReadoutGui.tcl \ + ReadoutState.tcl \ + RemoteInfo.tcl \ + ScalerParameterGUI.tcl \ + UniqueInstance.tcl \ + directories.tcl \ + rsh.tcl \ + scalerParameterDialog.tcl scalerParameterDialog_ui.tcl \ + selectReadout.tcl selectReadout_ui.tcl \ + selectReadoutDialog.tcl \ + warning.tcl \ + bells.tcl \ + Monitor.tcl \ + RunTime.tcl + +TCLAPPS=ReadoutShell + + +TCLTESTS = daqparameters.test directories.test experiment.test filesystem.test \ + initconfig.test installroot.test ostest.test readoutcontrol.test \ + readoutguitest.tk scalerparametergui.tk \ + selectreadoutest.tk system.test \ + testrunner.tk tests.test + +EXTRA_DIST = $(TCLPACKAGES) $(TCLAPPS) $(TCLTESTS) \ + ReadoutShell.tcl \ + ReadougGUIPanel.ui \ + RunReadout.sh \ + scalerParameterDialog.ui \ + selectReadout.ui \ + warning.tcl InstallRoot.tcl.in + + +bin_PROGRAMS = SecretTk + +SecretTk_SOURCES = SecretTk.c + +SecretTk_LDFLAGS= $(TCL_LDFLAGS) $(X11LIBS) + + +lib_LTLIBRARIES = libWait.la +libWait_la_SOURCES = WaitPackage.cpp + +libWait_la_LDFLAGS = @top_srcdir@/base/tclplus/libtclPlus.la \ + @top_srcdir@/base/exception/libException.la \ + @top_srcdir@/base/CopyrightTools/libLicense.la \ + -version-info $(SOVERSION) + +libWait_la_LIBADD = -ltclPlus -lException \ + $(TCL_LDFLAGS) $(X11LIBS) -lLicense \ + -lm -lstdc++ -lgcc -lc + +INCLUDES = -I@top_srcdir@/base/headers \ + -I@top_srcdir@/base/tclplus/ \ + -I@top_srcdir@/base/CopyrightTools \ + $(TCL_FLAGS) -DHOME=\"$(prefix)\" \ No newline at end of file Added: trunk/nextgen/daq/readoutgui/Makefile.in =================================================================== --- trunk/nextgen/daq/readoutgui/Makefile.in (rev 0) +++ trunk/nextgen/daq/readoutgui/Makefile.in 2009-03-27 18:45:11 UTC (rev 2114) @@ -0,0 +1,623 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = SecretTk$(EXEEXT) +subdir = daq/readoutgui +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libWait_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libWait_la_OBJECTS = WaitPackage.lo +libWait_la_OBJECTS = $(am_libWait_la_OBJECTS) +libWait_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libWait_la_LDFLAGS) $(LDFLAGS) -o $@ +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_SecretTk_OBJECTS = SecretTk.$(OBJEXT) +SecretTk_OBJECTS = $(am_SecretTk_OBJECTS) +SecretTk_LDADD = $(LDADD) +SecretTk_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(SecretTk_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libWait_la_SOURCES) $(SecretTk_SOURCES) +DIST_SOURCES = $(libWait_la_SOURCES) $(SecretTk_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPUNIT_LDFLAGS = @CPPUNIT_LDFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EPICS_BIN = @EPICS_BIN@ +EPICS_INCLUDES = @EPICS_INCLUDES@ +EPICS_LDFLAGS = @EPICS_LDFLAGS@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GENGETOPT = @GENGETOPT@ +GREP = @GREP@ +HAVE_DOCBOOK2PDF = @HAVE_DOCBOOK2PDF@ +HAVE_GENGETOPT = @HAVE_GENGETOPT@ +HAVE_XMLTO = @HAVE_XMLTO@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNEL_SOURCE_DIR = @KERNEL_SOURCE_DIR@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOVERSION = @SOVERSION@ +STRIP = @STRIP@ +TCLSH_CMD = @TCLSH_CMD@ +TCL_FLAGS = @TCL_FLAGS@ +TCL_LDFLAGS = @TCL_LDFLAGS@ +THREADCXX_FLAGS = @THREADCXX_FLAGS@ +THREADC_FLAGS = @THREADC_FLAGS@ +THREADLD_FLAGS = @THREADLD_FLAGS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TCLPACKAGES = Configuration.tcl \ + DAQParameters.tcl \ + ExpFileSystemConfig.tcl \ + Experiment.tcl \ + InitializeConfiguration.tcl \ + OS.tcl \ + ReadougGUIPanel.tcl ReadougGUIPanel_ui.tcl \ + ReadoutControl.tcl \ + ReadoutGui.tcl \ + ReadoutState.tcl \ + RemoteInfo.tcl \ + ScalerParameterGUI.tcl \ + UniqueInstance.tcl \ + directories.tcl \ + rsh.tcl \ + scalerParameterDialog.tcl scalerParameterDialog_ui.tcl \ + selectReadout.tcl selectReadout_ui.tcl \ + selectReadoutDialog.tcl \ + warning.tcl \ + bells.tcl \ + Monitor.tcl \ + RunTime.tcl + +TCLAPPS = ReadoutShell +TCLTESTS = daqparameters.test directories.test experiment.test filesystem.test \ + initconfig.test installroot.test ostest.test readoutcontrol.test \ + readoutguitest.tk scalerparametergui.tk \ + selectreadoutest.tk system.test \ + testrunner.tk tests.test + +EXTRA_DIST = $(TCLPACKAGES) $(TCLAPPS) $(TCLTESTS) \ + ReadoutShell.tcl \ + ReadougGUIPanel.ui \ + RunReadout.sh \ + scalerParameterDialog.ui \ + selectReadout.ui \ + warning.tcl InstallRoot.tcl.in + +SecretTk_SOURCES = SecretTk.c +SecretTk_LDFLAGS = $(TCL_LDFLAGS) $(X11LIBS) +lib_LTLIBRARIES = libWait.la +libWait_la_SOURCES = WaitPackage.cpp +libWait_la_LDFLAGS = @top_srcdir@/base/tclplus/libtclPlus.la \ + @top_srcdir@/base/exception/libException.la \ + @top_srcdir@/base/CopyrightTools/libLicense.la \ + -version-info $(SOVERSION) + +libWait_la_LIBADD = -ltclPlus -lException \ + $(TCL_LDFLAGS) $(X11LIBS) -lLicense \ + -lm -lstdc++ -lgcc -lc + +INCLUDES = -I@top_srcdir@/base/headers \ + -I@top_srcdir@/base/tclplus/ \ + -I@top_srcdir@/base/CopyrightTools \ + $(TCL_FLAGS) -DHOME=\"$(prefix)\" + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign daq/readoutgui/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign daq/readoutgui/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libWait.la: $(libWait_la_OBJECTS) $(libWait_la_DEPENDENCIES) + $(libWait_la_LINK) -rpath $(libdir) $(libWait_la_OBJECTS) $(libWait_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done ... [truncated message content] |
From: <ro...@us...> - 2009-04-08 21:21:50
|
Revision: 2119 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2119&view=rev Author: ron-fox Date: 2009-04-08 21:21:45 +0000 (Wed, 08 Apr 2009) Log Message: ----------- - Documentation - Get readout GUI ported. - Get readout gui build added to the top level make. Modified Paths: -------------- trunk/nextgen/configure.ac trunk/nextgen/daq/readoutgui/Experiment.tcl trunk/nextgen/daq/readoutgui/InstallRoot.tcl trunk/nextgen/daq/readoutgui/Makefile.in trunk/nextgen/daq/readoutgui/ReadougGUIPanel.tcl trunk/nextgen/daq/readoutgui/ReadougGUIPanel_ui.tcl trunk/nextgen/daq/readoutgui/ReadoutGui.tcl trunk/nextgen/daq/readoutgui/ReadoutShell.tcl trunk/nextgen/daq/readoutgui/directories.tcl trunk/nextgen/sbs/nsclapi/sbsVmeApi.xml trunk/nextgen/sbs/tclpackage/vmetcl.xml Added Paths: ----------- trunk/nextgen/sbs/puretcl/camac.xml trunk/nextgen/sbs/puretcl/wienercamac.xml Removed Paths: ------------- trunk/nextgen/daq/readoutgui/KeeplistGui.tcl Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/configure.ac 2009-04-08 21:21:45 UTC (rev 2119) @@ -430,6 +430,7 @@ daq/Makefile daq/format/Makefile daq/readoutgui/Makefile + daq/readoutgui/InstallRoot.tcl usb/Makefile usb/threadcom/Makefile usb/tclcommon/Makefile Modified: trunk/nextgen/daq/readoutgui/Experiment.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/Experiment.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/Experiment.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -59,27 +59,16 @@ # Parameters: # system - The ip address or dns of the system;. proc Experiment::spectrodaqURL {system} { - set sfd [open /etc/services r] - set services [read $sfd] - close $sfd - set services [split $services "\n"] - foreach service $services { - set name [lindex $service 0] - set portproto [split [lindex $service 1] /] - set port [lindex $portproto 0] - set proto [lindex $portproto 1] - append name : proto - lappend servicelist $name $port - } - array set servicearray $servicelist + global tcl_platform + # + # URl is of the form: + # tcp://host/username + # - if {[array names servicearray sdaq-link:tcp] == ""} { - set port 2602 - } else { - set port $servicearray(sdaq-link) - } + set user $tcl_platform(user) - append url tcp:// $system : $port / + set url "tcp://$system/$user" + return $url } # Experiment::waitFile name ?granularity ?timeout?? @@ -192,6 +181,7 @@ set segment 0 set name [file join $current [ExpFileSystem::GenRunFile $run $segment]] + puts "Looking at $name" while {[file exists $name]} { file delete -force $name incr segment @@ -199,6 +189,7 @@ } # Now we can create the target dir and tar the contents of experiment current to it. + puts "Creating $targetdir" file mkdir $targetdir catch { exec sh << \ @@ -214,13 +205,17 @@ set segment 0 while {1} { + puts "Segment $segment" set file [ExpFileSystem::GenRunFile $run $segment] set srcfile [file join $eventdir $file] + puts "Ready to copy $srcfile" if {![file exists $srcfile]} { break } set dstfile [file join $targetdir $file] + puts "..to $dstfile" set linkfile [file join $complete $file] + puts "..with a link $linkfile" file rename -force $srcfile $dstfile file attributes $dstfile -permissions 0440; # Make the saved file read-only catch {exec ln -s $dstfile $linkfile};# On overwrite links may exist. @@ -262,21 +257,20 @@ set user $::tcl_platform(user) set sourceHost [DAQParameters::getSourceHost] set SourceURL [Experiment::spectrodaqURL $sourceHost] - set ftpLoghost [DAQParameters::getFtpHost] - set ftpLogpasswd [DAQParameters::getPassword] + + + set EventlogPid [exec $Logrecorder --oneshot --path=$Stagedir --source=$SourceURL &] - cd $Stagedir - - set EventlogPid [exec $Logrecorder -one -source $SourceURL &] - Experiment::makeEventLink $nrun + + set startFile [file join $Stagedir .started] - Experiment::waitFile .ready 1000 $fileWaitTimeout - if {![file exists .ready]} { - Error "The event logger is not yet ready after a very long time" + Experiment::waitFile $startFile 1000 $fileWaitTimeout + if {![file exists $startFile]} { + error "The event logger is not yet ready after a very long time" } - file delete -force .ready + file delete -force $startFile } else { set EventlogPid 0; # So emergency end won't make abnormal end file. } @@ -305,13 +299,16 @@ if {[ReadoutControl::isTapeOn]} { # # Wait for eventlog to finish. - Experiment::waitFile .done 1000 $fileWaitTimeout - if {![file exists .done]} { + + set donefile [file join [ExpFileSystem::WhereisCurrentEventData] .exited] + + Experiment::waitFile $donefile 1000 $fileWaitTimeout + if {![file exists $donefile]} { Diagnostics::Warning "eventlog may not have finished normally continuing with post run actions" } # TODO: Perhaps we should force event log to end if .done is not present yet? - file delete -force .done + file delete -force $donefile set EventlogPid 0 Modified: trunk/nextgen/daq/readoutgui/InstallRoot.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/InstallRoot.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/InstallRoot.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -1,6 +1,6 @@ package provide InstallRoot 1.0 namespace eval InstallRoot { -variable root /usr/opt/daq/8.2 +variable root /usr/opt/daq/10.0 proc Where {} { variable root return $root Deleted: trunk/nextgen/daq/readoutgui/KeeplistGui.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/KeeplistGui.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/KeeplistGui.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -1,270 +0,0 @@ -# -# This software is Copyright by the Board of Trustees of Michigan -# State University (c) Copyright 2005. -# -# You may use this software under the terms of the GNU public license -# (GPL). The terms of this license are described at: -# -# http://www.gnu.org/licenses/gpl.txt -# -# Author: -# Ron Fox -# NSCL -# Michigan State University -# East Lansing, MI 48824-1321 -# - - -package provide KeeplistGUI 2.0 -package require keeplistDialog -package require snit - -# -# This snit widget creates a dialog -# that displays the keep list dialog. -# The dialog is displayed and can be run either -# as a modal or non modal dialog. -# The package provides two helper functions: -# modalKeeplistDialog - Make a modal keeplist dialog -# keeplistDialog - Make a non modal keeplist dialog. -# -# options: -# -eligible - Set/Get the contents of the listbox -# of runs that are elligible for retension. -# -scheduled - Set/Get the contents of the listbox of runs -# that are scheduled for retension. -# -retained - Set/Get the contents of the listbox of runs -# that are already retained. -# -command - Register a script to be called when the Ok button -# is called, The script is given the widget name -# as a parameter. -# -cancelcmd - Register a script to be called when the Cancel button -# is called, the script is given the widget name as a parameter. -# Note that the command callback wrappers will destroy the GUI of the widget -# >after< the callback script is invoked. -# -# Public Methods (other than construction/destruction) -# modal - -# - -snit::widget keeplistGUI { - hulltype toplevel - option -eligible - option -scheduled - option -kept - option -command {} - option -cancelcmd {} - - # Constructor: - - constructor {args} { - keeplistDialog::init $win - $win.ok configure -command [mymethod onOk] - $win.cancel configure -command [mymethod onCancel] - $self configurelist $args - } - # Destructor: - - destructor { - } - - # Public members: - - # modal: - # Make the dialog modal. - # This is done by creating a hidden widget - # doing a grab and then a tkwait on the - # hidden window so that we exit when the - # hidden window is destroyed. - # Doing it this way also allows us to potentially - # de-modalize the dialog as a result of a -command - # (unsupported in this release) - # - method modal {} { - frame $win.hidden - grab $win - tkwait window $win.hidden - catch {grab release $win} - } - # Private members: - - method FillListBox {widget list} { - set newlist [lsort -command keeplistDialog::compareRunFiles $list] - $widget delete 0 end - foreach item $newlist { - $widget insert end $item - } - - } - # EndModalEventLoop - # If the dialog is modal ($win.hidden exists), - # the hidden widget is destroyed exiting the modal - # event loop. - # - method EndModalEventLoop {} { - if {[winfo exists $win.hidden]} { - destroy $win.hidden - } - } - # DispatchScript script parameter - # Dispatches a user script (if it is not empty) - # appending the parameter. - # - method DispatchScript {script parameter} { - if {$script != ""} { - eval $script $parameter - } - } - # Configuration set handlers: - - # Fill the elligible run list of the dialog box - # with the sorted list of runs in the list. - # The list is a set of filenames (with or without - # paths. - # The widget we are filling is $win.unkeptruns - # We use the proc - # keeplistDialog::compareRunFiles - # To help us sort the incoming list - # - onconfigure -eligible {list} { - $self FillListBox $win.unkeptruns $list - } - # Same as for -eligible - # except that the target widget is: - # $win.scheduledforkeep - onconfigure -scheduled {list} { - $self FillListBox $win.scheduledforkeep $list - } - # Same as for -eligible except that the widget - # filled is $win.keptruns - onconfigure -kept {list} { - $self FillListBox $win.keptruns $list - } - - # Configuration get handlers: - - # Retrieve and return the contents of the - # $win.unkeptruns list box. - # - oncget -eligible { - return [$win.unkeptruns get 0 end] - } - # Retrieve and return the contents of the - # $win.scheduledforkeep listbox. - # - oncget -scheduled { - return [$win.scheduledforkeep get 0 end] - } - # Retrieve and return the contents of the - # $win.kept listbox. - # - oncget -kept { - return [$win.keptruns get 0 end] - } - # Event handlers; - - # OK button was hit. - # If the user has registered a -command invoke it with the - # top level widget. - # After that, if the hidden widget exists, destroy it - # to exit the modal event loop, otherwise leave things - # well enough alone. - # - method onOk {} { - $self DispatchScript $options(-command) $win - $self EndModalEventLoop - } - # onCancel - # invokes the user's script and then destroys - # the window. Destroying the event loop ensures - # that the client cannot fetch modified lists. - # - method onCancel {} { - $self DispatchScript $options(-cancelcmd) $win - destroy $win - } -} - -namespace eval KeeplistGUI { - variable KeeplistModified 0 -} - -# KeeplistGui::StuffListBox widget filenames -# Stocks a listbox with run file names -# (not paths). The names are assumed to be -# runfiles and are inserted sorted by run number -# Parameters: -# widget - The name of the list box to stuff. -# filenames - The list of filenames (potentially with -# path information) to stuff into the box. -# -proc KeeplistGUI::StuffListBox {widget filenames} { - # First a new list with no path info: - - set nameonly "" - foreach file $filenames { - lappend nameonly [file tail $file] - } - - set nameonly [lsort -command keeplistDialog::compareRunFiles $nameonly] - - # Stuff the list box: - - foreach name $nameonly { - $widget insert end $name - } - -} - -# KeeplistGUI::KeeplistDialog Elligible Keeplist KeptList -# Let the user manipulate the kept run list. -# Kept runs are not deleted after a stage pass. -# Note that while the parameters are run files, they -# are turned into run names (e.g. run123-4096.evt). -# prior to being put in the list box. -# -# Parameters: -# Elligible - run files that are elligible for staging, but not -# marked for keep. -# KeepList - run files that are elligible for staging, but are -# scheduled to be retained. -# KeptList - Run files that have been staged and kept. -# (readonly). -# Returns the name of the toplevel widget it creates: -# -proc KeeplistGUI::keeplistDialog {topname Elligible KeepList KeptList} { - return [keeplistGUI $topname -eligible $Elligible -scheduled $KeepList -kept $KeptList] - -} -# Same as above, however the dialog is made modal and -# the return value is a 3 element list consisting of -# the contents of the three list boxes (eligible, scheduled and kept) -# on exit. -# If cancel, or destroyed, the original lists are returned. -# -proc KeeplistGUI::modalKeeplistDialog {topname Elligible Keeplist KeptList} { - set widget [KeeplistGUI::keeplistDialog $topname $Elligible $Keeplist $KeptList] - $widget modal - - if {[catch {$widget cget -eligible} values]} { - set values $Elligible - } - lappend result $values - - if {[catch {$widget cget -scheduled} values]} { - set values $Keeplist - } - lappend result $values - - if {[catch {$widget cget -kept} values]} { - set values $KeptList - } - lappend result $values - - catch {destroy $widget }; # Normal exit only destroys hidden. - - return $result - -} - - Modified: trunk/nextgen/daq/readoutgui/Makefile.in =================================================================== --- trunk/nextgen/daq/readoutgui/Makefile.in 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/Makefile.in 2009-04-08 21:21:45 UTC (rev 2119) @@ -35,14 +35,15 @@ host_triplet = @host@ bin_PROGRAMS = SecretTk$(EXEEXT) subdir = daq/readoutgui -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/InstallRoot.tcl.in $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = InstallRoot.tcl am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -303,6 +304,8 @@ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +InstallRoot.tcl: $(top_builddir)/config.status $(srcdir)/InstallRoot.tcl.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" Modified: trunk/nextgen/daq/readoutgui/ReadougGUIPanel.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/ReadougGUIPanel.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/ReadougGUIPanel.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -315,8 +315,8 @@ append w $base . host $w configure -text $host - append status $base . monitor - $status configure -host $host +# append status $base . monitor +# $status configure -host $host } # ReadougGUIPanel::setPath $path # Set the readout path for the gui. Modified: trunk/nextgen/daq/readoutgui/ReadougGUIPanel_ui.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/ReadougGUIPanel_ui.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/ReadougGUIPanel_ui.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -362,10 +362,10 @@ # Install the monitor widget: - package require spdaqMonitor +# package require spdaqMonitor - spdaqMonitor $base.monitor - grid x $base.monitor -in $root -column 3 -columnspan 8 +# spdaqMonitor $base.monitor +# grid x $base.monitor -in $root -column 3 -columnspan 8 # Resize Behavior grid rowconfigure $root 1 -weight 0 -minsize 2 -pad 0 Modified: trunk/nextgen/daq/readoutgui/ReadoutGui.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/ReadoutGui.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/ReadoutGui.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -34,7 +34,6 @@ package require DAQParameters package require Experiment package require bells -package require spdaqwidgets package require RunTime package require InstallRoot Modified: trunk/nextgen/daq/readoutgui/ReadoutShell.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/ReadoutShell.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/ReadoutShell.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -57,7 +57,6 @@ package require Configuration package require DAQParameters package require InitializeConfiguration -package require spdaqwidgets Modified: trunk/nextgen/daq/readoutgui/directories.tcl =================================================================== --- trunk/nextgen/daq/readoutgui/directories.tcl 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/daq/readoutgui/directories.tcl 2009-04-08 21:21:45 UTC (rev 2119) @@ -96,11 +96,11 @@ # GenRunFileBase # Returns the basename of a run file. # A run filename has the form: -# [format run%d_%d-%d.evt run segment buffersize] +# [format run%d-%d.evt run segment] # We're going to return the run%d part of this. # proc ExpFileSystem::GenRunFileBase {num} { - return [format run%d $num] + return [format run-%04d $num] } # GenRunFile # Generate the full name of a run file. @@ -114,16 +114,11 @@ proc ExpFileSystem::GenRunFile {num {seq 0}} { set fname [GenRunFileBase $num] - set buffer [DAQParameters::getBufferSize] - set buffer [expr {$buffer/2}] - # The form of the name depends on the sequence: - if {$seq} { - set fname [format %s_%d-%d.evt $fname $seq $buffer] - } else { - set fname [format %s-%d.evt $fname $buffer] - } + + set fname [format %s-%02d.evt $fname $seq] + return $fname } # WhereisRunFile Modified: trunk/nextgen/sbs/nsclapi/sbsVmeApi.xml =================================================================== --- trunk/nextgen/sbs/nsclapi/sbsVmeApi.xml 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/sbs/nsclapi/sbsVmeApi.xml 2009-04-08 21:21:45 UTC (rev 2119) @@ -1544,12 +1544,13 @@ </methodsynopsis> <methodsynopsis> <type>CVME<T>&</type> <methodname>operator++</methodname> - <methodparam><type>Int_t</type> + <methodparam><type>Int_t</type> <parameter>dummy</parameter> </methodparam> </methodsynopsis> <methodsynopsis> <type>CVME<T>&</type> <methodname>operator--</methodname> - <methodparam><type>Int_t</type></methodparam> + <methodparam><type>Int_t</type> <parameter>dummy</parameter> + </methodparam> </methodsynopsis> <methodsynopsis> <modifier>volatile</modifier> <type>UChar_t*</type> @@ -1800,6 +1801,7 @@ to the current pointer and returns that pointer. Note that as with the <literal>+=</literal> operator on normal pointers, the object this is applied to is modified. + </para> <methodsynopsis> <type>CVME<T>&</type> <methodname>operator-=</methodname> <methodparam> @@ -1837,7 +1839,7 @@ </para> <methodsynopsis> <type>CVME<T>&</type> <methodname>operator++</methodname> - <methodparam><type>Int_t</type> + <methodparam><type>Int_t</type> <parameter>dummy</parameter> </methodparam> </methodsynopsis> <para> @@ -1849,7 +1851,8 @@ </para> <methodsynopsis> <type>CVME<T>&</type> <methodname>operator--</methodname> - <methodparam><type>Int_t</type></methodparam> + <methodparam><type>Int_t</type> <parameter>dummy</parameter> + </methodparam> </methodsynopsis> <para> Implements the post decrement operator @@ -2250,12 +2253,12 @@ <type>UInt_t</type> <parameter>nOffset</parameter> </methodparam> </methodsynopsis> - <parameter> + <para> Same as <methodname>pokeb</methodname> however a 32 bit <parameter>lword</parameter> is written to <parameter>nOffset</parameter> longwords fromt he base address of the address window. - </parameter> + </para> <methodsynopsis> <type>UInt_t</type> <methodname>readl</methodname> @@ -2281,7 +2284,7 @@ Where possible, this function performs each read at a longword width. </para> - <methosynopsis> + <methodsynopsis> <type>UInt_t</type> <methodname>readw</methodname> <methodparam> <type>void*</type> <parameter>pBuffer</parameter> @@ -2292,7 +2295,7 @@ <methodparam> <type>size_t</type> <parameter>words</parameter> </methodparam> - </methosynopsis> + </methodsynopsis> <para> Same as <methodname>readl</methodname> however, <parameter>nOffset</parameter> is a word (16 bit) offset and @@ -2431,7 +2434,7 @@ <para> This class is an exception that can be thrown by the <methodname>CVMEInterface::Map</methodname> method. It is derived - from the <link linkend="CException"><classname>CException</classname></link> + from the <link linkend="manpage.cexception"><classname>CException</classname></link> class. See that page for full documentation on exception objects. </para> </refsect1> Added: trunk/nextgen/sbs/puretcl/camac.xml =================================================================== --- trunk/nextgen/sbs/puretcl/camac.xml (rev 0) +++ trunk/nextgen/sbs/puretcl/camac.xml 2009-04-08 21:21:45 UTC (rev 2119) @@ -0,0 +1,445 @@ +<!-- chapter libraries --> +<chapter> + <title>The CES CBD 8210 Tcl CAMAC Package</title> + <para> + This chapter describes a Tcl package (<literal>camac</literal>) that + allows Tcl scripts to perform CAMAC operations via CES CBD 8210 VME + CAMAC branch highway controllers. This can be used to + write control applications for CAMAC based modules. Note that as the + CBD 8201 is no longer in production we strongly recommend that you not + build any new applications around this module. + </para> + <para> + The functions in this library are loosely based on the ESONE CAMAC + function library specification (IEEE 758). The remainder of this chapter + describes: + <itemizedlist> + <listitem> + <para>How to incorporate this package into your scripts</para> + </listitem> + <listitem> + <para>An overview of how to use this package.</para> + </listitem> + </itemizedlist> + </para> + <para> + Reference information is available as well. See + <link linkend="manpage.camactcl">camac(3tcl)</link> + </para> + <section> + <title>Incorporating <literal>camac</literal> into your scripts</title> + <para> + Incorporating this package requires that you first make the + NSCLDAQ Tcl package respository visible to the Tcl package load + subsystem. Having done that, you must then explicitly load the + package via the <command>package require</command> command. + </para> + <para> + The Tcl package load subsystem search paths are a combination of + an environment variable (<varname>TCLLIBPATH</varname>), and a + set of global script variables (<varname>auto_path</varname>). + You can extend either of these mechanisms to include the + NSCLDAQ Tcl package repository in the set of directories searched + by the package load subsystem. + </para> + <para> + In the remainder of this section we are going to assume that you + have defined the environment variable <varname>DAQROOT</varname> + to be the base of the directory tree into which NSCLDAQ has been + installed. + </para> + <para> + The bash shell script fragment below shows how to add the NSCLDAQ + package repository to the <varname>TCLLIBPATH</varname> environment + variable. This script extends any existing <varname>TCLLIBPATH</varname> + definition rather than overwriting it + <informalexample> + <programlisting> +export TCLLIBPATH="$TCLLIBPATH $DAQROOT/TclLibs" + </programlisting> + </informalexample> + </para> + <para> + The Tcl script example below shows how to append the NSCLDAQ package + repository path to the list of paths in the <varname>auto_path</varname> + global variable. + <informalexample> + <programlisting> +global auto_path +global env +lappend auto_path [file join $env(DAQROOT) TclLibs] + </programlisting> + </informalexample> + </para> + </section> + <section> + <title>An overview of the use of the <literal>camac</literal> package</title> + <para> + The unit of control for the ESONE CAMAC functions on which this + package is based is a CAMAC module. The package allows you to form + connections to specific modules in specific branches an crates. + </para> + <para> + All of the commands in <literal>camac</literal> are placed in the + <literal>camac</literal> namespace. The Tcl + <command>namespace import</command> command can be used to import them + into the current or global namespace. + <warning> + <title>Warning</title> + <para> + The <literal>wienercamac</literal> package has an identical + set of commands in the <command>wienercamac</command> + namespace. If you are using both packages it is best + not to import their commands. + </para> + </warning> + </para> + <para> + The command <command>cdreg</command> (remember this is in the + <literal>camac</literal> namespace) is used to create a handle + to a module in a specific CAMAC crate. Once this handle has been + created, commands like <command>cssa</command> and + <command>cfsa</command> are used to perform operations on that + module. Additional block transfer commands exist to do + Qstop, Qscan and block transfers. + </para> + <para> + The implementation does not support LAM triggered functions, however + extensions to the standard are provided that allow you to poll the + crate for LAMs. Other extensions allow you to determine the set + of available CAMAC crates as well as to peform C and Z operations + on any crate assuming the controller is compatible with the + IEEE specifications of the A1/A2 crate controller (IEEE 596). + </para> + </section> + </chapter> + +<!-- /chapter --> + +<!-- manpage 3tcl --> +<refentry id="manpage.camactcl"> + <refmeta> + <refentrytitle>camac</refentrytitle> + <manvolnum>3tcl</manvolnum> + </refmeta> + <refnamediv> + <refname>camac</refname> + <refpurpose>Provide access to CES CBD8210 CAMAC to Tcl scripts</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <cmdsynopsis> + <command> +package require camac + </command> + </cmdsynopsis> + <cmdsynopsis> + <command> +camac::cdreg <replaceable>b c n ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::cfsa <replaceable>reg f a ?d?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::cssa <replaceable>reg f a ?d?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::qstop <replaceable>reg f a ?maxn?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::qscan <replaceable>reg f a ?maxn?</replaceable> + </command> +</cmdsynopsis> + + <cmdsynopsis> + <command> +camac::cblock <replaceable>reg f a num</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::isOnline <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::getGl <replaceable>b ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::C <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> +<cmdsynopsis> + <command> +camac::Z <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::isInhibited <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::Inhibit <replaceable>b c bool ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <cmdsynopsis> + <command> +camac::ReadLams <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + </refsynopsisdiv> + <refsect1> + <title>DESCRIPTION</title> + <para> + This package provides access to CAMAC modules via the + CES CBD 8210 branch highway driver to Tcl scripts. + Prior to use you must add the NSCLDAQ package repository path to the + Tcl package search list. + </para> + </refsect1> + <refsect1> + <title> + PACKAGE COMMANDS + </title> + <para> + The commands below share many of the same parameters: + <variablelist> + <varlistentry> + <term><replaceable>b</replaceable></term> + <listitem> + <para> + Is a branch number. For the CES CBD 8210 this is the + number set in the front panel branch number switch. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>c</replaceable></term> + <listitem> + <para> + A CAMAC crate number on some branch. This is set in the + front panel rotary switch of the A1 or A2 crate controller + installed in the right-most pair of slots of the crate. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>n</replaceable></term> + <listitem> + <para> + The slot number of a module in a CAMAC crate. Slots in + a CAMAC crate are numbered from 1 starting at the left. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>a</replaceable></term> + <listitem> + <para> + The subaddress within a module. A CAMAC modules is + defined to have 16 subaddresses numbered 0-15. + Each module uses this set of subaddresses differently.\ + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>vmecrate</replaceable></term> + <listitem> + <para> + A VME crate number in which at least one + CES CBD 8210 module has been installed. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>reg</replaceable></term> + <listitem> + <para> + A CAMAC module handle. These are produced using the + <command>camac::cdreg</command> command below. This is + used to select the CAMAC module operated on by several + of the commands. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + <cmdsynopsis> + <command> +package require camac + </command> + </cmdsynopsis> + <para> + Loads the <literal>camac</literal> package into the interpreter. The + commands loaded are all in the <literal>camac</literal> namespace. + The Tcl <command>namespace import</command> command can be used to + allow access to these commands without using a fully qualified namespace, + however if you are using other CAMAC Tcl libraries, beware as they will + most likely implement the same commands in a different namespace. + </para> + <cmdsynopsis> + <command> +camac::cdreg <replaceable>b c n ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Creates and returns a handle to a CAMAC module specified by + <parameter>b</parameter> <parameter>c</parameter> + <parameter>n</parameter> and <parameter>vmecrate</parameter>. + If the <parameter>vmecrate</parameter> parameter is omitted, + VME crate 0 is used by default. The command returns a value + that should be used as the <parameter>reg</parameter> parameter + in subsequent operations in this package. + </para> + <cmdsynopsis> + <command> +camac::cfsa <replaceable>reg f a ?d?</replaceable> + </command> +</cmdsynopsis> + <para> + Performs a CAMAC operation on the module defined by <parameter>reg</parameter>. + If the operation is a write, the <parameter>d</parameter> parameter must + be supplied and is the data to write. The CAMAC bus is a 24 bit bus, + so only the least significant 24 bits of <parameter>d</parameter> will + actually be written. + </para> + <para> + The command returns a 3 element Tcl list. The first element of this + list is the data parameter to the command if the <parameter>f</parameter> + code was a write code. If <parameter>f</parameter> indicated a read, + the first element of the list is the data read. If the + <parameter>f</parameter> was a control operation, the first element of the + list is meaningless. The second element of the list is the + Q-response for the operation and the third element the X-response. + </para> + <cmdsynopsis> + <command> +camac::cssa <replaceable>reg f a ?d?</replaceable> + </command> + +</cmdsynopsis> + <para> + Same as <command>camac::cfsa</command> however for data transfer operations, + this only transfers the least significant 16 bits. Note that for + the CES CBD 8210 16 bit operations are significantly faster than + 24 bit operations as the data paths to the module are only 16 bits wide. + </para> + <cmdsynopsis> + <command> +camac::qstop <replaceable>reg f a ?maxn?</replaceable> + </command> +</cmdsynopsis> + <para> + Performs a Q-stop block transfer from the module specified by + <parameter>reg</parameter> with the read function <parameter>f</parameter>. + Only read Q-stops are supported. The function is repeated until no + Q response is present or until <parameter>maxn</parameter> transfers + have been performed, whichever is first. The result of this command is + a Tcl list. Each element of the list a value read from the module during + the read operation. + </para> + <cmdsynopsis> + <command> +camac::qscan <replaceable>reg f a ?maxn?</replaceable> + </command> +</cmdsynopsis> + <para> + Peforms a Q-scan block transfer. In a Q-scan operation the subaddress + is incremented until the module does not return a Q at which point the + subaddress is reset to zero and the slot is incremented. This process + repeats until the read does not return a valid X-response or when + <parameter>maxn</parameter> is exceeeded. + </para> + <para> + The command returns a list of the data that has been returned from the + module. + </para> + <cmdsynopsis> + <command> +camac::cblock <replaceable>reg f a num</replaceable> + </command> +</cmdsynopsis> + <para> + Repeats the read operation <parameter>num</parameter> times putting + the results of the reads into a list that is returned by the command. + </para> + <cmdsynopsis> + <command> +camac::isOnline <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Returns true if the CAMAC crate selected by the command parameters is + online. This is not reliable as a probe for crates on branches that don't + exist. + </para> + <cmdsynopsis> + <command> +camac::getGl <replaceable>b ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Returns the value of the graded lam register for the + specified branch highway module. + </para> + <cmdsynopsis> + <command> +camac::C <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Peforms a C cycle on the selected CAMAC crate. This means that the + crate dataway C line is pulsed by the controller. + </para> +<cmdsynopsis> + <command> +camac::Z <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Performs a Z cycle on the selected CAMC crate. + </para> + <cmdsynopsis> + <command> +camac::isInhibited <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Returns true if the specified CAMAC crate is inhibited (its + <literal>I</literal> line is asserted). + </para> + <cmdsynopsis> + <command> +camac::Inhibit <replaceable>b c bool ?vmecrate?</replaceable> + </command> +</cmdsynopsis> + <para> + Sets the inhibit line of the specified crate to + <parameter>bool</parameter> + </para> + <cmdsynopsis> + <command> +camac::ReadLams <replaceable>b c ?vmecrate?</replaceable> + </command> +</cmdsynopsis> +<para> +Returns the LAM register of the controller for the specified crate. +</para> + </refsect1> + +</refentry> + + +<!-- /manpage --> \ No newline at end of file Modified: trunk/nextgen/sbs/tclpackage/vmetcl.xml =================================================================== --- trunk/nextgen/sbs/tclpackage/vmetcl.xml 2009-04-08 19:13:45 UTC (rev 2118) +++ trunk/nextgen/sbs/tclpackage/vmetcl.xml 2009-04-08 21:21:45 UTC (rev 2119) @@ -1,6 +1,6 @@ <!-- chapter commands --> -<chapter> +<chapter id="vmetclintro"> <title>Tcl access to the VME via the SBS interface</title> <para> The NSCL uses the Tcl/Tk scripting language to provide user interfaces This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2009-04-10 14:32:46
|
Revision: 2122 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2122&view=rev Author: ron-fox Date: 2009-04-10 14:32:44 +0000 (Fri, 10 Apr 2009) Log Message: ----------- Ensure that users can get a skeleton SBS Readout and that it will build and run. Start on readout docs as well Modified Paths: -------------- trunk/nextgen/Makefile.am trunk/nextgen/configure.ac trunk/nextgen/docconfig/config trunk/nextgen/sbs/readout/Makefile.am Added Paths: ----------- trunk/nextgen/sbs/readout/SBSRdoMakeIncludes.in trunk/nextgen/sbs/readout/SBSReadout.xml trunk/nextgen/sbs/readout/UserMakefile.in Modified: trunk/nextgen/Makefile.am =================================================================== --- trunk/nextgen/Makefile.am 2009-04-09 21:10:18 UTC (rev 2121) +++ trunk/nextgen/Makefile.am 2009-04-10 14:32:44 UTC (rev 2122) @@ -8,8 +8,10 @@ install-data-local: $(mkinstalldirs) @prefix@/TclLibs + $(mkinstalldirs) @prefix@/include echo "pkg_mkIndex @prefix@/TclLibs *.so" >makeindex.tcl $(TCLSH_CMD) <makeindex.tcl + $(INSTALL_SCRIPT) config.h @prefix@/include EXTRA_DIST=dotests Modified: trunk/nextgen/configure.ac =================================================================== --- trunk/nextgen/configure.ac 2009-04-09 21:10:18 UTC (rev 2121) +++ trunk/nextgen/configure.ac 2009-04-10 14:32:44 UTC (rev 2122) @@ -452,6 +452,8 @@ sbs/puretcl/Makefile sbs/vmemodules/Makefile sbs/readout/Makefile + sbs/readout/UserMakefile + sbs/readout/SBSRdoMakeIncludes docbuild/Makefile docconfig/Makefile]) Modified: trunk/nextgen/docconfig/config =================================================================== --- trunk/nextgen/docconfig/config 2009-04-09 21:10:18 UTC (rev 2121) +++ trunk/nextgen/docconfig/config 2009-04-10 14:32:44 UTC (rev 2122) @@ -1,2 +1,2 @@ commands utilities libraries servers frameworks -1daq 1epics 1tcl 1usbReadout 3daq 3tcl 3usbReadout +1daq 1epics 1tcl 1usbReadout 3daq 3tcl 3sbsReadout 3usbReadout Modified: trunk/nextgen/sbs/readout/Makefile.am =================================================================== --- trunk/nextgen/sbs/readout/Makefile.am 2009-04-09 21:10:18 UTC (rev 2121) +++ trunk/nextgen/sbs/readout/Makefile.am 2009-04-10 14:32:44 UTC (rev 2122) @@ -75,7 +75,7 @@ libSBSProductionReadout_la_LDFLAGS = -version-info 1:0:0 \ $(TCL_LDFLAGS) $(THREADLD_FLAGS) -EXTRA_DIST = options.ggo Skeleton.cpp +EXTRA_DIST = options.ggo Skeleton.cpp UserMakefile.in SBSRdoMakeIncludes.in noinst_PROGRAMS = Readout tests triggertests @@ -89,6 +89,15 @@ CLEANFILES = options.c options.h +install-exec-local: + $(mkinstalldirs) @prefix@/skeletons/sbs + $(mkinstalldirs) @prefix@/etc + $(mkinstalldirs) @prefix@/include/sbsreadout + $(INSTALL_SCRIPT) Skeleton.cpp @prefix@/skeletons/sbs + $(INSTALL_SCRIPT) Skeleton.h @prefix@/skeletons/sbs + $(INSTALL_SCRIPT) UserMakefile @prefix@/skeletons/sbs/Makefile + $(INSTALL_SCRIPT) SBSRdoMakeIncludes @prefix@/etc + $(INSTALL_SCRIPT) *.h @prefix@/include/sbsreadout options.c: options.ggo Added: trunk/nextgen/sbs/readout/SBSRdoMakeIncludes.in =================================================================== --- trunk/nextgen/sbs/readout/SBSRdoMakeIncludes.in (rev 0) +++ trunk/nextgen/sbs/readout/SBSRdoMakeIncludes.in 2009-04-10 14:32:44 UTC (rev 2122) @@ -0,0 +1,15 @@ +# +# Establish the compilers +# + +CC=@CC@ +CXX=@CXX@ +CXXLD=@CXX@ +CCLD=@CC@ + +CXXFLAGS=-g -I. -I@prefix@/include -I@prefix@/include/sbsreadout \ + @TCL_FLAGS@ @THREADCXX_FLAGS@ +CCFLAGS=$(CXXFLAGS) + +LDFLAGS=-L@prefix@/lib -lSBSProductionReadout -lException -ldaqthreads -ltclPlus \ + @TCL_LDFLAGS@ @THREADLD_FLAGS@ -Wl,"-rpath=@prefix@/lib" \ No newline at end of file Added: trunk/nextgen/sbs/readout/SBSReadout.xml =================================================================== --- trunk/nextgen/sbs/readout/SBSReadout.xml (rev 0) +++ trunk/nextgen/sbs/readout/SBSReadout.xml 2009-04-10 14:32:44 UTC (rev 2122) @@ -0,0 +1,32 @@ +<!-- chapter frameworks --> +<chapter> + <title>The SBS Readout framework</title> + <para> + This chapter describes a framework for reading out events via the SBS + PCI/VME bus bridge interface. This chapter describes + <itemizedlist> + <listitem> + <para>Basic concepts that underlie the framework</para> + </listitem> + <listitem> + <para>How to obtain a skeleton application which you can expand + into a real application, and build it.</para> + </listitem> + <listitem> + <para> + What parts of the skeleton application you will most likely + have to modify to produce a real application. + </para> + </listitem> + </itemizedlist> + </para> + <para> + Complete reference information is available in the 3sbsreadout part of + this manual. + </para> + +<!-- /chapter --> + +<!-- manpage 3sbsReadout --> + +<!-- /manpage --> \ No newline at end of file Added: trunk/nextgen/sbs/readout/UserMakefile.in =================================================================== --- trunk/nextgen/sbs/readout/UserMakefile.in (rev 0) +++ trunk/nextgen/sbs/readout/UserMakefile.in 2009-04-10 14:32:44 UTC (rev 2122) @@ -0,0 +1,44 @@ +# +# This establishes which version of NSCLDAQ we're using and where it's installed: +# Supposedly you only need to change this definition to update to a newer +# version of the software: + +INSTDIR=@prefix@ + +include $(INSTDIR)/etc/SBSRdoMakeIncludes + + +# +# The following allow you to add flags to all the default C and C++ compilation +# rules. In most cases C and C++ share the same set of compilation flags so: +# +# + +USERCCFLAGS= +USERCXXFLAGS=$(USERCCFLAGS) + +# If you have additional load flags (e.g. library dirs and libs): + +USERLDFLAGS= + +# +# This is a list of the objects that go into making the application +# Make, in most cases will figure out how to build them: + +OBJECTS=Skeleton.o + +Readout: $(OBJECTS) + $(CXXLD) -o Readout $(OBJECTS) $(USERLDFLAGS) $(LDFLAGS) + +clean: + rm -f $(OBJECTS) Readout + +depend: + makedepend $(USERCXXFLAGS) *.cpp *.c + + +help: + echo make - Build Readout. + echo make clean - Remove products from previous builds. + echo make depend - Add header dependencies to Makefile. + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ro...@us...> - 2009-04-17 21:02:05
|
Revision: 2130 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2130&view=rev Author: ron-fox Date: 2009-04-17 21:01:55 +0000 (Fri, 17 Apr 2009) Log Message: ----------- Document the SBS Readout software framework. Modified Paths: -------------- trunk/nextgen/docconfig/config trunk/nextgen/sbs/readout/CCAENV262Busy.h trunk/nextgen/sbs/readout/CReadoutMain.cpp trunk/nextgen/sbs/readout/CReadoutMain.h trunk/nextgen/sbs/readout/SBSReadout.xml trunk/nextgen/sbs/readout/Skeleton.cpp trunk/nextgen/sbs/readout/Skeleton.h Modified: trunk/nextgen/docconfig/config =================================================================== --- trunk/nextgen/docconfig/config 2009-04-14 22:31:00 UTC (rev 2129) +++ trunk/nextgen/docconfig/config 2009-04-17 21:01:55 UTC (rev 2130) @@ -1,2 +1,2 @@ commands utilities libraries servers frameworks -1daq 1epics 1tcl 1usbReadout 3daq 3tcl 3sbsReadout 3usbReadout +1daq 1epics 1tcl 1sbsReadout 1usbReadout 3daq 3tcl 3sbsReadout 3usbReadout Modified: trunk/nextgen/sbs/readout/CCAENV262Busy.h =================================================================== --- trunk/nextgen/sbs/readout/CCAENV262Busy.h 2009-04-14 22:31:00 UTC (rev 2129) +++ trunk/nextgen/sbs/readout/CCAENV262Busy.h 2009-04-17 21:01:55 UTC (rev 2130) @@ -43,7 +43,7 @@ private: CCaenIO& m_busy; public: - CCAENV262Busy(uint32_t base, unsigned crate); + CCAENV262Busy(uint32_t base, unsigned crate = 0); CCAENV262Busy(CCaenIO& module); CCAENV262Busy(const CCAENV262Busy& rhs); Modified: trunk/nextgen/sbs/readout/CReadoutMain.cpp =================================================================== --- trunk/nextgen/sbs/readout/CReadoutMain.cpp 2009-04-14 22:31:00 UTC (rev 2129) +++ trunk/nextgen/sbs/readout/CReadoutMain.cpp 2009-04-17 21:01:55 UTC (rev 2130) @@ -116,14 +116,14 @@ m_pExperiment = CreateExperiment(&parsedArgs); + // Add the application specific commands: + // Now initialize via the virtual functions. + addCommands(); - // State and run variables require the state/runvar manager - - CVariableBuffers* pVarbufs = new CVariableBuffers(*(getInterpreter())); SetupRunVariables(getInterpreter()); SetupStateVariables(getInterpreter()); @@ -141,10 +141,7 @@ } - // Add the application specific commands: - addCommands(); - // Setup our eventloop. @@ -241,10 +238,17 @@ CReadoutMain::addCommands() { CTCLInterpreter& interp(*getInterpreter()); - CRunControlPackage::getInstance(interp); + addCommands(&interp); // Trampoline to user's commands. } +void +CReadoutMain::addCommands(CTCLInterpreter* pInterp) { + CRunControlPackage::getInstance(*pInterp); + CVariableBuffers* pVarbufs = new CVariableBuffers(*pInterp); + +} + ////////////////////////////////////////////////////////////////////////////////////////////// /*! Modified: trunk/nextgen/sbs/readout/CReadoutMain.h =================================================================== --- trunk/nextgen/sbs/readout/CReadoutMain.h 2009-04-14 22:31:00 UTC (rev 2129) +++ trunk/nextgen/sbs/readout/CReadoutMain.h 2009-04-17 21:01:55 UTC (rev 2130) @@ -70,6 +70,7 @@ virtual void SetupReadout(CExperiment* pExperiment); virtual void SetupScalers(CExperiment* pExperiment); virtual void addCommands(); + virtual void addCommands(CTCLInterpreter* pInterp); protected: void startTclServer(std::string port); Modified: trunk/nextgen/sbs/readout/SBSReadout.xml =================================================================== --- trunk/nextgen/sbs/readout/SBSReadout.xml 2009-04-14 22:31:00 UTC (rev 2129) +++ trunk/nextgen/sbs/readout/SBSReadout.xml 2009-04-17 21:01:55 UTC (rev 2130) @@ -214,13 +214,13 @@ <varlistentry> <term><type>CCompoundEventSegment::EventSegmentIterator</type> <methodname>begin</methodname>()</term> - <listitemm> + <listitem> <para> Returns an iterator which 'points' to the beginning of the collection. Refer to the description below for information about iterators. </para> - </listitemm> + </listitem> </varlistentry> <varlistentry> <term><type>CCompoundEventSegment::EventSegmentIterator</type> @@ -546,21 +546,307 @@ <formalpara> <title>Busys</title> <para> - + During the time in which Readout is responding to a trigger it + is unable to accept a new trigger. During this time it is often + important to veto external electronics until the system is able to + accept the next trigger. This is the function of <firstterm>Busy</firstterm> + objects. </para> </formalpara> - + <para> + Busy objects are members of classes that are derived from + <classname>CBusy</classname> which has the following pure virtual + members: + </para> + <variablelist> + <varlistentry> + <term><type>void</type> <methodname>GoBusy</methodname></term> + <listitem> + <para> + This is called when due to software reasons the computer will + be unable to accept a trigger. For example, as the run ends. + It is important to note that the actual event by event busy should + be generated by hardware and then only cleared by software. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><type>void</type> <methodname>GoClear</methodname></term> + <listitem> + <para> + Called when the software is able to accept the next + trigger. + </para> + </listitem> + </varlistentry> + </variablelist> + <para> + The readout framework provides + <link linkend='manpage.ccaenv262busy'><classname>CCAENV262Busy</classname></link>, + and + <link linkend='manpage.cv977busy'><classname>CV977Busy</classname></link> as + prebuilt busy classes. This, and any busy class you create must be + registered to be used. The example below shows the creation and + registration of a <classname>CV977Busy</classname> object to + manage the busy. The physicsal module is in VME crate 0 and has a base + address of 0x00444400. + </para> + <informalexample> + <programlisting> +#include <CV977Busy.h> +... +void +Skeleton::SetupReadout(CExperiment* pExperiment) +{ + ... + pExperiment->EstablishBusy(new CV977Busy(0x444400)); + ... +} + </programlisting> + </informalexample> </section> <section> <title>Obtaining and building the skeleton application</title> <para> + The readout framework provides a skeleton application that you + can extend to a create a real readout application. + This section provides best practice methods to obtain the skeleton + and build it. </para> + <para> + Framework skeletons are all installed in the <filename>skeletons</filename> + directory of the NSCLDAQ installation tree. The following example shows + how we recommend obtaining this skeleton and how to perform a test build + of the skeleton. + </para> + <example> + <title>Obtaining the SBS readout skeleton</title> + <programlisting> +cd ~ +mkdir -p experiment/readout +cd experiment/readout +cp $DAQROOT/skeletons/sbs/* . + +make + + </programlisting> + </example> + <para> + The example creates the directory + <filename>~/experiment/readout</filename>. + Next the skeleton files are copied to that directory. + <command>make</command> is used to do a test build of the skeleton. + </para> + <note> + <title>NOTE!</title> + <para> + By itself the skeleton cannot take any useful data. You must + modify it to meet you readout needs, and build the modified + version. See + <link linkend='sbsrdo.sec.skeleton'>"Modify8ing the skeleton application to meet your needs</link>, + the next section for information about how to do this. + </para> + </note> </section> <section id='sbsrdo.sec.skeleton'> <title>Modifying the skeleton application to meet your needs</title> <para> + The skeleton provides several member functions that are called + in a specific order. You should fill some or all of these member + function in with actual code to set up the framwork to do what + you want it to do. </para> + <para> + If you add additional source files, you should modify the + <filename>Makefile</filename> as well so that they are incorporated + into the build. The simplest way to do this is to add them to the + definition of the <literal>OBJECTS</literal>macro in the + <filename>Makefile</filename>. + </para> + <para> + Let's look at the member functions in <filename>Skeleton.cpp</filename> + that you may have to fill in. These are listed in order of likelyhood + you'll need or want to add code to them. Note that all of these members + invoke the base class member functions they override. This ensures that + important functionality provided by those members is provided. + </para> + <variablelist> + <varlistentry> + <term><type>void</type> <methodname>SetupReadout</methodname>( + <type>CExperiment*</type> <parameter>pExperiment</parameter> + )</term> + <listitem> + <para> + Fill in code here to setup the event by event reaout + part of the framework. Specific work you must do is: + <itemizedlist> + <listitem> + <para> + Create and register an event trigger. + </para> + </listitem> + <listitem> + <para> + Create event segments and glue them together + into a coherent event segment hierarchy. + </para> + </listitem> + <listitem> + <para> + Register the top end event segment hierarchy + elements in the experiment's top level event + segment so that they will be invoked + at appropriate times. + </para> + </listitem> + </itemizedlist> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><type>void</type> <methodname>SetupScalers</methodname> ( + <type>CExperiment*</type> <parameter>pExperiment</parameter> + )</term> + <listitem> + <para> + Fill in code here to set up the scaler readout. + This involves: + </para> + <itemizedlist> + <listitem> + <para> + Create and register a scaler trigger. The + Skeleton provides sample code for registering + a timed trigger. + </para> + </listitem> + <listitem> + <para> + Create your scalers and glue them together + into a coherent scaler readout hierarchy via + scaler banks. + </para> + </listitem> + <listitem> + <para> + Register the top elements of the scaler readout + hierarchy with <parameter>pExperiment</parameter>'s + top level scaler bank so that your elements will + be invoked at the proper times. + </para> + </listitem> + + </itemizedlist> + </listitem> + </varlistentry> + <varlistentry> + <term><type>void</type> <methodname>addCommands</methodname> ( + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + )</term> + <listitem> + <para> + If you want to add application specific commands to the + framework, add them here. This is usually done by + writing subclasses derived from <classname>CObjectProcessor</classname>, + and creating an instance for each of these classes. + The comments prior to this method describe what you need + to do if you have existing procedural commands you want + to register. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><type>void</type> <methodname>SetupRunVariables</methodname> ( + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + )</term> + <listitem> + <para> + If you want to setup some pre-existing run variables, but + don't want to use a script to do this, you can define + them here. The simplest way to define a runvar is to + create the appropriate <command>runvar</command> command + string and pass it to <parameter>pInterp</parameter>-><methodname>Eval</methodname>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><type>void</type> <methodname>SetupStateVariables</methodname> ( + <type>CTCLInterpreter*</type> <parameter>pInterp</parameter> + )</term> + <listitem> + <para> + If you want to set up some pre-existing state variables, but + don't want to use a script to do this, you can define + them here. The simplest way to define a statevar is to + create the appropriate <command>statevar</command> command + string and passi to <parameter>pInterp</parameter>-><methodname>Eval</methodname>. + </para> + </listitem> + </varlistentry> + </variablelist> + </section> + <section id="sbsrdo.sec.commands"> + <title>Readout commands</title> + <para> + The SBS Readout framework automatically adds several commands. + These are described fully in the 1sbsReadout reference pages. + A brief summary of these commands is given here. + </para> + <para> + A cluster of commands allows you to perform run control operations. + These are the <command>begin</command>, <command>end</command>, + <command>pause</command> and <command>resume</command> commands. + </para> + <para> + The <command>begin</command> command also uses two Tcl global + variables to set the run state. These are: + <varname>title</varname> and <varname>run</varname>. + </para> + <para> + In addition the <command>statevar</command> and <command>runvar</command> + commands are defined. These allow the creation, listing and deleting + of Tcl variables that will be logged to the event stream periodically. + State variables are write-protected from Tcl scripts while the run is + active. Run variables can be modified during the active part of the + run. + </para> + <para> + Thus State variables are intended to log fixed unchanging parameters + of a run, such as documentation of the target, or beam ion or beam + species. Run variables are intended to log things that may change + over time, such as the temperature of the chamber, beamline magnet + readings and so on. + </para> + </section> + <section id='sbsrdo.sec.server'> + <title>Embedded Tcl server</title> + <para> + If requested, the readout program will run a Tcl server. This is + requested via the <option>--port</option> option when Readout is started. + If the value of the <option>--port</option> is an integer, that is + taken to be the port on which the server will listen for connections. + If the value of <option>--port</option> is <literal>managed</literal>, + the port manager will be contacted to dynamically allocate a port + for the <literal>Readout</literal> application. The server will + listen on that port. + </para> + <para> + One use of the tcl server is to modify run variables. For example, + an external program such as <application>controlpush</application> + can be run to data on specified EPICS process variables.l + </para> + </section> + <section id='sbsrdo.sec.running'> + <title>Running a readout application</title> + <para> + The readout application recognizes a few command options. + The full Readout command reference is described in + <link linkend='manpage.1sbsreadout'>Readout(1sbsReadout)</link>. + You can get a summary of the options by invoking Readout with + the <option>--help</option> option. + </para> + </section> </chapter> @@ -568,4 +854,3184 @@ <!-- manpage 3sbsReadout --> + <refentry id="manpage.cbusy"> + <refmeta> + <refentrytitle>CBusy</refentrytitle> + <manvolnum>3sbsReadout</manvolnum> + </refmeta> + <refnamediv> + <refname>CBusy</refname> + <refpurpose>Abstract base class for Busy module management.</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CBusy.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CBusy</classname></ooclass> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>GoBusy</methodname> + <void /><modifier>=0</modifier> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>GoClear</methodname> + <void /><modifier>=0</modifier> + </methodsynopsis> + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + <classname>CBusy</classname> is an abstract base class + for managing busy modules. When the Readout program accepts a + trigger, there is a <firstterm>deadtime</firstterm> during which it + is not able to accept subsequent trigger. External electronics often + needs to know when this deadtime is. + </para> + <para> + The normal way to provide a signal showing when the computer is busy + is to have some electronics module that acts like a latch. The + latch is set true by the trigger itself. Software clears the latch + when it is able to respond to the next trigger. + </para> + <para> + Concrete busy classes are created by deriving them from + <classname>CBusy</classname>. An instance of one of these concrete + classes should be created and registered with the + <link linkend='manpage.cexperiment'>CExperiment</link> + in <classname>Skeleton</classname>::<methodname>SetupReadout</methodname> + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>GoBusy</methodname> + <void /><modifier>=0</modifier> + </methodsynopsis> + <para> + Pure virtual function the framework calls when, for software + reasons, it is about to be unable to respond to triggers for + some extended period of time. This will be called when data taking + is about to stop due to a <command>end</command> or + <command>pause</command> command. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>GoClear</methodname> + <void /><modifier>=0</modifier> + </methodsynopsis> + <para> + Pure virtual function the framework calls when it's about to be + able to respond to triggers. In addition to calling this + member after processing each trigger, the framework will invoke + this at some point just prior to starting data taking as a result + of a <command>begin</command> or <command>resume</command> + command. + </para> + </refsect1> + </refentry> + + + <refentry id="manpage.ccaenv262busy"> + <refmeta> + <refentrytitle>CCAENV262Busy</refentrytitle> + <manvolnum>3sbsReadout</manvolnum> + </refmeta> + <refnamediv> + <refname>CCAENV262Busy</refname> + <refpurpose>Concrete busy class for the CAEN V262 input module.</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CCAENV262Busy> + </programlisting> + <classsynopsis> + <ooclass><classname>CCAENV262Busy : public CBusy</classname></ooclass> + <constructorsynopsis> + <methodname>CCAENV262Busy</methodname> + <methodparam> + <type>uint32_t</type> <parameter>base</parameter> + </methodparam> + <methodparam> + <type>unsigned</type> <parameter>crate</parameter> + </methodparam> + </constructorsynopsis> + <constructorsynopsis> + <methodname>CCAENV262Busy</methodname> + <methodparam> + <type>CCaenIO&</type> <parameter>module</parameter> + </methodparam> + </constructorsynopsis> + <constructorsynopsis> + <methodname>CCAENV262Busy</methodname> + <methodparam> + <modifier>const</modifier> <type>CCAENV262Busy&</type> + <parameter>rhs</parameter> + </methodparam> + </constructorsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>GoBusy</methodname> <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>GoReady</methodname> <void /> + </methodsynopsis> + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + This class uses the CAEN V262 I/O register to provide signals + needed to implement a computer busy. When you use this module, + module outputs have the following meanings: + <informaltable frame='all'> + <tgroup cols='2'> + <thead> + <row> + <entry>Output</entry> + <entry>Meaning</entry> + </row> + </thead> + <tbody> + <row> + <entry>SHP0</entry> + <entry><para>Computer is about to go busy for a long time</para></entry> + </row> + <row> + <entry>SHP1</entry> + <entry><para> + Computer is about to go ready.</para></entry> + </row> + <row> + <entry>SHP3</entry> + <entry><para> + Module clears are output just prior to releasing the + busy.</para></entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Note that <literal>SHP0</literal> is not a hardware signal. It means + that the computer is about to be busy due to data taking stopping or + pausing. To use this module you must have an external latch or + gate generator in latch mode. The latch should start on the OR + of the master trigger and <literal>SHP0</literal> it should clear + on <literal>SHP1</literal>. + </para> + <para> + The module clears are a convenience output and need not be used, however + if you can use them, this is quicker than clearing modules in software. + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis><type></type> + <methodname>CCAENV262Busy</methodname> + <methodparam> + <type>uint32_t</type> <parameter>base</parameter> + </methodparam> + <methodparam> + <type>unsigned</type> <parameter>crate</parameter> + </methodparam> + </methodsynopsis> + <para> + Construct a busy object. <parameter>base</parameter> is the + base address of the V262 module and <parameter>crate</parameter> the + VME crate in which the module lives. <parameter>crate</parameter> + is an optional parameter that defaults to <literal>0</literal>. + </para> + <methodsynopsis><type></type> + <methodname>CCAENV262Busy</methodname> + <methodparam> + <type>CCaenIO&</type> <parameter>module</parameter> + </methodparam> + </methodsynopsis> + <para> + Constructs a busy object. <parameter>module</parameter> is a + refererence to a <classname>CCaenIO</classname> module that + has already been constructed and will be the busy hardware + controlled by this object. + </para> + <methodsynopsis><type></type> + <methodname>CCAENV262Busy</methodname> + <methodparam> + <modifier>const</modifier> <type>CCAENV262Busy&</type> + <parameter>rhs</parameter> + </methodparam> + </methodsynopsis> + <para> + Copy constructs a new busy module that is a functional + equivalent to <parameter>rhs</parameter>. + </para> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>GoBusy</methodname> <void /> + </methodsynopsis> + <para> + Called by the framework to indicate the busy should + be asserted. This is not called in response to a gate. + Busy in response to a gate must happen at hardware speeds, + not software. + </para> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>GoReady</methodname> <void /> + </methodsynopsis> + <para> + Called by the framework to indicate it is able to react to + the next trigger. + </para> + </refsect1> + <refsect1> + <title>EXAMPLES</title> + <example> + <title>Creating and registering a V262 as a busy:</title> + <programlisting> +#include <CCAENV262Busy.h> +... +void +Skeleton::SetupReadout(CExperiment* pExperiment) +{ + ... + pExperiment->EstablishBusy(new CCAENV262(0x444400)); + ... +} + </programlisting> + </example> + </refsect1> + <refsect1> + <title> + SEE ALSO + </title> + <para> + <link linkend="manpage.cbusy">CBusy(3sbsReadout)</link> + <link linkend="CaenIO">CaenIO(3daq)</link> + <link linkend='manpage.ccaenv262trigger'>CCAENV262Trigger(3sbsReadout)</link> + </para> + </refsect1> + </refentry> + + <refentry id="manpage.ccaenv262trigger"> + <refmeta> + <refentrytitle>CCAENV262Triger</refentrytitle> + <manvolnum>3sbsReadout</manvolnum> + </refmeta> + <refnamediv> + <refname>CCAENV262Triger</refname> + <refpurpose>Trigger module with CAEN V262</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CCAEANV262Trigger.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CCAENV262Trigger : public CEventTrigger</classname></ooclass> + <constructorsynopsis> + <methodname>CCAENV262Trigger</methodname> + <methodparam> + <type>uint32_t</type> <parameter>base</parameter> + </methodparam> + <methodparam> + <type>unsigned</type> <parameter>crate</parameter> + <initializer>0</initializer> + </methodparam> + </constructorsynopsis> + <constructorsynopsis> + <methodname>CCAENV262Trigger</methodname> + <methodparam> + <type>CCaenIO&</type> <parameter>module</parameter> + </methodparam> + </constructorsynopsis> + <constructorsynopsis> + <methodname>CCAENV262Trigger</methodname> + <methodparam> + <modifier>const</modifier> + <type>CCAENV262Trigger&</type> <parameter>rhs</parameter> + </methodparam> + </constructorsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>bool</type> + <methodname>operator()</methodname><void /> + </methodsynopsis> + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + Implements a trigger class based on the hardware of the + CAEN V262 I/O register. When used as a triggerm odule, the + Following signals in the V262 have meaning: + <informaltable> + <tgroup cols='2'> + <thead> + <row> + <entry>Signal</entry> + <entry>Meaning</entry> + </row> + </thead> + <tbody> + <row> + <entry>IN0</entry> + <entry>Computer Master Gate (live)</entry> + </row> + <row> + <entry>SHP2</entry> + <entry><para> + Trigger acknowledge. The V262 does not latch signals + IN0 must be held true until SHP2 is signalled. + </para> + </entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis><type></type> + <methodname>CCAENV262Trigger</methodname> + <methodparam> + <type>uint32_t</type> <parameter>base</parameter> + </methodparam> + <methodparam> + <type>unsigned</type> <parameter>crate</parameter> + <initializer>0</initializer> + </methodparam> + </methodsynopsis> + <para> + Constructs a <classname>CCAENV262Trigger</classname> object. + The <parameter>base</parameter> parameter is the base address + of the CAEN V262 module to be used as a trigger. + The optional <parameter>crate</parameter> parameter specifies + which VME crate the module is in. If not supplied, + <parameter>crate</parameter> defaults to <literal>0</literal>. + </para> + <methodsynopsis> + <methodname>CCAENV262Trigger</methodname> + <methodparam> + <type>CCaenIO&</type> <parameter>module</parameter> + </methodparam> + </methodsynopsis> + <para> + Constructs a trigger object from an existing + <classname>CaenIO</classname> object. + <parameter>module</parameter> is the object that represents the + physical module that will be used as the trigger module. + </para> + <methodsynopsis> + <methodname>CCAENV262Trigger</methodname> + <methodparam> + <modifier>const</modifier> + <type>CCAENV262Trigger&</type> <parameter>rhs</parameter> + </methodparam> + </methodsynopsis> + <para> + Copy constructor. Contructs a trigger object from + <parameter>rhs</parameter>. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>bool</type> + <methodname>operator()</methodname><void /> + </methodsynopsis> + <para> + The trigger poll function. When the framework is able to accept + triggers, it will poll this method. A <literal>true</literal> + return indicates the presence of the trigger. Note that + this function will also strobe the SHP2 output when it sees a trigger, + making this a possibly destructive read of the trigger. + </para> + </refsect1> + <refsect1> + <title>EXAMPLES</title> + <para> + </para> + </refsect1> + <refsect1> + <title> + SEE ALSO + </title> + <para> + <link linkend='CaenIO'>CaenIO(3daq)</link> + <link linkend='manpage.ccaenv262busy'>CCAENV262Busy(3sbsReadout)</link> + <link linkend='manpage.ceventtrigger'>CEventTrigger(3sbsReadout)</link> + </para> + </refsect1> + </refentry> + + + <refentry id="manpage.ccompoundeventsegment"> + <refmeta> + <refentrytitle>CCompoundEventSegment</refentrytitle> + <manvolnum>3sbsReadout</manvolnum> + </refmeta> + <refnamediv> + <refname>CCompoundEventSegment</refname> + <refpurpose>Container for other event segments</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CCompoundEventSegment.h> + </programlisting> + <classsynopsis> + <ooclass><classname>CCompoundEventSegement : public CEventSegment</classname></ooclass> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>initialize</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>clear</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>disable</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>size_t</type> + <methodname>read</methodname> + <methodparam> + <type>void*</type> <parameter>pBuffer</parameter> + </methodparam> + <methodparam> + <type>size_t</type> <parameter>maxwords</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <type>void</type> <methodname>AddEventSegment</methodname> + <methodparam> + <type>CEventSegment*</type> <parameter>pSegment</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <type>void</type> <methodname>DeleteEventSegment</methodname> + <methodparam> + <type>CEventSegment*</type> <parameter>pSegment</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <modifier>virtual</modifier> <type>bool</type> + <methodname>isComposite</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>EventSegmentIterator</type> + <methodname>begin</methodname> <void /> + </methodsynopsis> + <methodsynopsis> + <type>EventSegmentIterator</type> + <methodname>end</methodname><void /> + </methodsynopsis> + <methodsynopsis> + <type>size_t</type> + <methodname>size</methodname><void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>size_t</type> <methodname>leafCount</methodname> <void /> + </methodsynopsis> + <methodsynopsis> + <type>size_t</type> <methodname>fullCount</methodname><void /> + </methodsynopsis> + <methodsynopsis> + <type>void</type> <methodname>visit</methodname> + <methodparam> + <type>CVisitor&</type> <parameter>visitor</parameter> + </methodparam> + </methodsynopsis> + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + <classname>CCompoundEventSegemnt</classname> provides an ordered + container for event segment objects (or rather pointers to event + segment objects). Since a <classname>CCompoundEventSegment</classname> + itself is an event segment you can build an arbitrarily deep hierarchy + of event segments using this class. + </para> + <para> + A rich set of facilities for navigating the event segment hierarchy + is provided though normally this hierarchy gets built at program initialization + time and is fixed throughout the lifetime of the program. Navigation models + include iteration and visitation. See Types and Public Data for + information about the class scoped data types that support these + models. + </para> + <para> + Event segments also provide a mechanism to determine if they are + containers via the <methodname>isComposite</methodname> member function. + </para> + </refsect1> + <refsect1> + <title> + Public member functions + </title> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>initialize</methodname> + <void /> + </methodsynopsis> + <para> + Part of the event segment interface. Does a deep initialization + of all events segments in the compound event segment. This is + done by calling the <methodname>initialize</methodname> + member on each element in the container. This implies that + if an element of the container is itself a compound event + segment, it's children will be recursively initialized. + </para> + <methodsynopsis> + <modifier>virtual</modifier> + <type>void</type> <methodname>clear</methodname> + <void /> + </methodsynopsis> + <para> + Part of the event segment interface. Does a deep clear of all + event segments. This is + done by calling the <methodname>clear</methodname> + member on each element in the container. This implies that + if an element of the container is itself a compound event + segment, it's children will be recursively cleared. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>void</type> + <methodname>disable</methodname> + <void /> + </methodsynopsis> + <para> + Part of the event segment interface. Does a deep disable of all + event segments. This is + done by calling the <methodname>disable</methodname> + member on each element in the container. This implies that + if an element of the container is itself a compound event + segment, it's children will be recursively disabled. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>size_t</type> + <methodname>read</methodname> + <methodparam> + <type>void*</type> <parameter>pBuffer</parameter> + </methodparam> + <methodparam> + <type>size_t</type> <parameter>maxwords</parameter> + </methodparam> + </methodsynopsis> + <para> + Part of the event segment interface. Does a deep read of all + event segments. This is + done by calling the <methodname>read</methodname> + member on each element in the container. This implies that + if an element of the container is itself a compound event + segment, it's children will be recursively read. + </para> + <para> + <parameter>pBuffer</parameter> points to the buffer into which + data should be read. <parameter>maxwords</parameter> is the + maximum number of words that can still fit in that buffer. + The method returns the number of words that were read by this + segment. + </para> + <methodsynopsis> + <type>void</type> <methodname>AddEventSegment</methodname> + <methodparam> + <type>CEventSegment*</type> <parameter>pSegment</parameter> + </methodparam> + </methodsynopsis> + <para> + Adds an event segment <parameter>pSegment</parameter> + to the end of the ordered container of + event segments in the compound. Very bad things will happen if + <parameter>pSegment</parameter>'s lifetime is not at least that of + the event segment. + </para> + <methodsynopsis> + <type>void</type> <methodname>DeleteEventSegment</methodname> + <methodparam> + <type>CEventSegment*</type> <parameter>pSegment</parameter> + </methodparam> + </methodsynopsis> + <para> + If <parameter>pSegment</parameter> is one of the immediate + children of the object, it is removed from the container. + If not, this is a no-op. Please note that this is not a deep + delete. If <parameter>pSegment</parameter> is actually a child + of some compound event segment in the container, it will not + be found and therefore not removed. + </para> + <para> + <parameter>pSegment</parameter> is removed from the container. + It is up to the calling software, if appropriate, to destroy + the actual object. + </para> + <methodsynopsis> + <modifier>virtual</modifier> <type>bool</type> + <methodname>isComposite</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <para> + This returns true. The member function <methodname>isComposite</methodname> + is provided in all event segments. It is true if the object + implements the interface of the compound event segment. + </para> + <methodsynopsis> + <type>EventSegmentIterator</type> + <methodname>begin</methodname> <void /> + </methodsynopsis> + <para> + Returns a begin of iteration iterator. See "Types and Public Data" + below for more about iterators. See as well <methodname>end</methodname> + below for typical usage. This iterator is a shallow iterator. + </para> + <methodsynopsis> + <type>EventSegmentIterator</type> + <methodname>end</methodname><void /> + </methodsynopsis> + <para> + Returns an iterator that points off the end of the container. + This can be used to determine when the iterator has visited + all members of the container. The function below shows a + typical usage. + </para> + <informalexample> + <programlisting> +CCompoundEventSegment es; +... +CCompoundEventSegment::EventSegmentIterator p = es.begin(); +while (p != es.end()) { + CEventSegment *pSegment = *p; + // + // Do something with pSegment: + ... + p++; +} + </programlisting> + </informalexample> + + <methodsynopsis> + <type>size_t</type> + <methodname>size</methodname><void /><modifier>const</modifier> + </methodsynopsis> + <para> + Returns the number of elements in the event segment container. + This is a shallow count. + </para> + <methodsynopsis> + <type>size_t</type> <methodname>leafCount</methodname> <void /> + </methodsynopsis> + <para> + Returns the number of 'terminal' nodes in the hierarchy. A + terminal node is one for which <methodname>isComposite</methodname> + returns <literal>false</literal>. This is a deep count. + </para> + <methodsynopsis> + <type>size_t</type> <methodname>fullCount</methodname><void /> + </methodsynopsis> + <para> + Returns the total number of nodes in the hiearchy. This is a deep + count. + </para> + <methodsynopsis> + <type>void</type> <methodname>visit</methodname> + <methodparam> + <type>CVisitor&</type> <parameter>visitor</parameter> + </methodparam> + </methodsynopsis> + <para> + Visits each node in the hieararchy and invokes the visitor + at each node at this level of the hierarchy. If deep visitation + is required, then whenever the visitor is handed a node for which + <methodname>isComposite</methodname> is true, it should invoke + this method on that node with itself as a parameter. + </para> + <para> + For more on the visitor class, see "Types and public data". + For a recipe for doing recursive visitation, see "EXAMPLES" + </para> + </refsect1> + <refsect1> + <title>Types and public data</title> + <para> + This class provides an iterator for its container; + <classname>CCompoundEventSegment::EventSegmentIterator</classname>. + This is a pointer like object. When dereferenced the iterator + returns a <type>CEventSegment*</type> for a segment that is in the + container. Increment moves the 'pointer' to the next item + in the container (shallow iteration). + </para> + <para> + The class provides an abstract base class on which Visitors can be + built: <classname>CCompoundEventSegment::CVisitor</classname>. + The definition of this class is shown below: + <informalexample> + <programlisting> + class CVisitor { + public: + virtual void operator()(CEventSegment* pSegment) = 0; + }; + </programlisting> + </informalexample> + </para> + <para> + The idea is that you would derive a class from that and + invoke the <methodname>visit</methodname> method with an object + of that class to do something to all nodes in the container. + </para> + </refsect1> + <refsect1> + <title>EXAMPLES</title> + <para> + This section shows how to do deep iteration both with visitors and + with iterators. The key is that whenever a compound is found + iteration or visitation is done recursively on that compond. + </para> + <example> + <title>Deep iteration of <classname>CCompondEventSegment</classname> elements</title> + <programlisting> +/* + Do something to all leaf nodes of the event segment + hierarchy +*/ +void doSomething(CCompoundEventSegment* pSegment) +{ + CCompoundEventSegment::EventSegmentIterator p = pSegment->begin(); + while (p != pSegment->end()) { + CEventSegment* pSeg = *p; + if (pSeg->isComposite()) { + doSomething(pSeg); // Recurse to go deep. + } + else { + // Do whatever needs doing here.... + } + p++; + } +} + </programlisting> + </example> + <example> + <title>Deep visitation of <classname>CCompoundEventSegment</classname> elements</title> + <programlisting> +class MyVisitor : public CCompoundEventSegment::CVisitor +{ + virtual void operator()(CEventSegment* pSeg) + { + if (pSeg->isCompound()) { + pSeg->visit(*this); + } + else { + // Do what needs doing to terminal nodes.... + } + } +}; +... +CCompoundEventSegment segment; +MyVisitor visitor; +segment.visit(visitor); // Visitor ensures deep visitation. + + </programlisting> + </example> + + </refsect1> + <refsect1> + <title> + SEE ALSO + </title> + <para> + <link linkend='manpage.ceventsegment'>CEventSegment(3sbsReadout)</link> + </para> + </refsect1> + </refentry> + + + <refentry id="manpage.cdocumentedpacket"> + <refmeta> + <refentrytitle>CDocumentedPacket</refentrytitle> + <manvolnum>3sbsReadout</manvolnum> + </refmeta> + <refnamediv> + <refname>CDocumentedPacket</refname> + <refpurpose>Encapsulate event data in a packet that is documented.</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <programlisting> +#include <CDocumentedPacket> + </programlisting> + <classsynopsis> + <ooclass><classname>CDocumentedPacket</classname></ooclass> + <constructorsynopsis> + <methodname>CDocumentedPacket</methodname> + <methodparam> + <type>unsigned short</type> <parameter>nTag</parameter> + </methodparam> + <methodparam> + <modifier>const</modifier> <type>std::string&</type> + <parameter>rName</parameter> + </methodparam> + <methodparam> + <modifier>const</modifier> <type>std::string&</type> + <parameter>Description</parameter> + </methodparam> + <methodparam> + <modifier>const</modifier> <type>std::string&</type> + <parameter>rVersion</parameter> + </methodparam> + </constructorsynopsis> + <methodsynopsis> + <type>int</type> <methodname>operator==</methodname> + <methodparam> + <modifier>const</modifier> <type>CDocumentedPacket&</type> + <parameter>rhs</parameter> + </methodparam> + <modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>int</type> <methodname>operator==</methodname> + <methodparam> + <modifier>const</modifier> <type>std::string&</type> + <parameter>rhs</parameter> + </methodparam> + <modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>int</type> <methodname>operator!=</methodname> + <methodparam> + <modifier>const</modifier> <type>CDocumentedPacket&</type> + <parameter>rhs</parameter> + </methodparam> + <modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>int</type> <methodname>operator!=</methodname> + <methodparam> + <modifier>const</modifier> <type>std::string&</type> + <parameter>rhs</parameter> + </methodparam> + <modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>unsigned short</type> <methodname>getTag</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>std::string</type> <methodname>getName</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>std::string</type> <methodname>getDescription</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>std::string</type> <methodname>getVersion</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>std::string</type> <methodname>getInstantiationDate</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>unsigned short*</type> <methodname>getHeaderPtr</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>bool</type> <methodname>getPacketInProgress</methodname> + <void /><modifier>const</modifier> + </methodsynopsis> + <methodsynopsis> + <type>std::string</type> <methodname>Format</methodname> + <void /> + </methodsynopsis> + <methodsynopsis> + <type>unsigned short*</type> <methodname>Begin</methodname> + <methodparam> + <type>unsigned short*</type> <parameter>rPointer</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <type>unsigned short*</type> <methodname>End</methodname> + <methodparam> + <type>unsigned short*</type> <parameter>rBuffer</parameter> + </methodparam> + </methodsynopsis> + </classsynopsis> + </refsynopsisdiv> + <refsect1> + <title>Description</title> + <para> + NSCL data taking programs should try to emit self describing event + data. This is facilitated by providing code to support the generation + of <firstterm>packets</firstterm>. A packet is a chunk of event data + with a three word header. The first longword (32 bits), is the + number of words in the packet, including the header. The last word + of the header is an identifying code. The remainder of the packet + are the data read out for that identifying code. + </para> + <para> + <ulink url="http://groups.nscl.msu.edu/userinfo/daq/nscltags.html"> + http://groups.nscl.msu.edu/userinfo/daq/nscltags.html</ulink> + defines the set of identifiers (tags) that are defined. The tag assigner + for permanent devices is + <ulink url="mailto:ba...@ns...">bazin at nscl dot msu dot edu</ulink>. + Contact him if you need a new tag assigned. + </para> + ... [truncated message content] |
From: <ro...@us...> - 2009-04-23 10:26:42
|
Revision: 2132 http://nscldaq.svn.sourceforge.net/nscldaq/?rev=2132&view=rev Author: ron-fox Date: 2009-04-23 10:26:34 +0000 (Thu, 23 Apr 2009) Log Message: ----------- Good compiles and passes the tests it should pass on lenny Modified Paths: -------------- trunk/nextgen/aclocal.m4 trunk/nextgen/base/CopyrightTools/test trunk/nextgen/base/dataflow/BlockingTests.cpp trunk/nextgen/base/dataflow/CRemoteAccess.cpp trunk/nextgen/base/dataflow/CRingMaster.cpp trunk/nextgen/base/dataflow/TransferTests.cpp trunk/nextgen/base/dataflow/ringtostdout.cpp trunk/nextgen/base/dataflow/stdintoring.cpp trunk/nextgen/base/exception/ErrnoException.cpp trunk/nextgen/base/exception/StreamIOError.cpp trunk/nextgen/base/exception/StreamIOError.h trunk/nextgen/base/exception/testErrnoException.cpp trunk/nextgen/base/tclplus/CLanguageTraceCallbacks.cpp trunk/nextgen/base/tclplus/CTCLServer.h trunk/nextgen/base/tclplus/TCLObjectProcessor.cpp trunk/nextgen/base/tclplus/TCLVariable.cpp trunk/nextgen/config.guess trunk/nextgen/config.sub trunk/nextgen/daq/format/CRingScalerItem.cpp trunk/nextgen/daq/format/CRingTextItem.cpp trunk/nextgen/daq/format/physcounttests.cpp trunk/nextgen/daq/readoutgui/Makefile.in trunk/nextgen/ltmain.sh trunk/nextgen/sbs/driver/dd/btp.mod.c trunk/nextgen/sbs/driver/dd/btp_mmap.c trunk/nextgen/sbs/tclpackage/Makefile.am trunk/nextgen/servers/portmanager/cpptest trunk/nextgen/servers/tclserver/tclAppInit.cpp trunk/nextgen/usb/tclcommon/CItemConfiguration.cpp trunk/nextgen/usb/vmusb/deviceDriver/C830.cpp trunk/nextgen/usb/vmusb/deviceDriver/CCAENChain.cpp trunk/nextgen/usb/vmusb/deviceDriver/CMarker.cpp trunk/nextgen/usb/vmusb/deviceDriver/CStack.cpp trunk/nextgen/utilities/controlpush/CSocket.cpp trunk/nextgen/utilities/controlpush/Main.cpp trunk/nextgen/utilities/daqstart/CLocalMonitoredProgram.cpp trunk/nextgen/utilities/daqstart/CMonitoredProgram.cpp trunk/nextgen/utilities/daqstart/CSink.cpp trunk/nextgen/utilities/daqstart/CSinkFactory.cpp Modified: trunk/nextgen/aclocal.m4 =================================================================== --- trunk/nextgen/aclocal.m4 2009-04-23 10:26:06 UTC (rev 2131) +++ trunk/nextgen/aclocal.m4 2009-04-23 10:26:34 UTC (rev 2132) @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.10 -*- Autoconf -*- +# generated automatically by aclocal 1.10.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. +# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,14 +11,17 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_if(m4_PACKAGE_VERSION, [2.61],, -[m4_fatal([this file was generated for autoconf 2.61. -You have another version of autoconf. If you want to use that, -you should regenerate the build system entirely.], [63])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(AC_AUTOCONF_VERSION, [2.61],, +[m4_warning([this file was generated for autoconf 2.61. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# serial 48 Debian 1.5.22-4 AC_PROG_LIBTOOL +# serial 52 Debian 1.5.26-4 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) @@ -106,7 +109,6 @@ AC_REQUIRE([AC_OBJEXT])dnl AC_REQUIRE([AC_EXEEXT])dnl dnl - AC_LIBTOOL_SYS_MAX_CMD_LEN AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE AC_LIBTOOL_OBJDIR @@ -181,7 +183,7 @@ test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= @@ -208,6 +210,8 @@ ;; esac +_LT_REQUIRED_DARWIN_CHECKS + AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], enable_win32_dll=yes, enable_win32_dll=no) @@ -268,8 +272,9 @@ # Check for compiler boilerplate output or warnings with # the simple compiler test code. AC_DEFUN([_LT_COMPILER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* @@ -281,14 +286,86 @@ # Check for linker boilerplate output or warnings with # the simple link test code. AC_DEFUN([_LT_LINKER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* +$rm -r conftest* ])# _LT_LINKER_BOILERPLATE +# _LT_REQUIRED_DARWIN_CHECKS +# -------------------------- +# Check for some things on darwin +AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + echo "int foo(void){return 1;}" > conftest.c + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib ${wl}-single_module conftest.c + if test -f libconftest.dylib; then + lt_cv_apple_cc_single_mod=yes + rm -rf libconftest.dylib* + fi + rm conftest.c + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[0123]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}" + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil="~$DSYMUTIL \$lib || :" + else + _lt_dsymutil= + fi + ;; + esac +]) + # _LT_AC_SYS_LIBPATH_AIX # ---------------------- # Links a minimal program and checks the executable @@ -298,12 +375,20 @@ # If we don't find anything, use the default library path according # to the aix ld manual. AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], -[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi],[]) +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_AC_SYS_LIBPATH_AIX @@ -534,13 +619,17 @@ rm -rf conftest* ;; -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; @@ -557,6 +646,9 @@ ;; *64-bit*) case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; @@ -597,7 +689,11 @@ *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) LD="${LD-ld} -64" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; esac ;; esac @@ -628,7 +724,7 @@ AC_CACHE_CHECK([$1], [$2], [$2=no ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -669,11 +765,12 @@ # ------------------------------------------------------------ # Check whether the given compiler option works AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], -[AC_CACHE_CHECK([$1], [$2], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" - printf "$lt_simple_link_test_code" > conftest.$ac_ext + echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings @@ -689,7 +786,7 @@ $2=yes fi fi - $rm conftest* + $rm -r conftest* LDFLAGS="$save_LDFLAGS" ]) @@ -787,24 +884,27 @@ fi ;; *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi ;; esac ]) @@ -957,7 +1057,7 @@ AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], @@ -965,7 +1065,7 @@ [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) @@ -1031,7 +1131,8 @@ # --------------------------------- # Check to see if options -c and -o are simultaneously supported by compiler AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no @@ -1039,7 +1140,7 @@ mkdir conftest cd conftest mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or @@ -1179,6 +1280,7 @@ darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" + old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -1196,7 +1298,8 @@ # ----------------------------- # PORTME Fill in your ld.so characteristics AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], -[AC_MSG_CHECKING([dynamic linker characteristics]) +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) library_names_spec= libname_spec='lib$name' soname_spec= @@ -1210,20 +1313,58 @@ version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" +m4_if($1,[],[ if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi +fi]) need_lib_prefix=unknown hardcode_into_libs=no @@ -1241,7 +1382,7 @@ soname_spec='${libname}${release}${shared_ext}$major' ;; -aix4* | aix5*) +aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no @@ -1380,12 +1521,8 @@ shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi + m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; @@ -1439,7 +1576,7 @@ shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; - freebsd*) # from 4.6 on + *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; @@ -1502,7 +1639,7 @@ postinstall_cmds='chmod 555 $lib' ;; -interix3*) +interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no @@ -1573,7 +1710,7 @@ # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi @@ -1679,6 +1816,10 @@ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; +rdos*) + dynamic_linker=no + ;; + solaris*) version_type=linux need_lib_prefix=no @@ -1774,6 +1915,13 @@ AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no +AC_CACHE_VAL([lt_cv_sys_lib_search_path_spec], +[lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"]) +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +AC_CACHE_VAL([lt_cv_sys_lib_dlsearch_path_spec], +[lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"]) +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" @@ -1784,7 +1932,8 @@ # _LT_AC_TAGCONFIG # ---------------- AC_DEFUN([_LT_AC_TAGCONFIG], -[AC_ARG_WITH([tags], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_ARG_WITH([tags], [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], [include additional configurations @<:@automatic@:>@])], [tagnames="$withval"]) @@ -2045,7 +2194,7 @@ # AC_PATH_TOOL_PREFIX # ------------------- -# find a file program which can recognise shared library +# find a file program which can recognize shared library AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_MSG_CHECKING([for $1]) @@ -2108,7 +2257,7 @@ # AC_PATH_MAGIC # ------------- -# find a file program which can recognise a shared library +# find a file program which can recognize a shared library AC_DEFUN([AC_PATH_MAGIC], [AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then @@ -2255,7 +2404,7 @@ # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], -[AC_CACHE_CHECK([how to recognise dependent libraries], +[AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= @@ -2272,7 +2421,7 @@ # whether `pass_all' will *always* work, you probably want this one. case $host_os in -aix4* | aix5*) +aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; @@ -2294,9 +2443,15 @@ mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump'. - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi ;; darwin* | rhapsody*) @@ -2341,7 +2496,7 @@ esac ;; -interix3*) +interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; @@ -2391,6 +2546,10 @@ lt_cv_deplibs_check_method=pass_all ;; +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + solaris*) lt_cv_deplibs_check_method=pass_all ;; @@ -2443,7 +2602,7 @@ lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do @@ -2659,10 +2818,10 @@ _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" +lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' +lt_simple_link_test_code='int main(){return(0);}' _LT_AC_SYS_COMPILER @@ -2698,7 +2857,7 @@ fi ;; -aix4* | aix5*) +aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi @@ -2755,6 +2914,7 @@ _LT_AC_TAGVAR(predeps, $1)= _LT_AC_TAGVAR(postdeps, $1)= _LT_AC_TAGVAR(compiler_lib_search_path, $1)= +_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)= # Source file extension for C++ test sources. ac_ext=cpp @@ -2764,10 +2924,10 @@ _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" +lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER @@ -2864,7 +3024,7 @@ # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - aix4* | aix5*) + aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -2877,7 +3037,7 @@ # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) @@ -2913,7 +3073,7 @@ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes + : else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported @@ -3023,59 +3183,31 @@ fi ;; darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes ; then - lt_int_apple_cc_single_mod=no + _LT_AC_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + if test "$GXX" = yes ; then output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -3158,9 +3290,7 @@ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - ;; + hppa*64*|ia64*) ;; *) _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; @@ -3228,7 +3358,7 @@ ;; esac ;; - interix3*) + interix[[3-9]]*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' @@ -3320,7 +3450,7 @@ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; - pgCC*) + pgCC* | pgcpp*) # Portland Group C++ compiler _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' @@ -3348,6 +3478,29 @@ # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; esac ;; lynxos*) @@ -3386,16 +3539,20 @@ _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no fi - output_verbose_link_cmd='echo' ;; osf3*) case $cc_basename in @@ -3557,15 +3714,10 @@ case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. We must also pass each convience library through - # to the system linker between allextract/defaultextract. - # The C++ compiler will combine linker options so we - # cannot just pass the convience library names through - # without $wl. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes @@ -3612,6 +3764,12 @@ fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac fi ;; esac @@ -3727,7 +3885,8 @@ # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. -AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP], +[AC_REQUIRE([LT_AC_PROG_SED])dnl dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each @@ -3852,10 +4011,15 @@ $rm -f confest.$objext +_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_AC_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_AC_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + # PORTME: override above test on systems where it is broken ifelse([$1],[CXX], [case $host_os in -interix3*) +interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_AC_TAGVAR(predep_objects,$1)= @@ -3863,19 +4027,51 @@ _LT_AC_TAGVAR(postdeps,$1)= ;; +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + solaris*) case $cc_basename in CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. - _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun' + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi ;; esac ;; esac ]) - case " $_LT_AC_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac @@ -3918,10 +4114,17 @@ _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code=" subroutine t\n return\n end\n" +lt_simple_compile_test_code="\ + subroutine t + return + end +" # Code to be used in simple link tests -lt_simple_link_test_code=" program t\n end\n" +lt_simple_link_test_code="\ + program t + end +" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER @@ -3953,7 +4156,7 @@ postinstall_cmds='$RANLIB $lib' fi ;; -aix4* | aix5*) +aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi @@ -4000,10 +4203,10 @@ _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}\n" +lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER @@ -4056,7 +4259,7 @@ _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" @@ -4130,6 +4333,7 @@ _LT_AC_TAGVAR(predeps, $1) \ _LT_AC_TAGVAR(postdeps, $1) \ _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_dirs, $1) \ _LT_AC_TAGVAR(archive_cmds, $1) \ _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ _LT_AC_TAGVAR(postinstall_cmds, $1) \ @@ -4145,6 +4349,7 @@ _LT_AC_TAGVAR(module_cmds, $1) \ _LT_AC_TAGVAR(module_expsym_cmds, $1) \ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ + _LT_AC_TAGVAR(fix_srcfile_path, $1) \ _LT_AC_TAGVAR(exclude_expsyms, $1) \ _LT_AC_TAGVAR(include_expsyms, $1); do @@ -4191,7 +4396,7 @@ # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: @@ -4428,6 +4633,10 @@ # shared library. postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_dirs, $1) + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) @@ -4516,7 +4725,7 @@ sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) @@ -4599,6 +4808,7 @@ # --------------------------------- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([LT_AC_PROG_SED]) AC_REQUIRE([AC_PROG_NM]) AC_REQUIRE([AC_OBJEXT]) # Check for command to grab the raw symbol name followed by C symbol from nm. @@ -4776,7 +4986,7 @@ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi - rm -f conftest* conftst* + rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then @@ -4825,13 +5035,16 @@ # like `-m68040'. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | os2* | pw32*) + mingw* | cygwin* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform @@ -4842,7 +5055,7 @@ # DJGPP does not support shared libraries at all _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; - interix3*) + interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; @@ -4868,7 +5081,7 @@ esac else case $host_os in - aix4* | aix5*) + aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor @@ -4964,7 +5177,7 @@ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; - pgCC*) + pgCC* | pgcpp*) # Portland Group C++ compiler. _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' @@ -4978,6 +5191,14 @@ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac ;; esac ;; @@ -5098,14 +5319,17 @@ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) @@ -5114,7 +5338,7 @@ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; - interix3*) + interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; @@ -5172,10 +5396,11 @@ esac ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) @@ -5224,6 +5449,22 @@ # All Alpha code is PIC. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; esac ;; @@ -5233,6 +5474,10 @@ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; + rdos*) + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + solaris*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' @@ -5292,7 +5537,7 @@ # if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + _LT_AC_TAGVAR(lt_cv_prog_compiler_pic_works, $1), [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; @@ -5316,7 +5561,7 @@ # wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + _LT_AC_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) @@ -5327,11 +5572,12 @@ # ------------------------------------ # See if the linker supports building shared libraries. AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], -[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ifelse([$1],[CXX],[ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in - aix4* | aix5*) + aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then @@ -5344,7 +5590,7 @@ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) _LT_AC_TAGVAR(link_all_deplibs, $1)=no @@ -5353,6 +5599,7 @@ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac + _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ],[ runpath_var= _LT_AC_TAGVAR(allow_undefined_flag, $1)= @@ -5383,12 +5630,14 @@ # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. - _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. _LT_CC_BASENAME([$compiler]) @@ -5438,7 +5687,7 @@ # See if GNU ld supports shared libraries. case $host_os in - aix3* | aix4* | aix5*) + aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(ld_shlibs, $1)=no @@ -5486,7 +5735,7 @@ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -5504,7 +5753,7 @@ fi ;; - interix3*) + interix[[3-9]]*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' @@ -5519,7 +5768,7 @@ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; - linux* | k*bsd*-gnu) + gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in @@ -5537,13 +5786,22 @@ ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi _LT_AC_TAGVAR(link_all_deplibs, $1)=no else @@ -5584,7 +5842,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 @@ -5649,7 +5907,7 @@ fi ;; - aix4* | aix5*) + aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -5669,7 +5927,7 @@ # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes @@ -5703,7 +5961,7 @@ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes + : else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported @@ -5796,7 +6054,7 @@ # The linker will automatically build a .lib file if we build a DLL. _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. - _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; @@ -5829,19 +6087,18 @@ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_und... [truncated message content] |