Initial revision
This commit is contained in:
321
evcontroller.tex
Normal file
321
evcontroller.tex
Normal file
@ -0,0 +1,321 @@
|
||||
\subsection{Environment Controller}
|
||||
An environemnet controller controls a piece of sample environemnet
|
||||
equipment. Thereby it does not really matter if the device in question
|
||||
is a temperature controller or a magnet or whatever. All devices need
|
||||
to be driven to a new value and there must be some scheme for
|
||||
monitoring the device during a measurement. This monitoring is done by the
|
||||
environment monitor described in the kernel section of this book.
|
||||
|
||||
Then there must be some type of logging facility. SICS defers logging to
|
||||
a separate module, the varlogger.
|
||||
|
||||
The Environment Controller (EVControl) is a kind of base class for all
|
||||
environment devices. This poses the question how SICS implements
|
||||
inheritance. The scheme is simple:
|
||||
\begin{itemize}
|
||||
\item The base class (in this case EVControl) will hold a void pointer.
|
||||
Derived classes are meant to add their datastructures at that level.
|
||||
Furthermore derived classes are required to provide a function, which
|
||||
deletes its private data.
|
||||
\item When overloading functions of the base class, the derived class
|
||||
should call the overloaded function of the base class whenever apropriate.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\subsubsection{Environment Controller Datastructures}
|
||||
To enhance understanding of this, see the definition of the datastructure
|
||||
used by EVControl:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$evdata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __EVControl {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pIDrivable pDrivInt;@\\
|
||||
\mbox{}\verb@ pEVInterface pEnvir;@\\
|
||||
\mbox{}\verb@ pEVDriver pDriv;@\\
|
||||
\mbox{}\verb@ EVMode eMode;@\\
|
||||
\mbox{}\verb@ float fTarget;@\\
|
||||
\mbox{}\verb@ char *pName;@\\
|
||||
\mbox{}\verb@ ObPar *pParam;@\\
|
||||
\mbox{}\verb@ int iLog;@\\
|
||||
\mbox{}\verb@ pVarLog pLog;@\\
|
||||
\mbox{}\verb@ int iWarned;@\\
|
||||
\mbox{}\verb@ int iTcl;@\\
|
||||
\mbox{}\verb@ int iStop;@\\
|
||||
\mbox{}\verb@ void *pPrivate;@\\
|
||||
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
|
||||
\mbox{}\verb@ } EVControl;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
The first field is a pointer to the usual object descriptor,
|
||||
the second field a pointer to an Drivable interface. Each environment
|
||||
controller needs to implement that in order to allow SICS drive the device
|
||||
to a new value. The third field is a pointer to an environment interface.
|
||||
This is needed in order to enable monitoring of the device when it has
|
||||
reached its target value. The fourth field is a pointer to the driver for
|
||||
the actual hardware. Next is the mode the device is in. Of course there
|
||||
must be floating point value which defines the current target value for the
|
||||
device. pName is a pointer to a string representing the name of the
|
||||
controller. Then there is a
|
||||
parameter array. iLog is a boolean which says if data should be logged
|
||||
for this controller or not. pLog is the a pointer to a Varlog structure
|
||||
holding the logging information. Then there is a switch, iWarned, which is
|
||||
used to prevent execessive output on environment controller error handling.
|
||||
iTcl is a boolean stating if the driver used is a proper C language driver
|
||||
or a Tcl driver.
|
||||
This is followed by the void pointer for use by a derived
|
||||
class. KillPrivate is a pointer to a function capable of deleting pPrivate
|
||||
properly.
|
||||
|
||||
|
||||
For the hardware drivers for environment controllers a similar scheme is
|
||||
used:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$evdriv {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __EVDriver {@\\
|
||||
\mbox{}\verb@ int (*SetValue)(pEVDriver self, float fNew);@\\
|
||||
\mbox{}\verb@ int (*GetValue)(pEVDriver self, float *fPos);@\\
|
||||
\mbox{}\verb@ int (*Send)(pEVDriver self, char *pCommand,@\\
|
||||
\mbox{}\verb@ char *pReplyBuffer, int iReplBufLen); @\\
|
||||
\mbox{}\verb@ int (*GetError)(pEVDriver self, int *iCode,@\\
|
||||
\mbox{}\verb@ char *pError, int iErrLen);@\\
|
||||
\mbox{}\verb@ int (*TryFixIt)(pEVDriver self, int iCode);@\\
|
||||
\mbox{}\verb@ int (*Init)(pEVDriver self);@\\
|
||||
\mbox{}\verb@ int (*Close)(pEVDriver self);@\\
|
||||
\mbox{}\verb@ void *pPrivate;@\\
|
||||
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
|
||||
\mbox{}\verb@ } EVDriver;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
If not stated otherwise, member functions return 0 on failure and 1 on
|
||||
success.
|
||||
This datastructure in detail: \begin{description}
|
||||
\item [SetValue] Sends a command to the environment device which drives it
|
||||
to a new value specified as second parameter. Translation to device specific
|
||||
values is done here. If an error occurs, SetValue returns 0, else 1.
|
||||
\item [GetValue] Asks the device its current measured value.
|
||||
If an error occurs, GetValue returns 0, 1 on success and -1 when there is
|
||||
data pending. GetValue will be used for enquiring status. Some devices have
|
||||
such a slow response that the first call will issue the command and the next
|
||||
ones will check for data availability and read eventually.
|
||||
\item [Send] Sends the command in pCommand to the environment device. For
|
||||
replies, a pointer to a ReplyBuffer is provided. iReplBufLen is the maximum
|
||||
length permissable for the ReplyBuffer. Send copies maximum iReplBufLen
|
||||
bytes into pReplyBuffer in order to prevent memory overwrite. The idea of
|
||||
send is to provide a means to load calibration data and parameters to the
|
||||
environment device.
|
||||
\item [GetError] GetError will be called when an error occurs. It is meant
|
||||
to set iCode to an internal error code and fill pError with an textual
|
||||
description of the error observed. Maximum iErrLen bytes of information
|
||||
will be copied to pError.
|
||||
\item [TryFixIt] TryFixIt will be called with the internal error code
|
||||
retuned by GetError in iCode as second parameter. TryAndFixIt then analyses
|
||||
the error code and figures out if something can be done in software to fix
|
||||
the problem. If so, the apropriate actions are performed. TryFixIt returns
|
||||
either DEVOK, if the device is OK, DEVFAULT, if TryFixIt cannot fix the
|
||||
problem and DEVREDO if TryFixIt manged to fix the problem but requires the
|
||||
last command to be resent.
|
||||
\item [Init] Init is meant to initialise or reinitialise the driver.
|
||||
\item [Close] Close is meant to close the driver and bring the device into a
|
||||
safe state.
|
||||
\item [pPrivate] is a pointer to a driver specific datastructure.
|
||||
\item [KillPrivate] is a pointer to a function which is capable of removing
|
||||
a drivers specific datastructure properly.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{Environment Controller Funtions}
|
||||
All of the functions below return 1 on success, 0 on failure if not sated
|
||||
otherwise. Most functions take a pointer to an environment controller
|
||||
data structure as first parameter.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$dvfunc {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------- live & death --------------------------------*/ @\\
|
||||
\mbox{}\verb@ typedef struct __EVControl *pEVControl;@\\
|
||||
\mbox{}\verb@ typedef struct __EVDriver *pEVDriver;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pEVControl CreateEVController(pEVDriver pDriv, char *pName, int *iErr);@\\
|
||||
\mbox{}\verb@ void DeleteEVController(void *pData);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------- driving ---------------------------------*/@\\
|
||||
\mbox{}\verb@ int EVCDrive(pEVControl self,SConnection *pCon, float fNew);@\\
|
||||
\mbox{}\verb@ int EVCGetPos(pEVControl self, SConnection *pCon,float *fVal);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------ parameters ----------------------------------*/@\\
|
||||
\mbox{}\verb@ EVMode EVCGetMode(pEVControl self);@\\
|
||||
\mbox{}\verb@ int EVCSetMode(pEVControl self, EVMode eNew);@\\
|
||||
\mbox{}\verb@ int EVCSetPar(pEVControl self, char *name, float fNew, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int EVCGetPar(pEVControl self, char *name, float *fVal);@\\
|
||||
\mbox{}\verb@ int EVCList(pEVControl self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@/*------------------------- logging -----------------------------------*/@\\
|
||||
\mbox{}\verb@ pVarLog EVCGetVarLog(pEVControl self);@\\
|
||||
\mbox{}\verb@/*----------------- Interface to SICS interpreter -----------------------*/@\\
|
||||
\mbox{}\verb@ int EVControlWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int EVControlFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
The functions in more detail:
|
||||
\begin{description}
|
||||
\item [CreateEVController] CreateEVController creates and initialises a
|
||||
EVController. All interface functions are initialised with default
|
||||
functions. The first parameter is a pointer to the driver to use, the second
|
||||
the name of the thing.
|
||||
\item [DeleteEVController] cleans a EVController from memory. A
|
||||
KillFunction type for the SICS interpreter.
|
||||
\item [EVCDrive] drives an EVcontroller to the new value fNew.
|
||||
\item [EVCGetPos] retrieves the actual value of the environment value from
|
||||
the device. It is put into fVal.
|
||||
\item [EVCSetPar] sets a parameter in the EVControllers internal database.
|
||||
name is the name of the parameter, fNew the value it should get. A
|
||||
connection object is passed in this call, which will be used for error
|
||||
reporting and in order to check if the client is permitted to change the
|
||||
parameter.Parameters recognized are:
|
||||
\begin{description}
|
||||
\item [Tolerance] The permissable deviation from the target value before an
|
||||
error is raised.
|
||||
\item [Access] which user id has permission to access this controller.
|
||||
Permited values are: 0 == internal, 1 == Manager, 2 == User, 3 == Spy.
|
||||
\item [ErrorHandler] determines which error handling strategy will be used
|
||||
if the EVcontroller gets out of range. Recognized values are:
|
||||
0 == do nothing, 1 == pause measurement till back in tolerance, 2 ==
|
||||
interrupt, 3 == drive controller to a value considered safe.
|
||||
\item [SaveValue] Value to be used as safe value if ErrorHandler 3 is
|
||||
requested.
|
||||
\item [Interrupt] The interrupt to issue, when interrupt error handling had
|
||||
been requested. Will also be used as interrupt if a hardware failure is
|
||||
detected while driving. Valid values are: 0 == Continue, 1 == Abort
|
||||
Operation (Count), 2 == Abort Scan, 3 == Abort Batch processing, 4 == Halt
|
||||
system, 6 == end SICS server.
|
||||
\item [UpperLimit] The upper limit of values possible for the environment
|
||||
device.
|
||||
\item [LowerLimit] The lower limit of values possible for the environment
|
||||
device.
|
||||
\end{description}
|
||||
\item [EVCGetPar] retrieves the value of a parameter. Name must be one of
|
||||
the recognized names.
|
||||
\item [EVCGetMode] retrieves the mode the EVController is in.
|
||||
\item [EVCList] lists all the parameters to pCon.
|
||||
\item[EVCGetVarLog] returns a pointer to the variable logger for this
|
||||
controller.
|
||||
\item [EVControlWrapper] is the interpreter interface to the EVController.
|
||||
See the documentation for commands understood.
|
||||
\item [EVControlFactory] is the SICS function needed for creation and
|
||||
deletion of environment controllers.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"evcontroller.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ E N V I R O N M E N T C O N T R O L L E R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This is the base class for all environment controllers. @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSEVCONTROL@\\
|
||||
\mbox{}\verb@#define SICSEVCONTROL@\\
|
||||
\mbox{}\verb@#include "varlog.h"@\\
|
||||
\mbox{}\verb@@$\langle$dvfunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
\verb@"evcontroller.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ Environment controller datastructure@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@/*-------- Parameter defines */@\\
|
||||
\mbox{}\verb@#define TOLERANCE 0@\\
|
||||
\mbox{}\verb@#define ACCESS 1@\\
|
||||
\mbox{}\verb@#define ERRORHANDLER 2@\\
|
||||
\mbox{}\verb@#define INTERRUPT 3@\\
|
||||
\mbox{}\verb@#define UPLIMIT 4@\\
|
||||
\mbox{}\verb@#define LOWLIMIT 5@\\
|
||||
\mbox{}\verb@#define SAFEVALUE 6@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$evdata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
\verb@"evdriver.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ Environment device driver datastructure@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#define DEVOK 1@\\
|
||||
\mbox{}\verb@#define DEVFAULT 0@\\
|
||||
\mbox{}\verb@#define DEVREDO 2@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$evdriv {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*-------------------- life & death of a driver --------------------------*/@\\
|
||||
\mbox{}\verb@ pEVDriver CreateEVDriver(int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ void DeleteEVDriver(pEVDriver pDriv);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
Reference in New Issue
Block a user