400 lines
16 KiB
OpenEdge ABL
400 lines
16 KiB
OpenEdge ABL
\documentstyle{report}
|
|
|
|
\setlength{\oddsidemargin}{0in}
|
|
\setlength{\evensidemargin}{0in}
|
|
\setlength{\topmargin}{0in}
|
|
\addtolength{\topmargin}{-\headheight}
|
|
\addtolength{\topmargin}{-\headsep}
|
|
\setlength{\textheight}{8.9in}
|
|
\setlength{\textwidth}{6.5in}
|
|
\setlength{\marginparwidth}{0.5in}
|
|
|
|
\title{SINQHM-Utility\\ Utility functions for the \\
|
|
SINQ Histogram memory}
|
|
\author{David Maden, Mark K\"onnecke, April 1997}
|
|
|
|
\begin{document}
|
|
\maketitle
|
|
\clearpage
|
|
|
|
\chapter{Introduction}
|
|
This file describes some Utility functions for interfacing with the SinQ
|
|
histogram memory server. This device is described in great detail elsewhere
|
|
(D. Maden: The SINQ Histogram Memory, Feb. 1997).
|
|
All the real time processing
|
|
for this HM is done by an on-board computer in a VME crate. This on board
|
|
computer also runs TCP/IP and a server program which allows for
|
|
configuration and communication with the HM.
|
|
For configuration an
|
|
connection to the main server is installed which handles the configuration
|
|
requests. For starting data collection and retrieval of information a second
|
|
connection is needed. This is obtained by sending a request to the main
|
|
server on the on board computer. This main server will than spawn a second
|
|
process on the on board computer which is dedicated to serving our requests.
|
|
The mainserver sends a packet containing the new port number our secondary
|
|
server is listening to. Than the driver can connect to this secondary server
|
|
in order to exchange data. According to this scheme the utility functions
|
|
divide into two groups: Master Server commands and data aquisition commands.
|
|
|
|
\section{Code organisation}
|
|
The code dealing with the SINQ histogram memory is organised in four
|
|
files: sinqhm.w, the literate programming file which creates sinqhm.i and
|
|
sinqhm.h as well as the LateX documentation for the interface, sinqhm.i is
|
|
an internal header file and contains typedefs and function definitions for
|
|
relevant for the implementation of the utility functions only. sinqhm.h
|
|
defines the public interface functions. sinqhm.c finally is the source file
|
|
which implements the utilities.
|
|
|
|
\section{The SINQHM data structure}
|
|
In order to transport the necessary status information around, each function
|
|
will take a pointer to the data structure defined below as first parameter.
|
|
For TOF mode it is necessary to store some imformation per detector bank.
|
|
This information is kept in a bank data structure:
|
|
|
|
@d SBank @{
|
|
typedef struct __SBANK {
|
|
int iStart;
|
|
int iEnd;
|
|
int iFlag;
|
|
int iEdgeLength;
|
|
int iDelay;
|
|
unsigned int *iEdges;
|
|
} SBank, *pSBank;
|
|
@}
|
|
The fields are:
|
|
\begin{description}
|
|
\item[iStart] The number of the detector with which this bank starts.
|
|
\item[iEnd] The number of the last detector for this bank.
|
|
\item[iFlag] A flag which indicates if the bank has a fixed bin widths. 0
|
|
denotes fixed bin width, 1 variable time binning.
|
|
\item[iEdgeLength] is the length of the edge array.
|
|
\item[iEdges] is an array of integer values describing the lower edges of
|
|
the bins. Its content depends on the value of iFlag. With a equally spaced
|
|
time binning (iFlag = 0) is is sufficient to give values for the first two
|
|
bins. If the time binning varies, nBins+1 values are necessary describing
|
|
the lower edges of all time bins.
|
|
\end{description}
|
|
|
|
@d SType @{
|
|
typedef struct __SINQHM {
|
|
char *pHMComputer;
|
|
int iMasterPort;
|
|
int iMasterSocket;
|
|
int iClientPort;
|
|
int iClientSocket;
|
|
int iBinWidth;
|
|
int iLength;
|
|
int iRank;
|
|
int iPacket;
|
|
int iBanks;
|
|
SBank pBank[MAXBANK];
|
|
} SINQHM;
|
|
@}
|
|
|
|
The first item in this structure is the name of the histogram memory
|
|
computer, the second the port number at which the master server is
|
|
listening. iClientPort defines a port for data communication. If no such
|
|
port is open, this value will be 0. iStatus is a status flag. iBanks is the
|
|
number of detector banks defined. pSBank is an array of bank data structures
|
|
describing the detector banks. In order to
|
|
maintain this data structure two functions are defined:
|
|
|
|
\section{Byte swapping}
|
|
These utility functions preform byte swapping as needed. In order for this
|
|
to work please make sure that the following typedefs represent the correct
|
|
types for your compiler and computer.
|
|
|
|
@d SType @{
|
|
/*---------------------------- Type definitions, machine dependent--------*/
|
|
typedef short int SQint16; /* 16 bit integer */
|
|
typedef int SQint32; /* 32 bit integer */
|
|
@}
|
|
|
|
@d Protos @{
|
|
pSINQHM CreateSINQHM(char *pHMComputer, int iMasterPort);
|
|
pSINQHM CopySINQHM(pSINQHM self);
|
|
void DeleteSINQHM(pSINQHM self);
|
|
void SINQHMSetPar(pSINQHM self, int iRank, int iLength, int iBinWidth);
|
|
@}
|
|
|
|
The first function creates a new SINQHM data structure and initialises the
|
|
fields with the parameters given. Their meanings correspond to those
|
|
mentioned above for the description of the data structure. DeleteSINQHM
|
|
frees all memory associated with a SINQHM structure given by self. The
|
|
pointer to self is invalid ever afterwards.
|
|
CopySINQHM creates a copy of the SINQHM structure passed in with self.
|
|
|
|
\section{SINQHM error handling}
|
|
If not denoted otherwise all public SINQHM functions return an integer 1 on
|
|
success. In the more common case of failure, a negative error code is
|
|
returned. This error code can be transformed into a human readable form by a
|
|
call to:
|
|
|
|
@d Protos @{
|
|
int SINQHMError2Text(int iErr, char *pBuffer, int iBufLen);
|
|
@}
|
|
|
|
This function takes as first parameter the error code, as second a pointer
|
|
to a text buffer for the error message and as third parameter the length of
|
|
the buffer. Maximum iBufLen characters will be copied to pBuffer.
|
|
|
|
\section{Master Server command functions}
|
|
These functions mainly serve to configure the histogram memory and to obtain
|
|
socket-id's for client data aquisition servers. The following functions are
|
|
needed:
|
|
|
|
@d Protos @{
|
|
int SINQHMConfigure(pSINQHM self, int iMode, int iRank, int iLength,
|
|
int iBinWidth, int iLowBin, int iCompress);
|
|
|
|
int SINQHMDeconfigure(pSINQHM self, int iHarsh);
|
|
int SINQHMGetStatus(pSINQHM self,int *iMode, int *iDaq,
|
|
int *iRank, int *iBinWidth,
|
|
int *iLength, int *iClients);
|
|
int SINQHMDebug(pSINQHM self, int iLevel);
|
|
int SINQHMKill(pSINQHM self);
|
|
|
|
@}
|
|
|
|
@d IProtos @{
|
|
@}
|
|
|
|
SINQHMConfigure configures the master server for data aquisition. Besides
|
|
the pointer to a SINQHM structure it takes the following parameters:
|
|
iMode is the combination of mode and submode bits as defined in
|
|
sinqhm_defs.h. iLength is the length of
|
|
the histograms. iBinWidth is the size of the histogram memory bins in bytes.
|
|
Currently the values 1,2 and 4 are allowed. iClients is the number of active
|
|
clients at the histogram memory computer. iRank is the number of histograms.
|
|
iLowBin is the start of the histogram memory. Usually this is 0, but someone
|
|
may choose to strat at a different memory location. iCompress is for
|
|
compression. All data will be right shifted by iCompress bits before
|
|
storage. To my knowledge this feature is currently not implemented.
|
|
|
|
|
|
SINQHMDeconfigure deconfigures the histogram memory. This is necessary prior
|
|
to reconfiguration. The only parameter iHarsh defines how brutal the master
|
|
server is with this. There may still be clients active at the histogram
|
|
memory. If iHarsh is 0, SINQHMDeconfig returns an error in this case. If
|
|
iHarsh is 1, the clients will be killed and the master server returns to a
|
|
virgin state.
|
|
|
|
SINQHMGetStatus allows to query the state of the master server. Parameters
|
|
have the same meaning as given with SINQHMConfigure. Except of course
|
|
iClients which is the number of currently active clients at the histogram
|
|
memory. iDaq show the status of data aquisition: 0 denotes stopped, 1
|
|
denotes running and 2 denotes inhibited.
|
|
|
|
SINQHMDebug sets the debug level of the histogram memory server. That server
|
|
may print messages to its Com 1 port. This command configures the amount of
|
|
information available at this channel. This function is of no use for normal
|
|
users.
|
|
|
|
SINQHMKill stops the histogram memory master server and all its children.
|
|
WARNING: After this call a manual restart of the histogram memory master
|
|
server or a reboot of the histogram memory computer has to be performed.
|
|
Do not use this function unless you are a SINQ histogram memory guru.
|
|
|
|
\section{TOF bin description functions}
|
|
Configuring the TOF binning of the histogram memory requires two steps. In
|
|
the first step you define the binning of all required banks. Then in a
|
|
second step, this data is packed up and forwarded to the histogram memory.
|
|
Thus the following functions are required:
|
|
|
|
@d TOFProto @{
|
|
int SINQHMDefineBank(pSINQHM self, int iBankNumber, int iStart, int iEnd,
|
|
float *iEdges, int iEdgeLength);
|
|
@}
|
|
@d TOFintern @{
|
|
static int SINQHMTimeBin(pSINQHM self, int iMode);
|
|
@}
|
|
SINQHDefineBank defines the time binning for a single detector bank.
|
|
iBankNumber defines the number of the detector bank to define. iStart and
|
|
iEnd select the range of detectors beloning to this detector bank. iEdges
|
|
is the array of time binnings. iEdgeLength is the length of the edges array.
|
|
|
|
SINQHMTimeBin actually sends the new time binning to the histogram memory.
|
|
SINQHMTimeBin is a static internal function.
|
|
|
|
|
|
\section{Data aquisition functions}
|
|
These functions allow to do data aquisition and retrieve or set histograms.
|
|
Data aquisition is fairly involved. In order for data aquisition to happen
|
|
the histogram memory internal filler process must be running. This is
|
|
controlled by the StartDAQ/StopDAQ pair. However, any client can inhibit
|
|
data processing. This feature is targeted towards clients monitoring
|
|
environment devices. Such clients thus can pause data aquisition in order to
|
|
allow environment variables to get in the defined range again. This is
|
|
controlled by the InhibitDAQ/ContinueDAQ pair of functions. Please note,
|
|
that after starting a new data aquisition session the inhibit flag is
|
|
cleared by default.
|
|
|
|
@d Protos @{
|
|
int SINQHMOpenDAQ(pSINQHM self);
|
|
int SINQHMCloseDAQ(pSINQHM self);
|
|
|
|
int SINQHMStartDAQ(pSINQHM self);
|
|
int SINQHMStopDAQ(pSINQHM self);
|
|
int SINQHMInhibitDAQ(pSINQHM self);
|
|
int SINQHMContinueDAQ(pSINQHM self);
|
|
|
|
int SINQHMWrite(pSINQHM self, int iNum, int iStart, int iEnd,
|
|
void *pData);
|
|
long SINQHMSize(pSINQHM self, int iNum, int iStart, int iEnd);
|
|
int SINQHMRead(pSINQHM self, int iNum, int iStart, int iEnd,
|
|
void *pData, int iDataLen);
|
|
int SINQHMZero(pSINQHM self, int iNum, int iStart, int iEnd);
|
|
@}
|
|
|
|
SINQHMOpenDAQ must be the first call and will create the slave server in the
|
|
histogram memory server which is than responsible for answereing our further
|
|
requests. Without this call any other call will return an error!
|
|
|
|
SINQHMCloseDAQ closes a data aquisition session.
|
|
|
|
SINQHMStartDAQ starts data aquisition.
|
|
|
|
SINQHMInhibitDAQ causes data aquisition to pause.
|
|
|
|
SINQHMContinueDAQ causes a paused data aquisition to continue.
|
|
|
|
SINQHMStopDAQ stops data aquisition.
|
|
|
|
SINQHMWrite is used to initialise the histograms in the histogram memory to
|
|
a specific value. The histogram to write is selected by iNum. If iNum is -1
|
|
the whole histogram memory area is written. iStart and iEnd define a subset
|
|
of the histogram to write. pData is a pointer to a data area which is going
|
|
to be copied to the histogram memory.
|
|
|
|
SINQHMSize returns the necessary size in bytes for a buffer large enough to
|
|
hold all the data requested with the following read parameters.
|
|
|
|
SINQHMRead reads histograms. The parameters iNum, iStart and iEnd have the
|
|
same meaning as with SINQHMWrite. Maximum iDataLen bytes of data are copied
|
|
to the memory area pointed to by pData.
|
|
|
|
SINQHMZero clears the histogram iNum from iStart to iEnd to 0.
|
|
A recommended call prior
|
|
to any serious data aquisition.
|
|
|
|
\section{Further internal routines}
|
|
@d IProtos @{
|
|
static int OpenMasterConnection(pSINQHM self);
|
|
static int GetMasterReply(pSINQHM self, struct rply_buff_struct *reply,
|
|
int iBufLen);
|
|
static int SendDAQCommand(pSINQHM self, int iCommand, int *iDaq);
|
|
@}
|
|
OpenMasterCoonection tries to open a connection to the SINQ histogram memory
|
|
master server ready to send data.
|
|
|
|
GetMasterReply collects the reply from the master server.
|
|
|
|
SendDAQCommand sends iCommand to the client server. Returns the current
|
|
status of the data aquisition flag in iDaq for further analysis.
|
|
|
|
@d ErrCode @{
|
|
#define HMCOMPUTER_NOT_FOUND -2
|
|
#define SOCKET_ERROR -3
|
|
#define BIND_ERROR -4
|
|
#define CONNECT_ERROR -5
|
|
#define RECEIVE_ERROR -6
|
|
#define INSUFFICIENT_DATA -7
|
|
#define BYTE_ORDER_CHAOS -8
|
|
#define HIST_BAD_CREATE -9
|
|
#define HIST_BAD_STATE -10
|
|
#define HIST_BAD_VALUE -11
|
|
#define HIST_BAD_RECV -12
|
|
#define HIST_BAD_ALLOC -13
|
|
#define HIST_BAD_CODE -14
|
|
#define SEND_ERROR -15
|
|
#define CLOSE_ERROR -16
|
|
#define INVALID_HARSH -17
|
|
#define SOFTWARE_ERROR -18
|
|
#define DAQ_INHIBIT -19
|
|
#define DAQ_NOTSTOPPED -20
|
|
@}
|
|
|
|
@o sinqhm.h -d @{
|
|
/*---------------------------------------------------------------------------
|
|
S I N Q H M
|
|
Some utility functions for interfacing to the SINQ histogram memory
|
|
server.
|
|
|
|
David Maden, Mark Koennecke, April 1997
|
|
|
|
copyright: see implementation file.
|
|
-----------------------------------------------------------------------------*/
|
|
#ifndef SINQHMUTILITY
|
|
#define SINQHMUTILITY
|
|
#include "sinqhm_def.h"
|
|
|
|
typedef struct __SINQHM *pSINQHM;
|
|
/*------------------------------ Error codes -----------------------------*/
|
|
@< ErrCode @>
|
|
|
|
/*------------------------------ Prototypes ------------------------------*/
|
|
@< Protos @>
|
|
@< TOFProto @>
|
|
#endif
|
|
@}
|
|
|
|
@o sinqhm.i @{
|
|
/*---------------------------------------------------------------------------
|
|
|
|
Internal header file for the SINQ histogram memory utility functions.
|
|
|
|
David Maden, Mark Koennecke April 1997
|
|
----------------------------------------------------------------------------*/
|
|
#ifndef SINQHMINTERNAL
|
|
#define SINQHMINTERNAL
|
|
#define MAXBANK 1
|
|
@< SBank @>
|
|
@< SType @>
|
|
@< IProtos @>
|
|
@< TOFintern @>
|
|
#endif
|
|
|
|
@}
|
|
|
|
\chapter{The SINQ histogram memory Tcl wrapper}
|
|
In order to allow for status displays via Tcl/TK, for debugging and general
|
|
availability a Tcl wrapper for the SINQ histogram memory functions has been
|
|
devised. It works similar to the widget commands as used for TK. On startup
|
|
the extra command SINQHM is available. The syntax is: \\
|
|
\leftline{SINQHM name computer port }\\
|
|
This command will create another command called name which symbolises a
|
|
connection to the histogram memory at computer listening to port. The new
|
|
object created is a control object. This control object understands the
|
|
commands listed below. Each command has to be prepended with the name you
|
|
specified in the call to SINQHM.
|
|
\begin{itemize}
|
|
\item {\bf config iMode iOver iRank iLength iBinWidth} configures a histogram
|
|
memory.
|
|
\item {\bf status} return a status message of the HM.
|
|
\item {\bf deconfig iHarsh} deconfigures the HM.
|
|
\item {\bf debug iLevel} sets internal debug level.
|
|
\item {\bf exit} do not use this! Kills the HM.
|
|
\item {\bf DAQ name } creates a data aquisition client named name.
|
|
\item {\bf delDAQ name} kills the data aquisition client named name.
|
|
\end{itemize}
|
|
|
|
After the last call there exists a new command name which represents a data
|
|
aquisition client, capabale of reading and writing data. This DAQ client
|
|
understands the commands listed below. Again, each command has to prepended
|
|
with the name given in the DAQ command above.
|
|
\begin{itemize}
|
|
\item {\bf read iNum iStart iEnd arname} reads histogram iNum from
|
|
iStart to iEnd. The data will be stored in the array arname.
|
|
\item {\bf write iNum iStart iEnd data} writes data to the histogram iNum
|
|
from iStart iEnd bins. data must be an Tcl-array with indexes from 0 to
|
|
iEnd which contains the values to write.
|
|
\item {\bf zero} zeroes the histogram memory.
|
|
\item {\bf start} starts data aquisition.
|
|
\item {\bf stop} stops data aquisition.
|
|
\item {\bf inhibit} inhibits data aquisition.
|
|
\item {\bf continue} continues an inhibited data aquisition session.
|
|
\end{itemize}
|
|
|
|
|
|
|
|
\end{document} |