170 lines
8.0 KiB
TeX
170 lines
8.0 KiB
TeX
\subsubsection{The Tcl Environment Driver}
|
|
Sometimes a quick way for defining an environment
|
|
device driver is needed. A suitable way for doing this
|
|
is to define the device driver in the SICS servers Tcl macro language. Then
|
|
a device driver can even be developed and tested offline from a psish before
|
|
inclusion in the server. Clearly a means of communication between SICs and
|
|
the actual device is needed. Usually this communication happens via
|
|
a RS--232 serial port. Such a communication is catered for by the SICS
|
|
serialport command. This section describes the environment device driver
|
|
which links the SICS C code with Tcl. For each of the device drivers
|
|
functions a C language wrapper function is provided, which in turn calls
|
|
the Tcl interpreter with some parameters. This scheme is initialised by
|
|
providing the Tcl environment device driver with the name of a Tcl array
|
|
which has to hold Tcl implementations for all the necessary driver functions.
|
|
The name of this array will also be passed to each of the Tcl procedures as
|
|
first parameter. The Tcl procedures to define for a Tcl driver are:
|
|
\begin{description}
|
|
\item[Init] to be called at initialisation of the driver. This Tcl procedure must connect
|
|
to the device and prepare it for accepting further commands. The parameters to
|
|
init are all the parameters still left in the command line after the name
|
|
of the Tcl array in the EVFactory command line.
|
|
\item[Close] should close down the connection to the device after bringing the
|
|
device into a clean state.
|
|
\item[SetValue] will be called with a float value as second parameter. It
|
|
should issue a command to set the device to a new value. The return value is an
|
|
integer error code, defined by the driver. Error returns use the normal Tcl mechanism
|
|
with the Tcl error command. On errors a negative error code defined by the driver
|
|
must be returned.
|
|
\item[GetValue] reads the current value from the device. The return value is
|
|
either the floating point value of the current control variable or the
|
|
string pending if the request is still pending. In case of failure an error
|
|
is returned with a negative integer error code.
|
|
\item[Send] should concatenate all parameters and send them down to the
|
|
device. Returns error codes as described above.
|
|
\item[GetError] gets as a parameter the negative error code possibly returned
|
|
from one of the calls above. GetError should return a textual description
|
|
of the error.
|
|
\item[TryFixIt] gets as a parameter a negative error code as returned from one
|
|
of the calls described above. TryFixIt should do everything possible in
|
|
software to get the device working again: perhaps send some commands,
|
|
reopen the connection or whatever apropriate. Depending on the success
|
|
of this TryFixIt returns either DEVREDO if the command shall be resend or
|
|
DEVFAIL if the problem cannot be fixed without human intervention.
|
|
\item[Wrapper] This function will will be called by the environment variable
|
|
interpreter wrapper function before the general part of the wrapper
|
|
function gets executed. Its purpose is the handling of subcommands special
|
|
to the specific environment device. For instance modifying its mode of
|
|
operation or setting special variables not covered in the general
|
|
environment device setup. It has to return 1 on success, 0 on failure. On
|
|
failure it has to print error messages as well.
|
|
\end{description}
|
|
|
|
In order to do all this a new driver must be defined. This driver needs the
|
|
following data structure:
|
|
|
|
\begin{flushleft} \small
|
|
\begin{minipage}{\linewidth} \label{scrap1}
|
|
$\langle$tclevdat {\footnotesize ?}$\rangle\equiv$
|
|
\vspace{-1ex}
|
|
\begin{list}{}{} \item
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ typedef struct __TclEv {@\\
|
|
\mbox{}\verb@ char *pArray;@\\
|
|
\mbox{}\verb@ char *pInit;@\\
|
|
\mbox{}\verb@ char *pClose;@\\
|
|
\mbox{}\verb@ char *pSetValue;@\\
|
|
\mbox{}\verb@ char *pGetValue;@\\
|
|
\mbox{}\verb@ char *pSend;@\\
|
|
\mbox{}\verb@ char *pGetError;@\\
|
|
\mbox{}\verb@ char *pTryFixIt;@\\
|
|
\mbox{}\verb@ char *pWrapper;@\\
|
|
\mbox{}\verb@ char *pName;@\\
|
|
\mbox{}\verb@ Tcl_Interp *pTcl;@\\
|
|
\mbox{}\verb@ int iLastError;@\\
|
|
\mbox{}\verb@ } TclEv, *pTclEv;@\\
|
|
\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 fields correspond to the names of the Tcl functions to call for each of the
|
|
functions specified above. Plus the name of a Tcl array used for storing
|
|
driver special data in Tcl. iLastError will be used to keep the last error code.
|
|
pName is the name of the device in SICS. This will be copied into the
|
|
Tcl-array describing the device as MyName. May be used to set general
|
|
evcontroller parameters from within driver code and for error messages.
|
|
|
|
SICS sees this driver through the following interface:
|
|
\begin{flushleft} \small
|
|
\begin{minipage}{\linewidth} \label{scrap2}
|
|
$\langle$tclevint {\footnotesize ?}$\rangle\equiv$
|
|
\vspace{-1ex}
|
|
\begin{list}{}{} \item
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ pEVDriver CreateTclDriver(int argc, char *argv[],char *pName, SConnection *pCon);@\\
|
|
\mbox{}\verb@ int UpdateTclVariable(pEVDriver self, char *name, float fVal);@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ int TclEnvironmentWrapper(SConnection *pCon, SicsInterp *pSics, @\\
|
|
\mbox{}\verb@ void *pData, int argc, char *argv[]);@\\
|
|
\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}
|
|
\begin{description}
|
|
\item[CreateTclDriver] creates the Tcl driver and initialises it.
|
|
\item[UpdateTclVariable] will be called from the general environment
|
|
variable parameter update code in order to allow updating of Tcl variables
|
|
as well.
|
|
\item[TclEnvironmentWrapper] is the interpreter wrapper function for a Tcl
|
|
driver.
|
|
\end{description}
|
|
|
|
\begin{flushleft} \small
|
|
\begin{minipage}{\linewidth} \label{scrap3}
|
|
\verb@"tclev.h"@ {\footnotesize ? }$\equiv$
|
|
\vspace{-1ex}
|
|
\begin{list}{}{} \item
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
|
\mbox{}\verb@ T C L E N V I R O N M E N T@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ This is the header file for an environment device driver defined in @\\
|
|
\mbox{}\verb@ the Tcl macro language. Dor more details see tclev.tex@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ copyright: see copyright.h@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ Mark Koennecke, February 1998@\\
|
|
\mbox{}\verb@------------------------------------------------------------------------------*/@\\
|
|
\mbox{}\verb@#ifndef SICSTCLEV@\\
|
|
\mbox{}\verb@#define SICSTCLEV@\\
|
|
\mbox{}\verb@ @\\
|
|
\mbox{}\verb@@$\langle$tclevint {\footnotesize ?}$\rangle$\verb@ @\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@#endif@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@@$\diamond$
|
|
\end{list}
|
|
\vspace{-2ex}
|
|
\end{minipage}\\[4ex]
|
|
\end{flushleft}
|
|
\begin{flushleft} \small
|
|
\begin{minipage}{\linewidth} \label{scrap4}
|
|
\verb@"tclev.i"@ {\footnotesize ? }$\equiv$
|
|
\vspace{-1ex}
|
|
\begin{list}{}{} \item
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
|
\mbox{}\verb@ Tcl environment device driver data structure definition file. @\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ No general usable header file.@\\
|
|
\mbox{}\verb@@\\
|
|
\mbox{}\verb@ Mark Koenencke, February 1998@\\
|
|
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
|
\mbox{}\verb@@$\langle$tclevdat {\footnotesize ?}$\rangle$\verb@@\\
|
|
\mbox{}\verb@@$\diamond$
|
|
\end{list}
|
|
\vspace{-2ex}
|
|
\end{minipage}\\[4ex]
|
|
\end{flushleft}
|