Initial revision
This commit is contained in:
497
interface.tex
Normal file
497
interface.tex
Normal file
@ -0,0 +1,497 @@
|
||||
\subsection{Object interfaces}\label{inter}
|
||||
In order to present themselves to the system SICS objects need to adhere to
|
||||
certyain interfaces. These interfaces are described in this
|
||||
section. Thus this section is one of the most important sections of
|
||||
theis document, read carefully!
|
||||
|
||||
A first
|
||||
requirement was that it must be possible to inquire the capabilities of an
|
||||
object at run time. A second one was that the system should be extendable.
|
||||
This means it should be possible to add new interfaces or modify them as the
|
||||
need arises. In order to achieve this the idea of the interface
|
||||
datastructure (INDS) was conceived. An INDS contains all the variables and
|
||||
functions which make up an interface. Then it is possible to create such a
|
||||
datastructure and pass it around. Each object can now be requested to pass
|
||||
an INDS of a certain type on demand. What is still needed is a standard way
|
||||
of asking a SICS object for such a datastructure. This is achieved by the
|
||||
means of the object descriptor. This is a datastructure which contains
|
||||
everything necessary to identify an object to SICS. This requires a
|
||||
convention which is that {\em each SICS objects has to have a pointer to an
|
||||
object descriptor as first element of its own datastructure.} All this
|
||||
probably gets clearer once the actual datastructures have been discussed.
|
||||
|
||||
|
||||
As usual, functions return 1 on success and 0 on failure.
|
||||
|
||||
\subsubsection{The object descriptor}
|
||||
Let's start with the objectdescriptor:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$obdes {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ In SICS there is the to find out what an@\\
|
||||
\mbox{}\verb@ object is capable of at runtime. If this has been done a general@\\
|
||||
\mbox{}\verb@ way to access those capabilities is needed. In order to do all@\\
|
||||
\mbox{}\verb@ this each SICS-object is required to carry an object descriptor@\\
|
||||
\mbox{}\verb@ struct as first parameter in its class/object struct. Additionslly@\\
|
||||
\mbox{}\verb@ it is required to initialize this struct to something sensible.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ This file defines this struct. Additionally a few functions of@\\
|
||||
\mbox{}\verb@ general use are prototyped.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, June, 1997@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyrigth: see implementation file @\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSDESCRIPTOR@\\
|
||||
\mbox{}\verb@#define SICSDESCRIPTOR@\\
|
||||
\mbox{}\verb@#include <stdio.h>@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ char *name;@\\
|
||||
\mbox{}\verb@ int (*SaveStatus)(void *self, char *name,FILE *fd);@\\
|
||||
\mbox{}\verb@ void *(*GetInterface)(void *self, int iInterfaceID);@\\
|
||||
\mbox{}\verb@ } ObjectDescriptor, *pObjectDescriptor;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /*---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ pObjectDescriptor CreateDescriptor(char *name);@\\
|
||||
\mbox{}\verb@ void DeleteDescriptor(pObjectDescriptor self);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*============================================================================@\\
|
||||
\mbox{}\verb@ Objects which do not carry data need a dummy descriptor. Otherwise@\\
|
||||
\mbox{}\verb@ drive or scan will protection fault when trying to drive something@\\
|
||||
\mbox{}\verb@ which should not be driven. This is defined below.@\\
|
||||
\mbox{}\verb@*/@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@typedef struct {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDescriptor;@\\
|
||||
\mbox{}\verb@ }Dummy, *pDummy;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pDummy CreateDummy(char *name);@\\
|
||||
\mbox{}\verb@ void KillDummy(void *pData); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int iHasType(void *pData, char *Type);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\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 element of the object descriptor is a {\bf name} which is better
|
||||
described as a type identifier. This specifies the type of the object.
|
||||
|
||||
|
||||
The function {\bf SaveStatus} will be called automatically by SICS when the
|
||||
server is closing down or a status backup is requested. Each object is meant
|
||||
to print the commands necessary to configure it back into its current state
|
||||
into the file passed as a parameter. The idea is that by executing the file
|
||||
thus created the system gets back into the state before closedown.
|
||||
|
||||
The heart of the interface system is the {\bf GetInterface}
|
||||
function. It takes as arguments a pointer to the datastructure on which it
|
||||
is called and an integer ID
|
||||
for the interface. These ID's are defined in the file interface.h. This
|
||||
function is meant to return a pointer to the apropriate interface
|
||||
datastructure after this call. If the object does not implement the interface
|
||||
requested, this function should return NULL. New interfaces can be added
|
||||
into the scheme by defining new ID's, interfaces and objects which implement
|
||||
them.
|
||||
|
||||
It is {\bf important} to note, that the objects themselves are responsible
|
||||
for allocating and freeing memory for the interface structures. Client never
|
||||
should need to worry how to dispose of these structures. Moreover this
|
||||
scheme ensures that changes to the interface due to some command given to
|
||||
the object are immediatetly visible through the whole system.
|
||||
|
||||
Additionally this header file defines a few relatively uninteresting
|
||||
functions for object descriptor maintainance. Slightly more interesting is
|
||||
the Dummy structure, which will be used to find the object descriptor in a
|
||||
given objects data structure.
|
||||
|
||||
|
||||
\subsubsection{The drivable interface}
|
||||
As first example of an interface the drivable interface will be given. This
|
||||
interface is implemented by all devices or varaibles which can be driven to
|
||||
a value. Most notable example are motors, but composite variables and
|
||||
environment controllers fit this bill as well.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$driv {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ int ID;@\\
|
||||
\mbox{}\verb@ int (*Halt)(void *self);@\\
|
||||
\mbox{}\verb@ int (*CheckLimits)(void *self, float fVal, @\\
|
||||
\mbox{}\verb@ char *error, int iErrLen);@\\
|
||||
\mbox{}\verb@ long (*SetValue)(void *self, SConnection *pCon,@\\
|
||||
\mbox{}\verb@ float fVal);@\\
|
||||
\mbox{}\verb@ int (*CheckStatus)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ float (*GetValue)(void *self, SConnection *pCon); @\\
|
||||
\mbox{}\verb@ int iErrorCount;@\\
|
||||
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
|
||||
\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 first member of this structure is an ID which can be used in order to
|
||||
check if the right datastructure has been obtained.
|
||||
|
||||
The second field is a pointer to a {\bf Halt} function. This function will be
|
||||
called in an emergency and is meant to send a stop command to the device.
|
||||
|
||||
The third field is a pointer to the {\bf CheckLimits} function. This function is
|
||||
given a float value as second parameter. This is the new value the device
|
||||
should go to. CheckLimits checks if this position is permitted. If so it
|
||||
returns 1 else 0.
|
||||
|
||||
The {\bf SetValue} member is a pointer to a function which actually makes the
|
||||
object start to move to its new position.
|
||||
|
||||
The {\bf CheckStatus} function will be called in order to check for the current
|
||||
status of the device during operation. Possible return values are:
|
||||
\begin{itemize}
|
||||
\item OKOK if everything is OK.
|
||||
\item HWIdle if the device is idle i. e. doing nothing.
|
||||
\item HWFault if the device is in trouble.
|
||||
\item HWBusy if the device is still running.
|
||||
\item HWPosFault when the device is principally OK but has not reached the
|
||||
position specified, for instance because somebody has put a slab of concrete
|
||||
into the instruments way.
|
||||
\end{itemize}
|
||||
|
||||
The last function which makes up this interface is {\bf GetValue} which is meant
|
||||
to return the current position of the device.
|
||||
|
||||
{\bf iErrorCount} is the number of number of failed driving commands on this drivable
|
||||
item. This can be used by motors to check and abort the experiment if there
|
||||
are to many errors. This is to stop a scan command hammer at a blocked motor
|
||||
a hundred times.
|
||||
|
||||
{\bf GetDrivableInterface} is a convenience function which checks object pData for
|
||||
the existence of a drivable interface. If it exists a pointer to it will be
|
||||
returned. NEVER free this pointer. If no drivable interface exists, NULL
|
||||
will be returned.
|
||||
|
||||
\subsubsection{The Countable Interface}
|
||||
This is an interface for interacting with anything which counts.
|
||||
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$count {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ int ID;@\\
|
||||
\mbox{}\verb@ int (*Halt)(void *self);@\\
|
||||
\mbox{}\verb@ int (*StartCount)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*CheckCountStatus)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*Pause)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*Continue)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*TransferData)(void *self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ } ICountable, *pICountable;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pICountable GetCountableInterface(void *pObject); @\\
|
||||
\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}
|
||||
{\bf Halt and StartCount} are self explaining, they just do what they say. Please
|
||||
note, that counting configuration must have happened before usage of this
|
||||
interface.
|
||||
|
||||
{\bf Pause} pauses a data aquisition. It does NOT abort it. {\bf Continue}
|
||||
continues a paused data aquisition.
|
||||
|
||||
{\bf CheckCountStatus} works much like CheckStatus in the IDrivable interface
|
||||
described above. However, there is an additional return code: HWNoBeam. This
|
||||
is retuned if a monitor is below a certain threshold, i. e. the beam is off.
|
||||
|
||||
{\bf TransferData} will be called at the end of each counting operation and is
|
||||
meant to update the internal datastructures of the counter. Some counters
|
||||
choose to keep the last count in their own datastructure, some such as
|
||||
histogram memories might choose to leave them in the hardware. This function
|
||||
has been conceived in order to ensure that the first type of counters is
|
||||
supported.
|
||||
|
||||
{\bf GetCountableInterface} is a convenience function which checks object pData for
|
||||
the existence of a countable interface. If it exists a pointer to it will be
|
||||
returned. NEVER free this pointer. If no countable interface exists, NULL
|
||||
will be returned.
|
||||
|
||||
\subsubsection{The Callback Interface}
|
||||
The Callback Interface is SICS suport for component behaviour for objects.
|
||||
Consider objects A and B. A now is able to generate certain events when it's
|
||||
state changes. For instance if A is a variable that its value is changed.
|
||||
B may then choose to register a function with A which gets automatically
|
||||
called whenever A generates the apropriate event. B is thus automatically
|
||||
notified about A's status change and can act accordingly to it. In contrast
|
||||
to the interfaces defined above, this interface is defined in terms of a set
|
||||
of functions which manipulate the interface and not as a data structure of
|
||||
overloadable functions.
|
||||
|
||||
The first thing to define for such an interface is the type of the callback
|
||||
function:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
$\langle$callfunc {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef void (*KillFuncIT)(void *pData);@\\
|
||||
\mbox{}\verb@ typedef int (*SICSCallBack)(int iEvent, void *pEventData, @\\
|
||||
\mbox{}\verb@ void *pUserData);@\\
|
||||
\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 callback function is meant to return 0 for failure or 1 for success.
|
||||
This infomation may be needed by an event invoking object if to continue an
|
||||
operation or not. The first parameter passed to {\bf SICSCallBack} is the id of
|
||||
the generated event. Clearly the communicating objects need to agree on
|
||||
these event. In SICS events types will be held in an header file event.h.
|
||||
The next parameter to SICSCallBack is a pointer to void. The event
|
||||
generating object may choose to pass additional data along with the event.
|
||||
Suitable event datastructures are also defined in event.h. The last
|
||||
parameter to SICSCallBack is a pointer to a datastructure defined by the
|
||||
owner of the callback routine when registering the callback. {\bf pKill} is a
|
||||
function which will be called automatically when the callback is deleted and
|
||||
whose sole task is to delete pUserData properly.
|
||||
|
||||
Then there are the functions needed to interface with the callback
|
||||
interface:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
$\langle$cifunc {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __ICallBack *pICallBack;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* event source side */@\\
|
||||
\mbox{}\verb@ pICallBack CreateCallBackInterface(void);@\\
|
||||
\mbox{}\verb@ void DeleteCallBackInterface(pICallBack self);@\\
|
||||
\mbox{}\verb@ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /* callback client side */@\\
|
||||
\mbox{}\verb@ long RegisterCallback(pICallBack pInterface, int iEvent, SICSCallBack pFunc,@\\
|
||||
\mbox{}\verb@ void *pUserData, KillFuncIT pKill);@\\
|
||||
\mbox{}\verb@ int RemoveCallback(pICallBack pInterface, long iID);@\\
|
||||
\mbox{}\verb@ int RemoveCallback2(pICallBack pInterface, void *pUserData);@\\
|
||||
\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 callback interface has two parts: A part the event generating object has
|
||||
to deal with and a part the interested object has to use. There is no way of
|
||||
enforcing this convention. However, SICS programmers should stick to it,
|
||||
otherwise weird things may happen.
|
||||
|
||||
The first two functions just deal with creating and deleting the callback
|
||||
interface data structure. {\bf CreateCallBackInterface} returns NULL if the
|
||||
request fails, or a pointer on success.
|
||||
|
||||
|
||||
{\bf InvokeCallBack} is responsible for invoking the registered callback functions
|
||||
and will be called only by the source object for the event. This function
|
||||
will scan the list of registered callback function for callback function
|
||||
which are registered for the event ID specified as second parameter. Each of
|
||||
them will be invoked with the event data given as third parameter. If any of
|
||||
the callback functions returns Failure this function will do so as well.
|
||||
Else 1 is returned. The event data structure belongs to the object invoking
|
||||
the callback. It should never be deleted in callback functions.
|
||||
|
||||
The next functions deal with the client side of the callback interface.
|
||||
|
||||
{\bf RegisterCallBack} registers a callback function with the interface. The first
|
||||
parameter is the interface to register the callback with. The second
|
||||
parameter is the event ID for which this callback is defined. pFunc is the
|
||||
pointer to the actual callback function. Finally pUserData is a pointer to
|
||||
some user defined data structure which shall be passed as pUserData when the
|
||||
callback is called. RegisterCallback retuns a long value which server as an
|
||||
identifier for the callback registration. If the registration fails, this
|
||||
function returns 0.
|
||||
|
||||
{\bf RemoveCallBack} is used to delete a registered callback. The first parameter
|
||||
is the interface to act upon, the second is the callback ID as returned by
|
||||
RegisterCallBack.
|
||||
|
||||
{\bf RemoveCallback2} is another variant for removing callbacks. This time the
|
||||
search key for deletion is the pointer to user data. All callbacks related
|
||||
to this user data in the interface specified will be removed.
|
||||
|
||||
All these functions are implemented in the file callback.c.
|
||||
|
||||
\subsubsection{The Environment Interface}
|
||||
This interface is used by the environment monitor in order to monitor
|
||||
the status of a environment controller. The interface looks like this:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
$\langle$envir {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ int iID;@\\
|
||||
\mbox{}\verb@ EVMode (*GetMode)(void *self);@\\
|
||||
\mbox{}\verb@ int (*IsInTolerance)(void *self);@\\
|
||||
\mbox{}\verb@ int (*HandleError)(void *self);@\\
|
||||
\mbox{}\verb@ } EVInterface, *pEVInterface;@\\
|
||||
\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 enum {\bf EVMode} describes the mode a environment controller can be in. The
|
||||
default is Idle, no action necessary. EVDrive means that the controller is
|
||||
currently being driven to a new value and the device executor has control.
|
||||
EVMonitor means that the environment monitor has to take care of the
|
||||
controller. EVError is set if the controller is out of tolerances.
|
||||
|
||||
{\bf GetMode} retrieves the current operation mode of the controller.
|
||||
|
||||
{\bf IsInTolerance} returns 1 if the controller is still within tolerances,
|
||||
0 otherwise.
|
||||
|
||||
{\bf HandleError} will be automatically called when IsInTolerance returns 0.
|
||||
Its purpose is to implemnt the error handling startegy for the controller
|
||||
in question.
|
||||
|
||||
|
||||
The environment interface has just one function associated with it:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap7}
|
||||
$\langle$envfunc {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pEVInterface CreateEVInterface(void);@\\
|
||||
\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}
|
||||
{\bf CreateEVInterface} just creates an environment interface.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap8}
|
||||
\verb@"obdes.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$obdes {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap9}
|
||||
\verb@"interface.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ I N T E R F A C E S@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Any object in SICS has to adhere to the object descriptor interface (see@\\
|
||||
\mbox{}\verb@ file obdes.h). Furthermore SICS objects may choose to support other@\\
|
||||
\mbox{}\verb@ interfaces as well. These interfaces are defined.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, June 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ For more documentation see interface.w, interface.tex@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see SICS impelementation files@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#ifndef SICSINTERFACES@\\
|
||||
\mbox{}\verb@#define SICSINTERFACES@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* interface ID's used to recognize an interface */@\\
|
||||
\mbox{}\verb@#define DRIVEID 513@\\
|
||||
\mbox{}\verb@#define COUNTID 713@\\
|
||||
\mbox{}\verb@#define CALLBACKINTERFACE 947@\\
|
||||
\mbox{}\verb@#define ENVIRINTERFACE 949@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* ----------------------- The drivable interface -----------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$driv {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pIDrivable CreateDrivableInterface(void);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* ------------------------ The countable interface ---------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$count {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pICountable CreateCountableInterface(void);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* ------------------------- The CallBack Interface --------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$callfunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\langle$cifunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*---------------------- The Environment Interface --------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$envir {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\langle$envfunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\subsection{More interfaces}
|
||||
For completeness it should be mentioned that besides these interfaces
|
||||
there exist further important interfaces in SICS. This includes the
|
||||
interface to the SICS interpreter defined in
|
||||
\ref{scinter}. Furthermore the data structures defined for the various
|
||||
types of drivers within SICS may be considered interfaces as
|
||||
well. Then there is the interface to the client as defined by the
|
||||
functions of the connection interface.
|
||||
|
||||
|
Reference in New Issue
Block a user