Initial revision
This commit is contained in:
45
doc/manager/alias.htm
Normal file
45
doc/manager/alias.htm
Normal file
@ -0,0 +1,45 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Aliases in SICS</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Aliases in SICS</H1>
|
||||
<P>
|
||||
SICS knows two different kinds of aliases: object aliases and command
|
||||
aliases. This is confusing but finds its explanation in the structure
|
||||
of SICS internals.
|
||||
</P>
|
||||
<h2>Object Aliases</h2>
|
||||
<p>
|
||||
An object alias is another name for a first class object installed
|
||||
into the SICS interpreter. For instance a second name for a motor. For
|
||||
instance the motor twotheta is quite often aliased to a4. Such an
|
||||
alias can be used like a normal SICS objects. Even in commands which
|
||||
access internal SICS interfaces like the drive command or
|
||||
others. Object aliases are installed into SICS with the SICSAlias
|
||||
command:
|
||||
<DL>
|
||||
<DT>SicsAlias newname oldname
|
||||
<DD>This command installs newname as alias for the object oldname.
|
||||
</dl>
|
||||
SicsAlias can only be used within initialization scripts.
|
||||
</p>
|
||||
<h2>Command Aliases</h2>
|
||||
<p>
|
||||
Command aliases are shortcuts for lengthy commands. For instance one
|
||||
might want to define A4LL as a shortcut for "a4 softlowerlim". This is
|
||||
just to save typing or adapt SICS to MAD users who appear to have an
|
||||
unlimited memory for 2-4 letter acronyms. It is possible to redefine a
|
||||
SICS object with this for instance to define tt as an alias for
|
||||
temperature. However if one tries to use tt in a drive command it will
|
||||
fail because it is just a text replacement. A command alias can be
|
||||
installed into SICS at any time with manager privilege and the
|
||||
command:
|
||||
<DL>
|
||||
<DT>alias shortcut bla bla bla ....
|
||||
<DD>This define shortcut as an alias for everything behind it.
|
||||
</DL>
|
||||
A shortcut may take parameters.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
55
doc/manager/client.htm
Normal file
55
doc/manager/client.htm
Normal file
@ -0,0 +1,55 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>SICS Client Configuration</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>SICS Client Configuration</H1>
|
||||
<P>
|
||||
Currently, SICS clients are written in Tcl/TK. This means that these programs
|
||||
are just scripts wich can be edited. Such editing is necessary in order to let
|
||||
the clients know how to connect to a server. All client configuration
|
||||
information is kept in an array named INI which is at the very top of the file.
|
||||
Configurable values in INI are:
|
||||
<DL>
|
||||
<DT> DefUser
|
||||
<DD> The SICS user name for the initial logon to the server when connecting.
|
||||
<DT>DefPasswd
|
||||
<DD> The password of the default user for logon.
|
||||
<DT>ServerPort
|
||||
<DD> The port number where the server is listening.
|
||||
<DT>InterruptPort
|
||||
<DD> The interrupt port number of the server.
|
||||
<DT>box
|
||||
<DD> The computer on which the SICS server is running.
|
||||
<DT>usPasswd
|
||||
<DD>The password of the SICS user. This is used as password when setting
|
||||
user rights from the menu.
|
||||
<DT>muPasswd
|
||||
<DD>The password of the SICS managers. This is used as password when setting
|
||||
user rights from the menu.
|
||||
<DT>logpath
|
||||
<DD>Only for the command line client. On request of the SICS users each
|
||||
command line client logs all I/O into a logfile. This logfile resides on the
|
||||
computer running the SICS server. This allows SICS managers to check what
|
||||
user have done to the machine. The logpath element defines the path to the
|
||||
directory where the automatically
|
||||
created log files are kept on the computer running the SICS server.
|
||||
</DL>
|
||||
The rest of the parameters and the file is programmers only. Reasonable values
|
||||
for those parameters can be found in the server configuration file. And of course,
|
||||
you need to know where the server is running.
|
||||
</P>
|
||||
<p>
|
||||
At the very top of the client script there is the full path name of the Tcl/TK
|
||||
interpreter to run in. This must be a wish for the command line client and a
|
||||
blt_wish for the status display client. This may need to be changed if a client
|
||||
comes up with: command not found. Valid copies of these executables can be
|
||||
found in /data/lnslib/bin. Tcl/TK needs own libraries of scripts as well. The
|
||||
places where these libraries sit is defined through the environment variables
|
||||
TCL_LIBRARY and TK_LIBRARY. Suitable libraries are under /data/lnslib. For
|
||||
details inspect /data/lnlib/bin/lns.login. When moving a client to a machine
|
||||
where the clients need to run stand alone this stuff needs to be copied and
|
||||
TCL_LIBRARY and TK_LIBRARY properly defined in the .login file.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
68
doc/manager/cliinst.htm
Normal file
68
doc/manager/cliinst.htm
Normal file
@ -0,0 +1,68 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Installing SICS Java Clients on PC's</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Installing SICS Java Clients on PC's</H1>
|
||||
<P>
|
||||
Some of the newer SICS clients are written in Java. Java is a platform
|
||||
independent system. This means the SICS client applications can be run as
|
||||
native PC systems as well. Both at home and at SINQ. In order to do this two
|
||||
pieces of software are required:
|
||||
<ul>
|
||||
<li>A Java Runtime system.
|
||||
<li>The SICS application.
|
||||
</ul>
|
||||
And the two of them need to be married which each other in some secret way.
|
||||
This document tells you how to do it.
|
||||
</P>
|
||||
<h2>Installing SICS Java Clients on IBM compatible PC's</h2>
|
||||
<p>
|
||||
A prerequisite for the installation of the software is either the Windows 95
|
||||
or Windows NT operating system. Pure DOS or Windows 3.* systems won't do.
|
||||
</p>
|
||||
<p>
|
||||
Installing the java runtime on your computer is easy: On the laboratory
|
||||
Windows NT server, lns00, there exists a share called lnslib. Below lnslib
|
||||
there is a directory called java. In this directory there is a executable
|
||||
file called jdk115-win32. Simply double clicking that one will invoke an
|
||||
installer which installs java on your PC's harddisk.
|
||||
Answer questions as required and soon you will be done.
|
||||
</p>
|
||||
<p>
|
||||
In the same directory: lns00//lnslib/java, the SICS client application files
|
||||
can be found as well. Currently available are:
|
||||
<ul>
|
||||
<li>sicsclient.jar or zip for the SICS Command Line Client
|
||||
<li>powderstatus.jar or zip for the powder diffractometer status display (DMC and
|
||||
HRPT).
|
||||
<li>sansstatus.jar or zip for the SANS status display.
|
||||
</ul>
|
||||
Copy those files wherever you like on your harddisk. But remember where you
|
||||
put them. You may even consider to use the ones stored at lns00.
|
||||
</p>
|
||||
<p>
|
||||
Now the java run time and the SICS application need to be married. This is
|
||||
done via batch files. Template batch files to be configured by you are
|
||||
stored at lns00//lnslib/java. Currently availabel are:
|
||||
<ul>
|
||||
<li>sics.bat for the Sics Command Line Client
|
||||
<li>powderstatus.bat for the Powder Diffractometer Status Display
|
||||
<li>sansstatus.bat for the SANS Status Display
|
||||
</ul>
|
||||
Copy the required batch files to a place somewhere on your path. Copying
|
||||
alone does not do the job, the batch files need to be configured. Edit the
|
||||
batch file with notepad. Make the variable jheim point to the directory
|
||||
where you installed the java run time kit. Set the variabel sheim to the
|
||||
directory to which you copied the SICS application jar file.
|
||||
</p>
|
||||
<p>
|
||||
Then you should be done. You may start the application by invoking the batch
|
||||
file from the command line. You may also create a shortcut on your desktop
|
||||
to the batch file using standard windows procedures. If you start the
|
||||
application from the desktop you also get a DOS window each time. If you
|
||||
dislike this go into Properties/shortcut of the shortcut on the desktop and
|
||||
configure the textfield labelled Run to Minimized.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
217
doc/manager/command.htm
Normal file
217
doc/manager/command.htm
Normal file
@ -0,0 +1,217 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Command Initialisation</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Command Initialisation</h2>
|
||||
<p>
|
||||
Besides the general SICS commands which are available for all instruments,
|
||||
there exist instrument specific commands. Such instrument specific
|
||||
objects are configured into the system through special commands in the
|
||||
initialisation file. Such special commands are described here.
|
||||
<DL>
|
||||
<DT>MakeRuenBuffer
|
||||
<DD>MakeRuenBuffer makes the RünBuffer system available.
|
||||
<DT>MakeDrive
|
||||
<DD>MakeDrive craetes the drive command.
|
||||
<DT>MakeScanCommand name countername headfile recoverfil
|
||||
<DD>MakeScanCommand initialises the SICS internal scan command. It will be
|
||||
accessible as name in the system. The next parameter is the name of a valid
|
||||
counter object to use for counting. The next parameter is the full pathname of
|
||||
a header description file. This file describes the contents of the header of
|
||||
the data file. The format of this file is described below. The parameter
|
||||
recoverfil is the full pathname of a file to store recover data. The internal
|
||||
scan command writes the state of the scan to a binary file after each scan point.
|
||||
This allows for restarting of aborted scans.
|
||||
<DT>MakePeakCenter scancommand
|
||||
<DD>MakePeakCenter initialises the peak analysis commands peak and center. The
|
||||
only parameter is the name of the internal scan command.
|
||||
<DT>DMCInit
|
||||
<DD>DMCInit creates the DMC StoreData command. This command writes NeXus files
|
||||
for DMC.
|
||||
<DT>InitSANS dictionary-filename
|
||||
<DD>InitSANS creates the StoreData command for SANS. This command writes
|
||||
the current state of the instrument into a NeXus file. The structure of the
|
||||
NeXus file is described in a special dictionary file which is a required
|
||||
parameter to this command. For details about the format of this file see
|
||||
the NXDICT-API documentation.
|
||||
<DT> Publish name access
|
||||
<DD> The SICS server uses Tcl as its internal macro language. However, it was felt
|
||||
that the whole Tcl command set should not be available to all users
|
||||
from the command line without any protection. There are reasons for this: careless use
|
||||
of Tcl may clog up memory, thereby grinding the system to a halt. Invalid Tcl statements
|
||||
may cause the server to hang. Last not least, Tcl contains commands to manipulate files
|
||||
and access the operating system. This is a potential security problem when the server
|
||||
is hacked. However, in order to make macro procedures available the Publish
|
||||
command exists. It makes a Tcl command name available to SICS users with the
|
||||
access code access. Valid values for access are: Internal, Mugger, User and Spy.
|
||||
<DT> MakeMulti name
|
||||
<DD> SANS uses a special syntax feature where several motors are grouped into a
|
||||
component group. For example beamstop or detector. MakeMulti creates such a
|
||||
group with the name name. Once such a group has been created, it has to be
|
||||
configured. For this a few configuration commands are available:
|
||||
<DL>
|
||||
<DT>name alias motname compname
|
||||
<DD> This command makes motor motname available as component motor compname.
|
||||
For example: <b>bs alias bsx x</b> makes motor bsx available as x in the beamstop
|
||||
group. Then the bsx motor can be driven by the command <b>bx x = 12.</b>.
|
||||
<DT> name pos posname motname value motname value ....
|
||||
<DD> The group command supports the notion of named positions. This means that
|
||||
a special combination of angles can be accessed through a name. This commands
|
||||
defines such a named position with the name posname. posname is followed by pairs
|
||||
of motorname value which define the position.
|
||||
<DT>name endconfig
|
||||
<DD>Once a group has been completely defined the configuration process must be
|
||||
ended with endconfig.
|
||||
</DL>
|
||||
<DT>MakeMono name M1 M2 M3 M4
|
||||
<DD>This command creates a crystal monochromator object. Such a
|
||||
monochromator object is necessary for the usage of the wavelength or energy
|
||||
variables. The parameter name defines the name of the monochromator object
|
||||
in the system. M1 and M2 are the names of the Theta and two Theta motors
|
||||
respectively. M3 is an optional parameter defining a motor for driving the
|
||||
horizontal curvature. M4 is an optional parameter defining a motor for
|
||||
driving the vertical curvature of the monochromator.
|
||||
<DT>InitToken tokenpassword
|
||||
<DD> This command initialises the token control management system with the
|
||||
token command. The single parameter tokenpassword specifies the password for
|
||||
the token force command.
|
||||
<DT>MakeHKL theta omega chi phi
|
||||
<DD>MakeHKL creates the hkl command for the calculation of settings for a four
|
||||
circle diffractometer. The four parameters are the names of the motors
|
||||
driving the two theta, omega, chi and phi circles of the diffractometer.
|
||||
These motors must already exists before this command may succeed.
|
||||
<DT>MakeDifrac tth om chi phi cter
|
||||
<DD>This command installs the Difrac subsystem into SICS. Difrac is a
|
||||
whole F77 package for controlling a four circle
|
||||
diffractometer. Afterwards Difrac commands are available in SICS with
|
||||
the prefix dif, for example dif ah calls the difrac ah command. Difrac
|
||||
is described in more detail elsewhere. The parameters are the four
|
||||
circle motors two theta, omega, chi and phi and the counter.
|
||||
<DT>MakeOptimise name countername
|
||||
<DD>This command installs the Peak Optimiser into the SICS server. The Peak
|
||||
Optimiser is an object which can locate the maximum of a peak with respect
|
||||
to several variables. The arguments are: name, the name under which the Peak
|
||||
Optimiser can be accessed within SICS and countername, which is the name of
|
||||
an already configured SICS counter box.
|
||||
<DT>MakeTRICSNEXUS datanumber fileroot dictionaryfile
|
||||
<DD>MakeTRICSNEXUS creates the object for writing TRICS NeXus files. This
|
||||
command creates a new command with the name nexus which is is used for
|
||||
interacting with this object. MakeTRICSNEXUS expects three parameters: The
|
||||
first one is the name of a data number object used for automatic data file
|
||||
name creation. The second is the full pathname to the directory where the
|
||||
dat should go. The third one is the full path name of the NXDICT dictionary
|
||||
file to use for positioning data in the NeXus file. Besides these explicit
|
||||
parameter the nexus object relies on the presence of a plethora of other
|
||||
objects in the system. The MakeTRICSNEXUS command should be at the end of
|
||||
the file.
|
||||
<DT>MakeAmor2T name da
|
||||
<DD>This creates a virtual two theta motor for the reflectometer
|
||||
AMOR. The two parameters are the name of the object in SICS and a
|
||||
Tcl-array with configuration parameters. The needed elements of this
|
||||
array are:
|
||||
<DL>
|
||||
<DT>mom
|
||||
<DD>The monochromator omega motor.
|
||||
<DT>som
|
||||
<DD>The sample omega motor.
|
||||
<DT>coz
|
||||
<DD> The height movement of the detector.
|
||||
<DT>cox
|
||||
<DD> The movement of the detector along the optical bench.
|
||||
<DT>stz
|
||||
<DD> The height movement of the sample connected to the omega circle.
|
||||
<DT>soz
|
||||
<DD> The height movement of the sample table.
|
||||
<DT>d4b
|
||||
<DD>The motor moving the whole diaphragm 4 up.
|
||||
<DT>d5b
|
||||
<DD>The motor moving the whole diaphragm 5 up.
|
||||
<DT>com
|
||||
<DD>The omega mevement of the detector.
|
||||
</DL>
|
||||
An example:
|
||||
<pre>
|
||||
set a2t(mom) mom
|
||||
set a2t(som) som
|
||||
set a2t(coz) coz
|
||||
set a2t(cox) cox
|
||||
set a2t(stz) stz
|
||||
set a2t(soz) soz
|
||||
set a2t(d4b) d4b
|
||||
set a2t(d5b) d5b
|
||||
set a2t(com) com
|
||||
MakeAmor2T a2t a2t
|
||||
</pre>
|
||||
creates a virtual AMOR two theta motor with the name a2t.
|
||||
<dt>MakeStoreAmor hm
|
||||
<dd>Creates an object for writing reflectometer data files. The name
|
||||
of the command is storeamor. The parameter hm denotes the histogram
|
||||
memory object.
|
||||
<dt>MakeAmorStatus name scan hm
|
||||
<dd>This creates a helper object for the reflectometer status display
|
||||
with name name. This object performs some operations on behalf of the
|
||||
status display for the reflectometer AMOR. The parameter scan denotes
|
||||
the name of the scan object. The parameter hm the name of the
|
||||
histogram memory object.
|
||||
<DT>MakeMesure name scanobject hklobject omega o2t fileroot datanumberobject
|
||||
<DD>MakeMesure installs the single counter four circle diffractometer
|
||||
measurement procedure into SICS. It will be accessible as object name
|
||||
afterwards. MakeMesure takes a lot of parameters:
|
||||
<dl>
|
||||
<Dt>scanobject
|
||||
<DD>The name of the internal scan object.
|
||||
<DT>hklobject
|
||||
<DD>The name of the object which does crystallographic calculations.
|
||||
<DT>omega
|
||||
<DD>The name of the motor driving omega.
|
||||
<DT>o2t
|
||||
<DD>The name of the omega two theta virtual motor for omega two theta scans.
|
||||
<DT>fileroot
|
||||
<DD>The full path to the data file directory without final /
|
||||
<dt>datanumberobject
|
||||
<DD>The name of the SICS data number object for creating unique file
|
||||
numbers.
|
||||
</dl>
|
||||
<DT>MakeSANSWave name velo_name
|
||||
<DD>> Installs a velocity selector wavelength variable into SICS. The
|
||||
variable will have the name given as first parameter. Usually lambda is a
|
||||
good idea. The second parameter, velo_name, is the name of the velocity
|
||||
selector which is controlled by this wavelength variable.
|
||||
<DT>MakeHklscan scan hkl
|
||||
<DD>Installs a command named hklscan which allows scans in reciprocal space
|
||||
expressed as Miller Indizes on a four circle diffractometer. scan must be
|
||||
the name of a scan object as created by MakeScanCommand. hkl is the name of
|
||||
a hkl calculation object as created by makeHKL.
|
||||
<dT>MakeXYTable myname
|
||||
<DD>Creates a XYTable object with the name myname. This object can store a
|
||||
list of x-y values.
|
||||
</DL>
|
||||
</p>
|
||||
<h4>The Scan Command Header Description File</h4>
|
||||
<p>
|
||||
The SICS internal scan command allows to configure the contents of the header of
|
||||
the ASCII scan data file through a template header file. This section describes
|
||||
the contents of this file. This header description file consists of normal
|
||||
text mixed with a few special keywords. The normal test will be copied to
|
||||
output verbatim. The keywords indicate that their place will be replaced by
|
||||
values at run time. Currently only one keyword per line is supported.
|
||||
Keywords recognized are:
|
||||
<DL>
|
||||
<DT>!!DATE!!
|
||||
<DD>Will be replaced with the file creation date.
|
||||
<DT>!!VAR(name)!!
|
||||
<DD>Will be replaced with the value of the SICS variable name.
|
||||
<DT>!!DRIV(name)!!
|
||||
<DD>Will be replaced with the value drivable variable name. Drivable variables are
|
||||
all motors and all variables which may be used in a drive or run command.
|
||||
<DT>!!ZERO(name)!!
|
||||
<DD>Will be replaced with the value of the softzero point for motor name.
|
||||
<DT>!!FILE!!
|
||||
<DD>Will be replaced by the creation name of the file.
|
||||
</DL>
|
||||
Please note that text behind such a keyword in the line will not be copied to
|
||||
the output.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
18
doc/manager/cron.htm
Normal file
18
doc/manager/cron.htm
Normal file
@ -0,0 +1,18 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Reoccuring Tasks</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Reoccuring Tasks</H1>
|
||||
<P>
|
||||
Sometimes it may be necessary to execute a SICS command at regular
|
||||
time intervalls. This can be achieved with the sicscron command:
|
||||
<DL>
|
||||
<DT>sicscron intervall bla blab blab
|
||||
<DD>This command installs a reoccuring task into SICS. The first
|
||||
parameter is the intervall in seconds between calls to the SICS
|
||||
command. Everything behind that is treated as the command to execute.
|
||||
</DL>
|
||||
</P>
|
||||
</BODY>
|
||||
</HTML>
|
190
doc/manager/hwini.htm
Normal file
190
doc/manager/hwini.htm
Normal file
@ -0,0 +1,190 @@
|
||||
<html>
|
||||
<head>
|
||||
<title> SICS Hardware Configuration</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>SICS Hardware Configuration</h2>
|
||||
<p>
|
||||
Hardware is configured into the SICS system by executing special hardware
|
||||
configuration commands from the server initialisation file. These commands
|
||||
are described here. Much SICS hardware is hooked up to the system via RS-232
|
||||
interfaces. The SICS server communicates with such devices through a serial
|
||||
port server program running on a Macintosh PC. All such devices require on
|
||||
initialisation the following parameters:
|
||||
<ul>
|
||||
<li><b>hostname</b> The name of the macintosh computer.
|
||||
<li><b>port</b> The port number where the serial port server program is
|
||||
listening for requests. It is given on the Macintosh screen when the serial
|
||||
port server is running. It is usually 4000.
|
||||
<li><b>channel</b> The number of the RS-232 interface on the Macintosh. 0 is
|
||||
the standard Macintosh modem port, 1 is the standard Macintosh printer port,
|
||||
2 is the first connector on the interface extension box. This leads to much
|
||||
confusion which can be healed with a simple rule: If a device is connected
|
||||
to the Macintosh serial port extension box, then its channel number is the
|
||||
interface number on the box plus one.
|
||||
</ul>
|
||||
|
||||
</p>
|
||||
<h3> Motors</h3>
|
||||
<p>
|
||||
The following commands are available to install motors into the system:
|
||||
<DL>
|
||||
<DT> Motor name SIM lowlim uplim err speed
|
||||
<DD> This command creates a simulated
|
||||
motor with the lower limits lowlim, the upper limit uplim, an ratio of
|
||||
randomly generated errors err and a driving speed of speed. Use this for
|
||||
testing and instrument simulation.
|
||||
<DT>Motor name EL734 host port chan no
|
||||
<DD>This command creates a stepper motor named name which is controlled through a
|
||||
El734 motor controller. The
|
||||
parameters host, port, chan have the meanings defined above. no is the
|
||||
number of the motor in the EL734 motor controller.
|
||||
<DT>Motor name EL734DC host port chan no
|
||||
<DD>This command creates an analog motor named name which is controlled through a
|
||||
El734DC motor controller. The
|
||||
parameters host, port, chan have the meanings defined above. no is the
|
||||
number of the motor in the EL734DC motor controller.
|
||||
</DL>
|
||||
</p>
|
||||
|
||||
<h3>Counting Devices</h3>
|
||||
<p>
|
||||
<DL>
|
||||
<DT>MakeCounter name SIM
|
||||
<DD>This command creates a simulated single counter
|
||||
accessible as object name.
|
||||
<DT>MakeCounter name EL737 host port chan
|
||||
<DD>This command creates a single
|
||||
counter name, using an EL737 driver. The counter is at host host, listening
|
||||
at port port and sits at serial port chan.
|
||||
</DL>
|
||||
</p>
|
||||
<h4>Histogram Memory</h4>
|
||||
<p>
|
||||
Due to the large amount of parameters, histogram memories are configured
|
||||
differently. A histogram memory object is created using a special
|
||||
creation command. This command is described below. Then a lot of options need to
|
||||
be configured. The commands used for setting these options and their meanings
|
||||
are defined in the <a href =
|
||||
../user/histogram.htm> user </a> documentation because histogram memories
|
||||
may be reconfigured at runtime. The sequence of configuartion options is
|
||||
ended with the command hmname init. This last command actually initialises the
|
||||
HM. Histogram memory objects can be created using the command:
|
||||
<DL>
|
||||
<DT> MakeHM name type
|
||||
<DD> The parameter name specifies the name under which the HM will be
|
||||
avialable in the system. type specifies which type of driver to use.
|
||||
Currently two types of drivers are supported: SIM for a simulated HM and
|
||||
SINQHM for the SINQ histogram memory. Please care to note, that the SINQHM
|
||||
requires a EL737 counter box for count control. This counter must have been
|
||||
defined before creating the HM object.
|
||||
</DL>
|
||||
As an example the configuration of a SINQHM HM with the name banana will be
|
||||
shown:
|
||||
<pre>
|
||||
MakeHM banana SINQHM
|
||||
banana configure HistMode Normal
|
||||
banana configure OverFlowMode Ceil
|
||||
banana configure Rank 1
|
||||
banana configure Length 400
|
||||
banana configure BinWidth 4
|
||||
banana preset 100.
|
||||
banana CountMode Timer
|
||||
banana configure HMComputer psds04.psi.ch
|
||||
banana configure HMPort 2400
|
||||
banana configure Counter counter
|
||||
banana init
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<h3>Velocity Selectors</h3>
|
||||
<p>
|
||||
A velocity selector is configured in a three step process. First a Tcl array
|
||||
is filled with the necessary configuration options for the actual velocity
|
||||
selector driver. In a second step the
|
||||
velocity selector is created with a special command. In a third step the
|
||||
forbidden regions for the velocity selector are defined. Currently two
|
||||
drivers for velocity selctors are known: a SIM driver for a simulated
|
||||
velocity selector and a DORNIER driver for a Dornier velocity selector
|
||||
hooked to a SINQ serial port setup. The last one needs a parameter array
|
||||
containing the fields Host, Port, Channel and Timeout. Host, Port and
|
||||
Channel have the meanings as defined at the very top of this section.
|
||||
Timeout is the maximum time to wait for responses from the velocity selector.
|
||||
A large value is required as the dornier velocity selector is very slow.
|
||||
The second step is performed through the following commands:
|
||||
<DL>
|
||||
<DT>VelocitySelector name tilt-motor SIM
|
||||
<DD> This command installs a simulated velocity selector with the name name
|
||||
into the system. tilt-motor is used for driving the tilt angle of the
|
||||
selector. tilt-motor must exist before this command can be executed
|
||||
successfully.
|
||||
<DT>VelocitySelector name tilt-motor DORNIER arrayname
|
||||
<DD> This command installs a dornier velocity selector into the system. name
|
||||
and tilt-motor have the same meanings as described above. arrayname is the
|
||||
Tcl-array with the driver configuration parameters.
|
||||
</DL>
|
||||
As an example the configuration of a dornier velocity selector named
|
||||
nvs is shown:
|
||||
<pre>
|
||||
set dornen(Host) lnsp25.psi.ch
|
||||
set dornen(Port) 4000
|
||||
set dornen(Channel) 6
|
||||
set dornen(Timeout) 5000
|
||||
VelocitySelector nvs tilt DORNIER dornen
|
||||
nvs add -20 28800
|
||||
nvs add 3800 4500
|
||||
nvs add 5900 6700
|
||||
nvs add 8100 9600
|
||||
</pre>
|
||||
</p>
|
||||
<h3>Chopper</h3>
|
||||
<p>
|
||||
Chopper systems are handled via a generic controller object. This basicly
|
||||
consists of two components: One object represents the actual
|
||||
controller. This basic object allows to query parameters only. Then
|
||||
there is for each parameter which can be controlled from SICS in this
|
||||
controller an adapter object. These adapter object are virtual motors
|
||||
which can be driven with the normal run or drive commands. Currently
|
||||
two drivers for this scheme exists: one for a simulated device, the
|
||||
other for the Dornier Chopper Controller at FOCUS. The first step when
|
||||
initializing this system is the installation of the general controller
|
||||
object into SICS. This is done with the commands:
|
||||
<pre>
|
||||
MakeChopper name sim
|
||||
MakeChopper name docho mac port channel
|
||||
</pre>
|
||||
The first command simply installs a simulated controller.
|
||||
The second command install a controller with a driver for the FOCUS
|
||||
Dornier Chopper system. Mac, port and channel are the usual Macintosh
|
||||
terminal server parameters which describe where the chopper controller
|
||||
is connected to through its RS-232 interface. After both commands the
|
||||
controller is available as command name within SICS.
|
||||
</p>
|
||||
<p>
|
||||
A drivable parameter at this controller is installed with a command
|
||||
similar to this:
|
||||
<pre>
|
||||
ChopperAdapter vname cname pname lower upper
|
||||
</pre>
|
||||
vname is the name under which the virtual motor will appear in
|
||||
SICS. cname is the name of the controller object installed into SICS
|
||||
with the commands in the previous paragraph. pname is the name of the
|
||||
drivable parameter in the controller. upper and lower are the upper
|
||||
and lower limits for this parameter. More then one of these commands
|
||||
can be given for each general controller.
|
||||
</p>
|
||||
<p>
|
||||
After this, the parameter can be modified by a command like:
|
||||
<pre>
|
||||
drive vname newvalue
|
||||
</pre>
|
||||
</p><p>
|
||||
To be expanded. Please note, that environment devices such as temperature
|
||||
controllers are dynamically configured into the system at run time.
|
||||
Therefore the necessary commands are described in the user documentation.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
39
doc/manager/ini.htm
Normal file
39
doc/manager/ini.htm
Normal file
@ -0,0 +1,39 @@
|
||||
<html>
|
||||
<head>
|
||||
<title> Overview of SICS Initialization </title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Overview of SICS Initialization</h2>
|
||||
<p>
|
||||
The command to start the SICServer is: <b> SICServer inifile </b>. So, what
|
||||
happens at the initialization of the SICS server? First, internally, a set
|
||||
of standard SICS commands is initialized, than a set of special
|
||||
initialization commands. These are special commands which help to configure
|
||||
the SICS server to match the actual hardware present on the hall floor and
|
||||
to define the commands available later on. Following this, the SICS server
|
||||
will read the initialization file specified on the command line or servo.tcl
|
||||
as a default. Using the data supplied in this file, the server will be
|
||||
configured. At this stage all special initialization commands, all
|
||||
Tcl-mechanisms and all SICS commands already initialized are available.
|
||||
After this is done, the server will delete the initialisation commands from
|
||||
its internal command list (No need to carry them around all the time). Now a
|
||||
status backup file will be read. This file contains normal SICS statements
|
||||
which initialise parameter values to the values they had before the last
|
||||
shutdown of the server. Such a file is automatically written whenever a
|
||||
normal shutdown of the server happens.
|
||||
</p>
|
||||
<p>
|
||||
The SICS server configuration file is essentially a SICS macro language
|
||||
file. This implies that all general SICS commands and Tcl mechanisms are
|
||||
available. Additionally the configuration file (and only the configuration
|
||||
file) may use special commands for the installation of:
|
||||
<ul>
|
||||
<li>SICS server options.
|
||||
<LI>SICS variables.
|
||||
<LI>Special commands.
|
||||
<LI>Hardware
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
26
doc/manager/inifile.htm
Normal file
26
doc/manager/inifile.htm
Normal file
@ -0,0 +1,26 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>SICS Xerver Configuration</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>SICS Server Configuration</H1>
|
||||
<P>
|
||||
There is only one executable image of the SICS server for all instruments. The
|
||||
commands and hardware available for a particular instrument is defined
|
||||
through the instrument initialisation file. The contents of this file are
|
||||
described below.
|
||||
</P>
|
||||
<!latex-off>
|
||||
<p>
|
||||
Go to:
|
||||
<ul>
|
||||
<li> An <a href = ini.htm> Overview </a> about SICS initialisation.
|
||||
<li> A description of SICS <a href = option.htm>options</a>.
|
||||
<li> A discussion of SICS <a href = var.htm> variables</a>.
|
||||
<li> Advice about <a href=hwini.htm> hardware </a> configuration.
|
||||
<li> A description of <a href = command.htm> command </a> initialisation.
|
||||
</ul>
|
||||
</p>
|
||||
<!latex-on>
|
||||
</BODY>
|
||||
</HTML>
|
116
doc/manager/iscan.htm
Normal file
116
doc/manager/iscan.htm
Normal file
@ -0,0 +1,116 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The Internal Scan Command</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>The Internal Scan Command</H1>
|
||||
<P>
|
||||
Scans are preformed from a variety of commands in SICS. All these commands
|
||||
are just Tcl--wrappers around an internal scan object implemented in C. This
|
||||
section describes this internal scan command and how it works. This internal
|
||||
scan command is installed into the SICS server via the <a href=command.htm>MakeScanCommand
|
||||
command</a> in the initialisation file. This command install the internal
|
||||
scan object under a user defined name. For the rest of this document it is
|
||||
assumed that this name is xxscan.
|
||||
</P>
|
||||
The scan object (named here xxscan, but may have another name) understands
|
||||
the following commands:
|
||||
<DL>
|
||||
<DT>xxscan add name start step
|
||||
<DD>This command adds the variable specified by the argument name to the
|
||||
list of variables scanned in the next scan. The arguments start and step
|
||||
define the starting point and the sptep width for the scan on this variable.
|
||||
<DT>xxscan clear
|
||||
<DD>clears the list of scan variables. Must be called before each scan with
|
||||
different parameters.
|
||||
<DT>xxscan run NP mode preset
|
||||
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
|
||||
the counter mode to use (this can be either timer or monitor) and preset
|
||||
which is the preset value for the counter. Scan data is written to an output
|
||||
file.
|
||||
<DT>xxscan silent NP mode preset
|
||||
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
|
||||
the counter mode to use (this can be either timer or monitor) and preset
|
||||
which is the preset value for the counter. The difference to run is, that
|
||||
this scan does not produce an output file.
|
||||
<DT>xxscan recover
|
||||
<DD>Recovers an aborted scan. The scan object writes a file with all data
|
||||
necessary to continue the scan after each scan point. If for some reason a
|
||||
scan has been aborted due to user intervention or a system failure, this
|
||||
scheme allows to continue the scan when everything is alright again. This
|
||||
works only if the scan has been started with run, not with silent.
|
||||
<DT>xxscan getfile
|
||||
<DD>This command retuns the name of the current data file.
|
||||
<DT>xxscan setchannel n
|
||||
<DD>Sometimes it is required to scan not the counter but a monitor. This
|
||||
command sets the channel to collect data from. The argument n is an integer
|
||||
ID for the channel to use.
|
||||
<DT>xxscan getcounts
|
||||
<DD>Retrieves the counst collected during the scan.
|
||||
<DT>xxscan getvardata n
|
||||
<DD>This command retrieves the values of a scan variable during the scan
|
||||
(the x axis). The argument n is the ID of the scan variable to retrieve data
|
||||
for. ID is 0 for the first scan variable added, 1 for the second etc.
|
||||
<DT>xxscan interest
|
||||
<DD>A SICS client can be automatically notified about scan progress. This is
|
||||
switched on with this command. Three types of messages are sent: A string
|
||||
NewScan on start of the scan, a string ScanEnd after the scan has finished
|
||||
and a string scan.Counts = {109292 8377 ...} with the scan values after each
|
||||
finished scan point.
|
||||
<DT>xxscan uninterest
|
||||
<DD> Uninterest switches automatic notification about scan progress off.
|
||||
<DT>xxscan integrate
|
||||
<DD> Calculates the integrated intensity of the peak and the variance of teh
|
||||
intensity for the last scan. Returns either an error, when insufficient scan
|
||||
data is available or a pair of numbers. Peak integration is performed along
|
||||
the method described by Grant and Gabe in J. Appl. Cryst. (1978), 11,
|
||||
114-120.
|
||||
<DT>xxscan window [newval]
|
||||
<DD>Peak Integration uses a window in order to determine if it is still in the
|
||||
peak or in background. This command allows to request the size of this
|
||||
window (without argument) or set it (with argument giving the new window
|
||||
size).
|
||||
<DT>xxscan simscan pos FWHM height
|
||||
<DD>This is a debugging command. It simulates scan data with a hundred
|
||||
points between an x axis ranging from 10 to 20. A gauss peak is produced
|
||||
from the arguments given: pos denotes the position of the peak maximum, FWHM
|
||||
is the full width at half maximum for the peak and height is its height.
|
||||
<DT>xxscan command tclcommand
|
||||
<DD>Sets the tcl command procedure to invoke at each scan point. See below
|
||||
for the description of user defined scans. Invoked without argument command
|
||||
returns the name of the current command procedure.
|
||||
<dt>xxscan configure mode
|
||||
<dd>Confugures the several possible scan modes for the scan
|
||||
object. Currently there are two:
|
||||
<ul>
|
||||
<li><b>standard</b>, the default mode writing ASCII files.
|
||||
<li><b>amor</b>, a special mode the reflectometer AMOR which writes
|
||||
NeXus files.
|
||||
</ul>
|
||||
</DL>
|
||||
</P>
|
||||
<p>
|
||||
<h2>User Defined Scans</h2>
|
||||
In some cases users wish to exert more influence about the scan. Especially
|
||||
about what gets counted. In order to cater for this a hook was implemented
|
||||
in the internal scan command. This hook allows to run a tcl procedure at each
|
||||
scan point. This Tcl procedure is required to return a string containing
|
||||
up to 11 values for counters and monitors. The first value will be the one
|
||||
used as counts in the data file. The others will be placed as monitors.
|
||||
Please note, that only the first three monitors are written to file as of
|
||||
current. In order to use this facility the following steps are required:
|
||||
<ol>
|
||||
<li>Write The Tcl-macro procedure to run. Make sure that is creates proper
|
||||
output.
|
||||
<li>Test the Tcl-procedure in SICS.
|
||||
<li>Install the Tcl-procedure into the scan object with the
|
||||
xxscan command name syntax.
|
||||
<li>Make the scan command use the Tcl procedure by setting channel to -10 with
|
||||
the xxscan setchannel -10 command.
|
||||
</ol>
|
||||
A hint: If you need to control the counting operation as well (because you
|
||||
are not using a counter to count) just run the scan object with a very low
|
||||
preset and do the counting yourself in your procedure.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
9
doc/manager/keepalive
Executable file
9
doc/manager/keepalive
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/ksh
|
||||
#---------------------------------------------------------------------------
|
||||
# script starts a program and restarts it whenever it dies.
|
||||
#
|
||||
# Mark Koennecke, Juli 1998
|
||||
#--------------------------------------------------------------------------
|
||||
while true; do
|
||||
$1
|
||||
done
|
82
doc/manager/macroman.htm
Normal file
82
doc/manager/macroman.htm
Normal file
@ -0,0 +1,82 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Programming SICS Macros</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H2>Programming SICS Macros</H2>
|
||||
<P>
|
||||
The SICS server has a built in macro language. This macro language is basically
|
||||
John Ousterhout's Tool Command Language Tcl. Tcl is described elsewhere.
|
||||
A sound knowledge of Tcl is required for programming SICS macros. The SICS macro
|
||||
language can be used for the following purposes:
|
||||
<UL>
|
||||
<li>Add hoc measurement procedures.
|
||||
<LI>Trial measurement procedures.
|
||||
<LI>Syntax adaptions to one's own favourite syntax.
|
||||
<LI>Building of cmore complex commands from the SICS primitives.
|
||||
</ul>
|
||||
The general procedure for defining a macro requires defining the macro in a new
|
||||
file, source this file from the configuration script and the use of the Publish
|
||||
command to make it available. New commands can best be defined as Tcl procedures,
|
||||
but the obTcl object oriented extension to Tcl is known to work as well. The SICS
|
||||
macro language allows to access:
|
||||
<ul>
|
||||
<li>Most Tcl commands.
|
||||
<li>All SICS commands.
|
||||
</ul>
|
||||
In the following sections a few pecularities of the SICS macro system will be
|
||||
discussed.
|
||||
</P>
|
||||
|
||||
<h3>Input/Output</h3>
|
||||
<p>
|
||||
It would be quite verbose and confusing for the user if all output from SICS
|
||||
commands called from a macro would appear on the screen during macro execution.
|
||||
Therefore all
|
||||
normal SICS output to a client is suppressed while executing a macro. Except
|
||||
error messages and warnings which will always be written to the
|
||||
client executing the macro. The output of a SICS command is available within the
|
||||
macro script through the normal Tcl mechanism as a return value. This allows for
|
||||
processing of SICS output within a macro. If the output to the client executing
|
||||
the macro is required this can be done with the ClientPut command, detailed in the
|
||||
user documantation.
|
||||
</p>
|
||||
<h3>Error Handling</h3>
|
||||
<p>
|
||||
Tcl has the feature that it aborts execution of a script when an error occurs.
|
||||
If a macro script needs to handle errors either from Tcl or from SICS commands
|
||||
this can be achieved by using the Tcl catch mechanism. A script can inquire the current interrupt value of the
|
||||
connection with the command <b>GetInt</b>. If a script can handle an error condition
|
||||
it may set the interrupt on the connection object with the <b>SetInt</b> command.
|
||||
The textual representations of interrupts for these commands are:
|
||||
continue, abortop, abortscan, abortbatch, halt, free, end.
|
||||
</p>
|
||||
<h3>Interacting with SICS within a Script</h3>
|
||||
<p>
|
||||
There exist a few commands which allow to inquire or manipulate SICS
|
||||
internals. Most of these commands are only available in macro scripts.
|
||||
<DL>
|
||||
<DT>SICSType thing.
|
||||
<DD> SICSType lets SICS find out if thing has some meaning within SICS. Possible return
|
||||
values are: DRIV for a drivable variable, COM for a SICS command, NUM for a numeric
|
||||
value and TEXT for anything else.
|
||||
<DT>SICSBounds var newval
|
||||
<DD>SICSBounds checks if newval violates the hardware or software limits of
|
||||
the variable var.
|
||||
<DT>SetStatus newval
|
||||
<DD>SetStatus sets the SICS status line to a new value. Possible values for
|
||||
newval are: Eager, UserWait, Count, NoBeam, Paused, Driving, Running,
|
||||
Scanning, Batch, Halt, Dead.
|
||||
<DT>SICSStatus var
|
||||
<DD>SICSStatus returns a integer value representing the current status of
|
||||
the object var. var must be a drivable or countable object. The integer code returned
|
||||
are defined in the SICS programmers documentation.
|
||||
</DL>
|
||||
</p>
|
||||
<p>
|
||||
Currently it is not possible to define object interfaces from within the SICS
|
||||
macro language. For the notion of object interfaces see the
|
||||
SICS programmers documentation. This may be implemented in future when needed.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
49
doc/manager/manager.htm
Normal file
49
doc/manager/manager.htm
Normal file
@ -0,0 +1,49 @@
|
||||
<html>
|
||||
<head>
|
||||
<title> SICS-Manager documentation </title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>SICS Manager Documentation</h1>
|
||||
<hr size=4 width="66%">
|
||||
<p ALIGN=CENTER>
|
||||
Mark Könnecke
|
||||
</p>
|
||||
<p ALIGN=CENTER>
|
||||
Labor für Neutronenstreuung
|
||||
</p>
|
||||
<p ALIGN=CENTER>
|
||||
Paul Scherrer Institut
|
||||
</p>
|
||||
<p ALIGN=CENTER>
|
||||
CH-5232 Villigen-PSI
|
||||
</p>
|
||||
<p ALIGN=CENTER>
|
||||
Switzerland
|
||||
</p>
|
||||
<p>
|
||||
This document describes the general setup of SICS, the configuration of the
|
||||
SICS server and its clients and the writing of macros in the
|
||||
SICS macro language. This document is aimed at SICS system managers and
|
||||
instrument scientists. This document requires that the SICS user documentation
|
||||
has been read and understood beforehand. For writing macros it is essential
|
||||
to understand John Ousterhouts Tool Command Language,
|
||||
which is described elsewhere.
|
||||
</p>
|
||||
<!latex-off>
|
||||
<p>
|
||||
Where to you want to go today?
|
||||
<ul>
|
||||
<li> To the general <a href =setup.htm> setup</a> section.
|
||||
<Li> To the <a href = inifile.htm> server initialision</a> section.
|
||||
<li> To the <a href = client.htm>client </a> configuration section.
|
||||
<li> To the section describing <a href=special.htm>special commands</a> for
|
||||
SICS administrators or programmers.
|
||||
<li> Commands for <a href=status.htm>status display</a> support.
|
||||
<li> To the <a href="macroman.htm">macro</a> programming section.
|
||||
<LI> <a href = trouble.htm>Troubleshooting</a> hints.
|
||||
<Li> Hints for <a href = "move.htm">moving</a> the SICS server or for Exchanging the serial port server.
|
||||
</ul>
|
||||
</p>
|
||||
<!latex-on>
|
||||
</body>
|
||||
</html>
|
59
doc/manager/managerman
Normal file
59
doc/manager/managerman
Normal file
@ -0,0 +1,59 @@
|
||||
\documentclass[12pt,a4paper]{report}
|
||||
%%\usepackage[dvips]{graphics}
|
||||
%%\usepackage{epsf}
|
||||
\setlength{\textheight}{24cm}
|
||||
\setlength{\textwidth}{16cm}
|
||||
\setlength{\headheight}{0cm}
|
||||
\setlength{\headsep}{0cm}
|
||||
\setlength{\topmargin}{0cm}
|
||||
\setlength{\oddsidemargin}{0cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\hoffset}{0cm}
|
||||
\setlength{\marginparwidth}{0cm}
|
||||
|
||||
\begin{document}
|
||||
%html -d hr " "
|
||||
%html -s report
|
||||
\begin{center}
|
||||
\begin{huge}
|
||||
SICS--Managers--Manual \\
|
||||
\end{huge}
|
||||
Version 1.0, October,1997\\
|
||||
Dr. Mark K\"onnecke \\
|
||||
Labor f\"ur Neutronenstreuung\\
|
||||
Paul Scherrer Institut\\
|
||||
CH--5232 Villigen--PSI\\
|
||||
Switzerland\\
|
||||
\end{center}
|
||||
\clearpage
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
\chapter{Introduction}
|
||||
This document describes the general setup of SICS, the configuration of the
|
||||
SICS server and its clients and the writing of macros in the
|
||||
SICS macro language. This document is aimed at SICS system managers and
|
||||
instrument scientists. This document requires that the SICS user
|
||||
documentation
|
||||
has been read and understood beforehand. For writing macros it is essential
|
||||
to understand John Ousterhouts Tool Command Language,
|
||||
which is described elsewhere.
|
||||
|
||||
%html setup.htm 1
|
||||
%html inifile.htm 1
|
||||
%html ini.htm 1
|
||||
%html option.htm 1
|
||||
%html var.htm 1
|
||||
%html hwini.htm 1
|
||||
%html command.htm 1
|
||||
%html special.htm 1
|
||||
%html serial.htm 2
|
||||
%html status.htm 2
|
||||
%html sps.htm 2
|
||||
%html iscan.htm 2
|
||||
%html alias.htm 2
|
||||
%html cron.htm 2
|
||||
%html client.htm 1
|
||||
%html ../user/trouble.htm 1
|
||||
%html move.htm 1
|
||||
\end{document}
|
64
doc/manager/motor.tex
Normal file
64
doc/manager/motor.tex
Normal file
@ -0,0 +1,64 @@
|
||||
\documentclass[12pt,a4paper]{article}
|
||||
%%\usepackage[dvips]{graphics}
|
||||
%%\usepackage{epsf}
|
||||
\setlength{\textheight}{24cm}
|
||||
\setlength{\textwidth}{16cm}
|
||||
\setlength{\headheight}{0cm}
|
||||
\setlength{\headsep}{0cm}
|
||||
\setlength{\topmargin}{0cm}
|
||||
\setlength{\oddsidemargin}{0cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\hoffset}{0cm}
|
||||
\setlength{\marginparwidth}{0cm}
|
||||
\parskip .5cm
|
||||
|
||||
\begin{document}
|
||||
\begin{center}
|
||||
\begin{huge}
|
||||
Saving EL734 Motor Parameters on Unix
|
||||
\end{huge}
|
||||
16-October-1998\\
|
||||
\end{center}
|
||||
EL734 motor controllers occasionally loose their built in parameters.
|
||||
Therefore it is necessary to save their parameters and to have a way to load
|
||||
them to the motor controller when need arises. This can be done with
|
||||
David Maden's EL734\_test
|
||||
program. This program has now been made available on DigitalUnix. For each
|
||||
SICS instrument motor parameters are stored at two independent locations:
|
||||
\begin{itemize}
|
||||
\item In the motor directory of the instrument account. For example:
|
||||
/home/DMC/motor
|
||||
\item On lnsa10 in the lnslib account in a motor/instrument directory. For
|
||||
example: /data/lnslib/motor/dmc
|
||||
\end{itemize}
|
||||
In each of these directories there is an instrument specific shell script
|
||||
which does the job. It has a name such as instrumentmotor, for example
|
||||
dmcmotor . This shell script expects one argument which must be one of the
|
||||
keywords load or save. With the option save specified motor parameters are
|
||||
read from the controller and stored into files. With the option load the
|
||||
stored motor parameters are loaded into the motor controller. Thus the
|
||||
procedure for saving and restoring motor parameters becomes:
|
||||
\begin{enumerate}
|
||||
\item change to the directory with the motor parameters
|
||||
(/home/INSTRUMENT/motor or /data/lnslib/motor/instrument).
|
||||
\item type: instrumentmotor save for saving motor parameters to disk.
|
||||
\item type instrumentmotor load for loading motor parameters to the
|
||||
controller.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{Large}
|
||||
It is the instrument scientists responsability to save motor parameters to
|
||||
disk after changes to both locations.
|
||||
\end{Large}
|
||||
|
||||
In order to make this more interesting, files at lnsa10 are write protected.
|
||||
In order to overwrite those you need to use the unix command chmod.
|
||||
|
||||
Saving motor parameters generates files with names like motNUM1@NUM2.par
|
||||
with NUM1, NUM2 being numbers. This means: motor number NUM1 at EL734 motor
|
||||
controller at Macintosh channel NUM2. These files can be edited when you
|
||||
know what you are doing. The command syntax is described in the El734 motor
|
||||
controller manual.
|
||||
|
||||
|
||||
\end{document}
|
59
doc/manager/move.htm
Normal file
59
doc/manager/move.htm
Normal file
@ -0,0 +1,59 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Moving SICS</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Moving SICS</H1>
|
||||
<H2> Moving the SICS Server to a new Computer</h2>
|
||||
<P>
|
||||
Moving the SICS server from one computer to another involves quite a
|
||||
few steps:
|
||||
<OL>
|
||||
<LI>Recreate the directory structure on the new computer.
|
||||
<LI>Copy all necessary files across:
|
||||
<ul>
|
||||
<li> A copy of the SICServer.
|
||||
<li> A copy of the instrument configuration file.
|
||||
<li> All macro scripts used by this instrument.
|
||||
<li> The DataNumber file.
|
||||
<li> The necessary data file dictionary or header description files.
|
||||
<li> The client programs.
|
||||
</ul>
|
||||
All necessary files should be available from backup or under the
|
||||
/data/lnslib/sics/instrument tree on lnsa10.
|
||||
<LI>Edit the instrument configuration file and make all pathnames reflect the
|
||||
new directory structure. It should be enough to adapt the home variable at the
|
||||
top, but better check. All paths references must be renewed if the directory
|
||||
structure is changed from the one described <a href = "setup.htm">above</a>.
|
||||
<LI>Edit the client scripts to reflect the new location of the server. Only the
|
||||
box and logpath parameters should need to be changed.
|
||||
<LI> Edit the DataNumber file and set the number above the last valid data file
|
||||
number used. Otherwise the automatic numbering scheme
|
||||
for data files gets messed up.
|
||||
<LI>Test the new Installation!
|
||||
</OL>
|
||||
</P>
|
||||
<h2>Exchanging the Macintosh Serial Port Server</h2>
|
||||
<p>In its current configuration at SINQ, SICS requires a Macintosh PC running a serial
|
||||
port server program. Exchanging this Macintosh requires the following steps:
|
||||
<OL>
|
||||
<LI>Exchange the Macintosh physically. Plug everything as it was before the
|
||||
exchange. Not every Macintosh can be used. Any other Macintosh from another
|
||||
instrument or the spare Macintosh from the EDV-cabin will do. Other
|
||||
Macintoshs require some serious screwing and software installation
|
||||
procedures.
|
||||
<LI>Edit the instrument configuration file and replace all references to the name of
|
||||
the old Macintosh PC with the name of the new Macintosh PC.
|
||||
<LI>Test it!
|
||||
</OL>
|
||||
If you do not plug the serial devices back onto the Macintosh as they were, you
|
||||
need to adapt the channel numbers in the configuration file as well. The standard
|
||||
plugging scheme for the serial port extension box on the Macintosh is like this:
|
||||
<OL>
|
||||
<LI>Motor Controller 1
|
||||
<LI>Motor Controller 2
|
||||
<LI>Counter Box
|
||||
</OL>
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
82
doc/manager/mug
Normal file
82
doc/manager/mug
Normal file
@ -0,0 +1,82 @@
|
||||
\documentclass[12pt,a4paper]{article}
|
||||
%%\usepackage[dvips]{graphics}
|
||||
%%\usepackage{epsf}
|
||||
\setlength{\textheight}{24cm}
|
||||
\setlength{\textwidth}{16cm}
|
||||
\setlength{\headheight}{0cm}
|
||||
\setlength{\headsep}{0cm}
|
||||
\setlength{\topmargin}{0cm}
|
||||
\setlength{\oddsidemargin}{0cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\hoffset}{0cm}
|
||||
\setlength{\marginparwidth}{0cm}
|
||||
\parskip .5cm
|
||||
|
||||
\begin{document}
|
||||
%html -d hr " "
|
||||
%html -s article
|
||||
\begin{center}
|
||||
\begin{huge}
|
||||
Notes To SICS Instrument Scientists\\
|
||||
\end{huge}
|
||||
3-Juli-1998\\
|
||||
\end{center}
|
||||
|
||||
%html ../user/sicsinvoc.htm
|
||||
%html sicsnews.htm
|
||||
|
||||
\section{User Names and Passwords}
|
||||
\begin{itemize}
|
||||
\item All instruments have know an account {\bf lnsuser 98lns2} with user
|
||||
privilege.
|
||||
\item Manager passwords are:
|
||||
\begin{itemize}
|
||||
\item TOPSI: Mugger Daniel
|
||||
\item DMC: Manager Lucas
|
||||
\item SANS: Manager Joachim
|
||||
\end{itemize}
|
||||
User names and passwords can be changed by editing the instrument
|
||||
configuration file.
|
||||
\end{itemize}
|
||||
|
||||
\section{SICS on the WWW}
|
||||
\subsection{Client access}
|
||||
Following decisions made at a recent SICS user meeting, SICS clients are
|
||||
made avaialable on the WWW. Access is restricted to the PSI domain. A
|
||||
username and a password is needed in order to access the clients. This is
|
||||
currently set to: sinquser 98sinq2.
|
||||
The URL's for the clients are:
|
||||
\begin{description}
|
||||
\item[Command Line Client]http://lns00.psi.ch/sics/client/sicsclient.html
|
||||
\item[DMC Status]http://lns00.psi.ch/sics/client/powderstatus.html
|
||||
\item[TOPSI Status]http://lns00.psi.ch/sics/client/topsistatus.html
|
||||
\item[SANS Status]http://lns00.psi.ch/sics/client/sansstatus.html
|
||||
\end{description}
|
||||
|
||||
\subsection{Documentation}
|
||||
|
||||
All SICS User documentation is accessible at:\\
|
||||
http://lns00.psi.ch/sics/index.html \\
|
||||
Postscript versions of the SICS user
|
||||
documentation inhabit the doc directory of your instrument account.
|
||||
|
||||
The SICS manager documentation is also available on WWW. URL:\\
|
||||
http://lns00.psi.ch/sics/manager/manager.htm \\Access
|
||||
to this directory is
|
||||
restricted to the psi.ch domain. A username and password must be given in
|
||||
order to be given access to these pages. These values are currently set to:
|
||||
bigboss DJLmanager (can be remembered as: Daniel, Joachim, Lukas manager).
|
||||
|
||||
There is now a WWW document which informs about new SICS features, bug fixes
|
||||
etc. This is available at:\\
|
||||
http://lns00.psi.ch/sics/manager/sicsnews.htm \\
|
||||
The same access restrictions as given for the manager documentation above
|
||||
apply.
|
||||
|
||||
Installation instructions for SICS clients on PC's can be found at:\\
|
||||
http://lns00.psi.ch/sics/cliinst.htm\\
|
||||
Currently only real PC's are covered,
|
||||
but instructions for Mac's will follow some day or another. Any volunteers?
|
||||
|
||||
|
||||
\end{document}
|
173
doc/manager/mug.tex
Normal file
173
doc/manager/mug.tex
Normal file
@ -0,0 +1,173 @@
|
||||
\documentclass[12pt,a4paper]{article}
|
||||
%%\usepackage[dvips]{graphics}
|
||||
%%\usepackage{epsf}
|
||||
\setlength{\textheight}{24cm}
|
||||
\setlength{\textwidth}{16cm}
|
||||
\setlength{\headheight}{0cm}
|
||||
\setlength{\headsep}{0cm}
|
||||
\setlength{\topmargin}{0cm}
|
||||
\setlength{\oddsidemargin}{0cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\hoffset}{0cm}
|
||||
\setlength{\marginparwidth}{0cm}
|
||||
\parskip .5cm
|
||||
|
||||
\begin{document}
|
||||
\begin{center}
|
||||
\begin{huge}
|
||||
Notes To SICS Instrument Scientists\\
|
||||
\end{huge}
|
||||
3-Juli-1998\\
|
||||
\end{center}
|
||||
|
||||
% html: Beginning of file: `../user/sicsinvoc.htm'
|
||||
|
||||
\section{SICS Invocation}
|
||||
|
||||
\label{f0}
|
||||
|
||||
SICS is a client server system. This means there are two programs. The first
|
||||
is a
|
||||
SICServer which does the actual instrument control work. A user rarely needs
|
||||
to bother about this server program as it is meant to run all the time.
|
||||
See instructions below if things go wrong. The user has only to deal with
|
||||
the SICS client programs. These implement the user interface to SICS.
|
||||
SICS Clients and the SICServer communicate with each other through TCP/IP
|
||||
sockets.
|
||||
|
||||
Currently four SICS clients are available:
|
||||
\begin{itemize}
|
||||
\item A command line control client which allows to control the measurement.
|
||||
\item A status display for DMC.
|
||||
\item A status display for TOPSI.
|
||||
\item A status display for SANS.
|
||||
\end{itemize}
|
||||
These programs can be started on a DigitalUnix system by issuing the
|
||||
following commands at the command prompt:
|
||||
\begin{description}
|
||||
\item[sics \&] for the control client.
|
||||
\item[powderstatus \&] for the DMC status display client.
|
||||
\item[topsistatus \&] for the TOPSI status display.
|
||||
\item[sansstatus \&] for the SANS status display.
|
||||
\end{description}
|
||||
On a PC you may find icons for starting the different prograsm on the
|
||||
desktop.
|
||||
Each of these clients has usage instructions online which can be displayed
|
||||
through the help/about menu entry.
|
||||
|
||||
\subsection{Connecting and Logging in}
|
||||
|
||||
|
||||
|
||||
After startup any SICS client is not connected to a SICS server and thus not
|
||||
active. A connection is established through the connect menu of the client.
|
||||
|
||||
SICS is a multi user instrument control system. In order to prevent
|
||||
malicious manipulations of the instrument SICS supports a hierarchy of user
|
||||
rights. In order to run an experiment you need at least user level privilege.
|
||||
In order to achieve this privilege you have to invoke the User Parameter/Set
|
||||
Rights dialog. There you have to enter the apropriate username and password
|
||||
kindly provided by your instrument scientist.
|
||||
|
||||
\subsection{Restarting the Server}
|
||||
|
||||
|
||||
|
||||
The SICS server should be running all the time. It is only down if something
|
||||
went wrong. You can check for the presence of the SICS server by loging in
|
||||
to the instrument computer and typing {\bf CheckSICS} at the command
|
||||
prompt. The output will tell you what is happening. If you need to restart
|
||||
the SICS server log in as the instrument user at the instrument computer and
|
||||
invoke the apropriate command to start the server. These are:
|
||||
\begin{description}
|
||||
\item[DMC] Computer = lnsa05,User = DMC, Command = DMCServer
|
||||
\item[TOPSI] Computer = lnsa03,User = TOPSI, Command = TOPSIServer
|
||||
\item[SANS] Computer = lnsa07,User = SANS, Command = SANSServer
|
||||
\end{description}
|
||||
If all this does not help look under trouble shooting
|
||||
SICS.
|
||||
% html: End of file: `../user/sicsinvoc.htm'
|
||||
% html: Beginning of file: `sicsnews.htm'
|
||||
|
||||
\section{SICS News Ticker}
|
||||
|
||||
\label{f2}
|
||||
|
||||
This page contains information about the latest bug fixes, releases and other
|
||||
miscellaneous information about SICS.
|
||||
|
||||
|
||||
\subsection{Juli 1998}
|
||||
|
||||
|
||||
\begin{description}
|
||||
\item[Status OutOfMemory] Bug in status display clients fixed which caused OutOfMemory after
|
||||
some time of automatic update.
|
||||
\item[topsistatus ] TOPSI has got a java status client now as well. Can be invoked with
|
||||
{\bf topsistatus}. On the WWW also.
|
||||
\item[commandlog] On popular demand the SICS server can now write a log file which logs all
|
||||
communication between clients with user or manager privilege and the SICserver.
|
||||
This log is off by default. There is a new SICS command
|
||||
commandlog which serves to configure this log.
|
||||
\item[8-fold counterboxes.] SICS now reads all eight monitors.
|
||||
\item[sicsinstall] There is now a shell script which automatizes updating and installing SICS. For more
|
||||
information see the setup section of the SICS managers guide.
|
||||
\end{description}
|
||||
|
||||
% html: End of file: `sicsnews.htm'
|
||||
|
||||
\section{User Names and Passwords}
|
||||
\begin{itemize}
|
||||
\item All instruments have know an account {\bf lnsuser 98lns2} with user
|
||||
privilege.
|
||||
\item Manager passwords are:
|
||||
\begin{itemize}
|
||||
\item TOPSI: Mugger Daniel
|
||||
\item DMC: Manager Lucas
|
||||
\item SANS: Manager Joachim
|
||||
\end{itemize}
|
||||
User names and passwords can be changed by editing the instrument
|
||||
configuration file.
|
||||
\end{itemize}
|
||||
|
||||
\section{SICS on the WWW}
|
||||
\subsection{Client access}
|
||||
Following decisions made at a recent SICS user meeting, SICS clients are
|
||||
made avaialable on the WWW. Access is restricted to the PSI domain. A
|
||||
username and a password is needed in order to access the clients. This is
|
||||
currently set to: sinquser 98sinq2.
|
||||
The URL's for the clients are:
|
||||
\begin{description}
|
||||
\item[Command Line Client]http://lns00.psi.ch/sics/client/sicsclient.html
|
||||
\item[DMC Status]http://lns00.psi.ch/sics/client/powderstatus.html
|
||||
\item[TOPSI Status]http://lns00.psi.ch/sics/client/topsistatus.html
|
||||
\item[SANS Status]http://lns00.psi.ch/sics/client/sansstatus.html
|
||||
\end{description}
|
||||
|
||||
\subsection{Documentation}
|
||||
|
||||
All SICS User documentation is accessible at:\\
|
||||
http://lns00.psi.ch/sics/index.html \\
|
||||
Postscript versions of the SICS user
|
||||
documentation inhabit the doc directory of your instrument account.
|
||||
|
||||
The SICS manager documentation is also available on WWW. URL:\\
|
||||
http://lns00.psi.ch/sics/manager/manager.htm \\Access
|
||||
to this directory is
|
||||
restricted to the psi.ch domain. A username and password must be given in
|
||||
order to be given access to these pages. These values are currently set to:
|
||||
bigboss DJLmanager (can be remembered as: Daniel, Joachim, Lukas manager).
|
||||
|
||||
There is now a WWW document which informs about new SICS features, bug fixes
|
||||
etc. This is available at:\\
|
||||
http://lns00.psi.ch/sics/manager/sicsnews.htm \\
|
||||
The same access restrictions as given for the manager documentation above
|
||||
apply.
|
||||
|
||||
Installation instructions for SICS clients on PC's can be found at:\\
|
||||
http://lns00.psi.ch/sics/cliinst.htm\\
|
||||
Currently only real PC's are covered,
|
||||
but instructions for Mac's will follow some day or another. Any volunteers?
|
||||
|
||||
|
||||
\end{document}
|
86
doc/manager/mug.txt
Normal file
86
doc/manager/mug.txt
Normal file
@ -0,0 +1,86 @@
|
||||
SICS Invocation
|
||||
|
||||
SICS is a client server system. This means there are two programs. The first
|
||||
is a SICServer which does the actual instrument control work. A user rarely
|
||||
needs to bother about this server program as it is meant to run all the
|
||||
time. See instructions below if things go wrong. The user has only to deal
|
||||
with the SICS client programs. These implement the user interface to SICS.
|
||||
SICS Clients and the SICServer communicate with each other through TCP/IP
|
||||
sockets.
|
||||
|
||||
Currently four SICS clients are available:
|
||||
|
||||
* A command line control client which allows to control the measurement.
|
||||
* A status display for DMC.
|
||||
* A status display for TOPSI.
|
||||
* A status display for SANS.
|
||||
|
||||
These programs can be started on a DigitalUnix system by issuing the
|
||||
following commands at the command prompt:
|
||||
|
||||
sics &
|
||||
for the control client.
|
||||
powderstatus &
|
||||
for the DMC status display client.
|
||||
topsistatus &
|
||||
for the TOPSI status display.
|
||||
sansstatus &
|
||||
for the SANS status display.
|
||||
|
||||
On a PC you may find icons for starting the different prograsm on the
|
||||
desktop. Each of these clients has usage instructions online which can be
|
||||
displayed through the help/about menu entry.
|
||||
|
||||
Connecting and Logging in
|
||||
|
||||
After startup any SICS client is not connected to a SICS server and thus not
|
||||
active. A connection is established through the connect menu of the client.
|
||||
|
||||
SICS is a multi user instrument control system. In order to prevent
|
||||
malicious manipulations of the instrument SICS supports a hierarchy of user
|
||||
rights. In order to run an experiment you need at least user level
|
||||
privilege. In order to achieve this privilege you have to invoke the User
|
||||
Parameter/Set Rights dialog. There you have to enter the apropriate username
|
||||
and password kindly provided by your instrument scientist.
|
||||
|
||||
Restarting the Server
|
||||
|
||||
The SICS server should be running all the time. It is only down if something
|
||||
went wrong. You can check for the presence of the SICS server by loging in
|
||||
to the instrument computer and typing CheckSICS at the command prompt. The
|
||||
output will tell you what is happening. If you need to restart the SICS
|
||||
server log in as the instrument user at the instrument computer and invoke
|
||||
the apropriate command to start the server. These are:
|
||||
|
||||
DMC
|
||||
Computer = lnsa05,User = DMC, Command = DMCServer
|
||||
TOPSI
|
||||
Computer = lnsa03,User = TOPSI, Command = TOPSIServer
|
||||
SANS
|
||||
Computer = lnsa07,User = SANS, Command = SANSServer
|
||||
|
||||
If all this does not help look under trouble shooting SICS.
|
||||
SICS News Ticker
|
||||
|
||||
This page contains information about the latest bug fixes, releases and
|
||||
other miscellaneous information about SICS.
|
||||
|
||||
Juli 1998
|
||||
|
||||
Status OutOfMemory
|
||||
Bug in status display clients fixed which caused OutOfMemory after some
|
||||
time of automatic update.
|
||||
topsistatus
|
||||
TOPSI has got a java status client now as well. Can be invoked with
|
||||
topsistatus. On the WWW also.
|
||||
commandlog
|
||||
On popular demand the SICS server can now write a log file which logs
|
||||
all communication between clients with user or manager privilege and
|
||||
the SICserver. This log is off by default. There is a new SICS command
|
||||
commandlog which serves to configure this log.
|
||||
8-fold counterboxes.
|
||||
SICS now reads all eight monitors.
|
||||
sicsinstall
|
||||
There is now a shell script which automatizes updating and installing
|
||||
SICS. For more information see the setup section of the SICS managers
|
||||
guide.
|
60
doc/manager/option.htm
Normal file
60
doc/manager/option.htm
Normal file
@ -0,0 +1,60 @@
|
||||
<html>
|
||||
<head>
|
||||
<TITLE>Sics options</TITLE>
|
||||
</head>
|
||||
<body>
|
||||
<h2>SICS Options and Users</h2>
|
||||
<p>
|
||||
|
||||
The SICS server has an internal options database which holds such values
|
||||
as port number to listen too and the like. Additionally there exists a user
|
||||
database. Currently these values are configured from the initialisation
|
||||
file. The commands to do this are:<ul>
|
||||
<li> <b> ServerOption name value </b> defines the server option name to be
|
||||
value.
|
||||
<li> <b> SicsUser name password accesscode </b> defines a user with name
|
||||
and password and an access right accesscode. Accesscode is an integer from 1
|
||||
to 3 for User, Manager and Spy rights. A user with Spy right may look at
|
||||
everything but cannot change anything. A user with user privilege may change
|
||||
most of the SICS parameters, perform measurements etc. A user with manager
|
||||
privilege may do everything to the system.
|
||||
</ul>
|
||||
The Sics server currently uses the following options:<ul>
|
||||
<li> <b> ReadTimeOut </b> The server checks in each cycle of the main loop
|
||||
fro pending commands. Het waits for new commands for a specific period of
|
||||
time. This value is the ReadTimeOut. It should be as short as possible. This
|
||||
value may need to be increased if there are network performance problems. A
|
||||
good value is 100.
|
||||
|
||||
<li> <b> ReadUserPasswdTimeout </b> This is the time a client has to send a
|
||||
username password pair after a connection request. If nothing comes in in
|
||||
that time, the connection request is terminated.
|
||||
<li> <b>LogFileBaseName </b> defines the path and the base name for the
|
||||
server log file.
|
||||
<li> <b> ServerPort </b> defines the port number the server is listening
|
||||
to. Should be greater than 1024 and less than 64000. The port number should
|
||||
also be different from any other server port number in use on the system.
|
||||
Otherwise evil things may happen.
|
||||
<li> <b> InterruptPort </b> The SICS server can handle interrupts coming in
|
||||
as UDP messages on a special port. This option defines this UDP port
|
||||
number. The choice of possible port numbers is limited by the constraints
|
||||
given above in the ServerPort section. Espacillay this port number MUST be
|
||||
different from the ServerPort number. The UDP messages accepted are expected to consist of the string
|
||||
SICSINT followed by an interrupt number. For interrupt numbers see file
|
||||
interrupt.h.
|
||||
<li> <b> DefaultTclDirectory </b> specifies where Tcl defined commands are
|
||||
stored. When this is properly defined Tcl will autoload commands.
|
||||
<li> <b> StatusFile </b> defines the file to which he current state will be
|
||||
saved on close down of the server and restored from at startup time.
|
||||
<li><b>TelnetPort</b> The port number where the SICS server will be
|
||||
listening for telnet connections. If this option is missing login via telent
|
||||
to the SICS server is disabled.
|
||||
<li><b>TelWord</b> In order to login to SICS via telnet a magic word is
|
||||
needed. The login word, This option defines this word. If this option is
|
||||
missing telnet login to SICS is disabled.
|
||||
<li><b>LogFileDir</b> This server option defines the directory where
|
||||
commandlog log files are kept.
|
||||
</ul>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
103
doc/manager/serial.htm
Normal file
103
doc/manager/serial.htm
Normal file
@ -0,0 +1,103 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Accessing Macintosh Serial Ports</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Accessing Macintosh Serial Ports</H1>
|
||||
<P>
|
||||
Occasionally, it may be necessary to access the serial ports of the Macintosh PC
|
||||
directly in order to give commands to the motor controller, counter box or any
|
||||
device directly. Furthermore such a faclility is useful for coding
|
||||
environment device drivers in the SICS server macro language. The implementation
|
||||
of serial port access is highly SINQ specific and relies on the SINQ hardware
|
||||
concept. Besides, serial port access is realized in a different
|
||||
way then usual SICS objects. Usually SICS objects live in the SICS interpreter.
|
||||
Serial port access is implemented as an extension to the Tcl macro language.
|
||||
Essentially this is the same implementation as used in the psish.
|
||||
This section describes how to use serial port access. Several steps have to be performed:
|
||||
<ol>
|
||||
<li>Install the serialport command into the SICS server. This requires two lines to be added to
|
||||
the server startup script:
|
||||
<ul>
|
||||
<li>SerialInit
|
||||
<li>TclPublish serialport UserRights
|
||||
</ul>
|
||||
Where UserRights stands for one of the possible SICS user rights. See documentation
|
||||
for TclPublish above.
|
||||
<li> Each separate serial port will be represented by a name in the SICS server
|
||||
after it has been initialized. This name is also a command. These port names live
|
||||
in the Tcl interpreter and must be made accessible with TclPublish. For example for
|
||||
a port named p1 include this line in the server startup script:
|
||||
<ul>
|
||||
<li>TclPublish p1 User
|
||||
</ul>
|
||||
Replace User with the correct access code you want for a serial port. It is recommended
|
||||
to restrict serial port access to SICS managers only.
|
||||
<li> After starting the SICS server the command serialport is now available.
|
||||
<li> Now a serial port can be initialized with a command like this:
|
||||
<ul>
|
||||
<li>serialport name1 macintosh.name port channel force
|
||||
<li>Example: serialport p1 lnsp20.psi.ch 4000 5
|
||||
</ul>
|
||||
Such a command creates the command name1 and links it with serial port channel
|
||||
channel on the Macintosh-PC macintosh.name. Port is the port number on which the
|
||||
Macintosh serial port server is listening for connections (usually 4000).
|
||||
The last flag force is optional. If something is there, the connection to that
|
||||
port is done on a separate socket of its own. This has to do with some
|
||||
feature of the software interface to the Macintosh serial port server. This
|
||||
software interface tries to direct messages for multiple channels through one
|
||||
socket connection between the host and the Macintosh server. This is perfectly
|
||||
fine as long as none of the commands through this socket takes a long time
|
||||
to execute. However, if a RS-232 device takes a long time to respond, the whole
|
||||
socket is blocked. Fortunately, the Macintosh serial port server runs a separate
|
||||
thread of execution for each different socket. By forcing a new socket it can
|
||||
be achieved that such a slow device is decoupled from the rest. Exactly this
|
||||
is achieved with the force flag.
|
||||
|
||||
<li> Once the port has been initialised (for example p1) it is ready to operate.
|
||||
The port object allows to send data to the serial port and receive data from
|
||||
it. Furthermore some configuration is possible. The syntax is like this:
|
||||
<DL>
|
||||
<DT>portname -tmo number
|
||||
<DD>Sets the timeout for the serial port. This is the maximum amount of time
|
||||
the Macintosh serial port server waits for data to arrive from the RS-232 device.
|
||||
Increase this if a lot of <code>_BAD_TMO</code> error messages creep up.
|
||||
<DT>portname -sendterm string
|
||||
<DD> Sets the terminator which will be automatically added to the string which is
|
||||
sent. Some RS-232 devices require special terminators in order to accept a command.
|
||||
The serial port implementation ensures that such a terminator is sent after
|
||||
each message. This command allows to configure this terminator. Please note,
|
||||
that the terminator string needs to be enclosed in quotes. An example:
|
||||
<ul>
|
||||
<li><code>p1 -sendterm "\r\n"</code>
|
||||
</ul>
|
||||
This sets the terminator to carriage return - line feed.
|
||||
<DT>portname -replyterm string.
|
||||
<DD>The Macintosh terminal server expects the RS-232 device to send a terminator
|
||||
when it is done with sending answers. It even supports multiple lines to be
|
||||
sent as a reply. This expected reply terminator is set with this command.
|
||||
The string may may be four characters long. An example: <code>1\r\n</code> sets
|
||||
the expected terminator to one of <code>\r\n</code>. One of them is expected. Thus the
|
||||
first character is the count of terminators to expect, followed by the characters
|
||||
possible as terminators. This string must usually be quoted.
|
||||
<DT>portname blablalakjdl
|
||||
<DD>When none of the options -tmo, -replyterm, -sendterm, is found everything after
|
||||
portname is sent to the RS-232 device. The reply from the RS-232 device is printed.
|
||||
</DL>
|
||||
</ol>
|
||||
The defaults set for the configuration parameters of the serial port connection
|
||||
are suited for the EL734, EL737 and ITC4 devices usually encountered at SINQ. For
|
||||
other RS-232 devices consult the manuals hopefully delivered with the device.
|
||||
The defaults are: 100 for timeout, <code>1\r\n</code> for the reply terminator and
|
||||
<code>\r\n</code>for the send terminator.
|
||||
</p>
|
||||
<p>
|
||||
Please note, that the SICS server serial port access is a convenience feature for
|
||||
SICS managers and instrument scientists. It is needed for implementing
|
||||
environment device drivers in the Tcl macro language. If serial port connections must be
|
||||
debugged the Macintosh versaterm software or on a IBM-PC the kermit program
|
||||
are much better suited to the task.
|
||||
</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
89
doc/manager/setup.htm
Normal file
89
doc/manager/setup.htm
Normal file
@ -0,0 +1,89 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>General SICS Setup</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>General SICS Setup</H1>
|
||||
<P>
|
||||
SICS is a client server system. This implies that there is a server program
|
||||
which implements all the functionlity and client programs which implement
|
||||
the user interface. The client program is the only thing the user is
|
||||
intended to see. This also means that the location of the client programs is
|
||||
quite independent from the computer where the server runs. In the following
|
||||
the layout of a server installation is described as established at SINQ.
|
||||
</P>
|
||||
<p>
|
||||
For each instrument there is a data aquisition computer. On this computer
|
||||
there exists a user name and consequently a home directory for the
|
||||
instrument. In the following text this instrument root directory will be called
|
||||
sicsroot. This root directory has the following subdirectories:
|
||||
<DL>
|
||||
<DT>bin
|
||||
<DD> The bin directory is the place where the actual executable for the SICS
|
||||
server is kept along with local copies of all necessary clients, the server
|
||||
initialisation files and special macro files defined for the instrument.
|
||||
<DT>data
|
||||
<DD>The data directory is the central place where all data files collected
|
||||
at the instrument are stored. Additionally this directory holds a file named
|
||||
DataNumber which keeps the current serial number of the data files. This
|
||||
file should never be edited. However, on the first of january an instrument
|
||||
manager should reset the serial number in this file to 0.
|
||||
<DT>log
|
||||
<DD> The log directory contains the server log files and the automatically
|
||||
generated client log files. Any now and then, and especially when disk space
|
||||
problems loom, the client*.log files should be deleted by the instrument
|
||||
manager.
|
||||
<DT> doc
|
||||
<DD> This directory holds a copy of the SICS user documentation for the
|
||||
instrument. These are html files which can be viewed with WWW-browsers such
|
||||
as lynx or netscape.
|
||||
<DT> sim
|
||||
<DD> The sim directory is meant to hold all files necessary for a SICServer
|
||||
initialised for the instrument but configured with simulated hardware. This
|
||||
facility is meant for testing of command files.
|
||||
</DL>
|
||||
Besides these directories there should be nothing on the instrument account.
|
||||
All evaluated data, personal command files etc. should be held on the normal
|
||||
user account of the instrument user.
|
||||
</p>
|
||||
<p>
|
||||
For this purpose the /data/lnslib/bin directory holds copies of the
|
||||
apropriate command line and status display clients for each instrument. A user can make
|
||||
this directory (and much more) available by including the line <b>
|
||||
source /data/lnslib/bin/lns.login</b> into her .login file.
|
||||
</p>
|
||||
<h2> SICS Installation</h2>
|
||||
<p>
|
||||
All executables and files necessary to run SICS for each instrument is
|
||||
avaialable under the /data/lnslib/src/sics hierarchy. The bin directory
|
||||
holds general executable files and a directory for each instrument which
|
||||
holds instrument specific files. SICS installation on a unix system is
|
||||
greatly simplified by using the <b>sicsinstall</b> korn shell script. This
|
||||
script is available to each user. sicsinstall can be invoked simply by
|
||||
typing sicsinstall at the command prompt. sicsinstall needs a subcommand in
|
||||
order to know what it is expected to do:
|
||||
<dl>
|
||||
<DT>dev
|
||||
<DD>copies knew executables from the development area to the distribution
|
||||
directory. This command is meant to be used by computing staff only.
|
||||
<DT>devfull
|
||||
<DD>as dev, but copies all files. This command is meant to be used by computing staff only.
|
||||
<DT>dmc
|
||||
<DD>copies all files necessary for the instrument DMC.
|
||||
<DT>topsi
|
||||
<DD>copies all files necessary for the instrument TOPSI.
|
||||
<DT>sans
|
||||
<DD>copies all files necessary for the instrument SANS.
|
||||
<DT>doc
|
||||
<DD>updates only the documentation on your disk.
|
||||
<DT>exe
|
||||
<DD>copies only new executable files from the distribution area. This is the
|
||||
recommended option when you want to be sure, that you have the latest
|
||||
version of SICS before reporting a bug.
|
||||
</dl>
|
||||
Most of these options require you to be in the home directory of the
|
||||
instrument account. sicsinstall checks for this and warns you if this is not
|
||||
the case. Directory structures are checked for and created as needed.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
221
doc/manager/sicsinstall
Executable file
221
doc/manager/sicsinstall
Executable file
@ -0,0 +1,221 @@
|
||||
#!/usr/bin/ksh
|
||||
#----------------------------------------------------------------------------
|
||||
# script for installing SICS software on to a system.
|
||||
# The source of the data muste be visible to the filesystem.
|
||||
# This script installs SW into directories beyond your current directory
|
||||
# So, on an instrument account it would be feasible to run this from the
|
||||
# home directory. The script checks if we are at home, else it will print
|
||||
# a warning.
|
||||
#
|
||||
# this script understands a few arguments:
|
||||
#
|
||||
# dev - copies new executables from development area to
|
||||
# distribution area
|
||||
# devfull - copies all files from development area to
|
||||
# distribution area
|
||||
# dmc - installs all files for running dmc
|
||||
# topsi - install all files for topsi
|
||||
# sans - installs all files for sans
|
||||
# doc - updates only the documentation
|
||||
# exe - installs only new executables
|
||||
# debug - copies only the server to current directory
|
||||
# lib - copies clients from the distribution area to
|
||||
# the common program library.
|
||||
#
|
||||
# Mark Koennecke, Juli 1998
|
||||
#----------------------------------------------------------------------------
|
||||
#=========================== data area ====================================
|
||||
devdir=/data/koenneck/src/sics # development directory
|
||||
|
||||
disdir=/data/lnslib/src/sics # distribution directory
|
||||
|
||||
dirdir="bin data doc log" # SICS directories
|
||||
|
||||
bindir=/data/lnslib/bin # common directory for binaries
|
||||
|
||||
clients="sicsclient.jar powderstatus.jar sansstatus.jar topsistatus.jar"
|
||||
#======================= Functions ========================================
|
||||
#------------------ check if in home directory
|
||||
checkhome() {
|
||||
if [ $HOME != $(pwd) ]; then
|
||||
echo "You are not in your home directory."
|
||||
echo "This may cause a non standard SICS installation"
|
||||
echo "Do you want me to continue(Y,y) or abort(any other character)"
|
||||
read answer
|
||||
if [ \( $answer = Y \) -o \( $answer = y \) ]; then
|
||||
echo "OK, I start clobbering......"
|
||||
else
|
||||
echo "Script aborting........."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#------------------- print usage
|
||||
usage() {
|
||||
echo "USAGE:"
|
||||
echo "This script copies SICS software. You need to tell this program"
|
||||
echo "what to do by specifying one of the keywords below:"
|
||||
echo ""
|
||||
echo "dev - copies new executables from development area to"
|
||||
echo " distribution area (MK only)"
|
||||
echo "devfull - copies all files from development area to"
|
||||
echo " distribution area (MK only)"
|
||||
echo "dmc - installs all files for running dmc"
|
||||
echo "topsi - install all files for topsi"
|
||||
echo "sans - installs all files for sans "
|
||||
echo "doc - updates only the documentation"
|
||||
echo "exe - installs only new executables"
|
||||
echo "lib - copies new clients to common program area"
|
||||
echo ""
|
||||
echo "Mark Koennecke, LNS, Juli 1998"
|
||||
}
|
||||
#------------------ copy new executables
|
||||
copydev () {
|
||||
echo "Copying new executable files from development area to distribution.."
|
||||
cp $devdir/SICServer $devdir/psish/psish $devdir/psish/pish $disdir/bin
|
||||
for cl in $clients; do
|
||||
cp $devdir/SicsClient/$cl $disdir/bin
|
||||
done
|
||||
cp $devdir/replicator/replicator.jar $disdir/bin
|
||||
}
|
||||
#------------------ copy to common program area
|
||||
copylib() {
|
||||
echo "Copying new client files to common LNS program area"
|
||||
cp $disdir/bin/*.jar $bindir
|
||||
}
|
||||
#------------------ copy all new stuff
|
||||
copydevfull () {
|
||||
echo "Copying ALL files from development area to distribution.."
|
||||
copydev
|
||||
echo "Copying documentation"
|
||||
cp $devdir/user/*.htm $disdir/doc
|
||||
cp $devdir/user/*.html $disdir/doc
|
||||
cp $devdir/user/*.ps $disdir/doc
|
||||
cp $devdir/manager/*.htm $disdir/manager
|
||||
}
|
||||
#------------------ copy only new executables
|
||||
copyexe () {
|
||||
echo "Copying new executable files"
|
||||
cp $disdir/bin/SICServer $disdir/bin/psish $disdir/bin/pish bin
|
||||
for cl in $clients; do
|
||||
cp $disdir/bin/$cl bin
|
||||
done
|
||||
cp $disdir/bin/sics bin
|
||||
cp $disdir/bin/powderstatus bin
|
||||
cp $disdir/bin/sansstatus bin
|
||||
cp $disdir/bin/topsistatus bin
|
||||
cp $disdir/bin/replicator.jar
|
||||
}
|
||||
#----------------- copy documentation
|
||||
copydoc () {
|
||||
echo "Copying documentation"
|
||||
cp $disdir/doc/*.htm doc
|
||||
cp $disdir/doc/*.html doc
|
||||
cp $disdir/doc/*.ps doc
|
||||
}
|
||||
#----------------- DMC special files
|
||||
copydmc () {
|
||||
echo "Copying DMC special files"
|
||||
cp $disdir/bin/count.tcl $disdir/bin/init.tcl \
|
||||
$disdir/bin/log.tcl $disdir/bin/xydialog.tcl $disdir/bin/CheckSICS bin
|
||||
cp $disdir/bin/dmc/* bin
|
||||
if [ -e data/DataNumber ]; then
|
||||
echo "DataNumber found, OK"
|
||||
else
|
||||
echo "WARNING: Creating new DataNumber file with 0, adjust as needed"
|
||||
echo " 0" > data/DataNumber
|
||||
fi
|
||||
echo "Done, configuration files may need editing"
|
||||
}
|
||||
#----------------- TOPSI special files
|
||||
copytopsi () {
|
||||
echo "Copying TOPSI special files"
|
||||
cp $disdir/bin/count.tcl $disdir/bin/init.tcl \
|
||||
$disdir/bin/log.tcl $disdir/bin/CheckSICS bin
|
||||
cp $disdir/bin/topsi/* bin
|
||||
if [ -e data/DataNumber ]; then
|
||||
echo "DataNumber found, OK"
|
||||
else
|
||||
echo "WARNING: Creating new DataNumber file with 0, adjust as needed"
|
||||
echo " 0" > data/DataNumber
|
||||
fi
|
||||
echo "Done, configuration files may need editing"
|
||||
}
|
||||
#----------------- SANS special files
|
||||
copysans() {
|
||||
echo "Copying SANS special files"
|
||||
cp $disdir/bin/count.tcl $disdir/bin/init.tcl \
|
||||
$disdir/bin/log.tcl $disdir/bin/CheckSICS bin
|
||||
cp $disdir/bin/sans/* bin
|
||||
if [ -e data/DataNumber ]; then
|
||||
echo "DataNumber found, OK"
|
||||
else
|
||||
echo "WARNING: Creating new DataNumber file with 0, adjust as needed"
|
||||
echo " 0" > data/DataNumber
|
||||
fi
|
||||
echo "Done, configuration files may need editing"
|
||||
}
|
||||
|
||||
#------------------ check SICS directories
|
||||
checkdir() {
|
||||
echo "Checking directory structure, creating as needed"
|
||||
for dd in $dirdir; do
|
||||
if [ -d $dd ]; then
|
||||
echo "$dd present"
|
||||
else
|
||||
echo "Creating $dd"
|
||||
mkdir $dd
|
||||
fi
|
||||
done
|
||||
}
|
||||
#-------------- the case for checking the command parameter
|
||||
case ${1-nix} in
|
||||
dev)
|
||||
copydev
|
||||
;;
|
||||
devfull)
|
||||
copydevfull
|
||||
;;
|
||||
exe)
|
||||
checkhome
|
||||
checkdir
|
||||
copyexe
|
||||
;;
|
||||
doc)
|
||||
checkhome
|
||||
checkdir
|
||||
copydoc
|
||||
;;
|
||||
dmc)
|
||||
checkhome
|
||||
checkdir
|
||||
copyexe
|
||||
copydoc
|
||||
copydmc
|
||||
;;
|
||||
topsi)
|
||||
checkhome
|
||||
checkdir
|
||||
copyexe
|
||||
copydoc
|
||||
copytopsi
|
||||
;;
|
||||
sans)
|
||||
checkhome
|
||||
checkdir
|
||||
copyexe
|
||||
copydoc
|
||||
copysans
|
||||
;;
|
||||
lib)
|
||||
copylib
|
||||
;;
|
||||
debug)
|
||||
cp $devdir/SICServer .
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
echo "sicsinstall finished with more or less success"
|
33
doc/manager/sicsnews.htm
Normal file
33
doc/manager/sicsnews.htm
Normal file
@ -0,0 +1,33 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>SICS News Ticker</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>SICS News Ticker</H1>
|
||||
<P>
|
||||
This page contains information about the latest bug fixes, releases and other
|
||||
miscellaneous information about SICS.
|
||||
</P>
|
||||
<p>
|
||||
<h2>Juli 1998</h2>
|
||||
<DL>
|
||||
<DT>Status OutOfMemory
|
||||
<DD>Bug in status display clients fixed which caused OutOfMemory after
|
||||
some time of automatic update.
|
||||
<DT>topsistatus
|
||||
<DD>TOPSI has got a java status client now as well. Can be invoked with
|
||||
<b>topsistatus</b>. On the WWW also.
|
||||
<DT>commandlog
|
||||
<DD>On popular demand the SICS server can now write a log file which logs all
|
||||
communication between clients with user or manager privilege and the SICserver.
|
||||
This log is off by default. There is a new SICS command <a href="../commandlog.htm">
|
||||
commandlog</a> which serves to configure this log.
|
||||
<DT>8-fold counterboxes.
|
||||
<DD>SICS now reads all eight monitors.
|
||||
<DT>sicsinstall
|
||||
<DD>There is now a shell script which automatizes updating and installing SICS. For more
|
||||
information see the <a href="setup.htm">setup section</a> of the SICS managers guide.
|
||||
</DL>
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
264
doc/manager/sicsstat.tcl
Normal file
264
doc/manager/sicsstat.tcl
Normal file
@ -0,0 +1,264 @@
|
||||
# Motor phi
|
||||
phi SoftLowerLim 0.000000
|
||||
phi SoftUpperLim 360.000000
|
||||
phi SoftZero 0.000000
|
||||
phi Fixed -1.000000
|
||||
phi InterruptMode 0.000000
|
||||
phi AccessCode 2.000000
|
||||
# Motor chi
|
||||
chi SoftLowerLim 0.000000
|
||||
chi SoftUpperLim 360.000000
|
||||
chi SoftZero 0.000000
|
||||
chi Fixed -1.000000
|
||||
chi InterruptMode 0.000000
|
||||
chi AccessCode 2.000000
|
||||
# Motor omega
|
||||
omega SoftLowerLim -180.000000
|
||||
omega SoftUpperLim 360.000000
|
||||
omega SoftZero 0.000000
|
||||
omega Fixed -1.000000
|
||||
omega InterruptMode 0.000000
|
||||
omega AccessCode 2.000000
|
||||
# Motor twotheta
|
||||
twotheta SoftLowerLim 5.000000
|
||||
twotheta SoftUpperLim 120.000000
|
||||
twotheta SoftZero 0.000000
|
||||
twotheta Fixed -1.000000
|
||||
twotheta InterruptMode 0.000000
|
||||
twotheta AccessCode 2.000000
|
||||
banana CountMode timer
|
||||
banana preset 100.000000
|
||||
sample_mur (null)
|
||||
sample_mur setAccess 2
|
||||
email UNKNOWN
|
||||
email setAccess 2
|
||||
fax UNKNOWN
|
||||
fax setAccess 2
|
||||
phone UNKNOWN
|
||||
phone setAccess 2
|
||||
adress UNKNOWN
|
||||
adress setAccess 2
|
||||
# Counter counter
|
||||
counter SetPreset 1000.000000
|
||||
counter SetMode Timer
|
||||
# Motor som
|
||||
som SoftLowerLim 0.000000
|
||||
som SoftUpperLim 360.000000
|
||||
som SoftZero 0.000000
|
||||
som Fixed -1.000000
|
||||
som InterruptMode 0.000000
|
||||
som AccessCode 2.000000
|
||||
# Motor sax
|
||||
sax SoftLowerLim -30.000000
|
||||
sax SoftUpperLim 30.000000
|
||||
sax SoftZero 0.000000
|
||||
sax Fixed -1.000000
|
||||
sax InterruptMode 0.000000
|
||||
sax AccessCode 2.000000
|
||||
# Motor tilt
|
||||
tilt SoftLowerLim -15.000000
|
||||
tilt SoftUpperLim 15.000000
|
||||
tilt SoftZero 0.000000
|
||||
tilt Fixed -1.000000
|
||||
tilt InterruptMode 0.000000
|
||||
tilt AccessCode 0.000000
|
||||
# Motor detectorrotation
|
||||
detectorrotation SoftLowerLim -20.000000
|
||||
detectorrotation SoftUpperLim 20.000000
|
||||
detectorrotation SoftZero 0.000000
|
||||
detectorrotation Fixed -1.000000
|
||||
detectorrotation InterruptMode 0.000000
|
||||
detectorrotation AccessCode 2.000000
|
||||
# Motor detectory
|
||||
detectory SoftLowerLim -20.000000
|
||||
detectory SoftUpperLim 20.000000
|
||||
detectory SoftZero 0.000000
|
||||
detectory Fixed -1.000000
|
||||
detectory InterruptMode 0.000000
|
||||
detectory AccessCode 2.000000
|
||||
# Motor detectorx
|
||||
detectorx SoftLowerLim -20.000000
|
||||
detectorx SoftUpperLim 20.000000
|
||||
detectorx SoftZero 0.000000
|
||||
detectorx Fixed -1.000000
|
||||
detectorx InterruptMode 0.000000
|
||||
detectorx AccessCode 2.000000
|
||||
# Motor beamstopy
|
||||
beamstopy SoftLowerLim -20.000000
|
||||
beamstopy SoftUpperLim 20.000000
|
||||
beamstopy SoftZero 0.000000
|
||||
beamstopy Fixed -1.000000
|
||||
beamstopy InterruptMode 0.000000
|
||||
beamstopy AccessCode 2.000000
|
||||
# Motor beamstopx
|
||||
beamstopx SoftLowerLim -20.000000
|
||||
beamstopx SoftUpperLim 20.000000
|
||||
beamstopx SoftZero 0.000000
|
||||
beamstopx Fixed -1.000000
|
||||
beamstopx InterruptMode 0.000000
|
||||
beamstopx AccessCode 2.000000
|
||||
# Motor d2t
|
||||
d2t SoftLowerLim -20.000000
|
||||
d2t SoftUpperLim 20.000000
|
||||
d2t SoftZero 0.000000
|
||||
d2t Fixed -1.000000
|
||||
d2t InterruptMode 0.000000
|
||||
d2t AccessCode 2.000000
|
||||
# Motor d2l
|
||||
d2l SoftLowerLim -20.000000
|
||||
d2l SoftUpperLim 20.000000
|
||||
d2l SoftZero 0.000000
|
||||
d2l Fixed -1.000000
|
||||
d2l InterruptMode 0.000000
|
||||
d2l AccessCode 2.000000
|
||||
# Motor d2r
|
||||
d2r SoftLowerLim -20.000000
|
||||
d2r SoftUpperLim 20.000000
|
||||
d2r SoftZero 0.000000
|
||||
d2r Fixed -1.000000
|
||||
d2r InterruptMode 0.000000
|
||||
d2r AccessCode 2.000000
|
||||
# Motor d1t
|
||||
d1t SoftLowerLim -20.000000
|
||||
d1t SoftUpperLim 20.000000
|
||||
d1t SoftZero 0.000000
|
||||
d1t Fixed -1.000000
|
||||
d1t InterruptMode 0.000000
|
||||
d1t AccessCode 2.000000
|
||||
# Motor d1l
|
||||
d1l SoftLowerLim -20.000000
|
||||
d1l SoftUpperLim 20.000000
|
||||
d1l SoftZero 0.000000
|
||||
d1l Fixed -1.000000
|
||||
d1l InterruptMode 0.000000
|
||||
d1l AccessCode 2.000000
|
||||
# Motor d1r
|
||||
d1r SoftLowerLim -20.000000
|
||||
d1r SoftUpperLim 20.000000
|
||||
d1r SoftZero 0.000000
|
||||
d1r Fixed -1.000000
|
||||
d1r InterruptMode 0.000000
|
||||
d1r AccessCode 2.000000
|
||||
# Motor tasse
|
||||
tasse SoftLowerLim -130.000000
|
||||
tasse SoftUpperLim 130.000000
|
||||
tasse SoftZero 0.000000
|
||||
tasse Fixed -1.000000
|
||||
tasse InterruptMode 0.000000
|
||||
tasse AccessCode 2.000000
|
||||
# Motor sdm
|
||||
sdm SoftLowerLim -5.000000
|
||||
sdm SoftUpperLim 5.000000
|
||||
sdm SoftZero 0.000000
|
||||
sdm Fixed -1.000000
|
||||
sdm InterruptMode 0.000000
|
||||
sdm AccessCode 2.000000
|
||||
# Motor sgu
|
||||
sgu SoftLowerLim -20.000000
|
||||
sgu SoftUpperLim 20.000000
|
||||
sgu SoftZero 0.000000
|
||||
sgu Fixed -1.000000
|
||||
sgu InterruptMode 0.000000
|
||||
sgu AccessCode 2.000000
|
||||
# Motor sgl
|
||||
sgl SoftLowerLim -20.000000
|
||||
sgl SoftUpperLim 20.000000
|
||||
sgl SoftZero 0.000000
|
||||
sgl Fixed -1.000000
|
||||
sgl InterruptMode 0.000000
|
||||
sgl AccessCode 2.000000
|
||||
# Motor mgu
|
||||
mgu SoftLowerLim -50.000000
|
||||
mgu SoftUpperLim 50.000000
|
||||
mgu SoftZero 0.000000
|
||||
mgu Fixed -1.000000
|
||||
mgu InterruptMode 0.000000
|
||||
mgu AccessCode 2.000000
|
||||
# Motor stu
|
||||
stu SoftLowerLim -30.000000
|
||||
stu SoftUpperLim 30.000000
|
||||
stu SoftZero 0.000000
|
||||
stu Fixed -1.000000
|
||||
stu InterruptMode 0.000000
|
||||
stu AccessCode 2.000000
|
||||
# Motor stl
|
||||
stl SoftLowerLim -30.000000
|
||||
stl SoftUpperLim 30.000000
|
||||
stl SoftZero 0.000000
|
||||
stl Fixed -1.000000
|
||||
stl InterruptMode 0.000000
|
||||
stl AccessCode 2.000000
|
||||
# Motor mtu
|
||||
mtu SoftLowerLim -30.000000
|
||||
mtu SoftUpperLim 30.000000
|
||||
mtu SoftZero 0.000000
|
||||
mtu Fixed -1.000000
|
||||
mtu InterruptMode 0.000000
|
||||
mtu AccessCode 2.000000
|
||||
# Motor mtl
|
||||
mtl SoftLowerLim -30.000000
|
||||
mtl SoftUpperLim 30.000000
|
||||
mtl SoftZero 0.000000
|
||||
mtl Fixed -1.000000
|
||||
mtl InterruptMode 0.000000
|
||||
mtl AccessCode 2.000000
|
||||
# Motor a6
|
||||
a6 SoftLowerLim -30.000000
|
||||
a6 SoftUpperLim 30.000000
|
||||
a6 SoftZero 0.000000
|
||||
a6 Fixed -1.000000
|
||||
a6 InterruptMode 0.000000
|
||||
a6 AccessCode 2.000000
|
||||
# Motor a5
|
||||
a5 SoftLowerLim -30.000000
|
||||
a5 SoftUpperLim 30.000000
|
||||
a5 SoftZero 0.000000
|
||||
a5 Fixed -1.000000
|
||||
a5 InterruptMode 0.000000
|
||||
a5 AccessCode 2.000000
|
||||
# Motor a4
|
||||
a4 SoftLowerLim -130.000000
|
||||
a4 SoftUpperLim 130.000000
|
||||
a4 SoftZero 0.000000
|
||||
a4 Fixed -1.000000
|
||||
a4 InterruptMode 0.000000
|
||||
a4 AccessCode 2.000000
|
||||
# Motor a3
|
||||
a3 SoftLowerLim 0.000000
|
||||
a3 SoftUpperLim 360.000000
|
||||
a3 SoftZero 0.000000
|
||||
a3 Fixed -1.000000
|
||||
a3 InterruptMode 0.000000
|
||||
a3 AccessCode 2.000000
|
||||
# Motor a2
|
||||
a2 SoftLowerLim 30.000000
|
||||
a2 SoftUpperLim 120.000000
|
||||
a2 SoftZero 0.000000
|
||||
a2 Fixed -1.000000
|
||||
a2 InterruptMode 0.000000
|
||||
a2 AccessCode 2.000000
|
||||
# Motor a1
|
||||
a1 SoftLowerLim 30.000000
|
||||
a1 SoftUpperLim 120.000000
|
||||
a1 SoftZero 0.000000
|
||||
a1 Fixed -1.000000
|
||||
a1 InterruptMode 0.000000
|
||||
a1 AccessCode 2.000000
|
||||
user Daniel_the_Clementine
|
||||
user setAccess 2
|
||||
temperature ine
|
||||
|
||||
|
||||
|
||||
|
||||
0
|
||||
|
||||
00
|
||||
00
|
||||
|
||||
<EFBFBD>
|
||||
temperature setAccess 2
|
||||
sample DanielOxid
|
||||
sample setAccess 2
|
||||
title TopsiTupsiTapsi
|
||||
title setAccess 2
|
21
doc/manager/special.htm
Normal file
21
doc/manager/special.htm
Normal file
@ -0,0 +1,21 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Special Commands for SICS Administrators and Programmers</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Special Commands for SICS Administrators and Programmers</H1>
|
||||
<P>
|
||||
This section describes a few commands which need not be known to SICS users.
|
||||
<!latex-off>
|
||||
<UL>
|
||||
<li> Access Macintosh <a href="serial.htm"> serial </a>ports.
|
||||
<li> An internal <a href=iscan.htm> scan command</a>.
|
||||
<li> Accessing Siematic <a href="sps.htm">SPS</a> controllers.
|
||||
<li> <a href="alias.htm">Aliases</a>.
|
||||
<li> <a href="cron.htm">Reoccuring tasks</a>.
|
||||
</uL>
|
||||
<!latex-on>
|
||||
</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
58
doc/manager/sps.htm
Normal file
58
doc/manager/sps.htm
Normal file
@ -0,0 +1,58 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Siematic SPS Controllers</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Siematic SPS Controllers</H1>
|
||||
<P>
|
||||
Siematic SPS controllers are used at SinQ for handling all the things which
|
||||
fit in nowhere else. Such as operating air cushions on some instruments,
|
||||
reading variables from ADC's, reading status of shutters or other parts of
|
||||
the instrument and the like. Those SPS units have an RS-232 connector and
|
||||
understand a simple ASCII command protocoll.
|
||||
The Siematic SPS and its command protocoll are
|
||||
special to PSI and this section is probably of no interest to SICS managers
|
||||
outside. The SPS basiaclly support three operations:
|
||||
<ul>
|
||||
<li>Push a button.
|
||||
<li>Request status of instrument status packed into a bit.
|
||||
<li>Read an ADC.
|
||||
</ul>
|
||||
This is so user unfriendly that the usage of the SPS will mostly be packaged
|
||||
into Tcl-macros.
|
||||
</P>
|
||||
<p>
|
||||
A SPS unit can be configured into the SICS server with the command:<br>
|
||||
<b>MakeSPS name macintosh port channel</b> <br>
|
||||
The parameters are: the name of the SPS in SICS, the serial port server
|
||||
computer, the port where the serial port server is listening and the
|
||||
channel number of the SPS unit at the serial port server computer. An
|
||||
example: <br>
|
||||
MakeSPS sps1 lnsp25.psi.ch 4000 6 <br>
|
||||
configures a SPS unit at lnsp25.psi.ch at channel 5. The serial port server
|
||||
is listening at port number 4000. The SPS unit will be accessible as sps1 in
|
||||
SICS.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
After configuartion the following four commands are understood by name,
|
||||
shown with sps1 as example:
|
||||
<DL>
|
||||
<DT>sps1 push byte bit
|
||||
<DD>Corresponds to pushing the button mapped to the bit bit in the byte
|
||||
byte.
|
||||
<DT>sps1 adc num
|
||||
<DD> Reads the value in the ADC num. num can be between 0 to 7 for a maximum
|
||||
of eight ADC's. Please note, that the values read are raw values which
|
||||
usually must be converted in some way to physically meaningful values.
|
||||
<DT>sps1 status bit
|
||||
<DD>Reads the status of the bit bit. bit can be in the range 0 - 128.
|
||||
<DT>sps1 stat2 byte bit
|
||||
<DD>Reads the status bit bit in status byte byte. Is equivalent to status,
|
||||
but adds some syntatctic sugar.
|
||||
</DL>
|
||||
For all conversion factors, for all mappings of bytes and bits, consult the
|
||||
electronician who coded the SPS.
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
36
doc/manager/startsics
Executable file
36
doc/manager/startsics
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/ksh
|
||||
#-------------------------------------------------------------------------
|
||||
# shell sript to start the servers necessary for running SICS.
|
||||
# checks if they are not already running.
|
||||
#
|
||||
# Mark Koennecke, Juli 1998
|
||||
#------------------------------------------------------------------------
|
||||
inst=test
|
||||
shome=$HOME/src/sics
|
||||
# start SICServer
|
||||
ps waux > /tmp/ps.lis
|
||||
grep SICServer /tmp/ps.lis > /dev/null
|
||||
if [ $? -eq 1 ] ; then
|
||||
echo "Starting SICServer"
|
||||
cd $shome
|
||||
com="SICServer $inst.tcl"
|
||||
keepalive "$com" &
|
||||
else
|
||||
echo "SICServer exists"
|
||||
fi
|
||||
rm /tmp/ps.lis
|
||||
|
||||
# start replicator service
|
||||
ps waux > /tmp/ps.lis
|
||||
grep replicator.jar /tmp/ps.lis > /dev/null
|
||||
if [ $? -eq 1 ] ; then
|
||||
echo "Starting Data Replicator"
|
||||
cd $shome
|
||||
com1="jre -classpath /usr/lib/classes.zip:$shome/replicator.jar Replicator "
|
||||
com2=$sheim/replicator.conf
|
||||
com=$com1$com2
|
||||
keepalive "$com" &
|
||||
else
|
||||
echo "Data Replicator exists"
|
||||
fi
|
||||
rm /tmp/ps.lis
|
63
doc/manager/status.htm
Normal file
63
doc/manager/status.htm
Normal file
@ -0,0 +1,63 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Commands supporting SICS status displays</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>Commands For Supporting SICS Status Displays</H1>
|
||||
<P>
|
||||
The implementation of many status displays is greatly simplified by
|
||||
letting the SICS server do some of the hard work. The operation of
|
||||
these commands is usually invisible to users. Some even do not
|
||||
generate output accessible to the user because they send uuencoded
|
||||
information. This section documents these commands for completeness
|
||||
and as a reference for status display client writers.
|
||||
</P>
|
||||
<h2>The Reflectometer AMOR</h2>
|
||||
<p>
|
||||
The reflectometer AMOR probably has the most extensive of such
|
||||
modules. It does a lot of things. It is configured into SICS with the
|
||||
MakeAmorStatus command. Let us assume that it is configured into the
|
||||
system as amorstatus. This object supports the following commands:
|
||||
<dl>
|
||||
<dt>amorstatus interest
|
||||
<dd>This registers this connection for receiving automatic
|
||||
notifications. Automatic notifications send are:
|
||||
<DL>
|
||||
<dt>SCANSTART
|
||||
<dd> At scan start a message <b>ScanClear</b> is sent followed by the
|
||||
uuencoded new x-axis for the plot.
|
||||
<dt>SCANPOINT
|
||||
<dd>At each scan point the arrays of counts in both detector are sent
|
||||
in uuencoded form labelled arrow_spinupup and arrow_spinuplo.
|
||||
<DT>COUNTSTART
|
||||
<DD>The start of counting on the histogram memory. Send a message
|
||||
<b>TOFClear</b> and then the uuencoded time binning labelled
|
||||
arrow_time.
|
||||
<DT>FILELOADED
|
||||
<DD>activated each time user defined model data is loaded into the
|
||||
SICS server. This data gets send as arrow_name in uuencoded form. Both
|
||||
x- and y-axis are sent in floating point.
|
||||
</DL>
|
||||
Please note that floating point data is transformed to fixed point by
|
||||
multiplication of 65653 before transfer. The first number in each
|
||||
uuencoded message is an integer describing the length of the data. In
|
||||
case of double data such as fileloaded the y-data follows immediatetly
|
||||
after the x-data. Also the approriate data is automatically sent after
|
||||
the interest command.
|
||||
<dt>amorstatus collapse
|
||||
<dd>sums all counts in all detectors in time and sends the data back
|
||||
as an uuencoded image. The first two numbers in the message define the
|
||||
dimensions of the data.
|
||||
<dt>amorstatus sample name x1 x2 y1 y2
|
||||
<dd>Sums the detector counts on an area defined by the rectangle x1,
|
||||
x2, y1, y2. The length of this is the time binning. The data is sent
|
||||
back in uuencoded form labelled arrow_name.
|
||||
<dt>amorstatus clear
|
||||
<dd> Clears all user loaded data.
|
||||
<dt>amorstatus load filename scale
|
||||
<dd> loads user defined data for distribution to the status display
|
||||
clients. The y data is scaled according to the scale factor provided.
|
||||
</dl>
|
||||
</p>
|
||||
</BODY>
|
||||
</HTML>
|
11
doc/manager/template.htm
Normal file
11
doc/manager/template.htm
Normal file
@ -0,0 +1,11 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The Tcl-interface to the SINQ histogram memory</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H1>The Tcl-interface to The SINQ histogram memory</H1>
|
||||
<P>
|
||||
</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
207
doc/manager/trouble.htm
Normal file
207
doc/manager/trouble.htm
Normal file
@ -0,0 +1,207 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>SICS Trouble Shooting</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>SICS Trouble Shooting </h1>
|
||||
<hr size=4 width="66%">
|
||||
<p>
|
||||
There is no such thing as bug free software. There are always bugs, nasty
|
||||
behaviour etc. This document shall help to solve these problems. The usual
|
||||
symptom will be that a client cannot connect to the server or the server is
|
||||
not responding.
|
||||
</p>
|
||||
<p>
|
||||
An essential prerequisite of SICS is that the server is up
|
||||
and running. The system is configured to restart the SICServer whenever it
|
||||
fails. Only after a reboot or when the keepalive processes were killed (see
|
||||
below) the SICServer must be restarted. This is done for all instruments by
|
||||
typing:
|
||||
<pre>
|
||||
startsics
|
||||
</pre>
|
||||
at the command prompt. startsics actually starts two programs: one is
|
||||
the replicator application which is responsible for the automatic
|
||||
copying of data files to the laboratory server. The other is the SICS
|
||||
server. Both programs are started by means of a shell script called
|
||||
<b>keepalive</b>. keepalive is basically an endless loop which calls
|
||||
the program again and agaian and thus ensures that the program will
|
||||
never stop running.
|
||||
</p>
|
||||
<p>
|
||||
When the SICS server hangs, or you want to enforce an reinitialization of
|
||||
everything the server process must be killed. This can be accomplished either manually or through a shell script.
|
||||
</p>
|
||||
<h2>Stopping SICS</h2>
|
||||
<p>
|
||||
All SICS processes can be stopped through the command:
|
||||
<pre>
|
||||
killsics
|
||||
</pre>
|
||||
given at the unix command line. You must be the instrument user
|
||||
(for example DMC) on the instrument computer for this to work properly.
|
||||
</p>
|
||||
|
||||
<h2>Finding the SICS server</h2>
|
||||
<p>The first thing when killing the SICS server manually is to find the
|
||||
server process.
|
||||
Log in as Instrument user on the instrument computer (for instance DMC on
|
||||
lnsa05). Type the command:
|
||||
<pre>
|
||||
/home/DMC> ps -A
|
||||
</pre>
|
||||
Note the capital A given as parameter. The reward will be listing like this:
|
||||
<pre width =132>
|
||||
PID TTY S TIME CMD
|
||||
0 ?? R 01:56:28 [kernel idle]
|
||||
1 ?? I 1:24.44 /sbin/init -a
|
||||
3 ?? IW 0:00.20 /sbin/kloadsrv
|
||||
24 ?? S 40:39.58 /sbin/update
|
||||
97 ?? S 0:04.87 /usr/sbin/syslogd
|
||||
99 ?? IW 0:00.03 /usr/sbin/binlogd
|
||||
159 ?? S 1:43.70 /usr/sbin/routed -q
|
||||
285 ?? S 1:00.45 /usr/sbin/portmap
|
||||
293 ?? S 6:03.45 /usr/sbin/ypserv
|
||||
299 ?? I 0:00.37 /usr/sbin/ypbind -s -S psunix,lnsa05.psi.ch
|
||||
307 ?? I 0:00.52 /usr/sbin/mountd -i
|
||||
309 ?? I 0:00.07 /usr/sbin/nfsd -t8 -u8
|
||||
311 ?? I 0:00.09 /usr/sbin/nfsiod 7
|
||||
317 ?? S 5:51.54 /usr/sbin/automount -f /etc/auto.master -M /psi
|
||||
370 ?? I 0:28.58 -accepting connections (sendmail)
|
||||
389 ?? S 1:41.15 /usr/sbin/xntpd -g -c /etc/ntp.conf
|
||||
419 ?? S 6:00.16 /usr/sbin/snmpd
|
||||
422 ?? S 1:00.91 /usr/sbin/os_mibs
|
||||
438 ?? S 34:29.67 /usr/sbin/advfsd
|
||||
449 ?? I 3:16.29 /usr/sbin/inetd
|
||||
482 ?? IW 0:11.53 /usr/sbin/cron
|
||||
510 ?? IW 0:00.02 /usr/lbin/lpd
|
||||
525 ?? I 5:31.67 /usr/opt/psw/psw_agent -x/dev/null -f/usr/opt/psw/psw_agent.conf
|
||||
532 ?? I 0:00.74 /usr/opt/psw/psw_sensor_syswd 1 -x/dev/null
|
||||
555 ?? I 0:00.58 /usr/bin/nsrexecd
|
||||
571 ?? I 0:20.27 /usr/dt/bin/dtlogin -daemon
|
||||
583 ?? S 1:38.27 lpsbootd -F /etc/lpsodb -l 0 -x 1
|
||||
585 ?? IW 0:00.04 /usr/sbin/getty /dev/lat/620 console vt100
|
||||
586 ?? IW 0:00.03 /usr/sbin/getty /dev/lat/621 console vt100
|
||||
587 ?? I 35:59.85 /usr/bin/X11/X :0 -auth /var/dt/authdir/authfiles/A:0-aaarBa
|
||||
657 ?? I 0:01.46 rpc.ttdbserverd
|
||||
4705 ?? IW 0:00.05 dtlogin -daemon
|
||||
9127 ?? I 0:00.37 /usr/bin/X11/dxconsole -geometry 480x150-0-0 -daemon -nobuttons -verbose -notify -exitOnFail -nostdin -bg gray
|
||||
9317 ?? IW 0:00.73 dtgreet -display :0
|
||||
14412 ?? S 0:39.71 netscape
|
||||
15524 ?? I 0:00.57 rpc.cmsd
|
||||
21678 ?? S 0:00.11 telnetd
|
||||
31912 ?? S 0:10.65 /home/DMC/bin/SICServer /home/DMC/bin/dmc.tcl
|
||||
584 console IW + 0:00.21 /usr/sbin/getty console console vt100
|
||||
21978 ttyp1 S 0:00.63 -tcsh (tcsh)
|
||||
22269 ttyp1 R + 0:00.10 ps -A
|
||||
</pre>
|
||||
This is a listing of all running processes on the machine where this command
|
||||
has been typed. Note, in this case, at the bottom in the line starting with
|
||||
<tt> 31912 ?? </tt> an entry for the SICS server. In this example the server
|
||||
is running. If the server is down, no such entry would be present.
|
||||
</p>
|
||||
|
||||
<h2> Killing a hanging SICS server </h2>
|
||||
<p>
|
||||
Suppose, the situation is that the SICS server does not respond anymore. It
|
||||
needs to be forcefully exited. Please note, that it is always better to
|
||||
close the server via the <tt>Sics_Exitus</tt> command typed with manager
|
||||
privilege in one of the command clients. In order to kill the server it is
|
||||
needed to find him first using the scheme given above. The information
|
||||
needed is the number given as first item in the same line where the server
|
||||
is listed. In this case: <tt>31912</tt>. Please note, that this number will
|
||||
always be different. The command to force the server to stop is:
|
||||
<pre>
|
||||
/home/DMC> kill -9 31912
|
||||
</pre>
|
||||
Note, the second parameter is the number found with <tt>ps -A</tt>. The
|
||||
SICServer will be restarted automatically by the system. Occasionally, it
|
||||
may happen, that you cannot connect to the SICS server after such an
|
||||
operation. This is due to some network buffering problems. Doing the killing
|
||||
again usually solves the problem.
|
||||
</p>
|
||||
|
||||
<h2> Shutting The SICS Server Down Completely</h2>
|
||||
<p>
|
||||
This is done for you by the killsics shell script. Just type
|
||||
<pre>
|
||||
killsics
|
||||
</pre>
|
||||
at the unix command line. Here is what killsics does for you:
|
||||
In order to completely shutdown the SICS server two process must be killed:
|
||||
the actual SICS server and the process which automatically restarts the
|
||||
SICServer. The latter must be killed first. It can be found in the ps -A
|
||||
listing as a line reading <b>keepalive SICServer </b>. Kill that one as
|
||||
described above, then kill the SICServer. For restarting SICS after this,
|
||||
use the startsics command.
|
||||
</p>
|
||||
<h2>Restart Everything</h2>
|
||||
<p>
|
||||
If nothing seems to work any more, no connections can be obtained etc, then
|
||||
the next guess is to restart everything. This is especially necessary if
|
||||
mechanics or electronics people were closer to the instrument then 400 meters.
|
||||
<OL>
|
||||
<LI> Reboot the Macintosh PC by switching it off at the silver button on the
|
||||
left. Press deep and a few seconds to achieve an effect. The LED right to the
|
||||
button should be off, before you press again to boot the Macintosh.
|
||||
<LI> Reboot the histogram memory. It has a tiny button labelled RST. That' s
|
||||
the one. Can be operated with a hairpin, a ball point pen or the like.
|
||||
<LI> Wait 5 minutes. The Macintosh may take that time to come up again.
|
||||
<LI> Restart the SICServer. Watch for any messages about things not being
|
||||
connected or configured.
|
||||
<LI> Restart and reconnect the client programs.
|
||||
</OL>
|
||||
If this fails (even after a second) time there may be a network problem which
|
||||
can not be resolved by simple means.
|
||||
</p>
|
||||
<h2>Getting New SICS Software</h2>
|
||||
<p>
|
||||
Sometimes you might want to be sure that you have the latest SICS software.
|
||||
This is how to get it:
|
||||
<ol>
|
||||
<li>Login to the instrument account.
|
||||
<li>If you are no there type cd to get into the home directory.
|
||||
<li>Type <b>killsics</b> at the unix prompt in order to stop the SICS server.
|
||||
<li>Type <b>sicsinstall exe</b> at the unix prompt for copying new
|
||||
SICS software from the general distribution area.
|
||||
<li>Type <b> startsics</b> to restart the SICS software.
|
||||
</ol>
|
||||
</p>
|
||||
<h2>Hot Fixes</h2>
|
||||
<p>
|
||||
When there is trouble with SICS you may be asked by one of the SICS
|
||||
programmers to copy the most recent development reason of the SICS server
|
||||
to your machine. This is done as follows:
|
||||
<ol>
|
||||
<li>Login to the instrument account.
|
||||
<li>cd into the bin directory, for example: /home/DMC/bin.
|
||||
<li>Type <b> killsics</b> at the unix prompt in order to stop the SICS server.
|
||||
<li>Type <b>cp /data/koenneck/src/sics/SICServer .</b> at the unix prompt.
|
||||
<li>Type <b> startsics</b> to restart the SICS software.
|
||||
</ol>
|
||||
<b>!!!!!! WARNING !!!!!!!. Do this only when advised to do so by a competent
|
||||
SICS programmer. Otherwise you might be copying a SICS server in an
|
||||
instable experimental state!</b>
|
||||
</p>
|
||||
<h2> HELP debugging!!!!</h2>
|
||||
<p>
|
||||
The SICS server hanging or crashing should not happen. In order to sort such
|
||||
problems out it is very helpful if any available debugging information is
|
||||
saved and presented to the programmers. Information available are the log
|
||||
files as written continously by the SICS server and posssible core files
|
||||
lying around. They have just this name: core. In order to save them create a
|
||||
new directory (for example dump2077) and copy the stuff in there. This looks
|
||||
like:
|
||||
<pre>
|
||||
/home/DMC> mkdir dump2077
|
||||
/home/DMC> cp log/*.log dump2077
|
||||
/home/DMC> cp core dump2077
|
||||
</pre>
|
||||
The <tt>/home/DMC> </tt> is just the command prompt. Please note, that core
|
||||
files are only available after crashes of the server. These few commands
|
||||
will help to analyse the cause of the problem and to eventually resolve it.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
86
doc/manager/var.htm
Normal file
86
doc/manager/var.htm
Normal file
@ -0,0 +1,86 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>SICS Variables</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>SICS Variables </h2>
|
||||
<p>
|
||||
In SICS most parameters necessary for instrument control are kept with the SICS
|
||||
object implementing the functionality. However, there are some odd bits of
|
||||
information which need to be known, mostly additional information about and
|
||||
from the user, which should go into data files. Such information is kept in
|
||||
SICS variables, created with the command VarMake detailed below.
|
||||
</p>
|
||||
<p>
|
||||
Another usage for variables is to control composite movements of instrument
|
||||
components. For instance for changing the wavelength it is necessary to
|
||||
drive at least two motors, Theta and TwoTheta. Such behaviour is implemented
|
||||
with some SICS special variables. Their creation is described below.
|
||||
</p>
|
||||
<p>
|
||||
Variables are also used in order to control the SINQ automatic file name
|
||||
creation scheme for data files. At SINQ, data files are put into a special
|
||||
directory. The actual name consists of a prefix, a sequential number, the
|
||||
last two digits of the year and an ending. All these components are
|
||||
controlled by variables.
|
||||
</p>
|
||||
<p>
|
||||
The exact syntax for creating variables lokks like this:
|
||||
<ul>
|
||||
<li> <b> VarMake name type access </b> creates a simple variable name. The
|
||||
variable type can be Text, Int or Float. The access parameter defines who
|
||||
may may change the variable. Possible values are: Internal, Manager, User
|
||||
and Spy.
|
||||
<li> <b> MakeWaveLength nam mono </b> creates a wavelength variable nam.
|
||||
The monochromator mono is used for adjustment.
|
||||
<li> <b> MakeEnergy nam mono </b> creates a energy variable nam. The
|
||||
monochromator mono is used for adjustment.
|
||||
<li> <b> MakeO2T nam OM 2TM </b> creates an omega 2Theta dummy variable
|
||||
with name nam for omega 2Theta scans. OM defines an omega motor, 2TM a two
|
||||
theta motor.
|
||||
<li><b>MakeDataNumber SicsDataNumber filename</b> This command makes a
|
||||
variable SicsDataNumber available which holds the current sequential data
|
||||
file number. filename is the complete path to the file were this data
|
||||
number is stored. This file should never, ever be edited without good
|
||||
reason, i.e. resetting the sequential number to 0 at the beginning of a
|
||||
year.
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
There are quite a few SICS variables which have special usages and should be
|
||||
present. Some of them may need to be set by the user, all of them should be
|
||||
inspectable by the user. Many of these variables are used when writing
|
||||
NeXus data files. These special variables are:
|
||||
<DL>
|
||||
<DT> sample
|
||||
<DD> The sample name. To be set by the user.
|
||||
<DT> title.
|
||||
<DD> The experiment title.
|
||||
<DT> User
|
||||
<DD> The name of the user to be specified in a data file.
|
||||
<DT> Instrument.
|
||||
<DD> The name of the instrument.
|
||||
<DT> SicsDataPath
|
||||
<DD>The full path name of the instruments data directory. Should have a / at
|
||||
the end.
|
||||
<DT> SicsDataPrefix
|
||||
<DD> The prefix to use for data file names.
|
||||
<DT> SicsDataPostFix
|
||||
<DD> The ending to use for the data file name. Including the '.'.
|
||||
<DT> Adress
|
||||
<DD> The users adress.
|
||||
<DT> phone
|
||||
<DD> The users phone number.
|
||||
<DT> email
|
||||
<DD> The users e-mail adress.
|
||||
<DT> fax
|
||||
<DD> The users fax number.
|
||||
</DL>
|
||||
</p>
|
||||
<p>
|
||||
Some of the variables stated above should never be changed by a user. This
|
||||
can be achieved by the variable lock command described in the user
|
||||
documentation.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
1
doc/programmer/...aux
Normal file
1
doc/programmer/...aux
Normal file
@ -0,0 +1 @@
|
||||
\relax
|
5
doc/programmer/README
Normal file
5
doc/programmer/README
Normal file
@ -0,0 +1,5 @@
|
||||
The entry points in this file are:
|
||||
|
||||
pub.tex for a SICS publication
|
||||
programmer.tex for a SICS programming guide
|
||||
reference.tex for the SICS reference manual
|
140
doc/programmer/SCinter.tex
Normal file
140
doc/programmer/SCinter.tex
Normal file
@ -0,0 +1,140 @@
|
||||
\subsection{The SICS Interpreter} \label{scinter}
|
||||
The SICS interpreter does the first step of command interpretation. Each
|
||||
SICS command is a name followed by parameters. The interpreter holds for
|
||||
each command a function (the object function) and a data structure. When a
|
||||
command is invoked the list will be searched for a fitting command and then
|
||||
its object function will be invoked for further processing.
|
||||
|
||||
The object
|
||||
function is the object wrapper function as discussed in much detail in the
|
||||
Guide to Object Writers. It looks like this:
|
||||
\begin{verbatim}
|
||||
typedef int (*ObjectFunc)(pSConnection pCon, pSicsInterp pInter, void
|
||||
*pData, int argc, char *argv[]);
|
||||
\end{verbatim}
|
||||
{\bf pCon} is a pointer to the the connection for which the command
|
||||
was invoked. {\bf pInter} is the SICS interpreter in which the command
|
||||
was invoked. {argc, argv[]} are the command arguments similar to the
|
||||
classic C main() function arguments. This is an objects interface to
|
||||
the SICS interpreter.
|
||||
|
||||
|
||||
{\bf pData} is a pointer to a command own data structure. This data structure
|
||||
is deleted by the interpreter when the command is removed by calling
|
||||
a special removal function with the pointer as parameter. This
|
||||
function looks like this:
|
||||
\begin{verbatim}
|
||||
typedef void (*KillFunc)(void *pData);
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
In order to do ist job the SICS interpreter has for each command a data
|
||||
structure defined below:
|
||||
\begin{verbatim}
|
||||
typedef struct __Clist {
|
||||
char *pName;
|
||||
ObjectFunc OFunc;
|
||||
KillFunc KFunc;
|
||||
void *pData;
|
||||
struct __Clist *pNext;
|
||||
struct __Clist *pPrevious;
|
||||
} CommandList;
|
||||
\end{verbatim}
|
||||
The fields are: \begin{description}
|
||||
\item[name] The command name.
|
||||
\item[OFunc] The object wrapper function.
|
||||
\item[KFunc] The object data structure removal function.
|
||||
\item[pData] The objects data structure.
|
||||
\item[pNext, pPrevious] pointers necessary to maintain the doubly linked
|
||||
list of commands.
|
||||
\end{description}
|
||||
|
||||
The interpreter itself is described by the following data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct __SINTER
|
||||
{
|
||||
CommandList *pCList;
|
||||
OutCode eOut;
|
||||
void *pTcl;
|
||||
char **argv;
|
||||
int iDeleting;
|
||||
}SicsInterp;
|
||||
\end{verbatim}
|
||||
The fields are: \begin{description}
|
||||
\item[pCList] A pointer to the command list.
|
||||
\item[eOut] an out code.
|
||||
\item[pTcl] a pointer to the Tcl macro interpreter.
|
||||
\item[argv] An argv[] array with command arguments.
|
||||
\item[iDeleting] a flag which is set when the interpreter is in the
|
||||
process of being removed.
|
||||
\end{description}
|
||||
|
||||
Please note, that currently commands are searched for by linear scanning of
|
||||
the command list, doing a strcmp at each stop. This is inherently
|
||||
inefficient. If in some stage interpreter inefficiency is a problem this
|
||||
scheme should be chnaged to a hash table system or a randomized binary tree.
|
||||
|
||||
|
||||
The interpreter can be controlled with the following functions:
|
||||
\begin{description}
|
||||
\item[SicsInterp *InitInterp(void)]
|
||||
Makes a new interpreter. Returns him on success, else NULL
|
||||
\item[int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
|
||||
KillFunc pKFunc, void *pData)]
|
||||
Adds a new command, Returns True or False, depending on success
|
||||
Parameters:
|
||||
\begin{itemize}
|
||||
\item pInterp : the interpreter to add the command to.
|
||||
\item pName : the commands name
|
||||
\item pFunc : the object function to call when this command is
|
||||
invoked. Definition of type: see above
|
||||
\item pKFunc : function to call in order to delete command data.
|
||||
type definition: above
|
||||
\item pData : pointer to the command's own datastructure. Will be
|
||||
passed as pData with each call to Ofunc.
|
||||
\end{itemize}
|
||||
It is possible to install commands without an associated data structure.
|
||||
Then pData must be NULL. In such cases AddCommand provides a default data
|
||||
structure with a default object descriptor.
|
||||
\item[int RemoveCommand(SicsInterp *pInterp, char *pName)]
|
||||
Kills the command name from the interpreter pInterp
|
||||
\item[int InterpExecute(SicsInterp *self,pSConnection pCon,char *pCommand)]
|
||||
Executes a command in the interpreter self. Essentially converts
|
||||
pCommand in an argc, argv[] pair, sets various status things and
|
||||
invokes the object function. Takes care of status and error reporting
|
||||
afterwards.
|
||||
Parameters: \begin{itemize}
|
||||
\item self : interpreter to invoke command in.
|
||||
\item The connection pCon will be used for I/O and status reporting.
|
||||
\item The command to invoke is the string pCommand.
|
||||
\end{itemize}
|
||||
Returns -1 if the command can not be found.
|
||||
If the command is found, 1 is returned on success, 0 on failure in
|
||||
the command.
|
||||
\item[CommandList *FindCommand(SicsInterp *pInterp, char *name)]
|
||||
Searches the Interpreters pInterp command list for a command
|
||||
with name. Returns its data structure if found, NULL else
|
||||
\item[int WriteSicsStatus(SicsInterp *pSics,char *file)]
|
||||
SICS needs a way to save the status of each object into a file.
|
||||
This is done by invoking for each object the object descriptor
|
||||
function SaveStatus. This function does just that.
|
||||
Parameters: \begin{itemize}
|
||||
\item pSics : the interpreter to use.
|
||||
\item file : the file to write the information to.
|
||||
\end{itemize}
|
||||
Returns: 1 on success, 0 on failure.
|
||||
|
||||
\item[int InterpWrite(SicsInterp *pSics, char *buffer)]
|
||||
Writes result to Tcl, used for Macro mechanism.
|
||||
This is an internal function and should not be used.
|
||||
\item[void DeleteInterp(SicsInterp *self)]
|
||||
Deletes the interpreter self aand clears all asoociated datastructures.
|
||||
self will no longer be vaild after this.
|
||||
\item[FindAlias] find the alias for a given data structure. This is a
|
||||
special function required internally.
|
||||
\item[FindCommandData] is a convenience wrapper around FindCommand
|
||||
which returns the commands data structure instead the CommandList
|
||||
entry fo a given command name. Returns NULL, if the command was not
|
||||
found.
|
||||
|
||||
\end{description}
|
37
doc/programmer/alias.tex
Normal file
37
doc/programmer/alias.tex
Normal file
@ -0,0 +1,37 @@
|
||||
\subsection{The Alias Facility}
|
||||
Aliases make commands available under a different name. SICS currently supports two types of aliases:
|
||||
\begin{itemize}
|
||||
\item Object aliases. This is a facility for renaming first class SICS
|
||||
objects such as commands and hardware objects. This is installed into
|
||||
SICS by creating a new name in the interpreter but with the data
|
||||
structures of the original object. Thus all interface operations such
|
||||
as driving etc will work. Object aliases are installed from the
|
||||
initialization script through the SicsAlias command.
|
||||
\item Command aliases. This is just plain text replacement. For
|
||||
instance one may define ``sttll'' instead of ``a4 softlowerlim''. Such
|
||||
an alias can be installed with the ``alias'' command at any
|
||||
time. However, renaming a motor with this scheme will not work
|
||||
properly as this alias facility has no way to forward interfaces
|
||||
properly.
|
||||
\end{itemize}
|
||||
There is no
|
||||
data structure associated with object aliases. The trick is done by
|
||||
just putting in
|
||||
the same command as a new name into the interpreter.
|
||||
|
||||
Corrspondingly there is only one function to it:
|
||||
\begin{verbatim}
|
||||
int SicsAlias(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
\end{verbatim}
|
||||
SicsAlias is the object wrapper function which implements the alias command.
|
||||
|
||||
|
||||
Command aliases are implemented through:
|
||||
\begin{verbatim}
|
||||
int MakeAlias(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
\end{verbatim}
|
||||
There is a little trivial data structure associated with command
|
||||
aliases which is defined in alias.c.
|
||||
|
176
doc/programmer/amor2t.tex
Normal file
176
doc/programmer/amor2t.tex
Normal file
@ -0,0 +1,176 @@
|
||||
\subsection{AMOR Two Theta}
|
||||
AMOR is SINQ's new reflectometer. It has the peculiar feature that the
|
||||
two theta movement of the detector is expressed in translations along
|
||||
the reflectometer base axis and the detector height. Additionally the
|
||||
detector is tilted. The height of two diaphragms has to be adjusted as
|
||||
well. And, in polarizing mode, the analyzer has to be operated as
|
||||
well. Quite a complicated movement. I fear this module may only be
|
||||
useful for AMOR, but may be, other reflectometers may profit as well.
|
||||
This object implements this complex movement as a virtual motor.
|
||||
|
||||
The following formulas are used for the necessary calculations:
|
||||
\begin{eqnarray}
|
||||
delta height & = & h_{s} - R \sin \alpha \\
|
||||
delta x & = & |x_{c} - x_{s}| - R \cos \alpha \\
|
||||
omega & = & -2 MOM + 2 SOM \\
|
||||
\end{eqnarray}
|
||||
with
|
||||
\begin{eqnarray}
|
||||
h_{s} & = & \tan(2MOM)|x_{c} - x_{s}| \\
|
||||
R & = & \sqrt{hs^{2} - |x_{c} - x_{s}|^{2}} \\
|
||||
\alpha & = & 180 -90 - \beta - 2SOM \\
|
||||
\beta & = & 180 - 90 - 2MOM \\
|
||||
MOM & = & polarizer \omega \\
|
||||
SOM & = & sample \omega \\
|
||||
x_{c} & = & counter position \\
|
||||
x_{s} & = & sample position\\
|
||||
\end{eqnarray}
|
||||
The same equations hold true for the calculations of the diaphragm
|
||||
heights, just replace the distances. The equations for the analyzer
|
||||
are not yet known.
|
||||
|
||||
Due to this complicated movement this module needs to know about a lot
|
||||
of motors and a lot of parameters. The distances of the various
|
||||
components need to be modified at run time in order to allow for
|
||||
configuration changes. These are not motorized but must be entered
|
||||
manually.
|
||||
|
||||
\subsubsection{Data Structures}
|
||||
Consequently data structures are complex. The first data structure
|
||||
used is an entry in an array of motors to start:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$putput {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ pMotor pMot;@\\
|
||||
\mbox{}\verb@ char pName[80];@\\
|
||||
\mbox{}\verb@ float fTarget;@\\
|
||||
\mbox{}\verb@ }MotEntry, *pMotEntry;@\\
|
||||
\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[pMot] is a pointer to the motors data structure.
|
||||
\item[pName] is the name of the motor to start.
|
||||
\item[fTarget] is the target value for the motor.
|
||||
\end{description}
|
||||
|
||||
The next data structure is the class data structure for amor2t:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$amoredata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __AMOR2T {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pIDrivable pDriv;@\\
|
||||
\mbox{}\verb@ pMotor aEngine[MAXMOT];@\\
|
||||
\mbox{}\verb@ MotEntry toStart[MAXMOT];@\\
|
||||
\mbox{}\verb@ int iStart;@\\
|
||||
\mbox{}\verb@ ObPar *aParameter;@\\
|
||||
\mbox{}\verb@ }Amor2T;@\\
|
||||
\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[pDes] The standard SICS object descriptor.
|
||||
\item[pDriv] The drivable interface. The functions defined for the
|
||||
drivable interface implement most of the work of this class.
|
||||
\item[aEngine] An array of pointers to the motor data structures this
|
||||
class has to deal with. The proper initialization of this is taken
|
||||
care of during the initialization of the object.
|
||||
\item[toStart] An array of motors to start when all calculations have
|
||||
been performed.
|
||||
\item[iStart] The number of valid entries in toStart.
|
||||
\item[aParameter] An array of parameters for this object.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{The Interface}
|
||||
The interface to this module is quite primitive. Most of the
|
||||
functionality is hidden in the drivable interface. So there are only
|
||||
functions for interacting with the interpreter.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$amorinterface {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __AMOR2T *pAmor2T;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int Amor2TFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int Amor2TAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ void Amor2TKill(void *pData); @\\
|
||||
\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{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"amor2t.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ A m o r 2 T . i@\\
|
||||
\mbox{}\verb@ Internal data structure definitions for Amor2T. For details see amor2t.tex.@\\
|
||||
\mbox{}\verb@ DO NOT TOUCH! This file is automatically created from amor2t.w.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1999@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$putput {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$amoredata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
\verb@"amor2t.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ A m o r 2 T@\\
|
||||
\mbox{}\verb@ A class for controlling the two theta movement of a reflectometer. @\\
|
||||
\mbox{}\verb@ Especially the AMOR reflectometer at SINQ. For details see the file @\\
|
||||
\mbox{}\verb@ amor2t.tex. DO NOT TOUCH! This file is automatically created from amor2t.w@\\
|
||||
\mbox{}\verb@ with nuweb.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1999@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef AMOR2T@\\
|
||||
\mbox{}\verb@#define AMOR2T@\\
|
||||
\mbox{}\verb@@$\langle$amorinterface {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
71
doc/programmer/amorscan.tex
Normal file
71
doc/programmer/amorscan.tex
Normal file
@ -0,0 +1,71 @@
|
||||
\subsection{Amor Scan}
|
||||
This is a special adaption of the general scan routines for the
|
||||
reflectometer AMOR at SINQ. It works by replacing the configurable
|
||||
routines in the general scan command with special ones, suited to the
|
||||
reflectometers purpose. There are several adaptions to the standard
|
||||
scan command:
|
||||
\begin{itemize}
|
||||
\item Data is written to NeXus files instead of ASCII files.
|
||||
\item There are two counters to keep track of.
|
||||
\item Furthermore stubs are provided for dealing with spin flippers.
|
||||
\end{itemize}
|
||||
|
||||
In order to keep track of counters and monitors the following
|
||||
convention has been devised:
|
||||
\begin{itemize}
|
||||
\item GetCounts gets the main detector.
|
||||
\item GetMonitor 0 the second detector
|
||||
\item GetMonitor 1 the first detector other spin
|
||||
\item GetMonitor 2 the second detector other spin
|
||||
\item GetMonitor 3 the first monitor
|
||||
\item GetMonitor 4 the second monitor
|
||||
\end{itemize}
|
||||
Thus the monitor channels are used to keep the additional counter
|
||||
information.
|
||||
|
||||
This module provides only one external function:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$amorscan {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int ConfigureAmor(pScanData pScan);@\\
|
||||
\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}
|
||||
which configures the variable fields and function pointers in pScan to
|
||||
functions defined in this module. These then do the right thing. This
|
||||
module is also an example of how the scan command can be configured to do
|
||||
tricks based on the syntax and hooks defined in scan.*.
|
||||
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"amorscan.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ A M O R S C A N@\\
|
||||
\mbox{}\verb@ Adaption of the scan command to do things specific to the@\\
|
||||
\mbox{}\verb@ reflectometer AMOR at SINQ.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1999@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef AMORSCAN@\\
|
||||
\mbox{}\verb@#define AMORSCAN@\\
|
||||
\mbox{}\verb@@$\langle$amorscan {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
138
doc/programmer/amorstat.tex
Normal file
138
doc/programmer/amorstat.tex
Normal file
@ -0,0 +1,138 @@
|
||||
\subsection{Amor Status Display Support}
|
||||
The reflectometer AMOR has a few unique status display requirements:
|
||||
\begin{itemize}
|
||||
\item In scan mode up to four detector counts curves must be shown for
|
||||
the two counters in spin-up or spin-down mode. This needs to be
|
||||
updated after each scan point.
|
||||
\item Additionally user defined curves may need to be displayed.
|
||||
\item The usual helper information muste be displayed.
|
||||
\item In TOF mode it must be possible to define a region on the
|
||||
detector whose summed counts are displayed versus the time
|
||||
binning. This must be sent on request.
|
||||
\end{itemize}
|
||||
In order to cover all this a special object within SICS is required
|
||||
which deals with all this and packages information in a status display
|
||||
compliant way.
|
||||
|
||||
In order to do this the amorstatus object registers callbacks both
|
||||
with the histogram memory and the scan object. These callback
|
||||
functions are then responsible for updating the status displays. In
|
||||
order for amorstatus to be able to do this, the client must register
|
||||
itself with a special command.
|
||||
|
||||
In order to achieve all this some data structures are needed:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$asdata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ float *fX, *fY;@\\
|
||||
\mbox{}\verb@ int iNP;@\\
|
||||
\mbox{}\verb@ char *name;@\\
|
||||
\mbox{}\verb@ }UserData, *pUserData; @\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef struct __AMORSTAT {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pICallBack pCall;@\\
|
||||
\mbox{}\verb@ int iUserList;@\\
|
||||
\mbox{}\verb@ pScanData pScan;@\\
|
||||
\mbox{}\verb@ pHistMem pHM;@\\
|
||||
\mbox{}\verb@ int iTOF;@\\
|
||||
\mbox{}\verb@ }AmorStat, *pAmorStat;@\\
|
||||
\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 fourth data structure is the amor status object data structure. It
|
||||
has the following fields:
|
||||
\begin{description}
|
||||
\item[pDes] The standard SICS object descriptor.
|
||||
\item[pCall] The callback interface.
|
||||
\item[iUserList] A list of user data loaded data.
|
||||
\item[pScan] A pointer to the scan object.
|
||||
\item[pHM] A pointer to the histogram memory.
|
||||
\item[iTOF] A flag which is true if we are taking measurements in TOF
|
||||
mode.
|
||||
\end{description}
|
||||
|
||||
In terms of a function interface this object has not much to
|
||||
offer. Its main purpose is really as an interface to the status
|
||||
display clients and thus it is configured through the interpreter
|
||||
interface function. No need for other SICS objects to access it.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$asinter {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int AmorStatusFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int AmorStatusAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ void KillAmorStatus(void *pData);@\\
|
||||
\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{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"amorstat.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ A M O R S T A T U S@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Internal data structure definitions for the AMOR status display @\\
|
||||
\mbox{}\verb@ facilitator object. DO NOT CHANGE. This file is automatically@\\
|
||||
\mbox{}\verb@ created from amorstat.w.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1999@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$asdata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"amorstat.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ A M O R S T A T U S@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Public definitions for the AMOR status display @\\
|
||||
\mbox{}\verb@ facilitator object. DO NOT CHANGE. This file is automatically@\\
|
||||
\mbox{}\verb@ created from amorstat.w.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1999@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef AMORSTATUS@\\
|
||||
\mbox{}\verb@#define AMORSTATUS@\\
|
||||
\mbox{}\verb@@$\langle$asinter {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
64
doc/programmer/bruker.tex
Normal file
64
doc/programmer/bruker.tex
Normal file
@ -0,0 +1,64 @@
|
||||
\subsubsection{Bruker Magnet Controller B-EC-1}
|
||||
SANS is using a Bruker magnet controller. This controller is integrated
|
||||
into SICS as a derivate of an environment controller. The Bruker controller
|
||||
can be operated in two modes: in the first the current is controlled,
|
||||
in the second the current
|
||||
is controlled by an external hall sensor giving the magnetic field. Whatever
|
||||
is the controlling sensor, the magnetic field and the current need to be
|
||||
read. Furthermore this device supports switching the polarity. All this is
|
||||
achieved with a special driver and an additional wrapper function for
|
||||
handling extra commands. All this is implemented in the file bruker.h
|
||||
and bruker.c. The functions defined are:
|
||||
|
||||
\begin{verbatim}
|
||||
pEVDriver CreateBrukerDriver(int argc, char *argv[]);
|
||||
|
||||
int BrukerReadField(pEVControl self, float *fField);
|
||||
int BrukerReadCurrent(pEVControl self, float *fCurrent);
|
||||
|
||||
int BrukerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
\begin{description}
|
||||
\item[CreateBrukerDriver] creates a driver for the bruker magnet
|
||||
controller.
|
||||
\item[BrukerReadField] reads the current magnetic field.
|
||||
\item[BrukerReadCurrent] reads the current current in Ampere.
|
||||
\item[BrukerAction] a special SICS interpreter wrapper function for
|
||||
the Bruker Magnet. This function handles the few special Bruker
|
||||
commands and passes everything else to the standard environment
|
||||
controller handler function.
|
||||
\end{description}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
81
doc/programmer/buffer.tex
Normal file
81
doc/programmer/buffer.tex
Normal file
@ -0,0 +1,81 @@
|
||||
\subsection{The LNS R\"unbuffer}
|
||||
R\"unbuffers are a special LNS feature for handling instruments. Essentially
|
||||
a R\"unbuffer is a list of commands which can be executed as a block. On
|
||||
line editing of such a R\"unbuffer is supported as well. R\"unbuffers can
|
||||
also be saved to or read from disk files. R\"unbuffers are related to the
|
||||
batch file processing facility FileEval. However, there are subtle
|
||||
differences. The first is I/O: When evaluating a batch file with FileEval
|
||||
all messages except errors and warnings are suppressed. This is a nice
|
||||
feature if the file evaluated contains a macro, where a user might be
|
||||
confused when confronted with all internal messages. With R\"unbuffers all
|
||||
output is written to the user. R\"unbuffers support only SICS commands, with
|
||||
FileEval Tcl commands can be given as well.
|
||||
|
||||
|
||||
It turned out that the R\"unbuffer system together with the R\"unlist
|
||||
facility documented in the next section is rarely
|
||||
used. Experimentators prefer the batch file facility ``fileeval''
|
||||
instead. Consequently, this may be retracted and cleaned out in some
|
||||
stage.
|
||||
|
||||
A R\"unbuffer is characterized by a an own data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
pObjectDescriptor pDes; /* needed */
|
||||
char *name; /* BufferName */
|
||||
int iLineList; /* Handle to the Line List */
|
||||
} RuenBuffer, *pRuenBuffer;
|
||||
\end{verbatim}
|
||||
The fields:
|
||||
\begin{description}
|
||||
\item[pDes] A pointer to the usual SICS object descriptor.
|
||||
\item[name] The name of the R\"unbuffer.
|
||||
\item[iLineList] The handle of the lldlist holding the lines of the
|
||||
R\"unbuffer.
|
||||
\end{description}
|
||||
|
||||
Interaction with R\"unbuffers happesn through the functions listed below.
|
||||
All functions return 0 on failure or 1 on success, if not stated otherwise.
|
||||
Most functions take as first parameter a pointer to the R\"unbuffer to act
|
||||
upon.
|
||||
\begin{description}
|
||||
\item[pRuenBuffer CreateRuenBuffer(char *name)] creates a R\"unbuffer.
|
||||
Returns the pointer to the new r\"unbuffer on success, or NULL on failure.
|
||||
\item[void DeleteRuenBuffer(void *pSelf)] Deletes a R\"unbuffer.
|
||||
\item[pRuenBuffer CopyRuenBuffer(pRuenBuffer pOld, char *NewName)] copies a
|
||||
R\"unbuffer including all data lines. Returns NULL on failure, a pointer to
|
||||
a new R\"unbuffer structure otherwise.
|
||||
\item[int BufferAppendLine(pRuenBuffer self, char *line)] appends line to
|
||||
r\"unbuffer self.
|
||||
\item[int BufferDel(pRuenBuffer self, int iLine)] deletes line iLine from
|
||||
r\"unbuffer self.
|
||||
\item[int BufferInsertAfter(pRuenBuffer self, int iLine, char *line)]
|
||||
inserts line line AFTER line number iLine in the RuenBuffer self.
|
||||
\item[int BufferPrint(pRuenBuffer self, SConnection *pCon)]
|
||||
lists the contents of the RuenBuffer on the Connection pCon.
|
||||
\item[int BufferReplace(pRuenBuffer self, char *pattern, char *pReplace)]
|
||||
replaces all occurences of the string pattern in the whole RuenBuffer
|
||||
by the replacement string pReplace.
|
||||
\item[int BufferRun(pRuenBuffer self, SConnection *pCon, SicsInterp *pSics)]
|
||||
executes the lines of the Ruenbuffer one by one.
|
||||
Returns 1 on success, 0 on error.
|
||||
\item[int BufferSave(pRuenBuffer self, char *file)]
|
||||
writes the contents of Ruenbuffer self to the file specified by
|
||||
file.
|
||||
Returns 1 on success, 0 on error.
|
||||
\item[int BufferLoad(pRuenBuffer self, char *file)]
|
||||
reads the contents of file into the RuenBuffer self.
|
||||
Returns 1 on success, 0 on error.
|
||||
\item[int InitBufferSys(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The factory function for the
|
||||
R\"unbuffer system. Initialises the Buf command and the ruli command.
|
||||
\item[int BufferCommand(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The object wrapper function
|
||||
which implements the Buf command.
|
||||
\item[int BufferAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The object wrapper function for
|
||||
the R\"unbuffer itself.
|
||||
\item[pRuenBuffer FindRuenBuffer(SicsInterp *pSics, char *name)] finds
|
||||
r\"unbuffer name in the interpreter pSics. Returns a pointer to the
|
||||
r\"unbuffers data structure if it exists, NULL otherwise.
|
||||
\end{description}
|
75
doc/programmer/center.tex
Normal file
75
doc/programmer/center.tex
Normal file
@ -0,0 +1,75 @@
|
||||
\subsection{Fit and Center}
|
||||
This is a fit routine for SICS. It takes a scan and tries to find a peak and
|
||||
its position. Trials showed that fitting a gauss function is not robust
|
||||
enough for this facility which has to cope with bizarre peak shapes, half
|
||||
finished measurements and the like. The algorithm choosen tries to find the
|
||||
center of gravity of the peak. It does this by searching for the maximum
|
||||
point in the diagram first. Then the points where the peak is below
|
||||
half maximum are searched for either side of the peak. Within these
|
||||
limits the COG is calculated. When this is done fit will print some
|
||||
info about the peak.
|
||||
|
||||
Center will the drive the scan variable to the COG of the peak.
|
||||
|
||||
The interface to this simple facility is simple:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$fitinter {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __FitCenter *pFit;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ pFit CreateFitCenter(pScanData pScan);@\\
|
||||
\mbox{}\verb@ void DeleteFitCenter(void *pData);@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int CalculateFit(pFit self);@\\
|
||||
\mbox{}\verb@ /* @\\
|
||||
\mbox{}\verb@ CalcluateFit returns: -1 when left FWHM could not be found@\\
|
||||
\mbox{}\verb@ -2 when right FWHM could not be found@\\
|
||||
\mbox{}\verb@ 1 on success@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ int DriveCenter(pFit self, SConnection *pCon, SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int FitFactory(SConnection *pCon,SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int FitWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int CenterWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ 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{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"fitcenter.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ F I T C E N T E R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ A simple peak finding and center of gravity determination facility for@\\
|
||||
\mbox{}\verb@ SICS.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSFITCENTER@\\
|
||||
\mbox{}\verb@#define SICSFITCENTER@\\
|
||||
\mbox{}\verb@@$\langle$fitinter {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
351
doc/programmer/choco.tex
Normal file
351
doc/programmer/choco.tex
Normal file
@ -0,0 +1,351 @@
|
||||
\subsection{Chopper Controller}
|
||||
Yet another way to deal with a controller has beenn devised for
|
||||
SICS. This uses the concept of a general controller which can have
|
||||
parameters enquired and set. Furthermore it may have parameters which
|
||||
may be driven like a motor through a special adapter. This scheme is
|
||||
used for the chopper controller for FOCUS.
|
||||
\begin{itemize}
|
||||
\item A driver for a particular controller which allows to set and get
|
||||
parameters.
|
||||
\item The general controller object which holds things together.
|
||||
\item An adapter object which allows to drive special parameters in a general
|
||||
controller. Such adapter objects can be configured for each drivable parameter
|
||||
in a controller.
|
||||
\end{itemize}
|
||||
The test case for this way of doing things is a controller for running
|
||||
choppers. This is why it gets the name.
|
||||
|
||||
The chopper system in question is the FOCUS chopper system. There are two
|
||||
choppers, a fermi chopper and a disk chopper. This system can be run in two
|
||||
different modes: In synchronous mode both choppers run at a
|
||||
predefined ratio of speeds. For instance the fermi chopper is two
|
||||
times faster then the disk chopper. This means, that setting a new
|
||||
value for one chopper also changes the speed of the other chopper. In
|
||||
asynchronous mode both choppers operate independently. Also the ration
|
||||
to use for synchronous mode can be changed. Another parameter which
|
||||
frequently changes is the phase of the two choppers. In order to
|
||||
compensate for the fligh path between the two choppers there is a
|
||||
small angular displacement of the choppers against each other which
|
||||
varies with wavelength.
|
||||
|
||||
\subsubsection{The Controller Driver}
|
||||
The controller driver is represented by the following data structure:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$codri {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __CODRI *pCodri;@\\
|
||||
\mbox{}\verb@ typedef struct __CODRI {@\\
|
||||
\mbox{}\verb@ int (*Init)(pCodri self);@\\
|
||||
\mbox{}\verb@ int (*Close)(pCodri self);@\\
|
||||
\mbox{}\verb@ int (*Delete)(pCodri self);@\\
|
||||
\mbox{}\verb@ int (*SetPar)(pCodri self, @\\
|
||||
\mbox{}\verb@ char *parname,@\\
|
||||
\mbox{}\verb@ float fValue);@\\
|
||||
\mbox{}\verb@ int (*SetPar2)(pCodri self, @\\
|
||||
\mbox{}\verb@ char *parname,@\\
|
||||
\mbox{}\verb@ char *value);@\\
|
||||
\mbox{}\verb@ int (*GetPar)(pCodri self,@\\
|
||||
\mbox{}\verb@ char *parname,@\\
|
||||
\mbox{}\verb@ char *pBuffer,@\\
|
||||
\mbox{}\verb@ int iBufLen);@\\
|
||||
\mbox{}\verb@ int (*CheckPar)(pCodri self, @\\
|
||||
\mbox{}\verb@ char *parname);@\\
|
||||
\mbox{}\verb@ int (*GetError)(pCodri self, int *iCode,@\\
|
||||
\mbox{}\verb@ char *pError, @\\
|
||||
\mbox{}\verb@ int iErrLen);@\\
|
||||
\mbox{}\verb@ int (*TryFixIt)(pCodri self, int iCode);@\\
|
||||
\mbox{}\verb@ int (*Halt)(pCodri self);@\\
|
||||
\mbox{}\verb@ char *pParList;@\\
|
||||
\mbox{}\verb@ void *pPrivate;@\\
|
||||
\mbox{}\verb@ }Codri;@\\
|
||||
\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}
|
||||
All functions take a pointer to the controller driver itself as a
|
||||
parameter. All functions except TryFixIt and CheckPar
|
||||
return 0 on failure and 1 for success.
|
||||
\begin{description}
|
||||
\item[Init] initializes the controller driver. The parameters argc,
|
||||
argv are main() style parameters for the initialization of the
|
||||
controller driver.
|
||||
\item[Close] closes the connection to the controller but does not delete a thing.
|
||||
\item[Delete] closes the connection to the controller and deletes private data structures. Called when deleting the controller.
|
||||
\item[SetPar] tries to set the parameter parname to the value
|
||||
fValue. The last is floating point which covers the frequent
|
||||
occurence of numeric values.
|
||||
\item[SetPar2] The same as SetPar but uses test string as input for
|
||||
parameter setting.
|
||||
\item[GetPar] retrieves the parameter parname formatted as test. The
|
||||
value is put into the buffer pBuffer. iBufLen is the maximum number of
|
||||
bytes permissable for pBuffer.
|
||||
\item[CheckPar] When parameters are driven a means is needed to find
|
||||
out about the progress of operations and errors during the
|
||||
operation. This is done by CheckPar for the parameter parname. The
|
||||
return value of this function must be one of the HWBusy, HWError,
|
||||
HWDone family documented in the motor driver object description.
|
||||
\item[GetError] retrieves the last error. An integer error code is
|
||||
placed into iCode and a textual description of the problem is written
|
||||
to pError. Maximum iErrLen bytes are copied to pError.
|
||||
\item[TryFixIt] tries to fix the error condition specified by iCode in
|
||||
software if this possible. TryFisIt returns HWRedo if the last command
|
||||
needs to resent, HWFault if the problem could not be fixed and HWOK if
|
||||
the error can be ignored or was fully resolved.
|
||||
\item[pParList] is text string containing a comma separated list of
|
||||
all parameters understood by this driver.
|
||||
\item[pPrivate] Is a pointer to a driver specific specific data
|
||||
structure. This data structure will not be messed with by upper level code.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{The Controller Object}
|
||||
This is the general controller object visible from the SICS
|
||||
interpreter. This object allows to list all possible
|
||||
parameters. Internal functions are provided for setting
|
||||
parameters. But this is meant to be operated through a drive adapter
|
||||
object (see below) in SICS. Thus the interface to this object
|
||||
includes:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$chocoint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __CHOCO *pChoco;@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int CHGetParameter(pChoco self, char *pParName, @\\
|
||||
\mbox{}\verb@ char *pParValue, int iBuflen); @\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ pCodri CHGetDriver(pChoco self);@\\
|
||||
\mbox{}\verb@ int CHList(pChoco self, SConnection *pCon, char *name);@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\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}
|
||||
\begin{description}
|
||||
\item[CHGetParameter] retrieves the value of the parameter ParName
|
||||
converted to text. Maximum iBufLen of result or error text are copied into the
|
||||
buffer pParvalue.
|
||||
\item[CHGetDriver] returns a pointer to the controller driver. This
|
||||
function will be used by the drive adapters for interfacing with the
|
||||
driver directly.
|
||||
\item[CHList] prints a listing of all parameters to the client
|
||||
described by pCon. name is the name of the controller.
|
||||
\item[ChocoAction] is the SICS interpreter interface function for the
|
||||
controller.
|
||||
\item[ChocoFactory] is the SICS interpreter interface function which
|
||||
installs a controller into SICS.
|
||||
\end{description}
|
||||
|
||||
Most of the actual work of the controller is left to the driver. Thus
|
||||
the internal data structure for a controller object is very simple:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$chocodata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __CHOCO {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pCodri pDriv;@\\
|
||||
\mbox{}\verb@ } Choco;@\\
|
||||
\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}
|
||||
It consists just of the standard SICS object descriptor and a pointer
|
||||
to the driver.
|
||||
|
||||
\subsubsection{The Drive Adapter}
|
||||
Most of the work of the drive adaptor is hidden in the functions
|
||||
implementing the drivable interface. Thus the interface to the
|
||||
DriveAdapter is fairly simple:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
$\langle$adapter {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __CHADAPTER *pCHAdapter;@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int CHAdapterFactory(SConnection *pCon, SicsInterp *pSics, @\\
|
||||
\mbox{}\verb@ void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int CHAdapterAction(SConnection *pCon, SicsInterp *pSics, @\\
|
||||
\mbox{}\verb@ void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\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}
|
||||
\begin{description}
|
||||
\item[CHAdapterFactory] is the SICS interpreter factory function for
|
||||
creating a drive adapter.
|
||||
\item[CHAdapterAction] is the SICS interpreter function for
|
||||
representing the object in SICS. Just a single action is supported:
|
||||
request the value of the parameter.
|
||||
\end{description}
|
||||
|
||||
The data structure for the drive adapter is slightly more interesting:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
$\langle$adadata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __CHADAPTER {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pCodri pDriv;@\\
|
||||
\mbox{}\verb@ pIDrivable pInt;@\\
|
||||
\mbox{}\verb@ float fUpper;@\\
|
||||
\mbox{}\verb@ float fLower;@\\
|
||||
\mbox{}\verb@ float fTarget;@\\
|
||||
\mbox{}\verb@ char *pParName;@\\
|
||||
\mbox{}\verb@ }CHAdapter;@\\
|
||||
\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[pDes] is the standard object descriptor.
|
||||
\item[pDriv] is a pointer to the controller driver.
|
||||
\item[pInt] is a pointer to the drivable interface implemented by the
|
||||
adapter.
|
||||
\item[fUpper] upper limit for the parameter.
|
||||
\item[fLower] lower limit for the parameter.
|
||||
\item[pParName] is the name of the parameter which is driven through
|
||||
this adapter.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
\verb@"codri.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C o n t r o l l e r D r i v e r@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This file contains the description of the data structure for a@\\
|
||||
\mbox{}\verb@ general controller driver.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, January 1998@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef CODRIV@\\
|
||||
\mbox{}\verb@#define CODRIV@\\
|
||||
\mbox{}\verb@#define CHFAIL -1@\\
|
||||
\mbox{}\verb@#define CHREDO -2@\\
|
||||
\mbox{}\verb@#define CHOK -3@\\
|
||||
\mbox{}\verb@@$\langle$codri {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap7}
|
||||
\verb@"choco.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C h o p p e r C o n t r o l l e r@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This is both the header file for a general controller and a SICS@\\
|
||||
\mbox{}\verb@ chopper controller.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, January 1998@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef CHOCOSICS@\\
|
||||
\mbox{}\verb@#define CHOCOSICS@\\
|
||||
\mbox{}\verb@#include "codri.h"@\\
|
||||
\mbox{}\verb@@$\langle$chocoint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#ifdef CHOCOINTERNAL@\\
|
||||
\mbox{}\verb@@$\langle$chocodata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap8}
|
||||
\verb@"chadapter.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C H a d a p t e r@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This is the header file for a drive adapter for collaboration with a@\\
|
||||
\mbox{}\verb@ general device controller as implemented in choco.*@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, January 1998@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSCHADA@\\
|
||||
\mbox{}\verb@#define SICSCHADA@\\
|
||||
\mbox{}\verb@#include "codri.h"@\\
|
||||
\mbox{}\verb@@$\langle$adapter {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#ifdef CHADAINTERNAL@\\
|
||||
\mbox{}\verb@@$\langle$adadata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\subsubsection{To Do}
|
||||
This scheme seems to be quite promising for handling many SICS
|
||||
objects. The following enhancements could be considered. Allow to set
|
||||
certain primitive parameters without a drivable interface. And add an
|
||||
adapter for an environment variable in the controller.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
108
doc/programmer/costa.tex
Normal file
108
doc/programmer/costa.tex
Normal file
@ -0,0 +1,108 @@
|
||||
\subsection{The Command Stack}
|
||||
This is a helper class to the connection class.
|
||||
Each connection to a client has a command stack associated with it. The
|
||||
command stack is a stack of command strings as generated by the SICS
|
||||
clients. Commands are added to the top of the command queue by the network
|
||||
reader. Each time the task associated with a connection runs one command
|
||||
is popped from the command stack and executed. During execution the command
|
||||
stack must be locked in order to prevent commands being accepted by tasks
|
||||
busy waiting for some other process to finish.
|
||||
|
||||
Correspondingly, the interface to the command stack looks like this:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$costaint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __costa *pCosta;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*----------------------------- live & death ----------------------------*/@\\
|
||||
\mbox{}\verb@ pCosta CreateCommandStack(void);@\\
|
||||
\mbox{}\verb@ void DeleteCommandStack(pCosta self);@\\
|
||||
\mbox{}\verb@ int SetCommandStackMaxSize(pCosta self, int iNewSize);@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int CostaTop(pCosta self, char *pCommand);@\\
|
||||
\mbox{}\verb@ int CostaBottom(pCosta self, char *pCommand);@\\
|
||||
\mbox{}\verb@ int CostaPop(pCosta self,char **pPtr);@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ void CostaLock(pCosta self);@\\
|
||||
\mbox{}\verb@ void CostaUnlock(pCosta self);@\\
|
||||
\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}
|
||||
Internally, two data structure need to be defined, the first for the
|
||||
list implementing the command stack, the second for the command stack
|
||||
itself.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$costadat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef struct __costa {@\\
|
||||
\mbox{}\verb@ int iLock;@\\
|
||||
\mbox{}\verb@ int iList;@\\
|
||||
\mbox{}\verb@ int iMaxSize;@\\
|
||||
\mbox{}\verb@ int iCount;@\\
|
||||
\mbox{}\verb@ } Costa;@\\
|
||||
\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{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"costa.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C O S T A@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ A command stack implementation for SICS. To be used by each connection.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSCOSTA@\\
|
||||
\mbox{}\verb@#define SICSCOSTA@\\
|
||||
\mbox{}\verb@@$\langle$costaint {\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{scrap4}
|
||||
\verb@"costa.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C O S T A@\\
|
||||
\mbox{}\verb@ Internal data structures for the command stack.@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$costadat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
180
doc/programmer/counter.tex
Normal file
180
doc/programmer/counter.tex
Normal file
@ -0,0 +1,180 @@
|
||||
\subsection{The Counter}
|
||||
This is the SICS object responsible for handling single counters and
|
||||
monitors. As usual for SICS hardware objects the
|
||||
counter is subdivided in a driver and a logical object. The driver will be
|
||||
discussed first. The same concept with overlaying structures is used
|
||||
for counters as for motors in order to allow for different drivers.
|
||||
|
||||
\subsubsection{The Counter Driver}
|
||||
Counter drivers are polymorphic. This means that different drivers look the
|
||||
same to the logical counter objects. This is achieved by having pointers to
|
||||
functions in the driver. These pointers must be initialised by an actual driver
|
||||
with functions which implement the required behaviour.
|
||||
The counter driver is a large data structure defined below:
|
||||
\begin{verbatim}
|
||||
typedef struct __COUNTER {
|
||||
/* variables */
|
||||
char *name;
|
||||
char *type;
|
||||
CounterMode eMode;
|
||||
float fPreset;
|
||||
int iNoOfMonitors;
|
||||
long lCounts[MAXCOUNT];
|
||||
int iPause;
|
||||
/* functions */
|
||||
int (*GetStatus)(struct __COUNTER *self, float *fControl);
|
||||
int (*Start)(struct __COUNTER *self);
|
||||
int (*Pause)(struct __COUNTER *self);
|
||||
int (*Continue)(struct __COUNTER *self);
|
||||
int (*Halt)(struct __COUNTER *self);
|
||||
int (*ReadValues)(struct __COUNTER *self);
|
||||
int (*GetError)(struct __COUNTER *self, int *iCode,
|
||||
char *error, int iErrLen);
|
||||
int (*TryAndFixIt)(struct __COUNTER *self, int iCode);
|
||||
void *pData; /* counter specific data goes here, ONLY for
|
||||
internal driver use!
|
||||
*/
|
||||
} CounterDriver, *pCounterDriver;
|
||||
\end{verbatim}
|
||||
All functions take a pointer to a counter structure as first parameter. If
|
||||
not described otherwise all functions return 0 on failure and 1 on success.
|
||||
The fields have the following meanings:
|
||||
\begin{description}
|
||||
\item[name] The counter name in the system.
|
||||
\item[type] A string describing the counter type.
|
||||
\item[eMode] The counting mode of the counter. Can be eTimer for counting
|
||||
till a preset time has passed or ePreset for counting until one of the
|
||||
monitors has reached a certain count rate.
|
||||
\item[fPreset] Depending on the count mode either the time to count or the
|
||||
monitor rate to wait for for.
|
||||
\item[iNoOfMonitors] The number of monitors handled by this counter.
|
||||
\item[lCounts] An array which stores the counts in the array position 0, and
|
||||
the monitor counts in the other fields of the array.
|
||||
\item[iPause] A logical which is set when the counter is paused.
|
||||
\item[GetStatus] GetStatus is the first of the functions a driver has to
|
||||
define. GetStatus reads the counter status. Possible return values are:
|
||||
\begin{description}
|
||||
\item[HWIdle, OKOK] The counter is finished or idle.
|
||||
\item[HWFault] A fault has been found at the counter instead of an
|
||||
reasonable answer.
|
||||
\item[HWNoBeam] There is currently no incident beam. This is usually
|
||||
detected through a monitor which does not increase over time.
|
||||
\item[HWPause] Counting has been paused.
|
||||
\item[HWBusy] The counter is busy counting.
|
||||
\end{description}
|
||||
The parameter fControl is set to the current value of the counting control
|
||||
variable. This can either be the counting time already passed or the count
|
||||
rate of the control monitor in ePreset mode.
|
||||
\item[Start] Starts counting with the current mode and preset parameters.
|
||||
\item[Pause] pauses a counting operation.
|
||||
\item[Continue] continues a paused counting operation.
|
||||
\item[Halt] cancels a counting operation. This a emergency stop used when
|
||||
interrupting an operation.
|
||||
\item[ReadValues] reads the counter and the monitors in the lCounts array.
|
||||
This gets automatically called through the TransferData routine of the
|
||||
countable interface after a counting operations finishes. The point is that
|
||||
data is transfered from the counter once and further requests operate on the
|
||||
contents of the local array instead of bothering the hardware again.
|
||||
\item[GetError] This gets called when an error has been detected during one
|
||||
of the previous operations. The function has to return more information
|
||||
about the error: iCode an driver dependent integer error code and maximum
|
||||
iErrLen characters of problem description in error.
|
||||
\item[TryAndFixIt] takes the integer error code returned in iCode from
|
||||
GetError and tries to solve the problem with the hardware. This function can
|
||||
either return COREDO which means the problem has been fixed and the
|
||||
operation needs to redone or COTERM which means that it is not possible to
|
||||
resolve the problem in software.
|
||||
\item[pData] A pointer to a driver dependent data structure. Whereas the
|
||||
fields above are required and expected by the counter module for a driver,
|
||||
this is an area private to the actual driver.
|
||||
\end{description}
|
||||
|
||||
As most of the action of the counter driver is done in the functions given
|
||||
in its data structure only few functions are available in order to interact
|
||||
with it:
|
||||
\begin{description}
|
||||
\item[pCounterDriver CreateCounterDriver(char *name, char *type)] creates a
|
||||
general default counter driver structure.
|
||||
\item[void DeleteCounterDriver(pCounterDriver self)] deletes a counter
|
||||
driver.
|
||||
\item[pCounterDriver NewEL737Counter(char *name, char *host, int iPort,
|
||||
int iChannel)] creates a PSI--EL737 counter
|
||||
driver. The counter box is meant to be reachable at the terminal server
|
||||
host, listening at iPort and connected to channel iChannel at the macintosh.
|
||||
\item[void KillEL737Counter(pCounterDriver self)] deletes an EL737 counter
|
||||
driver.
|
||||
\item[pCounterDriver NewSIMCounter(char *name)] creates a simulated counter
|
||||
driver. Needed for software testing and instrument simulation.
|
||||
\item[void KillSIMCounter(pCounterDriver self)] deletes a simulated counter
|
||||
driver.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{The Logical Counter Object}
|
||||
This is the object which represents the counter to the system. For all
|
||||
actual hardware action the driver is called. The counter objects data
|
||||
structure:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
pObjectDescriptor pDes;
|
||||
char *name;
|
||||
int isUpToDate;
|
||||
int iExponent;
|
||||
pICountable pCountInt;
|
||||
pCounterDriver pDriv;
|
||||
pICallBack pCall;
|
||||
unsigned long tStart;
|
||||
} Counter, *pCounter;
|
||||
\end{verbatim}
|
||||
The fields:\begin{description}
|
||||
\item[pDes] The required object descriptor for any SICS object.
|
||||
\item[name] The counters name in the system.
|
||||
\item[isUpToDate] a logical which is true when counting is finished and the
|
||||
data in the drivers lCount array represent the correct values.
|
||||
\item[iExponent] The exponent to apply on preset values in monitor mode. At
|
||||
SINQ monitor count rates in millions are usual. The exponent saves typing
|
||||
all those 0's. Each monitor preset value given is multiplied by this value.
|
||||
\item[pCountInt] A pointer to the countable interface.
|
||||
\item[pDriv] A pointer to a counter driver for this counter.
|
||||
\item[pCall] A pointer to the callback interface implemented by this
|
||||
counter.
|
||||
\item[tStart] The start time of the last counting operation.
|
||||
\end{description}
|
||||
|
||||
Unlike the counter driver, there exist many functions for interaction with
|
||||
the counter. Mosts functions take a pointer to a counter structure as first
|
||||
parameter. In order to communicate error messages, functions which interact
|
||||
with hardware take a pointer to a connection object as parameter.
|
||||
\begin{description}
|
||||
\item[pCounter CreateCounter(char *name, pCounterDriver pDriv)] Creates a
|
||||
new counter object with name name and counter driver pDriv.
|
||||
\item[void DeleteCounter(void *self)] deletes a counter object.
|
||||
\item[int MakeCounter(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The counter object factory
|
||||
function. The function to be hacked (plus DeleteCounter) when a new driver
|
||||
needs to be introduced into the system.
|
||||
\item[int SetCounterMode(pCounter self, CounterMode eNew)] sets a new
|
||||
counter mode.
|
||||
\item[CounterMode GetCounterMode(pCounter self)] requests the current
|
||||
counter mode.
|
||||
\item[int SetCounterPreset(pCounter self, float fVal)] sets a new preset
|
||||
time or monitor.
|
||||
\item[float GetCounterPreset(pCounter self)] returns the current preset time
|
||||
or monitor.
|
||||
\item[long GetCounts(pCounter self, SConnection *pCon)] returns the detector
|
||||
counts.
|
||||
\item[long GetMonitor(pCounter self, int iNum, SConnection *pCon)] returns
|
||||
the monitor counts in monitor iNum. This function returns -1 when the
|
||||
requetsed monitor does not exist.
|
||||
\item[ GetNMonitor(pCounter self)] returns the number of monitors
|
||||
available.
|
||||
\item[int DoCount(pCounter self,float fPreset, SConnection *pCon, SicsInterp
|
||||
*pSics)] does a count operation with fPreset as preset value.
|
||||
\item[int CountAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The counter objects wrapper
|
||||
function. This function defines the user interface to the counter object.
|
||||
\end{description}
|
||||
|
||||
|
||||
|
||||
|
||||
|
16
doc/programmer/cron.tex
Normal file
16
doc/programmer/cron.tex
Normal file
@ -0,0 +1,16 @@
|
||||
\subsection{cron}
|
||||
This module allows to install commands into SICS which will be repeated
|
||||
periodically. The syntax is: sicscron intervall command. intervall is
|
||||
the time intervall and command is the command to execute. A problem
|
||||
is I/O becasue the original connection which installed the cron job
|
||||
may be lost. Therefore cron commands are executed within the context
|
||||
of special connection which does not do socket output. All I/O will be
|
||||
logged into the command log though for control. As
|
||||
this is a single system facility all data structure will be defined
|
||||
in the implementation file. The public interface to this is just the
|
||||
installation routine. This stuff is implemented in the files
|
||||
sicscron.h and sicscron.c.
|
||||
|
||||
The installation routine installs another task into the SICS system
|
||||
which will invoke the command to be executed at the predefined
|
||||
intervalls.
|
92
doc/programmer/danu.tex
Normal file
92
doc/programmer/danu.tex
Normal file
@ -0,0 +1,92 @@
|
||||
\subsection{Data Number}
|
||||
In some points of its life SICS has to write data files. The file names
|
||||
usually consist of a header, a serial number and an indicator for the
|
||||
year. The serial number must be unique and steadliy increasing. In order to
|
||||
achieve this, the serial number are written into a file after any change.
|
||||
Incrementing the serial number thus involves the following steps:
|
||||
\begin{itemize}
|
||||
\item Open file and read current number.
|
||||
\item Increment number
|
||||
\item Write File and close
|
||||
\end{itemize}
|
||||
This little task is implemented in this module.
|
||||
|
||||
The interface to this looks like:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$dni {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __DataNumber *pDataNumber;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pDataNumber CreateDataNumber(char *pFilename);@\\
|
||||
\mbox{}\verb@ void DeleteDataNumber(void *pData);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int IncrementDataNumber(pDataNumber self, int *iYear);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int DecrementDataNumber(pDataNumber self);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int DNWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int DEWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int DNFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ 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 [CreateDataNumber] creates a data number data structure. It checks if
|
||||
the file requested as parameter exists and asserts if not. Returns a pointer
|
||||
on success, NULL else.
|
||||
\item [DeleteDataNumber] deletes a data number structure form memory.
|
||||
\item [IncrementDataNumber] is the main working function of this module.
|
||||
It performs the steps listed above. It returns a new id for the data number
|
||||
in case of success, a negative value otherwise. iYear is filled with a value
|
||||
for the year.
|
||||
\item[DecrementDataNumber] decrements the data number and is used for
|
||||
implementing the killdata function. Whis is the invalidation of a
|
||||
data file by overwriting it.
|
||||
\item[DNWrapper] is the wrapper function which makes DataNumber accessible
|
||||
from within SICS.
|
||||
\item[DEWrapper] is the wrapper for the killdata functionality.
|
||||
\item [DNFactory] is the SICS factory function which creates a Data Number
|
||||
object from the initialisation file. Only parameter is the filename.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"danu.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ D A T A N U M B E R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ A module to provide a unique data number for data file writing.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSDATANUMBER@\\
|
||||
\mbox{}\verb@#define SICSDATANUMBER@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$dni {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
322
doc/programmer/devexec.tex
Normal file
322
doc/programmer/devexec.tex
Normal file
@ -0,0 +1,322 @@
|
||||
\subsection{The Device Executor}
|
||||
The Device Executor (devexec) is a core component of the system. It has to
|
||||
fulfill three main tasks:
|
||||
\begin{itemize}
|
||||
\item Permit non--blocking hardware operations.
|
||||
\item Ensure regular monitoring of running devices.
|
||||
\item Ensure that only one client controls the hardware.
|
||||
\end{itemize}
|
||||
The devexec in its current form monitors driving and counting
|
||||
operations only. The emonitor implements another monitor for
|
||||
environment controllers.
|
||||
|
||||
Please note, that this module is quite crucial for the functioning of
|
||||
SICS. Any changes here may have side effects throughout the whole
|
||||
system. Be VERY careful with any changes. The current version does its job!
|
||||
|
||||
Some users want to continue typing commands while some hardware device is
|
||||
still running. This is sensible, because some hardware devices require a
|
||||
lot of time before they run to completion. Some people also require to count
|
||||
while driving motors for quick overview measurements. This requirement was
|
||||
the main reason for the invention of the devexec.
|
||||
|
||||
Of course, when devices are in operation it is needed to check on them
|
||||
regularly in order to catch and report error conditions and in order to
|
||||
find out when devices are finished with their job.
|
||||
|
||||
In a client server system many clients might issue commands to the hardware.
|
||||
This could quickly lead into an undesirable form of chaos (There are
|
||||
desirable forms of chaos, but not here!). In order to prevent this a means
|
||||
is needed to ensure that at any given time only one client controls the
|
||||
hardware. This function is also performed by the devexec.
|
||||
|
||||
The device executor also has to take care of special error conditions.
|
||||
|
||||
\subsubsection{Starting Devices}
|
||||
These are the most important SICS operations. Environment controllers are
|
||||
monitored by the environment monitor. Then here is a convention: {\bf Any
|
||||
SICS object which
|
||||
initiates driving or counting operations has to do so by registering this
|
||||
operation with the devexec}. For this purpose the following interface
|
||||
functions are provided.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$devreg {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,@\\
|
||||
\mbox{}\verb@ void *pData, SConnection *pCon, float fNew);@\\
|
||||
\mbox{}\verb@ int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
|
||||
\mbox{}\verb@ char *name, float fNew);@\\
|
||||
\mbox{}\verb@ int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,@\\
|
||||
\mbox{}\verb@ char *name); @\\
|
||||
\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 main interface function is {\bf StartDevice}. The parameters are:
|
||||
\begin{itemize}
|
||||
\item {\bf self}. A pointer to the device executor in which SICS operates.
|
||||
\item {\bf name}. The name of the object which operates.
|
||||
\item {\bf pDes}. A pointer to the ObjectDescriptor of the object to drive or count.
|
||||
\item {\bf pData}. A pointer to the data structure coming with the object.
|
||||
\item {\bf pCon}. A pointer to the client connection on whose request the
|
||||
operation was initiated.
|
||||
\item {\bf fNew}. A floating point value which sets the target value for
|
||||
drivable devices.
|
||||
\end{itemize}
|
||||
{\bf StartMotor, StartCounter} are just convenience wrappers around
|
||||
StartDevice which retrieve objects from the SICS interpreter and calls
|
||||
StartDevice thereafter.
|
||||
|
||||
Once invoked StartDevice takes care of the following operations:
|
||||
\begin{itemize}
|
||||
\item It first checks on the connection object. If nobody else is running
|
||||
hardware it enters the connection object specifed as owner of the devexec in
|
||||
its data structure. If an owner was already specified by a prior drive or
|
||||
count request StartDevice checks if the connection requesting the new
|
||||
operation is the same. If this is not the case, an error message about this
|
||||
situation will be issued. If it is the case, i. e. the client requesting the
|
||||
new operation is the same as the one who has reserved the devexec, the
|
||||
operation is performed. This scheme reserves the devexec to one client.
|
||||
\item If the authorisation is OK, StartDevice then proceeds to start the
|
||||
drive or counting operation.
|
||||
\item StartDevice then enters all information regarding
|
||||
the running device into an list for future monitoring.
|
||||
\item If it not already running a DevExecTask is registered with the
|
||||
task module in order to ensure the monitoring of the devices running.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Monitoring devices}
|
||||
|
||||
From within the SICS main loops this special function is called:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$devcheck {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int CheckExeList(pExeList self);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ checks the entries for success and deletes entries which have finished@\\
|
||||
\mbox{}\verb@ operation. If there are none left, the pOwner will be set to NULL.@\\
|
||||
\mbox{}\verb@ */ @\\
|
||||
\mbox{}\verb@ int Wait4Success(pExeList self);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ long GetDevexecID(pExeList self);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int DevExecTask(void *pEL);@\\
|
||||
\mbox{}\verb@ void DevExecSignal(void *pEL, int iSignal, void *pSigData);@\\
|
||||
\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}
|
||||
CheckExeList then scan through its list of executing objects and request a
|
||||
status from each of them. The next action depend on the status returned from
|
||||
the device and any pending interrupts:
|
||||
\begin{itemize}
|
||||
\item If the device is still busy and no interrupts are pending, nothing
|
||||
happens.
|
||||
\item If there is a hardware error, this will be reported and apropriate
|
||||
actions are intitiated depending on the type of problem and possible
|
||||
interrupts being sets.
|
||||
\item If a device is done, either naturally or due to an error or interrupt,
|
||||
it is removed from devexec's list.
|
||||
\item If the list is empty, the owner field of the devexec's datastructure
|
||||
is reset to NULL. Then a new client is free to grab control over the
|
||||
hardware.
|
||||
\end{itemize}
|
||||
|
||||
{\bf DevExecTask} is the task function for the device executor. Calls
|
||||
CheckExeList in the end. If all devices registered with the devexec
|
||||
are finished running this function returns 0 and thus stops.
|
||||
|
||||
{\bf DevExecSignal} is the signal function for the device executor task.
|
||||
|
||||
{\bf Wait4Success} This function waits for the DevExecTask to
|
||||
end. This is the case when the current devices running are finished.
|
||||
There are occasions in the program where it is needed to wait for
|
||||
an operation to complete before other tasks can be tackled. Wait4Success is
|
||||
the function to call in such cases. Wait4Success returns DEVDONE for a
|
||||
properly finished operation, DEVERROR for an operation which finished
|
||||
with an error code and DEVINT for an aoperation which was interrupted
|
||||
by the user.
|
||||
|
||||
\subsubsection{Influencing Execution}
|
||||
In certain cases it is necessary to interact with running devices directly.
|
||||
This is done via the following interface.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$devstop {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int StopExe(pExeList self, char *name);@\\
|
||||
\mbox{}\verb@ int StopExeWait(pExeList self);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ will stop the entry name and its subentries from executing.@\\
|
||||
\mbox{}\verb@ If ALL is specified as name, everything will be stopped and@\\
|
||||
\mbox{}\verb@ the Executor cleared.@\\
|
||||
\mbox{}\verb@ StopExeWait will stop all running things and wait for the stop@\\
|
||||
\mbox{}\verb@ to complete.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ void ClearExecutor(pExeList self);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ clears the executor without sending commands to the devices.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int IsCounting(pExeList self);@\\
|
||||
\mbox{}\verb@ int PauseExecution(pExeList self);@\\
|
||||
\mbox{}\verb@ int ContinueExecution(pExeList self);@\\
|
||||
\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 StopExe} tackles the interrupting of pending operations. This may
|
||||
happen on a users request. StopExe then invokes a halt on that device.
|
||||
As parameters, the name of a device to stop can be specified. If ALL is
|
||||
given as name to StopExe all executing devices are stopped. Please note, that
|
||||
this stop does not automatically finish the operation. Motors need some time
|
||||
to stop, too. This function is usally called as consequence of an
|
||||
interrupt.
|
||||
|
||||
|
||||
{\bf ClearExecutor} clears the executor without invoking commands on the
|
||||
devices. Is probably only used internally to clean out the executor.
|
||||
|
||||
I some cases, for example if a environment controller gets out of range, an
|
||||
error handling strategy may want to pause counting until the problem has
|
||||
been rectified and continue afterwards. {\bf PauseExecution, ContinueExecution}
|
||||
take care of invoking the apropriate commands on all registered counting
|
||||
devices.
|
||||
|
||||
|
||||
\subsubsection{The Rest}
|
||||
The rest of the interface includes initialisation and deletion routines
|
||||
and some access routines. With the devexec being such an important system
|
||||
component a function {\bf GetExecutor} is provided which retrieves a pointer
|
||||
to the global SICS device executor.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"devexec.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ D E V I C E E X E C U T O R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Joachim Kohlbrecher wants to give several commands to the server@\\
|
||||
\mbox{}\verb@ and than wait for them to happen before proceeding. Actually a useful@\\
|
||||
\mbox{}\verb@ thing. A command will map to one or several positioning commands for a@\\
|
||||
\mbox{}\verb@ device. This scheme is also useful for implementing objects which@\\
|
||||
\mbox{}\verb@ drive several motors simulataneously, such as Monochromators. etc.@\\
|
||||
\mbox{}\verb@ However, the whole thing is rather complicated.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ It is forbidden, that several clients drive the instrument. In order@\\
|
||||
\mbox{}\verb@ to ensure this the Executor remembers the connection which emitted the@\\
|
||||
\mbox{}\verb@ first command. Subsequent AddExeEntries from different clients will@\\
|
||||
\mbox{}\verb@ be rejected. The owner will be reset when the execution is found finished@\\
|
||||
\mbox{}\verb@ in calls to CheckExe, Wait4Success or StopExe.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, December 1996@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyright: see implementation file@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSDEVEXEC@\\
|
||||
\mbox{}\verb@#define SICSDEVEXEC@\\
|
||||
\mbox{}\verb@#include "obdes.h"@\\
|
||||
\mbox{}\verb@#include "task.h"@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __EXELIST *pExeList;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* Returncodes */@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#define DEVDONE 1@\\
|
||||
\mbox{}\verb@#define DEVINT 0@\\
|
||||
\mbox{}\verb@#define DEVERROR 2@\\
|
||||
\mbox{}\verb@#define DEVBUSY 3@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ B I R T H & D E A T H@\\
|
||||
\mbox{}\verb@*/@\\
|
||||
\mbox{}\verb@ pExeList CreateExeList(pTaskMan pTask);@\\
|
||||
\mbox{}\verb@ void DeleteExeList(void *self);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/* ================= Functions to talk to the above ====================== */@\\
|
||||
\mbox{}\verb@@$\langle$devreg {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$devcheck {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ Waits for execution to finish. returns 1 on Success, 0 if problems@\\
|
||||
\mbox{}\verb@ ocurred. Than the Interrupt code shall be checked and acted upon@\\
|
||||
\mbox{}\verb@ accordingly.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ SConnection *GetExeOwner(pExeList self);@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int isInRunMode(pExeList self);@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int ListPending(pExeList self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ lists the Operations still pending on pCon. @\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$devstop {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------- Commands ------------------------------------*/@\\
|
||||
\mbox{}\verb@ int StopCommand(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ implements the stop command@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ lists all currently executing objects@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ int Success(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ waits until completion of all pending operations. Used in@\\
|
||||
\mbox{}\verb@ connection with non blocking operation such as motors started@\\
|
||||
\mbox{}\verb@ with run.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/* -------------------------- Executor management -------------------------*/@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ pExeList GetExecutor(void);@\\
|
||||
\mbox{}\verb@ void SetExecutor(pExeList pExe);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
52
doc/programmer/difrac.tex
Normal file
52
doc/programmer/difrac.tex
Normal file
@ -0,0 +1,52 @@
|
||||
\subsection{The Difrac Subsystem}
|
||||
Difrac is a F77 package for controlling a four circle diffractometer
|
||||
developed by P. Gabe and White for PC's. This package became only
|
||||
available very late. This package has been included into SICS for four
|
||||
circle diffraction. All the code for the difrac package resides in the
|
||||
difrac subdirectory to sics. For more information about the difrac
|
||||
system see the documentation coming with difrac. In order to
|
||||
integrate difrac into SICS the following steps had to be taken:
|
||||
\begin{itemize}
|
||||
\item Define an interface from SICS to DIFRAC.
|
||||
\item Modify the DIFRAC hardware control to run the hardware through
|
||||
SICS.
|
||||
\item Adapt I/O
|
||||
\item Modify DIFRAC to be a subsystem instead of a program of its own.
|
||||
\item Adapt measurement procedures to the special needs of TRICS.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{The Interface SICS to DIFRAC}
|
||||
This is implemented in difrac.c. It it is just a interface wrapper
|
||||
function which takes the command given and forwards it to the DIFRAC
|
||||
interpreter. A tricky bit about this ist, that this module has to keep
|
||||
track of which cconnection issued the command. This is done through a
|
||||
connection stack.
|
||||
|
||||
\subsubsection{DIFRAC HW control}
|
||||
DIFRAC controls the hardware through a couple of function originally
|
||||
defined in the file ralf.f. This file has been replaced by a file
|
||||
trics.f which in turn calls C-functions implemented in difrac.c which
|
||||
do the actual job.
|
||||
|
||||
\subsubsection{DIFRAC I/O}
|
||||
In contrast to many F77 prograsm DIFRAC has a very intelligent I/O
|
||||
system. All input is channelled through the function GETLIN in
|
||||
gwrite.f. This function has been modified to call a C-function which
|
||||
gets a line of input from SICS. This adpater is again in difrac.c. All
|
||||
output is printed first into a internal string buffer, COUT, and then
|
||||
printed using the function GWRITE. This function has been modified to
|
||||
call a C-function which writes the output to a SICS connection. The
|
||||
integration of DIFRAC into SICS was only possible because of the
|
||||
existence of this I/O system.
|
||||
|
||||
\subsubsection{Changes in DIFRAC}
|
||||
The DIFRAC main program was taken apart into a initialisation routine
|
||||
(difini.f) and a callable interpreter function (difint.f). Further
|
||||
changes were required because TRICS does not do continous scans in the
|
||||
way a X-ray four circle diffractometer does. DIFRAC's concept of a
|
||||
scan drives a motor slowly and collects data. This has been modified
|
||||
to do step scans for TRICS. Some commands which do not make sense
|
||||
within SICS have been disabled. Some little changes to measurement
|
||||
routines were necessary.
|
||||
|
||||
|
48
doc/programmer/dmc.tex
Normal file
48
doc/programmer/dmc.tex
Normal file
@ -0,0 +1,48 @@
|
||||
\subsection{DMC module}
|
||||
This module initialises all DMC specific commands. Currently there is only
|
||||
one: StoreData. This does not do much, it is just here as a container for
|
||||
things to come.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int InitDmc(SConnection *pCon, SicsInterp *pSics, void *pData, @\\
|
||||
\mbox{}\verb@ 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{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"dmc.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ D M C @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ this modules purpose is solely to initialise the commands specific to@\\
|
||||
\mbox{}\verb@ the powder diffractometer DMC.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koenencke, March 1997@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSDMC@\\
|
||||
\mbox{}\verb@#define SICSDMC@\\
|
||||
\mbox{}\verb@@$\langle$Protos {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
30254
doc/programmer/dmccom.eps
Normal file
30254
doc/programmer/dmccom.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/programmer/dmccom.gif
Normal file
BIN
doc/programmer/dmccom.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
22
doc/programmer/drive.tex
Normal file
22
doc/programmer/drive.tex
Normal file
@ -0,0 +1,22 @@
|
||||
\subsection{The Drive and Run Command}
|
||||
This command implements driving of real motors or virtual motors (variables
|
||||
which control multiple motors). The drive command has no associated data
|
||||
structure going with it. There are just a few function:
|
||||
\begin{description}
|
||||
\item[int Drive(SConnection *pCon,SicsInterp *pSics, char *name, float
|
||||
fNew)] drives motor name to fNew and waits for the motor to finish. Possible
|
||||
errors will be written to the connection object pCon.
|
||||
\item[int Start2Run(SConnection *pCon, SicsInterp *pSics, char *name, float
|
||||
fNew)] starts the motor name to run to fNew. This
|
||||
function will NOT wait for the motor to get there. In spite of this,
|
||||
possible errors will be printed to the connection object pCon.
|
||||
\item[int DriveWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])] the object wrapper
|
||||
function for the drive command.
|
||||
\item[int RunWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])] the object wrapper
|
||||
function for the run command.
|
||||
\item[int MakeDrive(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])]
|
||||
The factory command which installs the drive and run commands into SICS.
|
||||
\end{description}
|
140
doc/programmer/dynar.tex
Normal file
140
doc/programmer/dynar.tex
Normal file
@ -0,0 +1,140 @@
|
||||
\subsection{Dynamic Array}
|
||||
This section describes a dynamic array of arbitrary pointers. Dynamic means,
|
||||
that the array gets enlarged automatically when an index outside of the
|
||||
current bounds has been requested. Negative values are supported as well.
|
||||
|
||||
The interface to this module looks like this:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$dynarint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __SDynar *pDynar;@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ pDynar CreateDynar(int iStart, int iEnd, int iGrain, @\\
|
||||
\mbox{}\verb@ void (*DataFree)(void *pData));@\\
|
||||
\mbox{}\verb@ void DeleteDynar(pDynar self);@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int DynarPut(pDynar self, int iIndex, void *pData);@\\
|
||||
\mbox{}\verb@ int DynarPutCopy(pDynar self, int iIndex, void *pData, int iDataLen);@\\
|
||||
\mbox{}\verb@ int DynarReplace(pDynar self, int iIndex, void *pData, int iDatLen);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int DynarGet(pDynar self, int iIndex, void **pData);@\\
|
||||
\mbox{}\verb@ int DynarGetCopy(pDynar self, int iIndex, void *pData, int iDataLen);@\\
|
||||
\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}
|
||||
If not stated otherwise, all functions return 1 on success and 0 on failure.
|
||||
|
||||
\begin{description}
|
||||
\item[CreateDynar] creates a new dynamic array. On success a pointer to a
|
||||
new dynamic array is returned, else NULL. The parameters are: iStart, the
|
||||
initial start index of the array, iEnd, the initial end index of the array,
|
||||
iGrain, the packet of new space to allocate when the array is enlarged
|
||||
dynamically, DataFree, a function which takes a pointer to one of the data
|
||||
items stored in the dynamic array and the free's all the memory associated
|
||||
with the data item. DataFree will be used automatically by Dynar for
|
||||
releasing memory when data items are replaced or the whole array is deleted.
|
||||
\item[DeleteDynar] removes the dynamic arary from memory. The pointer to
|
||||
self will point to rubbish afterwards and shall not be used.
|
||||
\item[DynarPut] puts the pointer pData at position iIndex in the dynamic
|
||||
array. pData needs to be allocated from dynamic memory, otherwise you'll
|
||||
experience core dumps. A data item which was previously at the position
|
||||
denoted by iIndex will be freed.
|
||||
\item[DynarPutCopy] does the same as DynarPut, but copies the data item.
|
||||
iDataLen bytes of new memory will be allocated and the data from pData be
|
||||
put into it. Then this will be entered into the dynamic array at position
|
||||
iIndex.
|
||||
\item[DynarReplace] replaces the data at iIndex by the data pointed to by
|
||||
pData by a memcpy. If there was no data defined previously, this call has
|
||||
the same effect as DynarPutCopy.
|
||||
\item[DynarGet] retrieves the pointer pData at position iIndex from the dynamic
|
||||
array.
|
||||
\item[DynarGetCopy] copies iDataLen bytes from the data at position iIndex
|
||||
into the buffer pData. pData must be large enough to hold iDataLen bytes.
|
||||
|
||||
\end{description}
|
||||
|
||||
Nowe, here is the definition of the internal datastructure for the
|
||||
dynamic array class.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$dynardat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __SDynar {@\\
|
||||
\mbox{}\verb@ int iStart;@\\
|
||||
\mbox{}\verb@ int iEnd;@\\
|
||||
\mbox{}\verb@ int iGrain;@\\
|
||||
\mbox{}\verb@ void **pArray;@\\
|
||||
\mbox{}\verb@ void (*DataFree)(void *pData);@\\
|
||||
\mbox{}\verb@ } Dynar;@\\
|
||||
\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}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"sdynar.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ D Y N A M I C A R R A Y@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This file describes the interface to a dynamic array module for pointers.@\\
|
||||
\mbox{}\verb@ This sort of array resizes dynamically.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSDYNAR@\\
|
||||
\mbox{}\verb@#define SICSDYNAR@\\
|
||||
\mbox{}\verb@@$\langle$dynarint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"sdynar.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ D Y N A M I C A R R A Y@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This file defines the internal data structure used by the dynamic@\\
|
||||
\mbox{}\verb@ array module.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ More info: see sdynar.h@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$dynardat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
218
doc/programmer/emonitor.tex
Normal file
218
doc/programmer/emonitor.tex
Normal file
@ -0,0 +1,218 @@
|
||||
\subsection{SICS Sample Environment Handling}
|
||||
In addition to driving motors and counting SICS has to take care of sample
|
||||
environment devices as well. These can be temperature controllers, current
|
||||
controllers etc. It can be assumed, that SICS has to take care of
|
||||
intelligent sample environment devices only, i. e. devices which do their
|
||||
own realtime processing. SICS, however, has to implement the logic to drive
|
||||
an environment controller to a new value. Furthermore SICS has to do the
|
||||
error handling when an environment controller fails. In order to do this the
|
||||
following software components will be needed:
|
||||
\begin{itemize}
|
||||
\item An environment monitor. This component will register any active
|
||||
environment control device. A test function will be called from the main
|
||||
loop which checks for controller out of range and initiates error handling.
|
||||
\item A new interface, the environment interface (see \ref{interface}).
|
||||
\item Controller objects. One for each environment controller. Again, the
|
||||
SICS distinction between logical objects and hardware drivers will be
|
||||
maintained.
|
||||
\end{itemize}
|
||||
|
||||
Controller objects will be able to share some code among them. Each
|
||||
environemnt controller will hold a target value, a permissable tolerance,
|
||||
a selctor variable which defines the type of error handling to perform and
|
||||
an interrupt code to issue when that form of error handling is choosen.
|
||||
Furthermore each environment controller needs to implement the drivable
|
||||
interface (for driving to new values) and the environment interface (for
|
||||
monitoring the controller). Controller object will also share the error
|
||||
handling during the monitor phase between them. The scheme is that each controller will have a
|
||||
variable which selects the error handling mechanism. Depending on this
|
||||
variable an error managment routine will be invoked. Current two schemes for
|
||||
handling errors are supported:
|
||||
\begin{itemize}
|
||||
\item Print a warning but do nothing else.
|
||||
\item Interrupt: an interrupt will be issued.
|
||||
\item Pause: the measurement will be paused.
|
||||
\item Try to drive to a safe value. This may be used to rescue a oven
|
||||
gone haywire by setting a low setpoint where the device is safe.
|
||||
\end{itemize}
|
||||
This scheme allows for adding more error handling strategies when necessary
|
||||
and to implement them in one place for all environment controllers.
|
||||
Consequently, there will be some some general controller code in files
|
||||
evcontrol.*. In the object oriented paradigm environment controller would
|
||||
inherit from this general controller. This is implemented by delegation in
|
||||
SICS.
|
||||
|
||||
Please note, that any environment device has three modes of
|
||||
operation. The first, trivial one, is idle. The second one is the driving
|
||||
phase. This phase is entered when a drive or run command tries to set the
|
||||
controller to a new value. Once this target has been reached a environment
|
||||
controller will be registered in the environment monitor which will take
|
||||
care of monitoring the controller during its operation. This is the
|
||||
third stage: inMonitor.
|
||||
|
||||
|
||||
\subsection{The Environment Monitor}
|
||||
The environment monitors (emon) task is to register all active environment
|
||||
controllers. It will be called from the main loop to check if each
|
||||
registered environment controller is still within tolerances. If not, emon
|
||||
has to enforce error processing. Else it does nothing.
|
||||
|
||||
The environment monitor uses the following datastructures:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$emondat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __EnvMon {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ int iList;@\\
|
||||
\mbox{}\verb@ int iEnd;@\\
|
||||
\mbox{}\verb@ } EnvMon;@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ pDummy pDum;@\\
|
||||
\mbox{}\verb@ char *pName;@\\
|
||||
\mbox{}\verb@ pEVInterface pInter;@\\
|
||||
\mbox{}\verb@ } EVEntry, *pEVEntry; @\\
|
||||
\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}
|
||||
As it it will be accessible as SICS object emon needs an object descriptor.
|
||||
The other data member is a list of active controllers.
|
||||
|
||||
The EVEntry structure contains the data held in the list for each active
|
||||
controller. It is, disguised as pDum, a pointer to the controllers
|
||||
datastructure, the name of the controller, and the environment interface of
|
||||
the controller.
|
||||
|
||||
The following interface is implemented by the environment monitor:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$emonint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pEnvMon CreateEnvMon(void);@\\
|
||||
\mbox{}\verb@ void DeleteEnvMon(void *pData);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int EVRegisterController(pEnvMon self, char *pName, void *pData,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int EVUnregister(pEnvMon self, char *name);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int EVMonitorControllers(pEnvMon self);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int EVList(pEnvMon self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int EVWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pEnvMon FindEMON(SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int EnvMonTask(void *pEv);@\\
|
||||
\mbox{}\verb@ void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);@\\
|
||||
\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 CreateEnvMon} initialises a emon data structure. As usual it returns
|
||||
NULL on error, a pointer to a new structure on success.
|
||||
|
||||
{\bf DeleteEnvMon} deletes and emon data structure and frees all memory
|
||||
associated with it.
|
||||
|
||||
{\bf EVRegisterController} registers a controller for monitoring. The
|
||||
parameters are:
|
||||
\begin{itemize}
|
||||
\item {\bf self}. A pointer to the environment monitor where to register the
|
||||
controller.
|
||||
\item {\bf pName}. The name of the controller object.
|
||||
\item {\bf pData}. A pointer to the data structure belonging to the
|
||||
controller object.
|
||||
\item {\bf pCon}. A pointer to the client connection to which erros shall be
|
||||
reported.
|
||||
\end{itemize}
|
||||
|
||||
{\bf EVUnregister} Removes the controller name from the monitoring list.
|
||||
|
||||
{\bf EVMonitorControllers} is the function which will be called from the
|
||||
main loop and which is responsible for monitoring the registered
|
||||
controllers.
|
||||
|
||||
|
||||
{\bf EVList} prints a status report about the emon to the Connection object
|
||||
specified.
|
||||
|
||||
{\bf EVWrapper} is the wrapper function necessary to make the emon
|
||||
available from SICS. The user may interact with the emon through SICS. The
|
||||
user will be enabled to list the currently registered environment
|
||||
controllers and their current state and to register and unnregister
|
||||
controllers.
|
||||
|
||||
{\bf EnvMonTask} is the task function associated with the environment
|
||||
monitor. This is called by the task handling object and eventually
|
||||
invokes EVMonitorControllers for checking on the environment
|
||||
controllers configured into SICS.
|
||||
|
||||
{\bf EnvMonSignal} is the signale handler for the environment monitor task.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"emon.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 M O N I T O R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ The environment monitor is responsible for monitoring active environment@\\
|
||||
\mbox{}\verb@ devices. @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@ doc: programmers reference.@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSEMON@\\
|
||||
\mbox{}\verb@#define SICSEMON@\\
|
||||
\mbox{}\verb@ typedef struct __EnvMon *pEnvMon;@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$emonint {\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{scrap4}
|
||||
\verb@"emon.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ Internal header file defining the datastructure for the environment@\\
|
||||
\mbox{}\verb@ controller.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$emondat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
321
doc/programmer/evcontroller.tex
Normal file
321
doc/programmer/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}
|
110
doc/programmer/evdrivers.tex
Normal file
110
doc/programmer/evdrivers.tex
Normal file
@ -0,0 +1,110 @@
|
||||
\subsubsection{LTC-11 Driver}
|
||||
This is a driver for the Kyocera LTC-11 temperature controller which
|
||||
is used with the Kryo furnace at SINQ (funny idea, a kryo
|
||||
furnace). As with the ITC-4 this device has a few special functions
|
||||
and requires an additional interpreter function which delegates to the
|
||||
standard one for the general stuff. This is mainly the switching of
|
||||
the operation mode of the LTC-11. It has two modes: analog mode and
|
||||
heater mode. For more details about this see the controller
|
||||
manual. The driver is implemented in the
|
||||
file ltc11.h and ltc11.c. The following functions, besides those
|
||||
required for the standard driver, are defined:
|
||||
|
||||
\begin{verbatim}
|
||||
pEVDriver CreateLTC11Driver(int argc, char *argv[]);
|
||||
|
||||
int LTC11GetMode(pEVDriver self, int *iMode);
|
||||
int LTC11SetMode(pEVDriver self, int iMode);
|
||||
|
||||
int LTC11Action(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
\end{verbatim}
|
||||
These are:
|
||||
\begin{description}
|
||||
\item[CreateLTC11Driver] creates a driver for a LTC-11. Returns a
|
||||
pointer to a newly allocated LTC-11 driver or NULL in case of failure.
|
||||
\item[LTC11GetMode] retrieves the current operation mode of the
|
||||
LTC-11.
|
||||
\item[LTC11SetMode] sets the operation mode for the LTC-11.
|
||||
\item[LTC11Action] The interpreter interface function for the
|
||||
LTC-11. Implements the special commands for the LTC-11 and calls
|
||||
EVControlWrapper for anything else.
|
||||
\end{description}
|
||||
|
||||
|
||||
\subsubsection{The Dillution Cryostat}
|
||||
This is the old monster cryostat inherited from Saphir. Its driver is
|
||||
implemented in dilludriv.h and dilludriv.c. There is additional code
|
||||
for this device in the hardsup subdirectory in the file dillutil.h and
|
||||
dillutil.c. This device has a fairly involved command protocoll. A
|
||||
change of the set point requires heater output and and various
|
||||
parameters for the resistance bridge used for temperature measurement
|
||||
to be set. Then the set value has to be formatted in a range specific
|
||||
way in a hexidecimal format. Most of this code is a C adaption of an
|
||||
earlier F77 code from Elsenhans. Additionally this controller does not
|
||||
provide a temperature but a resistance value. This resistance value
|
||||
has to be converted to temperature through a calibration table. Thus
|
||||
there is an additional file, dilu.tem, which holds this conversion
|
||||
table.
|
||||
|
||||
\subsubsection{Eurotherm Temperature Controller}
|
||||
SANS is Eurotherm temperature controller somewhere. These controllers
|
||||
are quite common and the problem may come up again. The Eurotherm
|
||||
supports not one but several command protocolls, each weirder then the
|
||||
other. The implementation here serves the EI-Bisynch protocoll. The
|
||||
thing ahs to be configured manually to run this protocoll. This
|
||||
protocoll uses specific message formats for communication, the command
|
||||
protocoll is not plain ASCII. For more details about the protocoll see
|
||||
the documentation coming with the gadget. Due to this protocoll
|
||||
restriction the usual Send function of the driver just returns an
|
||||
error. The driver is impelemwnted
|
||||
in file eurodriv.h and eurodriv.c. The following functions are
|
||||
provided:
|
||||
\begin{verbatim}
|
||||
pEVDriver CreateEURODriv(int argc, char *argv[]);
|
||||
|
||||
/*
|
||||
these are hooks to implement further functionality which,
|
||||
I'am sure, Joachim Kohlbrecher will request.
|
||||
*/
|
||||
int EuroGetParameter(void **pData, char *pPar, int iLen, float *fVal);
|
||||
int EuroSetParameter(void **pData, char *pPar, int iLen,
|
||||
char *pFormat, float fVal);
|
||||
|
||||
\end{verbatim}
|
||||
These are:
|
||||
\begin{description}
|
||||
\item[CreateEuroDriver] creates a driver for a Eurotherm controller. Returns a
|
||||
pointer to a newly allocated Eurotherm driver or NULL in case of failure.
|
||||
\item[EuroGetParameter] gets one out of many parameters possible with
|
||||
the Eurotherm. This is a hook to implement further functionality. For
|
||||
possible values for parameter names pPar see the Eurotherm
|
||||
documentation. iLen is the length of pPar.
|
||||
\item[LTC11SetParameter] retrieves the value of a parameter from the
|
||||
Eurotherm. Again a hook for further expansion. pFormat is the format
|
||||
how to print the parameter into the command string.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{EL755 Magnet Controller}
|
||||
This is a driver for the PSI manufactured EL755 magnet
|
||||
controller. There is additional code for this in the hardsup directory
|
||||
with files el755\_utility.*. The functions there are documented in that
|
||||
file. For SICS there is only an adapter to this implemented in
|
||||
el755driv.h and el755driv.c. The only external function is a driver
|
||||
creation function with the usual parameters and return values.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
143
doc/programmer/event.tex
Normal file
143
doc/programmer/event.tex
Normal file
@ -0,0 +1,143 @@
|
||||
\subsection{SICS Events}
|
||||
This section lists the callback events known to Sics, their purpose, and
|
||||
their associated event datastructures when applicable. See the
|
||||
\ref{inter} section about callbacks for more information about
|
||||
callbacks. This only defines the integer codes possible. Please be
|
||||
aware that the implementation of the callbacks is a duty of the SICS
|
||||
objects generating it. The mentioning of an event code here means it
|
||||
is used somewhere in SICS but does not mean that it is implemented by
|
||||
all objects which might implement the event.
|
||||
|
||||
This module defines several event related functions as well.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$eFunc {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int Text2Event(char *pText);@\\
|
||||
\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 Text2Event } converts a text value into an event code. It returns -1
|
||||
if the event code is not known, else the apropriate event code.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$VE {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#define VALUECHANGE 0@\\
|
||||
\mbox{}\verb@#define MOTDRIVE 1@\\
|
||||
\mbox{}\verb@#define MONITOR 2 @\\
|
||||
\mbox{}\verb@#define ROTSTART 3@\\
|
||||
\mbox{}\verb@#define ROTMOVE 4@\\
|
||||
\mbox{}\verb@#define SCANEND 5@\\
|
||||
\mbox{}\verb@#define SCANSTART 6@\\
|
||||
\mbox{}\verb@#define SCANPOINT 7@\\
|
||||
\mbox{}\verb@#define WLCHANGE 8@\\
|
||||
\mbox{}\verb@#define REFLECTIONDONE 9@\\
|
||||
\mbox{}\verb@#define COUNTSTART 10@\\
|
||||
\mbox{}\verb@#define COUNTEND 11@\\
|
||||
\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[VALUECHANGE] This is a variable changing its value. As event data a pointer to the
|
||||
SicsVariable is passed along. This is defined in sicsvar.h.
|
||||
\item[MOTDRIVE] a motor is moving. The event data is the current position.
|
||||
\item[MONITOR] The control value for a counting operation has changed.
|
||||
The event data is the new value.
|
||||
\item[ROTSTART] A velocity selector is starting up.
|
||||
\item[ROTMOVE] A velocity selector changes its rotation speed.
|
||||
\item[SCANEND] A scan has ended.
|
||||
\item[SCANSTART] A new scan has been started.
|
||||
\item[SCANPOINT] A scan point has finished and there is new data.
|
||||
\item[WLCHANGE] is incoked when the wavelength of a crystal monochromator
|
||||
changes. The event parameter is a pointer to the wave length or energy
|
||||
variable being driven. Client code can then get what it needs to know.
|
||||
\item[REFLECTIONDONE] is issued when a single reflection of a four circle
|
||||
fiffractometer has been measured.
|
||||
\item[COUNTSTART] is an event which signals the start of a counting
|
||||
operation.
|
||||
\item[COUNTEND] is an event signalling the end of a counting operation.
|
||||
\end{description}
|
||||
|
||||
Furthermore event contains system wide signal codes which are interpreted in
|
||||
the signal functions provided by each SICS task. These code are
|
||||
evaluated by the TaskSignalFunction which may be configured for each
|
||||
SICS task. See the task section for more information. Here, only
|
||||
possible codes are defined.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$VSIG {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#define SICSINT 300@\\
|
||||
\mbox{}\verb@#define SICSBROADCAST 301@\\
|
||||
\mbox{}\verb@#define TOKENGRAB 302@\\
|
||||
\mbox{}\verb@#define TOKENRELEASE 303@\\
|
||||
\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[SICSINT] An interrupt has ocurred. The signal data is the interrupt
|
||||
number which ocurred.
|
||||
\item[SICSBROADCAST] A message shall be sent to each SICS client. The signal
|
||||
data is the string to send.
|
||||
\item[TOKENGRAB] A connection has successfully grabbed the control token.
|
||||
\item[TOKENRELEASE] A connection has released the control token.
|
||||
|
||||
\end{description}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"event.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ E V E N T@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This header file lists the event codes known to SICS. These event code@\\
|
||||
\mbox{}\verb@ are used in callback functions. Where apropriate, the event data@\\
|
||||
\mbox{}\verb@ structures are also defined in this file.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSEVENT@\\
|
||||
\mbox{}\verb@#define SICSEVENT@\\
|
||||
\mbox{}\verb@@$\langle$eFunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$VE {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------- Signals for the Signalfunction of each task ------------*/@\\
|
||||
\mbox{}\verb@@$\langle$VSIG {\footnotesize ?}$\rangle$\verb@ @\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
70
doc/programmer/faverage.tex
Normal file
70
doc/programmer/faverage.tex
Normal file
@ -0,0 +1,70 @@
|
||||
\subsection{The FOCUS Averager}
|
||||
This is a special object for the instrument FOCUS and its Status display
|
||||
client. In the FOCUS status display the averaged data from a number of
|
||||
detectors is displayed. Thus there is already a reduced form of data. The
|
||||
actual raw data would be 150*1024*4 bytes of data and possibly more. Rather
|
||||
then transporting all this data to the status display client at regular
|
||||
intervalls it was choosen to implement this averaging process at the server
|
||||
and only send the reduced form to the status display client. Which is two
|
||||
arrays of floating point data 1024 items long. This little object implements this
|
||||
averager.
|
||||
|
||||
As all SICS objects this object has a little data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct __FocusAverager {
|
||||
pObjectDescriptor pDes;
|
||||
pHistMem pHist;
|
||||
} FocusAverager;
|
||||
\end{verbatim}
|
||||
|
||||
The two fields are the standard object descriptor and a pointer to the
|
||||
histogram memory object holding the data.
|
||||
|
||||
The interface is minimal: it consists just of the factory function for
|
||||
installing this object into SICS and the actual function doing the
|
||||
averaging in the interpreter.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$faint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int MakeFA(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int FocusAverageDo(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\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}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"faverage.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ F o c u s A v e r a g e@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ An averager for FOCUS data. See faverage.tex for more details.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, October 1998@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef FOCUSAVERAGE@\\
|
||||
\mbox{}\verb@#define FOCUSAVERAGE@\\
|
||||
\mbox{}\verb@@$\langle$faint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
22
doc/programmer/fowrite.tex
Normal file
22
doc/programmer/fowrite.tex
Normal file
@ -0,0 +1,22 @@
|
||||
\subsection{FOCUS Data File Writing}
|
||||
FOCUS writes NeXus files. This file writing is impleneted in the files
|
||||
fowrite.h and fowrite.c. So these files contain the code for writing
|
||||
FOCUS NeXus files. But there is more to it: FOCUS has a scheme where
|
||||
the data file is updated any 20 minutes during the course of an
|
||||
measurement. This scheme is implemented with the following bits and
|
||||
pieces:
|
||||
\begin{itemize}
|
||||
\item Data file updating is triggered by a special task function,
|
||||
FoTask, which is installed into the SICS tasker when counting starts.
|
||||
\item The module registers callbacks with the histogram memory which
|
||||
are invoked when counting starts or ends. These callback functions
|
||||
take care of craeting a new file and updating it.
|
||||
\item There is a special command which allows to start and update the
|
||||
data file manually.
|
||||
\end{itemize}
|
||||
|
||||
As is it not likely that more then one FOCUS writing object is ever
|
||||
needed, all the data structures are file statics in fowrite.c. The
|
||||
external interface of this module is just a interpreter initialisation
|
||||
function and a interpreter interface function for interacting with the
|
||||
data file writing object.
|
83
doc/programmer/fupa.tex
Normal file
83
doc/programmer/fupa.tex
Normal file
@ -0,0 +1,83 @@
|
||||
\subsection{Function Parser}
|
||||
A utility module to take some of the pain from parsing input while
|
||||
writing text wrapper function for SICS.
|
||||
The idea is that you specify an array of function templates.
|
||||
These function templates will contain function names and argument
|
||||
information. This module will than parse the input against this
|
||||
template. It will return -1 if an error occurs and provide error
|
||||
information.
|
||||
On success the index of the function found will be returned.
|
||||
Arguments will have been updated with their proper values.
|
||||
Invoking functions ist still your job, probably in a switch statement
|
||||
following the call to the evaluation function.
|
||||
|
||||
The function parser supports these different argument types:
|
||||
\begin{verbatim}
|
||||
#define FUPATEXT 0 /* text*/
|
||||
#define FUPAINT 1 /* integer */
|
||||
#define FUPAFLOAT 2 /* a float */
|
||||
#define FUPAOPT 3 /* optional argument, in this case text contains it
|
||||
and iVal indicates its presence
|
||||
*/
|
||||
\end{verbatim}
|
||||
|
||||
Each template for a function has these fields:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
char *name;
|
||||
int iArgs;
|
||||
int pArgs[MAXARG];
|
||||
} FuncTemplate, *pFuncTemplate;
|
||||
\end{verbatim}
|
||||
\begin{description}
|
||||
\item[name] the name of the function.
|
||||
\item[iArgs] The number of arguments to the function.
|
||||
\item[pArgs] An array with iArgs entries of the integer argument description
|
||||
types stated above.
|
||||
\end{description}
|
||||
|
||||
On return the actual values of the arguments will be returned as a field in
|
||||
this structure, according to type.
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
char text[80];
|
||||
int iVal;
|
||||
float fVal;
|
||||
} FuPaArg;
|
||||
\end{verbatim}
|
||||
|
||||
The whole result is returned in the structure defined below:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
char pError[132];
|
||||
int iArgs;
|
||||
FuPaArg Arg[MAXARG];
|
||||
} FuPaResult;
|
||||
|
||||
\end{verbatim}
|
||||
The fields are: \begin{description}
|
||||
\item[pError] An error description in case of an error.
|
||||
\item[iArgs] the number of arguments actually read.
|
||||
\item[Arg] An array of argumnet result structures as defined above.
|
||||
\end{description}
|
||||
|
||||
Function parsing is done with this function:
|
||||
\begin{verbatim}
|
||||
int EvaluateFuPa(pFuncTemplate pTemplate,int iFunc, int argc, char *argv[],
|
||||
FuPaResult *pRes);
|
||||
\end{verbatim}
|
||||
The parameters are:
|
||||
\begin{description}
|
||||
\item[pTemplate] a parsing template.
|
||||
\item[iFunc] The number of functions in the template array.
|
||||
\item[argc,argv] The text to parse.
|
||||
\item[pRes] A pointer to a retuned result array.
|
||||
\end{description}
|
||||
The return value is -1 on error, or the number of the template identified on
|
||||
success.
|
||||
|
||||
|
||||
For more information, look on a usage example in counter.c.
|
||||
|
||||
|
||||
|
463
doc/programmer/hart.eps
Normal file
463
doc/programmer/hart.eps
Normal file
@ -0,0 +1,463 @@
|
||||
%!
|
||||
%%BoundingBox: 24 540 514 775
|
||||
%%Title: hart
|
||||
%%CreationDate: Fri May 30 10:02:56 1997
|
||||
%%Creator: Tgif-3.0-p7 by William Chia-Wei Cheng (william@cs.UCLA.edu)
|
||||
|
||||
/tgifdict 4 dict def
|
||||
tgifdict begin
|
||||
|
||||
/tgifellipsedict 6 dict def
|
||||
tgifellipsedict /mtrx matrix put
|
||||
|
||||
/tgifellipse
|
||||
{ tgifellipsedict begin
|
||||
/yrad exch def
|
||||
/xrad exch def
|
||||
/y exch def
|
||||
/x exch def
|
||||
/savematrix mtrx currentmatrix def
|
||||
x y translate
|
||||
xrad yrad scale
|
||||
0 0 1 0 360 arc
|
||||
savematrix setmatrix
|
||||
end
|
||||
} def
|
||||
|
||||
end
|
||||
|
||||
%%PageBoundingBox: 24 540 514 775
|
||||
tgifdict begin
|
||||
/tgifsavedpage save def
|
||||
|
||||
1 setmiterlimit
|
||||
1 setlinewidth
|
||||
|
||||
0 setgray
|
||||
|
||||
72 0 mul 72 11.00 mul translate
|
||||
72 128 div 100.000 mul 100 div dup neg scale
|
||||
|
||||
gsave
|
||||
|
||||
/tgiforigctm matrix currentmatrix def
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
112 163 moveto 227 163 lineto 227 189 lineto 112 189 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
125 99 moveto 214 99 lineto 214 150 lineto 125 150 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
202 112 moveto 202 138 lineto 138 138 lineto 138 112 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
368 99 moveto 509 99 lineto 509 176 lineto 368 176 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
573 75 moveto (Motor Controller) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
573 139 moveto (Motor Controller) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
573 228 moveto (Counter Box) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
573 305 moveto (Counter) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
368 382 moveto (Histogram) show
|
||||
368 399 moveto (Memory) show
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
560 202 moveto 726 202 lineto 726 240 lineto 560 240 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
330 355 moveto 483 355 lineto 483 445 lineto 330 445 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
48 266 moveto
|
||||
483 266 lineto
|
||||
tgiforigctm setmatrix
|
||||
5 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
432 176 moveto
|
||||
432 266 lineto
|
||||
tgiforigctm setmatrix
|
||||
5 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
150 189 moveto
|
||||
150 266 lineto
|
||||
tgiforigctm setmatrix
|
||||
5 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
381 266 moveto
|
||||
381 355 lineto
|
||||
tgiforigctm setmatrix
|
||||
5 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
176 292 moveto (TCP/IP) show
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
509 112 moveto
|
||||
560 74 lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
509 138 moveto
|
||||
560 138 lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
509 163 moveto
|
||||
560 214 lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
611 240 moveto
|
||||
611 291 lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
624 240 moveto
|
||||
624 291 lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
483 75 moveto (RS-232) show
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
560 48 moveto 752 48 lineto 752 96 lineto 560 96 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
560 112 moveto 752 112 lineto 752 160 lineto 560 160 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
560 288 moveto 672 288 lineto 672 320 lineto 560 320 lineto
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
384 126 moveto (Terminal) show
|
||||
384 143 moveto (Server) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
864 62 moveto (M1) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
864 126 moveto (M2) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
864 190 moveto (M3) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
864 254 moveto (M4) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
864 334 moveto (M5) show
|
||||
grestore
|
||||
|
||||
% OVAL
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath 864 56 32 24 tgifellipse
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% OVAL
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath 880 120 32 24 tgifellipse
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% OVAL
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath 880 184 32 24 tgifellipse
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% OVAL
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath 880 248 32 24 tgifellipse
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% OVAL
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath 880 328 32 24 tgifellipse
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
752 64 moveto
|
||||
832 48 lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
752 80 moveto
|
||||
848 112 lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
752 144 moveto
|
||||
848 176 lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
752 144 moveto
|
||||
848 240 lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
752 144 moveto
|
||||
848 320 lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
96 238 moveto (Data Aquisition Computer) show
|
||||
grestore
|
||||
|
||||
grestore
|
||||
tgifsavedpage restore
|
||||
end
|
||||
%MatchingCreationDate: Fri May 30 10:02:56 1997
|
BIN
doc/programmer/hart.gif
Normal file
BIN
doc/programmer/hart.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
656
doc/programmer/histogram.tex
Normal file
656
doc/programmer/histogram.tex
Normal file
@ -0,0 +1,656 @@
|
||||
|
||||
\subsection{Histogram memory}
|
||||
A histogram memory is the interface to a large multidetector. This is quite
|
||||
a complex piece of equipment. It does not only provide lots of data but also
|
||||
has a lot of configuration options. Things which need configuration are:
|
||||
histogram mode, overflow mode, measurement mode and the layout of the
|
||||
histograms. Let's discuss these different modes first.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$Modes {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef enum {@\\
|
||||
\mbox{}\verb@ eHTransparent,@\\
|
||||
\mbox{}\verb@ eHNormal,@\\
|
||||
\mbox{}\verb@ eHTOF,@\\
|
||||
\mbox{}\verb@ eHStrobo,@\\
|
||||
\mbox{}\verb@ eHRPT@\\
|
||||
\mbox{}\verb@ } HistMode;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
A histogram memory can be operated in transparent mode. It has not yet been
|
||||
defined what this means but it is sort of storing raw data from the detector
|
||||
without any summing or processing. Normal mode is better defined, this is
|
||||
sorting and summing data from the detector into apropriate bins for each
|
||||
detector. Time is not resolved. TOF mode means time of flight mode. In this
|
||||
mode incoming is not only sorted and summed into the correct detector bins
|
||||
but also resolved in time (which means energy for neutrons). This means for
|
||||
each detector there is a histogram counts versus time. Similar is
|
||||
stroboscopic mode (eHStrobo). In stroboscopic mode there is a histogram
|
||||
counts versus pulses for each physical detector. The bin switching is done
|
||||
via a secondary hardware signal or from software. This is useful for
|
||||
measuring diffraction data versus oscillating environment conditions. eHRPT
|
||||
is a special mode for the HRPT Cerca detector. It requires special handling,
|
||||
this is why there is a special flag.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$Modes {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef enum {@\\
|
||||
\mbox{}\verb@ eOIgnore,@\\
|
||||
\mbox{}\verb@ eOCeil,@\\
|
||||
\mbox{}\verb@ eOCount,@\\
|
||||
\mbox{}\verb@ eReflect@\\
|
||||
\mbox{}\verb@ } OverFlowMode;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
Histogram memories may support different schemes for handling overflow
|
||||
conditions. In this condition there are more counts than fit into the
|
||||
configured
|
||||
binwidth. The simplest thing to do is to ignore the condition and simply
|
||||
wrap over to zero (eOIgnore). The other mode is to keep the bin at the
|
||||
highest count possible (eOCeil). More sophisticated histogram memories
|
||||
maintain a separate list where all those overflowed bins are registered.
|
||||
This is eOCount. eReflect has nothing to do with overflows. It says that the
|
||||
histogram should be reflected. This means counter 1 becomes counter max etc.
|
||||
This is special for HRPT. It happens to live in the OverFlowMode enum because
|
||||
this is really a sub mode descriptor.
|
||||
|
||||
The measurement mode is the simple counter operation mode: wait for a timer
|
||||
or wait for a monitor to run full.
|
||||
|
||||
The layout of the histogram memory (HM) is defined by the rank (i.e. the number
|
||||
of dimensions of the HM, the number of points in each dimension and by the
|
||||
binwidth in bits for each bin. For TOF and stroboscopic modes information
|
||||
about the binning in time or pulses is needed as well. Needless to say that
|
||||
these values have to match the geometry of the detector.
|
||||
|
||||
Histograms usually have a number type associated with them. In order to
|
||||
minimise conversion overhead in the logical object, the data size will
|
||||
defined by a typedef, HistInt.
|
||||
|
||||
There is a scheme for handling all this configuration information
|
||||
which may even be more for a Histogram memory with a specific
|
||||
driver. There is a dictionary of configuration options in the logical
|
||||
histogram memory object. These options can be set with a special
|
||||
command. Then on initialisation first the logical histogram memory
|
||||
evaluates the general options and then the driver in its Config
|
||||
function evaluates the driver specific options.
|
||||
|
||||
|
||||
\subsubsection{The Histogram memory driver}
|
||||
Adhering to the Sics paradigm of dividing any device into a logical device
|
||||
and a hardware driver, the Sics histogram memory needs drivers as well. This
|
||||
section describes this driver interface. For an overview, see the structure
|
||||
definition:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$HistType {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HistDriver {@\\
|
||||
\mbox{}\verb@ /* configuration data */@\\
|
||||
\mbox{}\verb@ HistMode eHistMode;@\\
|
||||
\mbox{}\verb@ OverFlowMode eFlow;@\\
|
||||
\mbox{}\verb@ int iRank;@\\
|
||||
\mbox{}\verb@ int iDims[MAXDIM];@\\
|
||||
\mbox{}\verb@ int nDim;@\\
|
||||
\mbox{}\verb@ int iLength;@\\
|
||||
\mbox{}\verb@ int iBinWidth;@\\
|
||||
\mbox{}\verb@ float fTime[MAXCHAN];@\\
|
||||
\mbox{}\verb@ int iTimeChan;@\\
|
||||
\mbox{}\verb@ /* counting operations data */@\\
|
||||
\mbox{}\verb@ CounterMode eCount;@\\
|
||||
\mbox{}\verb@ float fCountPreset;@\\
|
||||
\mbox{}\verb@ /* status flags */@\\
|
||||
\mbox{}\verb@ int iReconfig;@\\
|
||||
\mbox{}\verb@ int iUpdate;@\\
|
||||
\mbox{}\verb@ /* interface functions */@\\
|
||||
\mbox{}\verb@ int (*Configure)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon,@\\
|
||||
\mbox{}\verb@ pStringDict pOpt,@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@ int (*Start)(pHistDriver self, @\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*Halt)(pHistDriver self);@\\
|
||||
\mbox{}\verb@ int (*GetCountStatus)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*GetError)(pHistDriver self, @\\
|
||||
\mbox{}\verb@ int *iCode,@\\
|
||||
\mbox{}\verb@ char *perror,@\\
|
||||
\mbox{}\verb@ int iErrlen);@\\
|
||||
\mbox{}\verb@ int (*TryAndFixIt)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ int iCode);@\\
|
||||
\mbox{}\verb@ int (*GetData)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*GetHistogram)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon,@\\
|
||||
\mbox{}\verb@ int i,@\\
|
||||
\mbox{}\verb@ int iStart, int iEnd,@\\
|
||||
\mbox{}\verb@ HistInt *pData);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int (*SetHistogram)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon,@\\
|
||||
\mbox{}\verb@ int i,@\\
|
||||
\mbox{}\verb@ int iStart, int iEnd,@\\
|
||||
\mbox{}\verb@ HistInt *pData);@\\
|
||||
\mbox{}\verb@ long (*GetMonitor)(pHistDriver self, @\\
|
||||
\mbox{}\verb@ int i,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ float (*GetTime)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*Preset)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon,@\\
|
||||
\mbox{}\verb@ HistInt iVal);@\\
|
||||
\mbox{}\verb@ int (*Pause)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*Continue)(pHistDriver self,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int (*FreePrivate)(pHistDriver self);@\\
|
||||
\mbox{}\verb@ void *pPriv;@\\
|
||||
\mbox{}\verb@ } HistDriver;@\\
|
||||
\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}
|
||||
Quite a lot, but a histogram memory is quite a complex piece of equipment.
|
||||
The configuration information is in the elements EhistMode, eOverFlowMode,
|
||||
iRank, iDims and iBinWidth fields. iDim and nDim desribe the logical
|
||||
dimensions of the histogram memory. These may be different from the
|
||||
dimensions used for data transfer. For instance the SANS detector is
|
||||
handled internally as 1600+ numbers where it really is a filed o
|
||||
128*128.
|
||||
Additionally there is an array of
|
||||
floating point values which denote the time binning for time-o-flight
|
||||
operation or the stroboscopic binning axis in stroboscopic mode.
|
||||
|
||||
The fields fPreset and CounterMode hold the counting parameter data.
|
||||
|
||||
Than there are two status fields. The first is iReconfig. This will be set
|
||||
to true, whenever any changes to the configuration to the HM are made. This
|
||||
will be tested against when starting a measurement and will force a
|
||||
configuration call to be issued. A call to the interface function Configure
|
||||
clears this flag. The other flag is iUpdate. This is only useful when an in
|
||||
memory copy of the histogrammed data is maintained on the host computer.
|
||||
This flag is set when a count gets started and gets cleared when counting is
|
||||
finished and all data has been transferred.
|
||||
|
||||
The next part defines the hardware interface functions to the histogram
|
||||
memory. Each of these functions must be defined by any complete
|
||||
implementation of a HM driver. If not stated otherwise these functions
|
||||
return 1 on success and 0 on failure. All functions take a pointer to their
|
||||
HistDriver structure as first parameter. Many functions have a pointer to an
|
||||
SConnection as parameter. This connection will be used for error reporting.
|
||||
|
||||
|
||||
\begin{itemize}
|
||||
\item {\bf Configure} configures the histogram memory to the specifications
|
||||
given in the fields of the HMdriver structure. Further driver specific
|
||||
information can be read from the options dictionary passed in.
|
||||
\item {\bf Start} starts a counting operation according to the current
|
||||
settings of the counter mode parameters.
|
||||
\item {\bf Halt} implements an emergency stop of a counting operation.
|
||||
\item {\bf GetCountStatus} serves to monitor the status of the counting
|
||||
operation. Possible return values to this call are:
|
||||
\begin{itemize}
|
||||
\item HWBUSY when still counting.
|
||||
\item HWNoBeam when the monitor is to low.
|
||||
\item HWIDLE or OKOK when nothing is going on.
|
||||
\item HWFault when there is an error on the device.
|
||||
\end{itemize}
|
||||
\item {\bf GetError} will be called whenever an error has been detected on
|
||||
the device. The task is to put an internal error code into the iCode
|
||||
parameter. The string parameter error will be filled with a text description
|
||||
of the error. But maximum iLen characters will be transferred to the error
|
||||
string in order to protect against memory corruption. Therefore iLen must be
|
||||
the maximum field length of error.
|
||||
\item {\bf TryAndFixIt} is the next function called in case of an error on
|
||||
the device. Its second parameter is the internal code obtained in the ICode
|
||||
parameter of the call to GetError. The task of this function is to examine
|
||||
the error code and do whatever is possible in software to fix the problem.
|
||||
TryAndFixIt returns one of the following values:
|
||||
\begin{itemize}
|
||||
\item MOTREDO when the error could be fixed, but the upper level code will
|
||||
need to rerun the command which failed.
|
||||
\item MOTFAIL when the software is unable to fix the problem and a real
|
||||
mechanic with a hammer is needed (or somebody able to reboot!).
|
||||
\item MOTOK when the error was fixed and nor further action is necessary.
|
||||
\end{itemize}
|
||||
\item {\bf GetData} transfers all the data collected in the HM into the
|
||||
host computers memory.
|
||||
\item {\bf GetHistogram} copies the histogram number i into the data space
|
||||
given by the pointer to a long array. A conversion from different binwidth
|
||||
to long is performed as well.
|
||||
\item {\bf SetHistogram} presets the histogram number i with the data
|
||||
given in lData. A conversion from different binwidth
|
||||
to long is performed as well. iStart and iStop define the start and end of
|
||||
the stretch of histogram to replace.
|
||||
\item {\bf GetMonitor} returns the counts in the monitor i. Returns a
|
||||
negative value on error. The error will have been printed to pCon.
|
||||
\item {\bf GetTime} returns the actual counting time.
|
||||
\item {\bf Preset} initializes the histogram memory to the value given by
|
||||
iVal.
|
||||
\item {\bf Pause} pauses data collection.
|
||||
\item {\bf Continue} continues a paused data collection.
|
||||
\item {\bf FreePrivate} will be called automatically by DeleteHistDriver and
|
||||
has the task to remove the private data installed by implementations of an
|
||||
actual histogram memory driver.
|
||||
\end{itemize}
|
||||
|
||||
The last entry in the HistDriver structure is a pointer to void. Rather then use the overlay structure as with motor drivers, histogram
|
||||
memory stores driver specific information in a driver specific sub
|
||||
data structure. This is the pointer to pPrivate. KillPrivate is a
|
||||
function which is able to delete the driver specific data structure
|
||||
properly.
|
||||
|
||||
As all the burden is up to the implementation of the histogram memory driver
|
||||
only these few functions operate on histogram memory drivers in general:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
$\langle$HistDrivProt {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pHistDriver CreateHistDriver(pStringDict pDict);@\\
|
||||
\mbox{}\verb@ void DeleteHistDriver(pHistDriver self);@\\
|
||||
\mbox{}\verb@ int HistDriverConfig(pHistDriver self, pStringDict pOpt,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\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}
|
||||
CreateHistDriver creates a new HistDriver data structure and returns it. Or
|
||||
NULL when the memory is exhausted. It also initialises the options database
|
||||
in pDict to the apropriate values.
|
||||
|
||||
|
||||
DeleteHistDriver removes a histogram memory driver from memory. It will
|
||||
automatically try and call Freeprivate in order to remove driver specific
|
||||
data. Than an the rest is removed. After this call self will point to
|
||||
rubbish.
|
||||
|
||||
|
||||
\subsubsection{The histogram memory object}
|
||||
Most of the HM data will be held with the driver as it is needed there for
|
||||
performing operations. Accordingly the datastructure associated with the
|
||||
histogram memory object is fairly simple:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
$\langle$HistST {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HistMem {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ int iAccess;@\\
|
||||
\mbox{}\verb@ int iExponent;@\\
|
||||
\mbox{}\verb@ pHistDriver pDriv;@\\
|
||||
\mbox{}\verb@ int iInit;@\\
|
||||
\mbox{}\verb@ pICountable pCountInt;@\\
|
||||
\mbox{}\verb@ pICallBack pCall;@\\
|
||||
\mbox{}\verb@ pStringDict pOption;@\\
|
||||
\mbox{}\verb@ HistInt *iLocalData;@\\
|
||||
\mbox{}\verb@ int iLocalLength;@\\
|
||||
\mbox{}\verb@ int iLocalUpdate;@\\
|
||||
\mbox{}\verb@ time_t tLocal;@\\
|
||||
\mbox{}\verb@ int iUpdateIntervall;@\\
|
||||
\mbox{}\verb@ } HistMem;@\\
|
||||
\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}
|
||||
According to the general Sics object interface the first field is the object
|
||||
descriptor. Note, that the histogram memory has to adhere to the countable
|
||||
objects interface. iAccess is the access code used to control user
|
||||
interaction with the HM. iExponent is the force of 10 used for calculating
|
||||
the actual preset value for counting in monitor mode.
|
||||
However, note, that all configuration commands will
|
||||
require Manager privilege at least. Then there is a pointer to the
|
||||
driver followed by pointers to the interfaces implemented by the histogram
|
||||
memory. pOption is a string dictionary of configuration options for the
|
||||
histogram memory.
|
||||
|
||||
In order to save network bandwidth and for efficiency the histogram memory
|
||||
object buffers the histogram memory in memory. The histogram itself resides
|
||||
in iLocalData. iLocalLength is the length of iLocalData. iLocalUpdate is a
|
||||
flag which will be set when counting operations (histogram changes ) are
|
||||
going on and cleared when the histogram has been completely read.
|
||||
When counting the local data will be updated only at certain intervalls.
|
||||
This is a configuration option. iUpdateIntervall is that intervall in
|
||||
seconds, tLocal is the time for the next scheduled update.
|
||||
|
||||
|
||||
The interaction with the histogram memory can be classified into four
|
||||
groups: basic initialisation and destruction, configuration, counting and
|
||||
data retrieval. The first group to look at are the basics:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pHistMem CreateHistMemory(char *drivername);@\\
|
||||
\mbox{}\verb@ void DeleteHistMemory(void *self);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
CreateHistMem creates a new histogram memory.
|
||||
On error this
|
||||
call returns NULL. On success a pointer to the new histogram memory object.
|
||||
CreateHistMem does NOT configure anything! A driver gets selected according
|
||||
to the driver name.
|
||||
|
||||
DeleteHistMemory removes a histogram memory from computer memory.
|
||||
Any references to self afterwards will
|
||||
point to rubbish.
|
||||
|
||||
The next group of functions refer to configuration.
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap7}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);@\\
|
||||
\mbox{}\verb@ int HistSetOption(pHistMem self, char *name, char *value);@\\
|
||||
\mbox{}\verb@ int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
HistGetOption caters for the retrieval of the current option given in name.
|
||||
Maximum iResultLen characters of result will be copied into result, or an
|
||||
error message if things go wrong.
|
||||
|
||||
HistSetOption sets the option name to value specified in value. No error
|
||||
checking except availability of the option and permission is done here.
|
||||
|
||||
HistConfigure updates the internal datastructures from the dictionary and
|
||||
does the actual configuration of the HM. Tons of error messages will be
|
||||
printed to pCon.
|
||||
|
||||
Valid names for the options in the dictionary are all the names in the
|
||||
histogram datastructure. Please note, that counting options are handled
|
||||
separately (see below). Additionally there may be driver specific options
|
||||
available. For iDim iRank numbers are expected which represent the
|
||||
dimensions of the HM.
|
||||
|
||||
The functions for counting and manipulation of counting parameters have been
|
||||
separated from the rest of the configuration. The reason is that the main
|
||||
configuration will only be performed by highly privileged users, whereas
|
||||
the counting operations will be accessible by normal users. Counting is
|
||||
controlled by the following functions:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap8}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ float GetHistPreset(pHistMem self);@\\
|
||||
\mbox{}\verb@ int SetHistPreset(pHistMem self, float fVal);@\\
|
||||
\mbox{}\verb@ CounterMode GetHistCountMode(pHistMem self);@\\
|
||||
\mbox{}\verb@ int SetHistCountMode(pHistMem self, CounterMode eNew);@\\
|
||||
\mbox{}\verb@ long GetHistMonitor(pHistMem self, int i, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ const float *GetHistTimeBin(pHistMem self, int *iLength);@\\
|
||||
\mbox{}\verb@ int GetHistLength(pHistMem self);@\\
|
||||
\mbox{}\verb@ int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);@\\
|
||||
\mbox{}\verb@ float GetHistCountTime(pHistMem self,SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int HistDoCount(pHistMem self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int HistBlockCount(pHistMem self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
The first four functions are simple parameter enquiry and manipulation
|
||||
functions. GetHistMonitor returns the count on monitor number i for the
|
||||
histogram memory. This function returns a negative value when the value
|
||||
specified for i is invalid.
|
||||
|
||||
HistDoCount actually starts a counting operation. It will not
|
||||
block and wait for counting to finish. Please note, that many counting
|
||||
manipulation functions are hidden in the functions of the countable
|
||||
interface, which the HM has to implement.
|
||||
|
||||
HistBlockCount also starts counting. But will block until counting has
|
||||
finished.
|
||||
|
||||
Another set of functions is needed for manipulation of the data in the
|
||||
histogram memory:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap9}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int SetHistogram(pHistMem self, SConnection *pCon,@\\
|
||||
\mbox{}\verb@ int i,int iStart, int iEnd, HistInt *lData);@\\
|
||||
\mbox{}\verb@ int GetHistogram(pHistMem self, SConnection *pCon,@\\
|
||||
\mbox{}\verb@ int i,int iStart, int iEnd, HistInt *lData, int iDataLen);@\\
|
||||
\mbox{}\verb@ HistInt *GetHistogramPointer(pHistMem self,SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
For histogram I/O the following aproach has been taken: Histograms are kept
|
||||
as linear arrays of data regardless of the layout of the detector. It is the
|
||||
task of upper level code to map the right histogram to the right position.
|
||||
This aproach was choosen for two reasons: 1.) simplification of interface,
|
||||
2.) easier to retrieve smaller chunks of data at a time.
|
||||
|
||||
With both SetHistogram and GetHistogram the parameter i denotes the
|
||||
histogram to retrieve. A value of -1 retrieves the whole lot. iStart and
|
||||
iEnd allow for extraction of a subset of a histogram. These values get
|
||||
ignored when trying to retrieve a whole HM content. These routines
|
||||
perform conversion to and from long to the binwidth of the HM. SetHistogram
|
||||
initialises the HM from the lData provided. GetHistogram reads an histogram
|
||||
into lData but maximum iDataLen items. PresetHistogram presets the HM to the
|
||||
value lVal. Can be used to clear the HM.
|
||||
|
||||
The histogram memory object buffers the histograms for a adjustable
|
||||
period of time. GetHistogramPointer retrieves a pointer to the local
|
||||
histogram buffer. It also makes sure, that the histogram has been
|
||||
updated if appropriate. This is provided for efficiency and saves some
|
||||
memory copying and duplication of data during operations. Thus memory
|
||||
consumption can be reduced. However, the drawback is that you mess
|
||||
directly with the histogram memory content which is potentially
|
||||
dangerous. Use this method with great care!
|
||||
|
||||
|
||||
A last group of functions are those needed to interface to the Sics
|
||||
interpreter:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap10}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
MakeHistMem is supposed to be called with two parameters: name and driver
|
||||
which denote the name of the HM object and the type of driver to use. If all
|
||||
is well, this call will create a command named name. Remember, that
|
||||
the HM is
|
||||
not yet configured!
|
||||
|
||||
HistAction is supposed to be where the action goes. HistAction understands
|
||||
the commands:\begin{itemize}
|
||||
\item {\bf name config option value} sets a configuration option.
|
||||
\item {\bf name init} configures the HM.
|
||||
\item {\bf name Preset val} returns the preset value if val is missing, else
|
||||
it sets it.
|
||||
\item {\bf name Mode val} returns the counting mode if val is missing, else
|
||||
it sets it.
|
||||
\item {\bf name count} starts a counting operation.
|
||||
\item {\bf name get number} gets histogram number. -1 as histogram number
|
||||
gets all.
|
||||
\item {\bf name set number val........} sets histogram number to the values
|
||||
following.
|
||||
\item {\bf name clear val} sets all the HM to val.
|
||||
\end{itemize}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap11}
|
||||
\verb@"HistMem.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H I S T M E M @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ header for the histogram memory object for SICS.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@ Mark Koennecke, April 1997@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHISTMEM@\\
|
||||
\mbox{}\verb@#define SICSHISTMEM@\\
|
||||
\mbox{}\verb@#define MAXDIM 3@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HistDriver *pHistDriver;@\\
|
||||
\mbox{}\verb@ typedef struct __HistMem *pHistMem;@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef int HistInt;@\\
|
||||
\mbox{}\verb@/*@\\
|
||||
\mbox{}\verb@ 32 bit integer on a DigitalUnix@\\
|
||||
\mbox{}\verb@*/@\\
|
||||
\mbox{}\verb@@$\langle$Modes {\footnotesize ?, \ldots\ }$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$Protos {\footnotesize ?, \ldots\ }$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap12}
|
||||
\verb@"HistDriv.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H I S T D R I V@\\
|
||||
\mbox{}\verb@ internal header file which includes the definition of the Histogram memory@\\
|
||||
\mbox{}\verb@ driver structure.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, April 1997@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHISTDRIV@\\
|
||||
\mbox{}\verb@#define SICSHISTDRIV@\\
|
||||
\mbox{}\verb@#define MAXCHAN 4096@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$HistType {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\langle$HistDrivProt {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap13}
|
||||
\verb@"HistMem.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H I S T M E M -- Internal@\\
|
||||
\mbox{}\verb@ internal header file which includes the definition of the Histogram memory@\\
|
||||
\mbox{}\verb@ data structure.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, April 1997@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHISTMEMINT@\\
|
||||
\mbox{}\verb@#define SICSHISTMEMINT@\\
|
||||
\mbox{}\verb@@$\langle$HistST {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
50
doc/programmer/histsim.tex
Normal file
50
doc/programmer/histsim.tex
Normal file
@ -0,0 +1,50 @@
|
||||
\subsubsection{Simulated histogram memory driver}
|
||||
This is a driver for a simulated histogram memory needed for software
|
||||
testing.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pHistDriver CreateSIMHM(pStringDict pOpt);@\\
|
||||
\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 only visible function defined is a creation function. Please note that
|
||||
all the interface functions need to be defined as well. For implementation
|
||||
of the countable interface this thing will use the simulated counter. All
|
||||
data retrieval members will return random numbers in the required amount.
|
||||
The call to configure will actually do nothing.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"histsim.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H I S T S I M@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ A simulated histogram memory for software testing.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, April 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHISTSIM@\\
|
||||
\mbox{}\verb@#define SICSHISTSIM@\\
|
||||
\mbox{}\verb@@$\langle$Protos {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
215
doc/programmer/hkl.tex
Normal file
215
doc/programmer/hkl.tex
Normal file
@ -0,0 +1,215 @@
|
||||
\subsection{Crystallographic Computations}
|
||||
The HKL object performs standard four circle calculations. I.e., given a UB
|
||||
matrix it calculates the four circle diffractometer setting angles required
|
||||
for a reflection with index hkl. The UB must be determined from a set of
|
||||
reflections found manually or automatically. This is done in an offline
|
||||
program. The code in this module is a direct reimplementation of fortran code
|
||||
provided by Jean Allibon, ILL with the MAD four circle diffractometer
|
||||
control program in ANSI-C. For theory, see the contribution by
|
||||
W.C. Hamilton in the International Tables for Crystallography, 1974 edition.
|
||||
|
||||
The object uses the following object data structure:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$hkldat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HKL {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ double fUB[9];@\\
|
||||
\mbox{}\verb@ double fLambda;@\\
|
||||
\mbox{}\verb@ int iManual;@\\
|
||||
\mbox{}\verb@ double fLastHKL[5];@\\
|
||||
\mbox{}\verb@ int iNOR;@\\
|
||||
\mbox{}\verb@ int iQuad;@\\
|
||||
\mbox{}\verb@ pMotor pTheta;@\\
|
||||
\mbox{}\verb@ pMotor pOmega;@\\
|
||||
\mbox{}\verb@ pMotor pChi;@\\
|
||||
\mbox{}\verb@ pMotor pPhi;@\\
|
||||
\mbox{}\verb@ pMotor pNu;@\\
|
||||
\mbox{}\verb@ pSelVar pMono;@\\
|
||||
\mbox{}\verb@ long lID;@\\
|
||||
\mbox{}\verb@ } HKL;@\\
|
||||
\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 are more or less self explaining:
|
||||
\begin{description}
|
||||
\item[pDes] The standard object descriptor.
|
||||
\item[fUB] The UB matrix.
|
||||
\item[iUB] is a flag which spcifies if a UB is specified.
|
||||
\item[fLambda] The wavelength of the neutrons.
|
||||
\item[iManual] A flag which defines if the wavelength has been set manually
|
||||
or is updated automatically from a wavelength variable.
|
||||
\item[fLastHKL] the HKL of the last reflection calculated.
|
||||
\item[iNor] a flag for normal beam calculation mode.
|
||||
\item[pTheta] The two theta motor. All motor are needed for boundary
|
||||
checking.
|
||||
\item[pOmega] The omega axis motor.
|
||||
\item[pChi] The chi axis motor.
|
||||
\item[pPhi] the phi axis motor.
|
||||
\item[pNu] the nu axis motor for normal beam geometry.
|
||||
This is detector tilt.
|
||||
\item[pMono] The selector variable doing the wavelength.
|
||||
\end{description}
|
||||
|
||||
The wavelength is a bit tricky. As it would be to time consuming to read two
|
||||
motors each time a calculation is performed, the lambda variable is updated
|
||||
by registering a callback with the selector variable handling the
|
||||
monochromator wavelength. As TriCS will be run with two monochromators on a
|
||||
lift a means has to be provided to change the selector variable online. An
|
||||
additonal feature is that the wavelength can be manipulated manually. This
|
||||
adresses the issue that automatic wavelength may be inaccurate due to
|
||||
lazy instrument scientists not adjusting their instruments.
|
||||
|
||||
In terms of an interface the following functions will be provided by this
|
||||
module:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$hklint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HKL *pHKL;@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ pHKL CreateHKL(pMotor pTheta, pMotor pOmega, @\\
|
||||
\mbox{}\verb@ pMotor pChi, pMotor pPhi, pMotor pNu);@\\
|
||||
\mbox{}\verb@ void DeleteHKL(void *pData);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int SetWavelengthVariable(SConnection *pCon, pHKL self, pSelVar pVar);@\\
|
||||
\mbox{}\verb@ int SetWavelengthManual(pHKL self, float fVal);@\\
|
||||
\mbox{}\verb@ int SetUB(pHKL self, float fUB[9]);@\\
|
||||
\mbox{}\verb@ int GetUB(pHKL self, float fUB[9]);@\\
|
||||
\mbox{}\verb@ int SetNOR(pHKL self, int iNOB);@\\
|
||||
\mbox{}\verb@ int GetLambda(pHKL self, float *fVal);@\\
|
||||
\mbox{}\verb@ int GetCurrentHKL(pHKL self, float fVal[3]);@\\
|
||||
\mbox{}\verb@ int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
|
||||
\mbox{}\verb@ float fSet[4],SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int RunHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, SConnection@\\
|
||||
\mbox{}\verb@ *pCon);@\\
|
||||
\mbox{}\verb@ int DriveHKL(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int DriveSettings(pHKL self, float fSet[4],SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||
\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}
|
||||
All functions return 0 on failure, 1 on success if not stated otherwise.
|
||||
Most functions take a pointer to a HKL data structure as first parameter.
|
||||
The function in more detail:
|
||||
\begin{description}
|
||||
\item[CreateHKL] creates a HKL object. The parameters are pointers to the
|
||||
four four circle motors. Returns NULL on failure, a pointer to the new
|
||||
object on success.
|
||||
\item[DeleteHKL] properly removes an HKL object from the system.
|
||||
\item[HKLFactory] The factory function which initialises an HKL object from
|
||||
the initialisation script.
|
||||
\item[SetWavelengthVariable] sets a new wavelength variable. Installs all
|
||||
necesarry callbacks for automatic update.
|
||||
\item[SetWaveLengthManual] deinstall all callbacks and forces the wavelength
|
||||
to the value specified a second parameter.
|
||||
\item[SetUB] sets the UB matrix.
|
||||
\item[SetNOR] sets the normal beam calculation flag to iNOR.
|
||||
\item[CalculateSettings] is the heart of this all. As the name suggests
|
||||
calculates the settings for a four circle diffractometer. The parameters
|
||||
are:
|
||||
\begin{description}
|
||||
\item[self] A pointer to a HKL data structure.
|
||||
\item[fHKL] The reflection indices to calculate the settings for.
|
||||
\item[fPsi] The psi value for the reflection. For psi scans. Set to 0 if not
|
||||
used.
|
||||
\item[iHamil] The index of the hamilton position to calculate. Can be an
|
||||
integer between 0 to 8. 0 denotes the normal case.
|
||||
\item[fSet] contains the required settings if the function returns with
|
||||
success. 0 = two theta, 1 = omega, 2 = chi, 3 = phi.
|
||||
\end{description}
|
||||
The function returns 1 on success, a negative value on failure. Possible
|
||||
error returns are:
|
||||
\begin{description}
|
||||
\item[HKLIMPOSSIBLE] the calculation was impossible.
|
||||
\item[HKLTHETALIMIT] a setting could be calculated but can not be accessed
|
||||
due to a limit on two theta.
|
||||
\end{description}
|
||||
\item[DriveHKL] calculates a setting and drives to the position. The
|
||||
parameters are the same as with CalculateSettings. With the addition of a
|
||||
pointer to the connection object doing the command for error messages and
|
||||
everything. The error returns are the same as with CalculateSettings
|
||||
well. With the addition of HKJMOTFAIL, which means that a motor failed to
|
||||
drive properly.
|
||||
\item[DriveSettings] drives to the the settings given in fSet.
|
||||
\item[HKLAction] is the interpreter wrapper function for the HKL object.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"hkl.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H K L@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Internal data structure description. See hkl.h, c,w for more details.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, February 1998@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$hkldat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"hkl.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H K L@\\
|
||||
\mbox{}\verb@ This SICS object performs angle setting calculations for a four circle @\\
|
||||
\mbox{}\verb@ diffractometer. The heart of this code is a C transcriptions of routines@\\
|
||||
\mbox{}\verb@ written by Jean Allibon at ILL for the MAD program. Theory is explained in@\\
|
||||
\mbox{}\verb@ the article by W. C. Hamilton in International Tables for Crystallography,@\\
|
||||
\mbox{}\verb@ 1974 edition.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, February 1998@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHKL@\\
|
||||
\mbox{}\verb@#define SICSHKL@\\
|
||||
\mbox{}\verb@#include "selector.h"@\\
|
||||
\mbox{}\verb@#include "selvar.h"@\\
|
||||
\mbox{}\verb@@$\langle$hklint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
111
doc/programmer/hklscan.tex
Normal file
111
doc/programmer/hklscan.tex
Normal file
@ -0,0 +1,111 @@
|
||||
\subsection{hklscan}
|
||||
hklscan is an object which implements scanning in reciprocal space. It belongs
|
||||
to the four circle diffraction line of commands. It requires the hkl object
|
||||
for doing four circle calculations and a scan object for doing the scanning.
|
||||
The scan object is configured by overloading its WriteScanPoints and
|
||||
ScanDrive functions to do the right thing for this. Thus most of the work
|
||||
is done in scan and hkl.
|
||||
|
||||
hklscan has its own data structure looking like this:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$hklscandat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HKLSCAN {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pScanData pScan;@\\
|
||||
\mbox{}\verb@ pHKL pCalc; @\\
|
||||
\mbox{}\verb@ float fStart[3];@\\
|
||||
\mbox{}\verb@ float fStep[3];@\\
|
||||
\mbox{}\verb@ float fPos[3];@\\
|
||||
\mbox{}\verb@ } sHklscan;@\\
|
||||
\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[pDes] The standard object descriptor.
|
||||
\item[pScan] The scan object used for scanning.
|
||||
\item[pCalc] The hkl object used for crystallographic computations.
|
||||
\item[fStart] The start values in H, K, L for scanning.
|
||||
\item[fStep] The step width in H, K, L.
|
||||
\item[fPos] The last position in H, K, L.
|
||||
\end{description}
|
||||
|
||||
The hklscan object defines the following external interface:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$hklscanfunc {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HKLSCAN *pHklscan;@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int HklScan(pHklscan self, SConnection *pCon, int iNP, int iMode,@\\
|
||||
\mbox{}\verb@ float fPreset);@\\
|
||||
\mbox{}\verb@/*---------------- interpreter functions -----------------------------------*/@\\
|
||||
\mbox{}\verb@ int HklscanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int HklscanAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\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}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"hklscan.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ Internal data structure for the hklscan object. DO NOT MODIFY. @\\
|
||||
\mbox{}\verb@ Modifications only in hklscan.i@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, June 1999@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$hklscandat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"hklscan.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ H K L S C A N@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ A class for doing scans in reciprocal space. This makes only sense at an@\\
|
||||
\mbox{}\verb@ four circle diffractometer. Most of the work is done in the HKL and scan@\\
|
||||
\mbox{}\verb@ objects. This class just adapts and used both objects to do the right thing.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, June 1999@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef HKLSCAN@\\
|
||||
\mbox{}\verb@#define HKLSCAN@\\
|
||||
\mbox{}\verb@@$\langle$hklscanfunc {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
32
doc/programmer/ini.tex
Normal file
32
doc/programmer/ini.tex
Normal file
@ -0,0 +1,32 @@
|
||||
\subsection{Initialisation file management}
|
||||
This module supports initialisation files with a simple structure.
|
||||
This is used to hold the internal SICS server options which are
|
||||
installed with the SicsOption initialisation commands. All the file
|
||||
handling stuff is dead code not used by SICS as of current. Any line
|
||||
is intended to
|
||||
contain one name value pair separated by an equlity sign. Lines beginning
|
||||
with a \verb+#+ are treated as comments, other lines not conforming to the name =
|
||||
value scheme are ignored. Another option (and the currently preferred one)
|
||||
to get values into the initialisation database is to use a special command
|
||||
SicsOption from the SICS initialisation file.
|
||||
These initialisation files are manipulated through
|
||||
the ifile module, implemented in ifile.h and ifile.c. The class in more
|
||||
detail:
|
||||
|
||||
|
||||
After reading the configuration options are stored in memory as a linked list with entries if the type shown below. \begin{verbatim}
|
||||
typedef struct __IFileE
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
struct __IFileE *pNext;
|
||||
} IPair;
|
||||
\end{verbatim}
|
||||
This datastructure is manipulated using the following functions:\begin{itemize}
|
||||
\item {\bf IPair *IFReadConfigFile(FILE *fp) }, expects as input a pointer to the configuration file. Than the function will read the file and initialise the configuration linked list from the data found in the file. On success a pointer to the head of the linked list is returned which is to be used in further calls to the configuration management functions. On failure NULL is returned.
|
||||
\item {\bf char *IFindOption(IPair *pList,char *name) }. Input is a pointer to a configuration list as returned by IFReadConfigFile and the name of the option requested (case sensitive). If this option exists a pointer to its value will be returned, else NULL. Never, ever, free the returned pointer as it belongs to this module.
|
||||
\item {\bf IPair *IFAddOption(IPair *pList,char *name, char *value) } Adds a name value pair to the list specified as first parameter. Returns a pointer to the new list including the new name value pair on succes, else the old pointer specified as input.
|
||||
\item {\bf int IFSaveOptions(IPair *pList,FILE *fp) }. Saves the options in the list to the file fp.
|
||||
\item {\bf void IFDeleteOptions(IPair *pList) }. Use this to delete the list after use. The list pList is no longer valid after this call. Omission of this call will result in wasted memory.
|
||||
\end{itemize}
|
||||
|
52
doc/programmer/integrate.tex
Normal file
52
doc/programmer/integrate.tex
Normal file
@ -0,0 +1,52 @@
|
||||
\subsection{Integrate}
|
||||
For four circle diffractometers it is usefull to be able to integrate the
|
||||
intensity of the peak from a collected counting profile. This module does
|
||||
just this. It uses the method as described by Grant \& Gabe in J. Appl. Cryst
|
||||
(1987), 11, 114-120. This method uses a moving window technique for finding
|
||||
the limits of the peak. This method was choosen for reason of its
|
||||
simplicity. The authors state, that the results are comparable to the
|
||||
Lehmann Larsen method used elsewhere. This is a utility module. Just a
|
||||
single function is implemented:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
\verb@"integrate.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ I N T E G R A T E@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Peak integration follwing the method described by Grant & Gabe in@\\
|
||||
\mbox{}\verb@ J. Appl. Cryst (1978), 11, 114-120.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, March 1998@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef GABEINTEGRATE@\\
|
||||
\mbox{}\verb@#define GABEINTEGRATE@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#define INTEGLEFT -1@\\
|
||||
\mbox{}\verb@#define INTEGRIGHT -2@\\
|
||||
\mbox{}\verb@#define INTEGNOPEAK -3@\\
|
||||
\mbox{}\verb@#define INTEGFUNNYBACK -4@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int GabePeakIntegrate(int m, int iCounts, long lCounts[], @\\
|
||||
\mbox{}\verb@ float *fIntens, float *fVariance);@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
Input to this routine is the number of counts and the counts themselves.
|
||||
Then m, the number of lookahead points to use. As a result fIntens will
|
||||
contain the summed Intensity and fVariance the sigma of the summed
|
||||
intensity. The function retusn 1 for success or a negative error code in
|
||||
case of trouble. These error codes are:
|
||||
\begin{description}
|
||||
\item[INTEGLEFT] no left side background found.
|
||||
\item[INTEGRIGHT] nor right side background found.
|
||||
\item[INTEGNOPEAK] The data does not contain a peak.
|
||||
\item[INTEGFUNNYBACK] the data has a strange background.
|
||||
\end{description}
|
69
doc/programmer/inter.tex
Normal file
69
doc/programmer/inter.tex
Normal file
@ -0,0 +1,69 @@
|
||||
\subsection{The SICS Interpreter}
|
||||
The SicsInterpreter implements a Tcl-look alike command list with each
|
||||
object having a similar wrapper function to those used in Tcl. But
|
||||
augmented with a pointer to a Connection structure in order to enable
|
||||
authorisation checking and providing the I/O context. The object wrapper
|
||||
function has a prototype looking like this:
|
||||
|
||||
|
||||
{\bf int ObjectWrapper(SConnection *pCon, SicsInterp *pInter, void *pData,
|
||||
int argc, char *argv); }
|
||||
|
||||
|
||||
pCon is the connection responsible for this call and holds necessary
|
||||
information for authorisation checking. pInter is the Sics interpreter.
|
||||
pData is a pointer to an object specific datastructure (the struct holding
|
||||
the motor data for instance). Argc and argv hold the arguments as in a C
|
||||
main program. The object wrapper is meant to evaluate the arguments, do the
|
||||
right thing to the object with them and than pass results back. There are
|
||||
two ways to do that. The prefered one is to copy results or error messages
|
||||
into the interpreters result space and associate an output code with the
|
||||
result space. After returning the interpreter will than copy these results
|
||||
to the client. However, a scan routine might want to print status
|
||||
information to the client during a lengthy operation. In this case the
|
||||
object can write directly to the connnection usinfg the provided connection
|
||||
pointer. The object wrapper function returns true or false depending on the
|
||||
success of the operation.
|
||||
|
||||
|
||||
The command list is a doubly linked list holding for each command a record
|
||||
containing: the commands name, a pointer to the objects object function, a
|
||||
pointer to the objects data structure (passed as pData) on invocations and a
|
||||
pointer to a function which is capable to delete the objects data structure.
|
||||
This function will be called when the object/command is removed. In the end
|
||||
the SicsInterpreter implements the following datastrucures an
|
||||
interfaces:\begin{verbatim} typedef struct __Clist {
|
||||
char *pName;
|
||||
ObjectFunc OFunc;
|
||||
KillFunc KFunc;
|
||||
void *pData;
|
||||
struct __Clist *pNext;
|
||||
struct __Clist *pPrevious;
|
||||
} CommandList;
|
||||
\end{verbatim}
|
||||
The structure held in a doubly linked list for each command.\begin{verbatim}
|
||||
typedef struct __SINTER
|
||||
{
|
||||
CommandList *pCList;
|
||||
char *pErrors;
|
||||
int iSpace;
|
||||
OutCode eOut;
|
||||
}SicsInterp;
|
||||
\end{verbatim}
|
||||
The interpreter data structure. Access only through the interface functions given below:\begin{itemize}
|
||||
\item {\bf SicsInterp *InitInterp(void) } creates a new interpreter. Returns a pointer on success, NULL on failure.
|
||||
\item {\bf int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc, KillFunc pKFunc, void *pData); } adds a new command to the commandlist of the specified interpreter. Returns True or false depending on success.
|
||||
\item {\bf int RemoveCommand(SicsInterp *pInterp, char *pName) } finds command name and removes it from the list. Returns True on success (command found) and False if it fails.
|
||||
\item {\bf int InterpExecute(SicsInterp *self,pSConnection pCon, char *pCommand) } executes pcommand in the SICS interpreter. Returns -1 if the command did not exist. If ist exists True or False is returned depending on the success of the command.
|
||||
\item {\bf int InterpWriteResult(SicsInterp *self,char *text) } used within object wrapper functions to append result text to the interpreter. Allocating sufficient memory is taken care of by this function.
|
||||
\item {\bf void InterpSetOutCode(SicsInterp *self, OutCode eCode) } does what it says.
|
||||
\item {\bf OutCode InterpGetOutCode(SicsInterp *self) } return the current output code for the interpreters result.
|
||||
\item {\bf CommandList *FindCommand(SicsInterp *pInterp, char *name) } return a pointer to a commandlist structure if the object specified by name exists, NULL else. Used in the definition of interpreter and macro functionality.
|
||||
\item {\bf const char *InterpGetResult(SicsInterp *self) } returns a pointer to the interpreter result space. This space is managed by the interpreter, never ever delete it in client code.
|
||||
\item {\bf void DeleteInterp(SicsInterp *self) } removes the interpreter, his command list etc. Frees all allocated memory for this interpreter.
|
||||
\item {\bf WriteSicsStatus(SicsInterp *pSics, char *file)} opens the file
|
||||
for writing and writes the current status of SICS objects int the file. In
|
||||
order to do so, the SaveStatus function of each object registered in the
|
||||
interpreter is called.
|
||||
\end{itemize}
|
||||
|
497
doc/programmer/interface.tex
Normal file
497
doc/programmer/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.
|
||||
|
||||
|
53
doc/programmer/interrupt.tex
Normal file
53
doc/programmer/interrupt.tex
Normal file
@ -0,0 +1,53 @@
|
||||
\subsection{Interrupt Handling}
|
||||
SICS needs a way to interrupt server processsing. This is done
|
||||
with this module.
|
||||
Interrupts may come in through two ways: They may be created
|
||||
internally or they may be user requested. For the last ones
|
||||
the main loop will poll an additional special interrupt
|
||||
port.
|
||||
|
||||
In order to do interrupting a set of interrupt codes are defined:
|
||||
\begin{verbatim}
|
||||
#define eContinue 0
|
||||
#define eAbortOperation 1
|
||||
#define eAbortScan 2
|
||||
#define eAbortBatch 3
|
||||
#define eHaltSystem 4
|
||||
#define eFreeSystem 5
|
||||
#define eEndServer 6
|
||||
\end{verbatim}
|
||||
Their meanings:
|
||||
\begin{description}
|
||||
\item[eContinue] Go on, interrupt nothing.
|
||||
\item[eAbortOperation] stop current hardware operation but no scans or
|
||||
batchfiles.
|
||||
\item[eAbortScan] stop current scan or operation but continue processing of
|
||||
batch files with next command.
|
||||
\item[eAbortBatch] Stop all processing, even batch files.
|
||||
\item[eHaltSystem, eFreeSystem] are currently unused.
|
||||
\item[eEndServer] is used internally by the SicsExitus command to run down
|
||||
the server.
|
||||
\end{description}
|
||||
|
||||
The interrupt module supports the following interface:
|
||||
\begin{description}
|
||||
\item[void ServerStopInterrupt(void)] stops interrupt processing.
|
||||
\item[void SetInterrupt(int iCode)]
|
||||
Send an interrupt to all connections. Use with care! More often an
|
||||
interrupt need to be set on a special connection. This can be done with
|
||||
SCSetInterrupt defined in conman.h.
|
||||
\item[int Interrupt2Text(int iInterrupt, char *text, int iTextLen)] converts
|
||||
iInterrupt to a text. Maximum iTextLen characters will be copied to text.
|
||||
\item[int Text2Interrupt(char *text)] Converts text, when applicable to an
|
||||
interrupt code which is returned. If the text is invalid -1 is returned.
|
||||
\item[int ClientSetupInterrupt(char *host, int iPort)] Creates a client side
|
||||
interrupt UDP port.
|
||||
\item[void ClientStopInterrupt(void)] removes an client side interrupt port
|
||||
created by ClientSetupInterrupt.
|
||||
\item[void SendInterrupt( int iCode)] sends an interrupt through the UDP
|
||||
port.
|
||||
\end{description}
|
||||
|
||||
Please note, that the interrupt implementation is distributed into two
|
||||
files: intserv.c for the server side stuff and intcli.c for the client side
|
||||
part. UDP interrupting is not fully tested.
|
107
doc/programmer/itc4.tex
Normal file
107
doc/programmer/itc4.tex
Normal file
@ -0,0 +1,107 @@
|
||||
\subsubsection{Oxford Instruments ITC4 Temperature Controllers}
|
||||
SINQ makes heavy use of Oxford Instruments ITC4 temperature controllers. In
|
||||
order to support them the following software components had to be defined in
|
||||
addition to the basic environmet controller interfaces:
|
||||
\begin{itemize}
|
||||
\item ITC4driver, naturally.
|
||||
\item A ITC4-controller object as derivation of environment controller. ITC4
|
||||
's allow you to select a sensor which you read as your standard sensor and a
|
||||
sensor which is used for automatic control. The ITC4 controller object adds
|
||||
just that additional functionality to the statndard environment controller.
|
||||
\end{itemize}
|
||||
The additional data, the selection of sensors, will be kept in the driver.
|
||||
This serves also an example for implementing inheritance without C++.
|
||||
|
||||
The driver interface:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$itcd {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ pEVDriver CreateITC4Driver(int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int ConfigITC4(pEVDriver self);@\\
|
||||
\mbox{}\verb@ int SetSensorITC4(pEVDriver self, int iSensor);@\\
|
||||
\mbox{}\verb@ int SetControlITC4(pEVDriver self, int iSensor);@\\
|
||||
\mbox{}\verb@ int GetSensorITC4(pEVDriver self);@\\
|
||||
\mbox{}\verb@ int GetControlITC4(pEVDriver self);@\\
|
||||
\mbox{}\verb@ int SetDivisorITC4(pEVDriver self, float iSensor);@\\
|
||||
\mbox{}\verb@ float GetDivisorITC4(pEVDriver self);@\\
|
||||
\mbox{}\verb@ int SetMultITC4(pEVDriver self, float iSensor);@\\
|
||||
\mbox{}\verb@ float GetMultITC4(pEVDriver self);@\\
|
||||
\mbox{}\verb@ int SetTMOITC4(pEVDriver self, int iSensor);@\\
|
||||
\mbox{}\verb@ int GetTMOITC4(pEVDriver self);@\\
|
||||
\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 ConfigITC4 is special. It has to be called to commit changes to the
|
||||
driver read and control parameters.
|
||||
|
||||
The ITC4 object interface:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$itco {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int ITC4Wrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int ITC4SetPar(pEVControl self, char *name, float fNew, @\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int ITC4GetPar(pEVControl self, char *name, float *fVal);@\\
|
||||
\mbox{}\verb@ int ITCList(pEVControl self, SConnection *pCon);@\\
|
||||
\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 defined are: new parameter handling functions, with just
|
||||
support for the two extra parameters added and a new Wrapper function for
|
||||
SICS. The meaning of all these functions, their parameters and return values
|
||||
are identical to those defined for an environment controller. Additionally,
|
||||
the standard environment controller functions will work as described. The
|
||||
functions described above are just needed to implement the extra parameters.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"itc4.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ ITC 4@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Support for Oxford Instruments ITC4 Temperature controllers for SICS.@\\
|
||||
\mbox{}\verb@ The meaning and working of the functions defined is as desribed for a@\\
|
||||
\mbox{}\verb@ general environment controller.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSITC4@\\
|
||||
\mbox{}\verb@#define SICSITC4@\\
|
||||
\mbox{}\verb@/*------------------------- The Driver ------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$itcd {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*------------------------- The ITC4 object ------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$itco {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
355
doc/programmer/kernelguide.tex
Normal file
355
doc/programmer/kernelguide.tex
Normal file
@ -0,0 +1,355 @@
|
||||
\chapter{Guide To SICS Kernel Facilities}
|
||||
In this chapter the facilities of the SICS servers kernel will be examined
|
||||
more closely. All the kernel modules and their function will be listed,
|
||||
together with some explanatory information and an overview about the
|
||||
application programmers interfaces (API) provided. This section should
|
||||
answer the questions: WHat is available?, Where to find what?,
|
||||
Why did they do that? Details of
|
||||
the API's mentioned are given in the reference section.
|
||||
|
||||
|
||||
The SICS servers kernel consists of the following objects and modules:
|
||||
\begin{itemize}
|
||||
\item The task manager , Files tasker.*.
|
||||
\item The network reader, Files nread.*.
|
||||
\item The network module, Files network.*.
|
||||
\item The connection object, Files conman.*.
|
||||
\item The SICS interpreter, Files SCinter.*.
|
||||
\item The SICS macro facility, Files macro.*, script.*.
|
||||
\item The device executor, Files devexec.*.
|
||||
\item The environment monitor, Files emon.c.
|
||||
\item The server himself, Files nserver.*
|
||||
\item The serverlog, Files servlog.*.
|
||||
\item A performance monitor, Files perfmon.*.
|
||||
\item The object factory, Files ofac.*.
|
||||
\item The options database, Files ifile.*.
|
||||
\item The password database, Files passwd.*.
|
||||
\item The main program, File SICSmain.c.
|
||||
\end{itemize}
|
||||
|
||||
\section{The Task Manager}
|
||||
The task manager implements cooperative multitasking in SICS. A task in the
|
||||
SICS sense is defined by a function, the task function. It is of the type:
|
||||
\begin{verbatim}
|
||||
int TaskFunction(void *pData);
|
||||
\end{verbatim}
|
||||
When it is time for the task to execute this function is called, with a
|
||||
parameter to a the tasks own data structure. This data structure must have
|
||||
been defined by the user of this module. The task function returns 1, if it
|
||||
shall continue to live, or 0 if it should be deleted from the task list.
|
||||
These task functions are kept in a list. The elements of this list are
|
||||
visited cyclically, when the scheduler runs.
|
||||
|
||||
The API to this object consists of functions for creating a task manager,
|
||||
adding tasks to the task list and to run the task list. Other functions
|
||||
allow to put a task into a wait state. This means that the task will not
|
||||
execute until another task has died (returned 0). Then the waiting task will
|
||||
continue execution at the point where it has called the wait function.
|
||||
For example, consider a task which wants to wait for say 10 seconds. This
|
||||
tasks name shall be BedTask. It does so by starting a second task, called
|
||||
ClockTask which checks if 10 seconds have passed and dies after this.
|
||||
BedTask then waits for this task. This makes BedTask look like this:
|
||||
\begin{verbatim}
|
||||
int BedTask(void *pData)
|
||||
{
|
||||
/* Code block 1.
|
||||
Fill in horrendously complex operations here.
|
||||
*/
|
||||
|
||||
lID = TaskRegister(pTasker, ClockTask,....)
|
||||
TaskWait(pTasker, lID, ....);
|
||||
|
||||
/* Code block 2.
|
||||
More horrendous computations.
|
||||
Will be executed after ClockTask died.
|
||||
*/
|
||||
|
||||
/* Beds never die!!! */
|
||||
return 1;
|
||||
}
|
||||
\end{verbatim}
|
||||
and ClockTask:
|
||||
\begin{verbatim}
|
||||
int ClockTask(void *pData)
|
||||
{
|
||||
if(10 seconds are gone)
|
||||
{
|
||||
/* death is lurking */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* continue running */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
The task manager supports a primitive means of inter task communication as
|
||||
well. Each registered task may not only have a task function associated with
|
||||
it, but also a SignalFunction. When a task feels like it, it may advise the
|
||||
task manager to send a signal and some data to all the other tasks. Signals
|
||||
are identified by integer numbers. The SignalFunction of each task will then
|
||||
be called. It has to check the signal and if it is of meaning to the task,
|
||||
do something appropriate with it. SICS uses this facility to distribute
|
||||
interrupts and broadcast messages to all tasks. Currently defined signal
|
||||
IDs are defined in file event.h.
|
||||
|
||||
\section{The Network Reader and the Network Module}
|
||||
The network module implements the mechanics of network connection. This
|
||||
module is the one which needs heavy reworking if the network protocol for
|
||||
SICS should be changed. For instance to Token--Ring or AppleTalk or
|
||||
whatever.
|
||||
The network reader implements the polling for network message in the SICS
|
||||
server. It is organized as one of the SICS system tasks. Polling in a POSIX
|
||||
environment is all about the select system call. The select system call
|
||||
allows to enquire if an open TCP/IP socket has data pending to be read, can
|
||||
be written to etc. For more details see the unix man pages for the select
|
||||
system call. An earlier version of the SICS server had a list of connection
|
||||
objects and each of them were checked for pending commands with a call to
|
||||
select. This proved to be inefficient with the system spending two thirds
|
||||
of its time in select. Then it was decided to make use of the fact that
|
||||
select can check more then one socket in one call. This gave birth to the
|
||||
network reader. Each network user in the SICS server can register his socket
|
||||
with the network reader. When the network reader tasks executes, it checks
|
||||
all registered sockets for pending data with one central select system call.
|
||||
This scheme improved system performance by a factor of 900.
|
||||
What happens when data is pending on a socket depends on the type of the
|
||||
socket.
|
||||
The network reader currently supports four types of sockets:
|
||||
\begin{itemize}
|
||||
\item Accept type sockets.
|
||||
\item Normal client sockets.
|
||||
\item UDP sockets.
|
||||
\item User sockets.
|
||||
\end{itemize}
|
||||
|
||||
The accept type of socket is the main server port where clients try to
|
||||
connect to. The network reader accepts the connection and tries to read a
|
||||
username/password pair for a specified amount of time.
|
||||
If the username/password is valid, the connection will be accepted,
|
||||
else it will be broken again. The username/password pair will be verified
|
||||
against the data in the password database. If a connection is accepted, a
|
||||
new connection object is created, a new connection task is registered into
|
||||
the system and the network reader registers a new client command port.
|
||||
|
||||
The normal client command ports are accepted connections from a client. The
|
||||
SICS server expects commands to be sent from the clients. Thus any data
|
||||
pending on such a socket will be read, split into single commands at the \\n
|
||||
and put into the connections command stack for execution. At this place
|
||||
there is also the check for the special interrupt string on command
|
||||
connections (see \ref{prot1}).
|
||||
|
||||
The SICS server accepts only interrupts on its UDP port. This will be checked
|
||||
for when handling data pending on the servers UDP port.
|
||||
|
||||
User type sockets are a feature for dealing with extremely slow hardware
|
||||
connections. Some hardware devices require a long time to answer requests.
|
||||
For example the Dornier velocity selector. This would block the SICS server
|
||||
or diminish its performance to unbearable levels. If situations like that
|
||||
occur somewhere in SICS object code, the object may call a special wait
|
||||
function which returns when data is pending on the socket. Thereby, other
|
||||
clients requests would be served, as the task switcher would run.
|
||||
This special wait facility is implemented in the network reader.
|
||||
|
||||
\section{The Connection Object}
|
||||
The connection object holds the execution context of the current client
|
||||
connection. Its data structure holds information about the network channel to
|
||||
the client connection, the command stack which the network reader fills with
|
||||
commands, a list of files where all I/O to and from this connection will be
|
||||
logged, the user rights associated with this client connection, interrupts,
|
||||
and flags which determine if the connection is currently executing in a
|
||||
macro or is busy. Functions exist which allow to interact with this object.
|
||||
Most of them will be discussed in section \ref{gow}. Associated with each
|
||||
connection is a task and a task function. Whenever this task executes, it
|
||||
will pop a command from the command stack and execute it in the
|
||||
interpreter. More details about the usage of the connection object can be
|
||||
found in the next chapter \ref{gow}.
|
||||
|
||||
\section{The SICS Interpreter and Macro Language}
|
||||
In order to understand this section a knowledge of some aspects of the C
|
||||
language interface to the Tcl interpreter helps. Interesting chapters include
|
||||
the sections about defining new commands in Tcl and the Tcl unknown
|
||||
mechanism. For more details see John Ousterhout's book.
|
||||
|
||||
In an earlier stage it was considered to use the Tcl interpreter as the SICS
|
||||
interpreter. This idea was discarded for some reasons: One was the
|
||||
difficulty of transporting the client execution context (i.e. the connection
|
||||
object) through the Tcl interpreter. There is no standard Tcl mechanism for
|
||||
doing that. The second was security: the Tcl
|
||||
interpreter is very powerful and can be abused. It was felt that the system
|
||||
had to be protected against such problems. The third reasons was that the
|
||||
set of user commands should not be cluttered with Tcl commands in order to
|
||||
prevent confusion. Programming macros is anyway something which is done by
|
||||
SICS managers or programmers. However, the SICS interpreter is still modeled
|
||||
very much like the Tcl-interpreter. A Tcl interpreter is still included in
|
||||
order to provide a full featured macro language. The SICS interpreter and the
|
||||
Tcl macro interpreter are still tightly coupled.
|
||||
|
||||
The SICS interpreter must forward commands to the SICS objects. For this the
|
||||
interpreter needs some help from the objects themselves. Each SICS object
|
||||
has to provide a wrapper function of the type:
|
||||
\begin{verbatim}
|
||||
int ObjectWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
\end{verbatim}
|
||||
in order to be visible from the interpreter. The parameters to this function
|
||||
are: a pointer to the client connection executing the command,
|
||||
the interpreter in which the command
|
||||
executes, a pointer to the objects data structure and an argc,
|
||||
\verb+argv[]+ pair
|
||||
like for an C language main program. This argc, \verb+argv[]+ pair contains the
|
||||
arguments to the wrapper function. The wrapper function is responsible for
|
||||
evaluating the arguments and do whatever is appropriate. It returns 0 on
|
||||
failure and 1 on success. The SICS interpreter holds a list of such wrapper
|
||||
functions. For each object the list holds:
|
||||
\begin{itemize}
|
||||
\item The name of the SICS object.
|
||||
\item The address of the objects wrapper function.
|
||||
\item The address of the objects data structure.
|
||||
\item The address of a function which can remove the objects data structure
|
||||
from memory cleanly. This is used when deleting an object/command from the
|
||||
interpreter to clean up memory.
|
||||
\end{itemize}
|
||||
Command interpretation then involves the following steps:
|
||||
\begin{enumerate}
|
||||
\item The command is parsed into an argc, \verb+argv[]+ pair.
|
||||
\item Using the first word of the command as a key, the list of objects is
|
||||
searched for a match.
|
||||
\item If a match is found, the objects wrapper function is invoked with the
|
||||
appropriate parameters.
|
||||
\item All the rest of command interpretation is done by the wrapper
|
||||
function.
|
||||
\end{enumerate}
|
||||
The SICS interpreter interface offers functions which allow to add or remove
|
||||
entries to and from the interpreters list of objects. Other functions allow
|
||||
to find objects (and their data structures) in this list. And of course,
|
||||
there is a function which executes a command in this interpreter.
|
||||
|
||||
|
||||
The Tcl macro interpreter is invoked either through the FileEval command or
|
||||
through commands made available through the Publish mechanism. Publish
|
||||
is a SICS manager command which makes a Tcl command or procedure
|
||||
visible in the SICS interpreter. Publish provides a special wrapper for a
|
||||
Tcl command, which first checks the user rights of the client connection which
|
||||
wants to execute the Tcl command. If the user rights are appropriate the
|
||||
command is invoked in the Tcl--interpreter. The Tcl interpreter has access
|
||||
to all normal SICS commands. This is implemented by using the Tcl
|
||||
unknown mechanism. If Tcl cannot find a command it invokes a command named
|
||||
unknown with the missing commands name as a parameter. Unknown is usually
|
||||
implemented as a Tcl script, loaded at Tcl startup time. The unknown function
|
||||
is then responsible for finding the missing command and execute it. The
|
||||
usual Tcl mechanism tries to find the missing command in Tcl libraries and
|
||||
as operating system commands. This mechanism has been modified for SICS such
|
||||
that unknown tries to find missing commands in Tcl libraries or in the SICS
|
||||
interpreter. This last bit is implemented as a special Tcl command
|
||||
SISCUnknown defined in macro.c. In order to invoke SICS command a connection
|
||||
object is needed. A suitable connection object is provided through a stack.
|
||||
Before invoking the Tcl-interpreter, the connection object from which the
|
||||
request has come is put at the bottom of a stack. The SICSUnknown routine
|
||||
then uses the last element of the stack as the connection object for
|
||||
invoking SICS. When control returns from the Tcl-interpreter, the connection
|
||||
is popped from the stack.
|
||||
|
||||
%% Idea: simplify: use Tcl as interpreter, have a wrapper around SICS
|
||||
%% objects which provide the SICS wrapper contexts. Add SICS commands to Tcl
|
||||
%% in a special data structure:
|
||||
%% struct TclSICS {
|
||||
%% (*ObjectWrapper);
|
||||
%% void *ObjectData;
|
||||
%% (*KillObject)
|
||||
%% };
|
||||
%% The Tcl wrapper function gets the connection object from the stack and
|
||||
%% invokes the SICS object function.
|
||||
%% This does not solve the Tcl security issue, though.
|
||||
%%
|
||||
|
||||
\section{The Device Executor}
|
||||
The device executor is responsible for executing and monitoring requests to
|
||||
the actual instrument hardware. In its current form the device executor can
|
||||
do this for any variable which can be driven (motors, temperature, composite
|
||||
variables) and counters (single counters, histogram memory). How this is
|
||||
done is explained in some detail in the section about SICS interfaces (see
|
||||
\ref{inter}) in the object writers guide. The interface to the device
|
||||
executor includes functions for starting, pausing, continuing devices and
|
||||
monitoring their status. Additionally there are some functions and SICS
|
||||
commands which allow to enquire about the status of the executor. If
|
||||
hardware is active, the device executor has a SICS system task running
|
||||
which initiates monitoring of devices. The device executor is built around a
|
||||
list of currently active hardware devices.
|
||||
|
||||
\section{The Environment Monitor}
|
||||
For the SICS concept for handling sample environment devices see
|
||||
\ref{evdev}.
|
||||
|
||||
\section{The Server}
|
||||
The server module defines a server data structure. A pointer to this
|
||||
data structure is the sole global variable in the SICS system. Its name is
|
||||
{\bf {\huge pServ}}. This data structure contains pointers to the most
|
||||
important SICS components: the interpreter, the task switcher, the device
|
||||
executor, the environment monitor and the network reader. This module also
|
||||
contains the code for initializing, running and stopping the server.
|
||||
|
||||
\section{The ServerLog}
|
||||
As part of the SICS kernel there exists a global server log file. This file
|
||||
contains:
|
||||
\begin{itemize}
|
||||
\item All traffic on all client connections. Even messages suppressed by the
|
||||
clients.
|
||||
\item All internal error messages.
|
||||
\item Notifications about important internal status changes.
|
||||
\end{itemize}
|
||||
This server log is meant as an aid in debugging the server. As the SICS
|
||||
server may run for days, weeks and months uninterrupted this log file may
|
||||
become very large. However, only the last thousand or so messages are really
|
||||
of interest when tracking a problem. Therefore a scheme is implemented to
|
||||
limit the disk space used by the server log. The server log writes
|
||||
cyclically into a number of files. A count of the lines is kept which were
|
||||
written to each file. Above a predefined count, a new file is started.
|
||||
As an interface the server log provides a function which allows to write
|
||||
a message to it. This can be used by any object in the system for
|
||||
interesting messages. The number of files to cycle through and the length of
|
||||
each file can be configured by defines at the top of servlog.c.
|
||||
|
||||
\section{The Performance Monitor}
|
||||
This facility provides the data for the Performance (see user documentation)
|
||||
command. The Performance Monitor is a task which increments a counter each
|
||||
time it is executed. After a predefined integration time (20 seconds) a new
|
||||
value cycles/per second is calculated. This is the data retrievable by the
|
||||
Performance command. This facility is not particularly necessary but proved
|
||||
useful for judging the impact of various system conditions on server
|
||||
performance. If at some stage performance needs to be boosted to the utmost
|
||||
and it is no longer the hardware which makes things slow, the performance
|
||||
monitor may well be removed from the system without harm.
|
||||
|
||||
\section{The Object Factory}
|
||||
During SICS initialization the SICS interpreters command list needs to be
|
||||
initialized. This is the task of the object factory. Its function
|
||||
IniIniCommand initializes all fixed, general SICS commands and all object
|
||||
creation commands. Then the server initialization file is processed from the
|
||||
server initialization code. After this is done, the server initialization
|
||||
code calls KillIniCommands which removes the now surplus object creation
|
||||
commands from the SICS interpreter. If new commands get added to SICS the
|
||||
object creation command or (for a permanent command) the object wrapper have
|
||||
to be registered with these two functions.
|
||||
|
||||
\section{SICS Options}
|
||||
Any system needs a way to configure itself. SICS uses options for internal
|
||||
parameters which should or need not be visible from the SICS interpreter. An
|
||||
option is a name value pair. For a definition of currently valid SICS
|
||||
options and how to create them see the SICS manager documentation. In terms
|
||||
of an interface this module allows to retrieve an option from the options
|
||||
database.
|
||||
|
||||
\section{The Password Database}
|
||||
The password database holds a triplet of username password and rights code
|
||||
for each user. This information is currently initialized from the server
|
||||
initialization file. This scheme is not very secure, as anybody with an
|
||||
account on the DAQ computer may view the file and thus the list of valid
|
||||
users. If this becomes a serious concern, this module has to be rewritten.
|
||||
|
||||
\section{The Server Main Function}
|
||||
This does not do much, just initialize the server, run it, and stop it.
|
||||
|
||||
|
||||
|
49
doc/programmer/macro.tex
Normal file
49
doc/programmer/macro.tex
Normal file
@ -0,0 +1,49 @@
|
||||
\subsection{The Macro Interpreter}
|
||||
This module is responsible for splicing the Tcl macro interpreter into
|
||||
the SICS framework. In order to achieve this several problems have to be
|
||||
adressed:
|
||||
\begin{itemize}
|
||||
\item How to make Tcl commands available from within SICS.
|
||||
\item How to call SICS with the correct execution context from Tcl macros.
|
||||
\end{itemize}
|
||||
The first problem is solved by overloading Tcl's unknown mechanism. The Tcl
|
||||
interpreter automatically invokes a procedure {\bf unknown} when it cannot
|
||||
find a command. The usual procedure in this case searches for Tcl procedures
|
||||
in libraries and then tries to invoke the command as a shell command. For
|
||||
SICS the last part has been cut off and replaced by a call to SICSUnknown
|
||||
which tries to find an appropriate SICS command.
|
||||
|
||||
The second problem is solved by maintaing a stack of connection objects.
|
||||
Before a Tcl command is invoked from SICS the current connection object is
|
||||
pushed on the stack. If in due course SICSUnknown needs to find a connection
|
||||
object in order to invoke a SICS object the last object from the stack will
|
||||
be used. If Tcl finishes, the connection object is popped from the stack.
|
||||
This is nicely shown in the TclAction code.
|
||||
All this is implemented in macro.c.
|
||||
|
||||
The macro module presents the following interface to the outside world:\begin{itemize}
|
||||
\item {\bf Tcl\_Interp *MacroInit(SicsInterp *pInter,SConnection *pCon) } initialises a Tcl interpreter with a SICS unknown mechanism. Furthermore deletes some Tcl standard commands which can be harmful in SICS. Returns a pointer to an interpreter on success, NULL else.
|
||||
\item {\bf void MacroDelete(Tcl\_Interp *pInter) } deletes an interpreter.
|
||||
\item {\bf int MacroFileEval(SConnection *pCon, SicsInterp *pInter, void *pData, int argc, char *argv) }, the SICS object wrapper function for script processing.
|
||||
\item {\bf int InternalFileEval(SConnection *pCon, SicsInterp *pInter,
|
||||
void *pData, int argc, char *argv) }, the SICS object wrapper
|
||||
function for script processing. This version suppresses output to the
|
||||
client however. All output goes into the command log only.
|
||||
\item {\bf int ClientPut(SConnection *pCon, SicsInterp *pInter, void *pData, int argc, char *argv) },
|
||||
the SICS object wrapper function for writing datato a client from
|
||||
within a Tcl--script.
|
||||
\item {\bf int MacroWhere(SConnection *pCon, SicsInterp *pInter,
|
||||
void *pData, int argc, char *argv) }, the SICS object wrapper
|
||||
function implementing the filewhere command.
|
||||
\item {\bf int TclPublish(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])} is the implmentation of the Publish command for the
|
||||
interpreter which installs a Tcl command into the system.
|
||||
\item {\bf int TransactAction (SConnection *pCon, SicsInterp *pInter,
|
||||
void *pData, int argc, char *argv) } This Function implements the
|
||||
transact command which executes an command and sends a string
|
||||
``TRANSACTIONFINISHED'' when the command finished executing.
|
||||
\item {\bf MacroPush} pushes a connection onto the Tcl connection
|
||||
stack.
|
||||
\item {\bf MacroPop} removes a connection for the Tcl connection
|
||||
stack.
|
||||
\end{itemize}
|
126
doc/programmer/mesure.tex
Normal file
126
doc/programmer/mesure.tex
Normal file
@ -0,0 +1,126 @@
|
||||
\subsection{Four Circle Single Counter Measurement Object}
|
||||
This object implements a basic single counter reflection measurement routine
|
||||
for four circle diffractometers. This object is able to read a reflection
|
||||
listing, drive to each reflection in the list, do a scan on it, integrate
|
||||
the scan results and write the results to ASCII files. Nothing sophisticated
|
||||
such as optimised measurement procedures and special background measurement
|
||||
programs. Three files will be created as output: one file with the ending
|
||||
.rfl which contains the reflection profiles for each reflection, a file .asc
|
||||
which contains a summary in form of HKL, I, sigma(I) for each reflection
|
||||
and a file ending .err which contains all the error messages obtained during
|
||||
the run.
|
||||
|
||||
|
||||
The interface to this object consists of these functions:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$mesureint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __Mesure *pMesure;@\\
|
||||
\mbox{}\verb@/*--------------------- live & death --------------------------------------*/@\\
|
||||
\mbox{}\verb@ pMesure CreateMesure(pHKL pCryst, pScanData pScanner, @\\
|
||||
\mbox{}\verb@ pMotor pOmega, char *pom, char *po2t,@\\
|
||||
\mbox{}\verb@ char *pFileRoot,pDataNumber pDanu);@\\
|
||||
\mbox{}\verb@ void DeleteMesure(void *pData);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int MesureFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@/*------------------- object functions -----------------------------------*/@\\
|
||||
\mbox{}\verb@ int MesureReflection(pMesure self, float fHKL[3], SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int MesureGenReflection(pMesure self, float fHKL[3],float fSet[4], SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int MesureStart(pMesure self, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int MesureReopen(pMesure self, char *filename, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int MesureClose(pMesure self);@\\
|
||||
\mbox{}\verb@ int MesureFile(pMesure self, char *pFile, int iSkip, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int MesureGenFile(pMesure self, char *pFile, int iSkip, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int MesureSetPar(pMesure self, char *name, float fVal);@\\
|
||||
\mbox{}\verb@ int MesureGetPar(pMesure self, char *name, float *fVal);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int MesureAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\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}
|
||||
All functions return 1 on success, 0 on failure.
|
||||
\begin{description}
|
||||
\item[CreateMesure] creates a new pMesure object. Parameters are the HKL
|
||||
object to use for cystallographic conversions and the scan object to use for
|
||||
doing the scans. This is followd by the motor for running omega, its name
|
||||
and the name of the motor for driving omega 2 theta. Finnaly the path to the
|
||||
data directory and the data number object for automatic filename creation is
|
||||
specified.
|
||||
\item[DeleteMesure] wipes the mesure object pData from memory.
|
||||
\item[MesureFactory] is the factory function for mesure which will be used
|
||||
by the interpreter to install mesure into the system.
|
||||
\item[MesureReflection] measures the single reflection fHKL. It drives
|
||||
there, calculates scan borders and performs the scan.
|
||||
\item[MesureGenReflection] measures the single reflection fHKL. It drives
|
||||
there, calculates scan borders and performs the scan. This version uses
|
||||
supplied values for the instrument settings.
|
||||
\item[MesureStart] sets everything up for a new measurement with new file
|
||||
names.
|
||||
\item[MesureReopen] reopens the files belonging to the file name given as
|
||||
base for appending. This is a recovery feature.
|
||||
\item[MesureFile] opens the file specified as second parameter and reads
|
||||
each line. Expected is a reflection to measure. Each reflection is then
|
||||
measured and output written. The last parameter iSkip allows to skip iSkip
|
||||
lines of the reflection file. This facility exists in order to restart work
|
||||
on an reflection file which had been interrupted for some reason.
|
||||
\item[MesureGenFile] opens the file specified as second parameter and reads
|
||||
each line. Expected is a reflection to measure. Each reflection is then
|
||||
measured and output written. The last parameter iSkip allows to skip iSkip
|
||||
lines of the reflection file. This facility exists in order to restart work
|
||||
on an reflection file which had been interrupted for some reason. This
|
||||
version acts upon files created by the program HKLGEN.
|
||||
\item[MesureSetPar] sets the parameter name of Mesure to fVal. A listing of
|
||||
possible parameters is given below.
|
||||
\item[MesureGetPar] returns the value of the parameter name in fVal.
|
||||
\item[MesureAction] implements the interpreter interface to the mesure
|
||||
object.
|
||||
\end{description}
|
||||
Mesure supports the following parameters:
|
||||
\begin{description}
|
||||
\item[np] the number of points per scan.
|
||||
\item[preset] The preset value for counting.
|
||||
\item[countmode] the counting mode, can be 0 for timer or 1 for monitor
|
||||
mode.
|
||||
\item[mode] can be 0 for omega 2theta scans or 1 for omega scans.
|
||||
\item[step] the scan step widths. This is allways in omega, in omega 2theta
|
||||
mode 2theta is always the double of this.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"mesure.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ M E S U R E@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ A SICS object for doing simple four circle measurements with a single@\\
|
||||
\mbox{}\verb@ counter. @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koenencke, April 1998@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSMESURE@\\
|
||||
\mbox{}\verb@#define SICSMESURE@\\
|
||||
\mbox{}\verb@@$\langle$mesureint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
209
doc/programmer/motor.tex
Normal file
209
doc/programmer/motor.tex
Normal file
@ -0,0 +1,209 @@
|
||||
\subsection{Motors}
|
||||
Most neutron scattering instruments have lots of motors to drive
|
||||
monochromators, samples and detectors through space.This module implements
|
||||
support for them. As usual for hardware objects in SICS motors are
|
||||
subdivided into a driver and the logical object.
|
||||
|
||||
\subsubsection{The Motor Driver}
|
||||
There is a problem here. There are some data fields and functions
|
||||
which must be present for any motor driver. Then there are fields
|
||||
which are specific just to a special implementation of a mot
|
||||
driver. There are several ways to deal with this. The way choosen for
|
||||
the motor driver is a kind of overlay. The first few fields of a valid
|
||||
motor driver structure MUST be specified in the same order as given
|
||||
below. A special motor driver can add additional fields at the end of
|
||||
the standard list. As an example for this scheme compare the
|
||||
AbstractMoDriv structure with the one for the EL734 motor driver.
|
||||
\begin{verbatim}
|
||||
typedef struct __AbstractMoDriv {
|
||||
/* general motor driver interface
|
||||
fields. REQUIRED!
|
||||
*/
|
||||
float fUpper; /* upper limit */
|
||||
float fLower; /* lower limit */
|
||||
char *name;
|
||||
int (*GetPosition)(void *self, float *fPos);
|
||||
int (*RunTo)(void *self,float fNewVal);
|
||||
int (*GetStatus)(void *self);
|
||||
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
|
||||
int (*TryAndFixIt)(void *self, int iError,float fNew);
|
||||
int (*ContinueAfterWarn)(void *self);
|
||||
int (*Halt)(void *self);
|
||||
}
|
||||
MotorDriver;
|
||||
\end{verbatim}
|
||||
All functions return 0 on failure or 1 on success, if not stated otherwise.
|
||||
The first parameter is always a pointer to the motor driver structure.
|
||||
The fields and their meanings: \begin{description}
|
||||
\item[fUpper,fLower] The hardware upper and lower limits for the motor.
|
||||
These are the real hardware limits as implemented by limit switches bolted
|
||||
to the instrument.
|
||||
\item[name] The real motor name.
|
||||
\item[GetPosition] retrieves the current hardware position of the motor into
|
||||
fPos.
|
||||
\item[RunTo] starts the motor to run to fNewVal. This sends a command to the
|
||||
motor and returns immediately.
|
||||
\item[GetStatus] requests the status from the motor. Possible answers are:
|
||||
\begin{description}
|
||||
\item[HWIdle, OKOK] The motor has finished or is idle.
|
||||
\item[HWFault] A fault has been found at the motor.
|
||||
\item[HWBusy] The motor is busy moving.
|
||||
\item[HWWarn] The motor hardware complained but managed to reach the
|
||||
requested position.
|
||||
\item[HWPosFault] The motor could not go where it should go for some reason.
|
||||
However, the motor is intact and ready to move somewhere else. This can
|
||||
happen when there is a concrete block in the instruments way which is not
|
||||
accounted for by a limit switch. This can also happen when the motor hits a
|
||||
limit switch. However, the general idea of SICS is that the limits will be
|
||||
checked for before even starting to run the motor. In order for this to
|
||||
work, the limits SICS knows about must macth those actually implemented.
|
||||
\end{description}
|
||||
\item[GetError] This gets called when an error has been detected during one
|
||||
of the previous operations. The function has to return more information
|
||||
about the error: iCode an driver dependent integer error code and maximum
|
||||
iErrLen characters of problem description in error.
|
||||
\item[TryAndFixIt] takes the integer error code returned in iCode from
|
||||
GetError and tries to solve the problem with the hardware. This function can
|
||||
either return MOTREDO which means the problem has been fixed and the
|
||||
operation needs to be redone, MOTOK when the problem has been fixed and no
|
||||
resending of a command is necessary or MOTFAIL which means that it is not
|
||||
possible to resolve the problem in software.
|
||||
\item[ContinueAfterWarn] will be called after a warning from the motor. This
|
||||
function is supposed to do whatever is needed to clear the warning from the
|
||||
motor and keep him going.
|
||||
\item[Halt] emergency stop the motor, NOW.
|
||||
\end{description}
|
||||
|
||||
As an example for a derived motor driver the SINQ EL734 motor driver is
|
||||
shown below. It add to the general fields the special things for that motor:
|
||||
host, port and channel number of the motor controller and a pointer to the
|
||||
driver communications structure.
|
||||
\begin{verbatim}
|
||||
typedef struct __MoDriv {
|
||||
/* general motor driver interface
|
||||
fields. REQUIRED!
|
||||
*/
|
||||
float fUpper; /* upper limit */
|
||||
float fLower; /* lower limit */
|
||||
char *name;
|
||||
int (*GetPosition)(void *self,float *fPos);
|
||||
int (*RunTo)(void *self, float fNewVal);
|
||||
int (*GetStatus)(void *self);
|
||||
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
|
||||
int (*TryAndFixIt)(void *self,int iError, float fNew);
|
||||
int (*ContinueAfterWarn)(void *self);
|
||||
int (*Halt)(void *self);
|
||||
|
||||
|
||||
/* EL-734 specific fields */
|
||||
int iPort;
|
||||
char *hostname;
|
||||
int iChannel;
|
||||
int iMotor;
|
||||
void *EL734struct;
|
||||
int iMSR;
|
||||
} EL734Driv;
|
||||
\end{verbatim}
|
||||
|
||||
Most of the interaction with the motor driver happens through the functions
|
||||
defined in its data structure. The rest is creation and deletion:
|
||||
\begin{description}
|
||||
\item[MotorDriver *CreateEL734(SConnection *pCon, int argc, char
|
||||
*argv[])]
|
||||
creates a EL734 motor driver. The argc, \verb+argv[]+ pair contains the
|
||||
necessary drive parameters.
|
||||
\item[MotorDriver *CreateEL734DC(SConnection *pCon, int argc, char
|
||||
*argv[])]
|
||||
created an EL734 DC motor driver.
|
||||
\item[void KillEL734(void *pData)] deletes a EL734 motor driver.
|
||||
\item[MotorDriver *CreateSIM(SConnection *pCon, int argc, char *argv[])]
|
||||
creates a simulation motor driver.
|
||||
\item[void KillSIM(void *pData)] deletes a simulated motor driver.
|
||||
\end{description}
|
||||
|
||||
\subsubsection{The Motor Logical Object}
|
||||
The motor object represents the motor to SICS. One of its responsabilities
|
||||
is to drive motor operations and error checking. The scheme
|
||||
implemented is that the motor object tries to bring the motor to its
|
||||
position at least three times before a failure is recorded. Also the
|
||||
motor object keeps track of a count of failed operations. If this
|
||||
count gets to high an interrupt is issued to stop the instrument. This
|
||||
was put in after Druechal tried to drive over a slab of concrete for a
|
||||
whole night and subsequently broke a clutch.
|
||||
Motors are represented by the
|
||||
following data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct __Motor {
|
||||
pObjectDescriptor pDescriptor;
|
||||
ObPar *ParArray;
|
||||
pIDrivable pDrivInt;
|
||||
pICallBack pCall;
|
||||
char *drivername;
|
||||
char *name;
|
||||
MotorDriver *pDriver;
|
||||
float fTarget;
|
||||
float fPosition;
|
||||
} Motor;
|
||||
typedef Motor *pMotor;
|
||||
\end{verbatim}
|
||||
The fields: \begin{description}
|
||||
\item[pDescriptor] The usual SICS object descriptor.
|
||||
\item[ParArray] A dictionary of parameter names and float values. This array
|
||||
holds all the different parameters used to operate the motor.
|
||||
\item[pDrivInt] A pointer to the drivable interface implemented by the motor
|
||||
object.
|
||||
\item[pCall] A pointer to the callback interface implemented by the motor
|
||||
object.
|
||||
\item[drivername] The name of the motor driver.
|
||||
\item[name] The name of the motor.
|
||||
\item[pDriver] A pointer to the motor driver to use.
|
||||
\item[fTarget] The target position for the motor.
|
||||
\item[fPosition] The last known position of the motor.
|
||||
\end{description}
|
||||
|
||||
Much of the action of the motor is hidden in the implementation of the
|
||||
drivable interface to the motor. Additionally the functions as given below
|
||||
are defined. All functions take a pointer to the motor object data structure
|
||||
as a parameter. They retun 0 on success or 1 on failure while not stated
|
||||
otherwise.
|
||||
\begin{description}
|
||||
\item[int MotorGetPar(pMotor self, char *name, float *fVal)] retrieves the
|
||||
value of the parameter name in fVal.
|
||||
\item[int MotorSetPar(pMotor self, SConnection *pCon, char *name, float
|
||||
fVal)] tries to write fVal to the parameter name. Errors are written to
|
||||
the connection pCon.
|
||||
\item[long MotorRun(void *self, SConnection *pCon, float fNew)] starts a
|
||||
motor running to fNew. Does not wait for the motor to finish.
|
||||
\item[int MotorCheckBoundary(pMotor self, float fVal, float *fHard,
|
||||
char *error, int iErrLen)] checks if the position
|
||||
fVal violates any of the motors software or hardware limits. In case of
|
||||
success a new hardware position is returned in fHard. fHard is then
|
||||
corrected for possible software zero points. In case of a limit violation
|
||||
maximum iErrLen characters of error information are returned in error.
|
||||
\item[int MotorCheckPosition(void *self, SConnection *pCon)] returns 1 if
|
||||
the motor is at the target position, 0 else, or -1 if the motor could not be
|
||||
read.
|
||||
\item[int MotorGetSoftPosition(pMotor self,SConnection *pCon, float *fVal)]
|
||||
reads the current motor position into fVal. This position is corrected for
|
||||
software zero points.
|
||||
\item[int MotorGetHardPosition(pMotor self,SConnection *pCon, float *fVal)]
|
||||
reads the current position of the motor as returned from the hardware.
|
||||
\item[int MakeMotor(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])] the motor factory function. To
|
||||
be hacked when a new driver needs to be included.
|
||||
\item[pMotor MotorInit(char *drivername,char *name, MotorDriver *pDriv)]
|
||||
creates a new motor object with driver pDriv. Returns NULL on failure.
|
||||
\item[void MotorKill(void *self)] deletes a motor object. Needs to be
|
||||
modified for a new driver in order to clean out the new driver properly.
|
||||
\item[int MotorAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])] the object wrapper function for
|
||||
the motor. Implements the user interface.
|
||||
\item[pMotor FindMotor(SicsInterp *pSics, char *name)] finds a motor name in
|
||||
the interpreter pSics. This is a convenience function. Returns NULL if no
|
||||
motor could be found, else a pointer to its data structure.
|
||||
\end{description}
|
||||
|
||||
|
||||
|
||||
|
||||
|
49
doc/programmer/mumo.tex
Normal file
49
doc/programmer/mumo.tex
Normal file
@ -0,0 +1,49 @@
|
||||
\subsection{Multiple Motors}
|
||||
Multiple Motors is a module which implements a special syntax for SANS.
|
||||
Motors are collected into a group. For example beamstop and manipulated
|
||||
through them. Furthermore multiple motors support named positions and a
|
||||
special position {\bf back} which is the position before the last movement.
|
||||
Multiple Motors works, but it if larger changes become necessary it might be
|
||||
sensible to drop it and replace it by a work alike in the macro language.
|
||||
Please note, that multiple motors starts motors to run, but does not wait
|
||||
for them to finish.
|
||||
|
||||
Multiple motors are characterized through the following data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct __MULMOT {
|
||||
pObjectDescriptor pDes;
|
||||
char *name;
|
||||
pStringDict pAlias;
|
||||
pStringDict pNamPos;
|
||||
ObPar *pParam;
|
||||
} MulMot;
|
||||
\end{verbatim}
|
||||
The fields are:
|
||||
\begin{description}
|
||||
\item[pDes] A pointer to the usual SICS object descriptor.
|
||||
\item[name] The name of the multi motor.
|
||||
\item[pAlias] A string dictionary which maps group internal motor names to
|
||||
real SICS motor names.
|
||||
\item[pNamPos] A string dictionary which maps named positions to the SICS
|
||||
command necessary to run to that position.
|
||||
\end{description}
|
||||
|
||||
Multiple motors are interfaced to with the following functions:
|
||||
\begin{description}
|
||||
\item[pMulMot MakeMultiMotor(void)] creates multi motors device. Returns a
|
||||
pointer to a new data structure on success, NULL in case of failure.
|
||||
\item[void KillMultiMotor(void *pData)] deletes a multi motor device.
|
||||
\item[int MultiWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, \\
|
||||
int argc, char *argv[])] The object wrapper function for
|
||||
multiple motors.
|
||||
\item[int MakeMulti(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The object factory function for
|
||||
multiple motors.
|
||||
\item[int ConfigMulti(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The configuration function for
|
||||
multiple motors.
|
||||
\end{description}
|
||||
|
||||
The implementation of multiple motors can be found in files mumo.c,
|
||||
mumoconf.c, mumo.h and mumo.i.
|
||||
|
1850
doc/programmer/napi.tex
Normal file
1850
doc/programmer/napi.tex
Normal file
File diff suppressed because it is too large
Load Diff
383
doc/programmer/nconman.tex
Normal file
383
doc/programmer/nconman.tex
Normal file
@ -0,0 +1,383 @@
|
||||
\subsection{The Connection Object}
|
||||
The connection object is a major player in the SICS world. The connection
|
||||
object represents an active connection between the SICS server and a client.
|
||||
There will be one connection object for each client connection. A lot of
|
||||
stuff is associated with a client connection:
|
||||
\begin{itemize}
|
||||
\item A task. This task will read one command from the command fifo and
|
||||
execute it.
|
||||
\item A command fifo which will be filled by the network reader.
|
||||
\item An execution context consisting of user rights for this connection
|
||||
and interrupt status.
|
||||
\item A communication channel to the client.
|
||||
\item A list of log files to which all traffic on the connection will be
|
||||
logged.
|
||||
\item An interface to the SICS interpreter which allows to configure
|
||||
certain aspects of the connection and makes the connection available as
|
||||
a command.
|
||||
\item A list of callbacks registered for the connection. A connection can
|
||||
be automatically notified about changes in system state. These callbacks
|
||||
have to be removed when the client server connection terminates. Otherwise
|
||||
callback code would write to a dead connection causing the program to
|
||||
crash.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Connection I/O}
|
||||
Due to user requirements for features not considered in the design the
|
||||
I/O facilities of connection have become quite involved.
|
||||
|
||||
Incoming commands are printed into client log files if configured, and
|
||||
into the commandlog if the connection has a privilege $\ge$ user
|
||||
privilege. This is implemented in SCInvoke. Also each command is
|
||||
printed to the server log.
|
||||
|
||||
Output is more sophisticated. First of all there are different output
|
||||
codes given as last parameter to SCWrite. The most important of these
|
||||
are:
|
||||
\begin{description}
|
||||
\item[eError] Error messages.
|
||||
\item[Warning] warnings.
|
||||
\item[Value] values requested by the client.
|
||||
\item[Status] status messages.
|
||||
\end{description}
|
||||
Clients can choose to suppress certain types of messages in order to
|
||||
reduce I/O.
|
||||
|
||||
The logic is mostly implemented in the
|
||||
file static function SCNormalWrite. The follwoing conditions are
|
||||
implemented:
|
||||
\begin{itemize}
|
||||
\item Any output is logged to the
|
||||
server log.
|
||||
\item If the privilege of the connection is $\ge$ user the
|
||||
output is printed to the commandlog as well.
|
||||
\item If the command is executing as part of a Tcl--macro script
|
||||
output to the socket is suppressed. The output is copied into the
|
||||
interpreter for further evaluation instead. This is done in order to
|
||||
prevent excessive output during macro evaluation and in order to make
|
||||
SICS results available in the Tcl interpreter. However, messages of
|
||||
type error or warning are printed to the socket even during macro
|
||||
evaluation.
|
||||
\item In the normal case the output is printed to the socket and all
|
||||
log files configured for the connection.
|
||||
\item As of recent the output function can be modified by setting a
|
||||
new function. One sich function exists which supresses all output to
|
||||
the socket. This is done in order to help when the connection gets
|
||||
lost. For instance with the cron command.
|
||||
\end{itemize}
|
||||
This aspect of the connection object could do with a cleanup. A
|
||||
possible cleanup path is the implementation of the different output
|
||||
strategies in different functions and devise a SCsetOutMode function which
|
||||
switches between the various possibilities. Also, it can be argued if
|
||||
the client specific log files are still needed. Then this part of the
|
||||
code can be cleaned out as well.
|
||||
|
||||
|
||||
\subsubsection{Command Execution Path}
|
||||
In the course of the SICS development the path of a command through
|
||||
the system has become more complex as well. This section describes how
|
||||
it works. The incoming command is collected at the socket by the
|
||||
NetReaderTask. This does a little processing and checks for interrupts
|
||||
issued on the connection and invokes them. But any normal command is
|
||||
put into the connections Command-FIFO. Thus ends the business of the
|
||||
NetReaderTask. The connections task function SCTaskFunction is
|
||||
invoked by the task manager in due time and checks for pending
|
||||
commands on the command stack. If a command is pending it is taken
|
||||
from the stack and executed through SCInvoke.
|
||||
|
||||
\subsubsection{Execution context}
|
||||
Each connection has a user right code associated with it. The there is
|
||||
a second protection scheme in SICS with the token system. This system
|
||||
reserves command input to a certain connection. In the connection
|
||||
object this scheme requires the iGrab field which defines if this
|
||||
connection may execute commands or not. This field is modified through
|
||||
the tasks signal handling function. Code implementing a command may
|
||||
call SCMatchRights in order to check for permission. SCMatchRights
|
||||
will also send appropriate error messages.
|
||||
|
||||
Errors are usually signalled by setting an interrupt code on the
|
||||
connection. An additional field, iError allows to give a more detailed
|
||||
error description if required.
|
||||
|
||||
\subsubsection{Callbacks}
|
||||
SICS can be configured to forward notifications about certain state
|
||||
changes to a connection automatically. This is implemented through the
|
||||
callback system. For more details see \ref{inter}. However, it is
|
||||
important that any callback acting on a connection is registered with
|
||||
the connection object. This allows the removal of the callback when
|
||||
the connection is closed. Otherwsie the system gets filled up with
|
||||
dead callbacks which usuallly cause core dumps when it is tried to
|
||||
send a message to a dead connection.
|
||||
|
||||
|
||||
\subsubsection{The Connection Data Structure}
|
||||
Given the plethora of things to take care of, each connection is
|
||||
represented by a rather large data structure.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$condat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __SConnection {@\\
|
||||
\mbox{}\verb@ /* object basics */@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ char *pName;@\\
|
||||
\mbox{}\verb@ long lMagic;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* I/O control */@\\
|
||||
\mbox{}\verb@ mkChannel *pSock;@\\
|
||||
\mbox{}\verb@ FILE *pFiles[MAXLOGFILES];@\\
|
||||
\mbox{}\verb@ int iMacro;@\\
|
||||
\mbox{}\verb@ int iTelnet;@\\
|
||||
\mbox{}\verb@ int iOutput; @\\
|
||||
\mbox{}\verb@ int iFiles;@\\
|
||||
\mbox{}\verb@ int (*write)(SConnection *pCon,@\\
|
||||
\mbox{}\verb@ char *pMessage, int iCode);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /* execution context */@\\
|
||||
\mbox{}\verb@ int eInterrupt;@\\
|
||||
\mbox{}\verb@ int iUserRights;@\\
|
||||
\mbox{}\verb@ int inUse;@\\
|
||||
\mbox{}\verb@ int iGrab;@\\
|
||||
\mbox{}\verb@ int iErrCode;@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* a FIFO */@\\
|
||||
\mbox{}\verb@ pCosta pStack;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /* callback registry */@\\
|
||||
\mbox{}\verb@ int iList;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* Tasking Stuff */@\\
|
||||
\mbox{}\verb@ int iEnd;@\\
|
||||
\mbox{}\verb@ }SConnection;@\\
|
||||
\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 are:
|
||||
\begin{description}
|
||||
\item[pDes] The usual object descriptor belonging to any object within the
|
||||
SICS interpreter. See \ref{inter} for details.
|
||||
\item[pName] The automatically generated name of the connection object in the
|
||||
interpreter.
|
||||
\item[lMagic] is a magic number used internally in order to check if
|
||||
the connection object given as a parameter is valid.
|
||||
|
||||
\item[pChannel] A pointer to a network channel structure. This channel
|
||||
will be used for I/O to the client. If thispointer is NULL I/O is done onto
|
||||
stdin/stdout instead.
|
||||
\item[pFiles] An array of file to which all I/O on this connection will be
|
||||
logged.
|
||||
\item[iOutPut] The currently valid output mask. SICS messages are classified
|
||||
into several output classes. If a message is going to be printed it must
|
||||
have a output class above the one configured as the mask. This was made in
|
||||
order to allow clients to suppress certain messages which are not of
|
||||
interest.
|
||||
\item[iFiles] The number of configured log files.
|
||||
\item[write] a pointer to a function which does the actual writing of
|
||||
a message to the connection.
|
||||
\item[iTelnet] is true when I/O is through a telnet connection.
|
||||
\item[iMacro] This flag is set when the connection is executing a Tcl
|
||||
script. In this mode mode all output is written into the Tcl interpreter and
|
||||
not written to the client. Thus a script can execute silently. As always,
|
||||
there is an exception: errors and warning will still be written to the
|
||||
client.
|
||||
|
||||
\item[iGrab] This is 0 when the connection may execute commands. It is 1 if
|
||||
another connection has grabbed the control token and commands may not be
|
||||
executed. For details about the token system, see the token reference.
|
||||
\item[eInterrupt] This is the current interrupt status of the connection.
|
||||
\item[iUserRights] This integer denotes the user rights associated with the
|
||||
connection. This value is initially deducted from the username password pair
|
||||
given at login to SICS. The value can be configured otherwise afterwards.
|
||||
iUserRights will be used to check at object level if a client may perform
|
||||
the requested operation or not.
|
||||
\item[iErrCode] is the last error code. I think this field is no longer
|
||||
used.
|
||||
|
||||
\item[pSics] is a pointer to an SICS interpreter where to invoke commands.
|
||||
\item[pStack] Is the command FIFO.
|
||||
\item[iList] This is the identifier of a lld list which holds the callbacks
|
||||
registered on this connection object.
|
||||
\item[iEnd] iEnd is a flag which is usually 0. It is set by certain
|
||||
interrupts or if the connection is broken and causes the connection task to
|
||||
end and the connection data structure to be removed from the system.
|
||||
\end{description}
|
||||
Quite a few places in SICS refer to this data structure directly,
|
||||
without a function interface. The reason for this is performance. Therefore
|
||||
this data structure is made public in the conman.h file.
|
||||
|
||||
|
||||
\subsubsection{Connection Functions}
|
||||
The interface to this data structure is defined by the following functions:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$conint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------ live & death ----------------------------*/@\\
|
||||
\mbox{}\verb@ SConnection *SCreateConnection(SicsInterp *pSics, mkChannel *pSock,@\\
|
||||
\mbox{}\verb@ int iUserRights);@\\
|
||||
\mbox{}\verb@ SConnection *SCCreateDummyConnection(SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@ void SCDeleteConnection(void *pVictim);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*------------------------------- tasking --------------------------------*/@\\
|
||||
\mbox{}\verb@ int SCTaskFunction(void *pCon);@\\
|
||||
\mbox{}\verb@ void SCSignalFunction(void *pCon, int iSignal, void *pSigData);@\\
|
||||
\mbox{}\verb@/* ***************************** I/O ************************************** */@\\
|
||||
\mbox{}\verb@ int SCAddLogFile(SConnection *self, char *name);@\\
|
||||
\mbox{}\verb@ void SCSetOutputClass(SConnection *self, int iClass);@\\
|
||||
\mbox{}\verb@ int SCWrite(SConnection *self, char *pBuffer, int iOut);@\\
|
||||
\mbox{}\verb@ int SCRead(SConnection *self, char *pBuffer, int iBufLen); @\\
|
||||
\mbox{}\verb@ int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);@\\
|
||||
\mbox{}\verb@ int SCSendOK(SConnection *self);@\\
|
||||
\mbox{}\verb@ int SCnoSock(SConnection *pCon);@\\
|
||||
\mbox{}\verb@/************************* CallBack *********************************** */@\\
|
||||
\mbox{}\verb@ int SCRegister(SConnection *pCon, SicsInterp *pSics,@\\
|
||||
\mbox{}\verb@ void *pInter, long lID);@\\
|
||||
\mbox{}\verb@ int SCUnregister(SConnection *pCon, void *pInter);@\\
|
||||
\mbox{}\verb@/******************************* Error **************************************/@\\
|
||||
\mbox{}\verb@ void SCSetInterrupt(SConnection *self, int eCode);@\\
|
||||
\mbox{}\verb@ int SCGetInterrupt(SConnection *self); @\\
|
||||
\mbox{}\verb@ void SCSetError(SConnection *pCon, int iCode);@\\
|
||||
\mbox{}\verb@ int SCGetError(SConnection *pCon); @\\
|
||||
\mbox{}\verb@/****************************** Macro ***************************************/@\\
|
||||
\mbox{}\verb@ int SCinMacro(SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int SCsetMacro(SConnection *pCon, int iMode); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* *************************** Info *************************************** */@\\
|
||||
\mbox{}\verb@ int SCGetRights(SConnection *self);@\\
|
||||
\mbox{}\verb@ int SCSetRights(SConnection *pCon, int iNew);@\\
|
||||
\mbox{}\verb@ int SCMatchRights(SConnection *pCon, int iCode);@\\
|
||||
\mbox{}\verb@ int SCGetOutClass(SConnection *self);@\\
|
||||
\mbox{}\verb@ int SCGetGrab(SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* **************************** Invocation ******************************** */@\\
|
||||
\mbox{}\verb@ int SCInvoke(SConnection *self,SicsInterp *pInter,char *pCommand);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*************************** User Command **********************************/@\\
|
||||
\mbox{}\verb@ int ConfigCon(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||
\mbox{}\verb@ int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||
\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[SCreateConnection] creates a new connection object. Parameters to this
|
||||
call are a pointer to a server data structure, a pointer to a network
|
||||
connection object and the user rights to use in this connection. This
|
||||
also adds a new task function for this connection to the task object.
|
||||
\item[SCCreateDummyConnection] creates a dummy connection for use during
|
||||
system initialisation. Printing to a socket will be suppressed for such a connection. But the output is printed to stdout.
|
||||
|
||||
\item[SCTaskFunction] is the task function which will be registered with the
|
||||
Tasker. This function reads a new command from the command stack (if
|
||||
available) and executes it in the interpreter.
|
||||
\item[SCSignalFunction] is the signal function for the connection
|
||||
object. This function handles interrupts and the token security
|
||||
system.
|
||||
\item[SCDeleteConnection] deletes a connection object and all its data
|
||||
structures. This function will be automatically called by the tasker when
|
||||
the task function returns with a 0.
|
||||
\item[SCAddLogFile] configures the log file name into the connection object.
|
||||
If this suceeds all I/O to the connection will be logged to this file as
|
||||
well.
|
||||
\item[SCSetOutputClass] sets the output class for the connection.
|
||||
\item[SCGetOutClass] returns the output class of the connection.
|
||||
\item[SCWrite] is the most important function of SConnection. Writes the
|
||||
buffer pBuffer with output code iOut to the client. {\em All output to the
|
||||
client has to be channelled through this function!}
|
||||
\item[SCRead] reads data from the client connection into the buffer pBuffer,
|
||||
but maximum iBufLen bytes.
|
||||
\item[SCPrompt] prompts the client for a reply. But waits only for certain
|
||||
timeout period. pPrompt is the prompt for the client, pResult is the buffer
|
||||
with the client reply. Maximum iLen bytes will be copied to
|
||||
pResult. Returns true (1) on a successfull read, else 0 (false).
|
||||
\item[SCSendOK] A short cut which sends OK to the client.
|
||||
\item[SCRegister] registers a callback with the connection. Parameters are:
|
||||
The interpreter to use, the interface with which the callback was
|
||||
registered and the ID of the callback. All automatic notifications to a
|
||||
client MUST be registered with this call. When the connection is deleted all
|
||||
these callbacks will be removed as well. Otherwise a core dump is bound to
|
||||
happen.
|
||||
\item[SCUnregister] will remove all callbacks on interface pInter for this
|
||||
connection.
|
||||
\item[SCSetInterrupt] sets an interrupt on the connection.
|
||||
\item[SCGetInterrupt] retrives the current interrupt status of the
|
||||
connection.
|
||||
\item[SCSetError] sets an error code in the connection.
|
||||
\item[SCGetError] retreives the current error code on the connection.
|
||||
\item[SCinMacro] returns true if the connection is executing a tcl script,
|
||||
returns false otherwise.
|
||||
\item[SCsetMacro] sets the iMacro flag.
|
||||
\item[SCGetRights] returns the current user rights associated with the
|
||||
connection.
|
||||
\item[SCGetGrab] gets the status of the control token for this connection.
|
||||
This calls returns 0 if the connection may execute commands and 1 if another
|
||||
connection has the control token.
|
||||
\item[SCSetRights] sets the user rights for the connection to a new value.
|
||||
\item[SCMatchRights] return true (1) if the iCode matches with the user
|
||||
rights of the connection, 0 (false) otherwise. SCMatchRights also checks for
|
||||
the status of the control token. Suitable error messages are written to pCon
|
||||
if the user rights do not match.
|
||||
\item[SCInvoke] invokes pCommand in the SICS interpreter pSics for the
|
||||
connection pCon. This function also prints the executed command into
|
||||
logfiles and into the commandlog.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"conman.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C O N N E C T I O N O B J E C T@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This file defines the connection object data structure and the interface to@\\
|
||||
\mbox{}\verb@ this data structure. This is one of the most important SICS components.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Substantially revised from a prior version.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSCONNECT@\\
|
||||
\mbox{}\verb@#define SICSCONNECT@\\
|
||||
\mbox{}\verb@#include <stdio.h>@\\
|
||||
\mbox{}\verb@#include "costa.h"@\\
|
||||
\mbox{}\verb@#include "SCinter.h"@\\
|
||||
\mbox{}\verb@#include "network.h"@\\
|
||||
\mbox{}\verb@#include "obdes.h"@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#define MAXLOGFILES 10@\\
|
||||
\mbox{}\verb@@$\langle$condat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#include "nserver.h"@\\
|
||||
\mbox{}\verb@@$\langle$conint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
38
doc/programmer/network.tex
Normal file
38
doc/programmer/network.tex
Normal file
@ -0,0 +1,38 @@
|
||||
\subsection{The network module}
|
||||
The network class encapsulates the network protocoll used for client server communications in SICS. This is the place to hack if SICS needs porting to other protocols. This class implements:\begin{verbatim}
|
||||
typedef struct {
|
||||
int sockid;
|
||||
int iType;
|
||||
struct sockaddr_in adresse;
|
||||
} mkChannel;
|
||||
\end{verbatim}
|
||||
|
||||
This is the datastructure maintained for each socket. Never deal with it
|
||||
directly but through the functions given below. Wherever a timeout is
|
||||
specified as a parameter below the following rule applies: If timout is
|
||||
greater 0, then timeout means a time in milliseconds to wait with a select
|
||||
system call for data to arrive. If timeout is less or equal then 0 the
|
||||
socket will block on input.
|
||||
\begin{itemize}
|
||||
\item {\bf mkChannel *NETOpenPort(int iPort) }, opens a server port on port number iPort for listening. If successful returns a pointer to a fresh mkChannel datastructure , else NULL.
|
||||
\item {\bf mkChannel *NETAccept(mkChannel *self, int timeout) }, waits timeout microseconds for a client requesting a connection to the server This is done with thke select system call. If a request comes in a new mkChannel structure is created and returned. If not NULL will be returned.
|
||||
\item {\bf mkChannel *NETConnect(char *name, int port) } tries to connect to a server specified by the hostname name and the port number port. Returns a pointer to a new mkChannel structure on success, NULL else.
|
||||
\item {\bf int NETWrite(mkChannel *self, char *buffer, long lLen) } writes lLen bytes from buffer to the socket specified by self. Returns True on succees, else False.
|
||||
\item {\bf long NETRead(mkChannel *self, char *buffer, long lLen, int timeout) } waits timeout microseconds for data to arrive at the socket specified by self. If data is available it will be copied into the buffer, but to a maximum length of lLen. Returns the length of data read, 0 if there is no data and -1 if an EOF occured on the socket (i.e the partner closed the connection).
|
||||
\item {\bf int NETClosePort(mkChannel *self) } If you are done with talking you can use this to close the connection. The socket specified by self can no longer be used after this. You still have to free the mkChannel though, if you want to do it properly. The function returns True on success, False (0) if the call failed.
|
||||
\item {\bf mkChannel *UDPOpen(int iPort) } opens a port for connectionless UDP-connection.
|
||||
\item {\bf mkChannel UDPConnect(int iPort) } connects a client to a UDP port for Data transfer.
|
||||
\item {\bf long UDPRead(mkChannel self, char *buffer, long lLen, int timeout) } reads data from a UDP port inot buffer, but maximum lLen bytes. Waits maximum timeout microseconds for data. Returns the number of bytes read or -1 for end of file.
|
||||
\item {\bf int UDPWrite(mkChannel *self, char *buffer, long lLen); } writes lLen bytes from buffer into an UDP channel.
|
||||
\end{itemize}
|
||||
|
||||
SICS needs I/O multiplexing, that is it needs to be able to handle request
|
||||
from many clients. Instead of spawning more processes or using threads with
|
||||
all the synchronisation problems associated with both of the above, I/O
|
||||
multiplexing is done with the select() system call here. Select uses a
|
||||
funny mask as input which specifies the id of the stream it is interested
|
||||
in. It requires the (stream-number (number, not FILE *) + 1 ) bit of the
|
||||
mask to be set for interest in stream number. This mask is set using macros
|
||||
defined in the apropriate header files.
|
||||
|
||||
|
660
doc/programmer/newsics.eps
Normal file
660
doc/programmer/newsics.eps
Normal file
@ -0,0 +1,660 @@
|
||||
%!
|
||||
%%BoundingBox: 2 358 358 785
|
||||
%%Title: newsics
|
||||
%%CreationDate: Thu Nov 20 13:43:31 1997
|
||||
%%Creator: Tgif-3.0-p7 by William Chia-Wei Cheng (william@cs.UCLA.edu)
|
||||
|
||||
/tgifdict 4 dict def
|
||||
tgifdict begin
|
||||
|
||||
/tgifarrowtipdict 8 dict def
|
||||
tgifarrowtipdict /mtrx matrix put
|
||||
|
||||
/tgifarrowtip
|
||||
{ tgifarrowtipdict begin
|
||||
/dy exch def
|
||||
/dx exch def
|
||||
/h exch def
|
||||
/w exch def
|
||||
/y exch def
|
||||
/x exch def
|
||||
/savematrix mtrx currentmatrix def
|
||||
x y translate
|
||||
dy dx atan rotate
|
||||
0 0 moveto
|
||||
w neg h lineto
|
||||
w neg h neg lineto
|
||||
savematrix setmatrix
|
||||
end
|
||||
} def
|
||||
|
||||
end
|
||||
|
||||
%%PageBoundingBox: 2 358 358 785
|
||||
tgifdict begin
|
||||
/tgifsavedpage save def
|
||||
|
||||
1 setmiterlimit
|
||||
1 setlinewidth
|
||||
|
||||
0 setgray
|
||||
|
||||
72 0 mul 72 11.00 mul translate
|
||||
72 128 div 100.000 mul 100 div dup neg scale
|
||||
|
||||
gsave
|
||||
|
||||
/tgiforigctm matrix currentmatrix def
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier-Bold findfont [24 0 0 -24 0 0] makefont setfont
|
||||
gsave
|
||||
192 36 moveto (The Taskloop) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
192 94 moveto (Device) show
|
||||
192 111 moveto (Executor) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
112 190 moveto (Network) show
|
||||
112 207 moveto (Reader) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
224 270 moveto (Client1 ) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
352 270 moveto (Client2) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
448 222 moveto (Client3) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
384 142 moveto (Emon) show
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
272 80 moveto
|
||||
288 80 288 128 16 arcto 4 {pop} repeat
|
||||
288 112 lineto
|
||||
288 128 176 128 16 arcto 4 {pop} repeat
|
||||
192 128 lineto
|
||||
176 128 176 80 16 arcto 4 {pop} repeat
|
||||
176 96 lineto
|
||||
176 80 288 80 16 arcto 4 {pop} repeat
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
192 176 moveto
|
||||
208 176 208 224 16 arcto 4 {pop} repeat
|
||||
208 208 lineto
|
||||
208 224 96 224 16 arcto 4 {pop} repeat
|
||||
112 224 lineto
|
||||
96 224 96 176 16 arcto 4 {pop} repeat
|
||||
96 192 lineto
|
||||
96 176 208 176 16 arcto 4 {pop} repeat
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
432 128 moveto
|
||||
448 128 448 160 16 arcto 4 {pop} repeat
|
||||
448 144 lineto
|
||||
448 160 368 160 16 arcto 4 {pop} repeat
|
||||
384 160 lineto
|
||||
368 160 368 128 16 arcto 4 {pop} repeat
|
||||
368 144 lineto
|
||||
368 128 448 128 16 arcto 4 {pop} repeat
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
288 240 moveto
|
||||
304 240 304 288 16 arcto 4 {pop} repeat
|
||||
304 272 lineto
|
||||
304 288 208 288 16 arcto 4 {pop} repeat
|
||||
224 288 lineto
|
||||
208 288 208 240 16 arcto 4 {pop} repeat
|
||||
208 256 lineto
|
||||
208 240 304 240 16 arcto 4 {pop} repeat
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
416 240 moveto
|
||||
432 240 432 288 16 arcto 4 {pop} repeat
|
||||
432 272 lineto
|
||||
432 288 336 288 16 arcto 4 {pop} repeat
|
||||
352 288 lineto
|
||||
336 288 336 240 16 arcto 4 {pop} repeat
|
||||
336 256 lineto
|
||||
336 240 432 240 16 arcto 4 {pop} repeat
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% RCBOX
|
||||
0 setgray
|
||||
gsave
|
||||
gsave
|
||||
newpath
|
||||
512 192 moveto
|
||||
528 192 528 240 16 arcto 4 {pop} repeat
|
||||
528 224 lineto
|
||||
528 240 448 240 16 arcto 4 {pop} repeat
|
||||
464 240 lineto
|
||||
448 240 448 192 16 arcto 4 {pop} repeat
|
||||
448 208 lineto
|
||||
448 192 528 192 16 arcto 4 {pop} repeat
|
||||
closepath
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
152 224 moveto
|
||||
32 48 atan dup cos 12.000 mul 200 exch sub
|
||||
exch sin 12.000 mul 256 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
3 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
200 256 12.000 5.000 48 32 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
200 256 12.000 5.000 48 32 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
304 264 moveto
|
||||
0 24 atan dup cos 12.000 mul 328 exch sub
|
||||
exch sin 12.000 mul 264 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
3 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
328 264 12.000 5.000 24 0 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
328 264 12.000 5.000 24 0 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
432 272 moveto
|
||||
-24 32 atan dup cos 12.000 mul 464 exch sub
|
||||
exch sin 12.000 mul 248 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
3 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
464 248 12.000 5.000 32 -24 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
464 248 12.000 5.000 32 -24 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
504 192 moveto
|
||||
-40 -48 atan dup cos 12.000 mul 456 exch sub
|
||||
exch sin 12.000 mul 152 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
3 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
456 152 12.000 5.000 -48 -40 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
456 152 12.000 5.000 -48 -40 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
368 144 moveto
|
||||
32 -152 atan dup cos 12.000 mul 216 exch sub
|
||||
exch sin 12.000 mul 176 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
3 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
216 176 12.000 5.000 -152 32 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
216 176 12.000 5.000 -152 32 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
[4 12] 0 setdash
|
||||
newpath
|
||||
368 136 moveto
|
||||
-32 -64 atan dup cos 10.000 mul 304 exch sub
|
||||
exch sin 10.000 mul 104 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
[] 0 setdash
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
304 104 10.000 4.000 -64 -32 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
304 104 10.000 4.000 -64 -32 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
[4 12] 0 setdash
|
||||
newpath
|
||||
176 104 moveto
|
||||
64 -32 atan dup cos 10.000 mul 144 exch sub
|
||||
exch sin 10.000 mul 168 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
2 setlinewidth
|
||||
stroke
|
||||
[] 0 setdash
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
144 168 10.000 4.000 -32 64 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
144 168 10.000 4.000 -32 64 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier-Bold findfont [20 0 0 -20 0 0] makefont setfont
|
||||
gsave
|
||||
128 407 moveto (SICS Interpreter and Macro Language) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier-Bold findfont [25 0 0 -25 0 0] makefont setfont
|
||||
gsave
|
||||
136 508 moveto (SICS Object Database) show
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
104 472 moveto 536 472 lineto 536 536 lineto 104 536 lineto
|
||||
closepath
|
||||
2 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier-Bold findfont [25 0 0 -25 0 0] makefont setfont
|
||||
gsave
|
||||
128 700 moveto (Hardware ) show
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
112 664 moveto 576 664 lineto 576 768 lineto 112 768 lineto
|
||||
closepath
|
||||
2 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
280 432 moveto
|
||||
40 0 atan dup cos 14.000 mul 280 exch sub
|
||||
exch sin 14.000 mul 472 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
280 472 14.000 6.000 0 40 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
280 472 14.000 6.000 0 40 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
176 536 moveto
|
||||
120 0 atan dup cos 14.000 mul 176 exch sub
|
||||
exch sin 14.000 mul 656 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
176 656 14.000 6.000 0 120 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
176 656 14.000 6.000 0 120 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
320 536 moveto
|
||||
120 -104 atan dup cos 14.000 mul 216 exch sub
|
||||
exch sin 14.000 mul 656 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
216 656 14.000 6.000 -104 120 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
216 656 14.000 6.000 -104 120 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
408 536 moveto
|
||||
120 80 atan dup cos 14.000 mul 488 exch sub
|
||||
exch sin 14.000 mul 656 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
488 656 14.000 6.000 80 120 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
488 656 14.000 6.000 80 120 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
[12 4] 0 setdash
|
||||
newpath
|
||||
248 288 moveto
|
||||
80 0 atan dup cos 8.000 mul 248 exch sub
|
||||
exch sin 8.000 mul 368 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
[] 0 setdash
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
248 368 8.000 3.000 0 80 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
248 368 8.000 3.000 0 80 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
[12 4] 0 setdash
|
||||
newpath
|
||||
376 288 moveto
|
||||
80 -120 atan dup cos 8.000 mul 256 exch sub
|
||||
exch sin 8.000 mul 368 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
[] 0 setdash
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
256 368 8.000 3.000 -120 80 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
256 368 8.000 3.000 -120 80 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
[12 4] 0 setdash
|
||||
newpath
|
||||
504 240 moveto
|
||||
496 312 lineto
|
||||
56 -224 atan dup cos 8.000 mul 272 exch sub
|
||||
exch sin 8.000 mul 368 exch sub lineto
|
||||
tgiforigctm setmatrix
|
||||
1 setlinewidth
|
||||
stroke
|
||||
[] 0 setdash
|
||||
grestore
|
||||
gsave
|
||||
tgiforigctm setmatrix
|
||||
newpath
|
||||
272 368 8.000 3.000 -224 56 tgifarrowtip
|
||||
1 setgray closepath fill
|
||||
0 setgray
|
||||
newpath
|
||||
272 368 8.000 3.000 -224 56 tgifarrowtip
|
||||
closepath fill
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
504 310 moveto (send commands) show
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
488 166 moveto (pass execution) show
|
||||
grestore
|
||||
|
||||
% BOX
|
||||
0 setgray
|
||||
gsave
|
||||
10 setmiterlimit
|
||||
gsave
|
||||
newpath
|
||||
96 368 moveto 624 368 lineto 624 432 lineto 96 432 lineto
|
||||
closepath
|
||||
2 setlinewidth
|
||||
stroke
|
||||
grestore
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
8 16 moveto
|
||||
56 120 lineto
|
||||
64 72 lineto
|
||||
104 168 lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
104 168 moveto
|
||||
80 152 lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% POLY/OPEN-SPLINE
|
||||
0 setgray
|
||||
gsave
|
||||
newpath
|
||||
104 168 moveto
|
||||
112 144 lineto
|
||||
tgiforigctm setmatrix
|
||||
4 setlinewidth
|
||||
stroke
|
||||
1 setlinewidth
|
||||
grestore
|
||||
|
||||
% TEXT
|
||||
0 setgray
|
||||
/Courier findfont [17 0 0 -17 0 0] makefont setfont
|
||||
gsave
|
||||
40 62 moveto (TCP/IP) show
|
||||
grestore
|
||||
|
||||
grestore
|
||||
tgifsavedpage restore
|
||||
end
|
||||
%MatchingCreationDate: Thu Nov 20 13:43:31 1997
|
BIN
doc/programmer/newsics.gif
Normal file
BIN
doc/programmer/newsics.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
160
doc/programmer/nread.tex
Normal file
160
doc/programmer/nread.tex
Normal file
@ -0,0 +1,160 @@
|
||||
\subsection{The Network Reader}
|
||||
The network readers task is to read incoming messages for the SICS server.
|
||||
These may come in four main forms.
|
||||
\begin{itemize}
|
||||
\item connection requests
|
||||
\item commands
|
||||
\item interrupts
|
||||
through a command channel
|
||||
\item interrupt messages on the UDP port.
|
||||
\end{itemize}
|
||||
A prior
|
||||
version of SICS had a select system call for each of these cases. It was
|
||||
found, that the code spent most of its time in the select system call
|
||||
thus intrdoducing a major performance problem.
|
||||
|
||||
The select system call can handle more then one file descriptor in one call.
|
||||
This is exactly what this module handles. It does a global select on
|
||||
all open sockets and forwards any pending data to approriate handlers.
|
||||
This scheme brought a drastic
|
||||
performance improvement.
|
||||
|
||||
Each of the messages to SICS is handled
|
||||
differently:
|
||||
|
||||
A connection request will be validated, a new connection object will be
|
||||
created and a new task for this connection object will be started.
|
||||
|
||||
A command will be placed in the apropriate command stack for the task
|
||||
belonging to this connection to work on in a later stage. The netreader will
|
||||
also take care that all commands are complete, this is the terminator
|
||||
\verb+\n+ or \verb+\r+ has been sent.
|
||||
|
||||
Both forms of interrupt will be interpreted and a suitable signal
|
||||
will be sent to all runing tasks if the interrupt request is valid.
|
||||
|
||||
In order to perform his tasks the network reader needs to maintain a list of
|
||||
all open sockets and their types. Additionally it needs to know about the
|
||||
SICS tasker.
|
||||
|
||||
The early version of SICS only supported connections on a plain
|
||||
socket. This feauture is not used any more in favour of the Telnet
|
||||
option described below. However, as this may be used to transport
|
||||
binary data, the obsolete code has not been removed.
|
||||
|
||||
Support for the internet TCP/IP standard telnet protocoll has been added in
|
||||
January 1998. Telnet things need to be handled differently, therefore two
|
||||
more socket types have been defined: A telnet listen socket on which
|
||||
requests for telnet connections are listened for, and a telnet command
|
||||
socket which actually process the telnet messages.
|
||||
|
||||
Support for user sockets was added in February 1998. User sockets provides a
|
||||
primitive interface to the network readers monitoring functions. This is
|
||||
part of a solution to one problem which can occur in SICS: The whole server
|
||||
is blocked if one of the serial devices is slow in responding. User sockets
|
||||
now provide a method for client code to register a socket for monitoring
|
||||
with the network reader and find out if data is pending at it. This support
|
||||
is provided by the functions: NetReadRegisterUserSocket,
|
||||
NetReadRemoveUserSocket, NetReadReadable and NetReadResetUser described
|
||||
below. NetReadWait4Data is a special wait function which waits for data to
|
||||
come in on a user socket. This function is problematic with dynamically
|
||||
creates and deleted objects such as environment device objects. Its use is
|
||||
therefore no longer recommended.
|
||||
|
||||
Thus the interface looks like this:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$nrint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef struct __netreader *pNetRead;@\\
|
||||
\mbox{}\verb@ typedef enum {naccept, command, udp, user, taccept, tcommand} eNRType;@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ pNetRead CreateNetReader(pServer pServ, int iPasswdTimeout,@\\
|
||||
\mbox{}\verb@ int iReadTimeout);@\\
|
||||
\mbox{}\verb@ void DeleteNetReader(void *pData);@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int NetReadRegister(pNetRead self, mkChannel *pSock, eNRType eType,@\\
|
||||
\mbox{}\verb@ SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int NetReadRegisterUserSocket(pNetRead self, int iSocket);@\\
|
||||
\mbox{}\verb@ int NetReadRemove(pNetRead self, mkChannel *pSock);@\\
|
||||
\mbox{}\verb@ int NetReadRemoveUserSocket(pNetRead self, int iSocket);@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int NetReaderTask(void *pReader); @\\
|
||||
\mbox{}\verb@ void NetReaderSignal(void *pUser, int iSignal, void *pSigData);@\\
|
||||
\mbox{}\verb@ int NetReadWait4Data(pNetRead self, int iSocket);@\\
|
||||
\mbox{}\verb@ int NetReadReadable(pNetRead self, int iSocket);@\\
|
||||
\mbox{}\verb@ int NetReadResetUser(pNetRead self, int iSocket);@\\
|
||||
\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}
|
||||
This starts off with the definition of a data type for the net reader and an
|
||||
enum which denotes the possible types of connections.
|
||||
\begin{description}
|
||||
\item[CreateNetReader] sets a new net reader up. Only parameter is a pointer
|
||||
to the task manager to use while creating new connections. iPasswdTimeout
|
||||
is the period in which a client is expected to send his userid/password
|
||||
pair. iReadTimeout is the time to wait on the select statement for a
|
||||
channel to become readable. Both time values are specified in milliseconds.
|
||||
\item[DeleteNetReader] deletes the net reader and all its data structures.
|
||||
Must be called in order to free all memory.
|
||||
\item[NetReadRegister] register the channel pSock of type eType with the net
|
||||
reader self. The parameter pData will only be interpreted for connections
|
||||
of type command. It must point to the command stack belonging to the
|
||||
connection which registers this socket.
|
||||
\item[NetReadRegisterUserSocket] registers a socket from within SICS foth
|
||||
the network reader. The client code to this module may then find out with a
|
||||
call to NetReadReadable if data is pending on this socket. This a
|
||||
convenience wrapper to NetReadRegister.
|
||||
\item[NetReadRemove] removes the socket pSock from the net reader. This must
|
||||
be done when closing the socket, otherwise the net reader will continue
|
||||
checking for pending data on this socket.
|
||||
\item[NetReadRemoveUserSocket] removes a user socket from
|
||||
monitoring. Again, this is a vonvenience wrapper around NetReadRemove.
|
||||
\item[NetReaderTask] is the net reader task function which will be
|
||||
registered with the task manager. This function builds the select
|
||||
mask, does the select and forwards incoming data to the appropriate
|
||||
handler functions. These are not documented here, as they are file
|
||||
static function in nread.c.
|
||||
\item[NetReaderSignal] is the signal handler for the net reader. It
|
||||
just stops the NetReaderTask when the SICS server is run down.
|
||||
\item[NetReadReadable] returns 1 if data is pending at the user socket or 0
|
||||
if not.
|
||||
\item[NetReadResetUser] resets a user socket to not readable.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"nread.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ N E T R E A D E R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This module will check for pending requests to the SICS server and@\\
|
||||
\mbox{}\verb@ initiate apropriate actions.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koenencke, September 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSNETREADER@\\
|
||||
\mbox{}\verb@#define SICSNETREADER@\\
|
||||
\mbox{}\verb@@$\langle$nrint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
123
doc/programmer/nserver.tex
Normal file
123
doc/programmer/nserver.tex
Normal file
@ -0,0 +1,123 @@
|
||||
\subsection{The SICS Server Object}
|
||||
This objects responsability is the proper initialisation and shutdown
|
||||
of the SICS server and the provision of some utility functions.
|
||||
The Server's data structure holds pointers to the most important parts of
|
||||
the system:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$servdat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __SicsServer {@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics;@\\
|
||||
\mbox{}\verb@ pTaskMan pTasker;@\\
|
||||
\mbox{}\verb@ pExeList pExecutor;@\\
|
||||
\mbox{}\verb@ pEnvMon pMonitor;@\\
|
||||
\mbox{}\verb@ mkChannel *pServerPort;@\\
|
||||
\mbox{}\verb@ pNetRead pReader;@\\
|
||||
\mbox{}\verb@ } SicsServer;@\\
|
||||
\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 are:
|
||||
\begin{description}
|
||||
\item[pSics] is a pointer to the SICS interpreter.
|
||||
\item[pTasker] is a pointer to the task scheduler.
|
||||
\item[pExecutor] is a pointer to the device executor. This module monitors
|
||||
variables during counting and driving operations.
|
||||
\item[pMonitor] is a pointer to an environment device controller monitor.
|
||||
This module monitors sample environment controllers.
|
||||
\item[pServerPort] points to a data structure describing the port at which
|
||||
the SICS server is listening for connections.
|
||||
\item[pReader] points to a data structure which defines the network
|
||||
communication object.
|
||||
\end{description}
|
||||
|
||||
|
||||
In terms of a function interface the server module supplies.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$servint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int InitServer(char *file, pServer *pServ);@\\
|
||||
\mbox{}\verb@ void RunServer(pServer self);@\\
|
||||
\mbox{}\verb@ void StopServer(pServer self);@\\
|
||||
\mbox{}\verb@/*----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ SicsInterp *GetInterpreter(void);@\\
|
||||
\mbox{}\verb@ pExeList GetExecutor(void);@\\
|
||||
\mbox{}\verb@ pTaskMan GetTasker(void);@\\
|
||||
\mbox{}\verb@ void ServerWriteGlobal(char *pMessage, int iCode);@\\
|
||||
\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}
|
||||
For most functions the name already says what it does. {\bf
|
||||
InitServer} initializes the SICS servers data structures. {\bf
|
||||
RunServer} implements the main loop and essentially calls the task
|
||||
modules ScheduleTask function for running all the SICS tasks which
|
||||
will handle the rest of the job. {\bf Stopserver} is responisble for
|
||||
closing the SICS server down in a sensible manner and in a well
|
||||
defined sequence of events.
|
||||
{\bf ServerWriteGlobal}
|
||||
is special. This function sends the message pMessage to all clients
|
||||
currently connected to the SICS server with the output code iCode. iCode has
|
||||
the same meaning as in the connection object.
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"nserver.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ N S E R V E R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ The SICS server main data structure and functions.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Restructured: September 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSNSERVER@\\
|
||||
\mbox{}\verb@#define SICSNSERVER@\\
|
||||
\mbox{}\verb@#include "conman.h"@\\
|
||||
\mbox{}\verb@#include "SCinter.h"@\\
|
||||
\mbox{}\verb@#include "emon.h"@\\
|
||||
\mbox{}\verb@#include "devexec.h"@\\
|
||||
\mbox{}\verb@#include "task.h"@\\
|
||||
\mbox{}\verb@#include "network.h"@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __SicsServer *pServer;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#include "nread.h"@\\
|
||||
\mbox{}\verb@@$\langle$servdat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\langle$servint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@ int UserWait(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int SicsWait(long lTime);@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
69
doc/programmer/nxamor.tex
Normal file
69
doc/programmer/nxamor.tex
Normal file
@ -0,0 +1,69 @@
|
||||
\subsection{AMOR NeXus Routines}
|
||||
This module implements a few functions for writing NeXus data files
|
||||
for the reflectoemter AMOR at SINQ, PSI. Nothing very exciting here:
|
||||
this is mostly boring repetetive code. Three functions are defined:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$namor {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int WriteAmorHeader(char *file, SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int WriteAmorScan(char *file, SConnection *pCon, pScanData pScan);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int WriteAmorTOF(char *file, SConnection *pCon, pHistMem pHM);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int AmorStore(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int AmorStoreMake(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\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}
|
||||
\begin{description}
|
||||
\item[WriteAmorHeader] writes all the AMOR header information and the
|
||||
zillions of motors.
|
||||
\item[WriteAmorScan] writes data when AMOR was operated in scanning
|
||||
mode.
|
||||
\item[WriteAmorTOF] writes AMOR data when used with the PSD in
|
||||
time-of-flight mode.
|
||||
\item[AmorStore] the command function implementing the storeamor
|
||||
command.
|
||||
\item[AmorStoreMake] the initialization function which creates the
|
||||
storeamor command.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"nxamor.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ N X A M O R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Some routines for writing NeXus files for the reflectometer AMOR at@\\
|
||||
\mbox{}\verb@ SINQ.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1999@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef NXAMOR@\\
|
||||
\mbox{}\verb@#define NXAMOR@\\
|
||||
\mbox{}\verb@@$\langle$namor {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
192
doc/programmer/nxdata.tex
Normal file
192
doc/programmer/nxdata.tex
Normal file
@ -0,0 +1,192 @@
|
||||
\subsection{NXdata}
|
||||
NXdata is a module for writing Powder Diffraction Data files. The
|
||||
routines here are somewhat obsolete as they refer to NeXus writing
|
||||
using the standard Napi routines which is quite involved. Usually,
|
||||
NeXus files are written from SICS through the NXDICT aware utility
|
||||
routines in NXUTIL.
|
||||
|
||||
If not stated
|
||||
otherwise, all routines return 1 on successful completion and 0 when an
|
||||
error is detected. Please note, that many of these routines expect to find
|
||||
certain data items in the Sics Interpreter. This implies, that any naming
|
||||
changes in the initialisation file might force changes in here as well.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ char *SNXMakeFileName(SicsInterp *pSics, SConnection *pCon);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
SNXMakeFileName creates a new filename from the SICS variables SicsDataPath,
|
||||
SicsDataPresript, SicsDataNumber and SicsDataEnding. SicsDataNumber will be
|
||||
incremented as well. The function returns a newly allocate buffer with the
|
||||
assembled filename or NULL on error. Note, that the caller is responsible
|
||||
for freeing the memory associated with the filename afterwards.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ NXhandle SNXStartFile(SConnection *pCon, SicsInterp *pSics); @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
First calls SNXMakeFileName in order to get a new Filename.
|
||||
Then a new Nexus file is
|
||||
created and all the standard headings are filled in: Filename, User,
|
||||
instrument, date etc. This routine also installs an error handler which
|
||||
prints errors to pCon.
|
||||
If successful, the SicsDataNumber is incremented and
|
||||
an NXhandle into the new file is returned. If there is a problem, NULL
|
||||
will be returned. The file returned will be positioned at root level.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int SNXStartEntry(NXhandle Nfil, int iNew, SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ void SNXFormatTime(char *pBuffer, int iBufLen);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
SNXFormatTime formats the current system time in a form compatible to the
|
||||
NeXus standard. Input parameters is a Buffer to hold the string and a
|
||||
length of the buffer. Maximum iBufLen characters will be copied to that
|
||||
buffer.
|
||||
|
||||
SNXStartEntry creates a new entry corresponding to iNew in the Nexus file
|
||||
Nfil. SNXStartEntry will position Nfil in this new entry. Any data items
|
||||
labeled as Comment or intent will be written to the file as well.
|
||||
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int SNFinishFile(NXhandle Nfil);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
SNFinishFile will end a Nexus file properly.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int SNMakeDMC(SConnection *pCon, SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
SNMakeDMC produces a Nexus DMC data file from the currently valid
|
||||
information. It orchestrates all of the above.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap7}
|
||||
$\langle$Protos {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@int SNStoreDMC(SConnection *pCon, SicsInterp *pSics, void *pData, int argc,@\\
|
||||
\mbox{}\verb@ char *argv[]);@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro defined by scraps ?, ?, ?, ?, ?, ?, ?.
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
SNStoreData is the wrapper function used to install a DMC data storage
|
||||
command in the Sics interpreter.
|
||||
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap8}
|
||||
\verb@"nxdata.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ N X D A T A@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Some routines for handling Nexus data file writing.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, April 1997@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ copyright: see implementation file.@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSNXDATA@\\
|
||||
\mbox{}\verb@#define SICSNXDATA@\\
|
||||
\mbox{}\verb@@$\langle$Protos {\footnotesize ?, \ldots\ }$\rangle$\verb@ @\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
3053
doc/programmer/nxdict.tex
Normal file
3053
doc/programmer/nxdict.tex
Normal file
File diff suppressed because it is too large
Load Diff
42
doc/programmer/nxsans.tex
Normal file
42
doc/programmer/nxsans.tex
Normal file
@ -0,0 +1,42 @@
|
||||
\subsection{NXUTIL}
|
||||
Ther are some utility functions for writing NeXus data files from
|
||||
SICS with the NXDICT-API. These are collected in the files nxutil.h
|
||||
and nxutil.c.
|
||||
|
||||
\begin{description}
|
||||
\item[int SNXSPutMotor(SicsInterp *pSics, SConnection *pCon, NXhandle hFil,
|
||||
NXdict pDict, char *pAlias, char *pName)] writes the
|
||||
value of a motor to file. The parameters are: \begin{description}
|
||||
\item[pSics] The SICS interpreter to search for the motor.
|
||||
\item[pCon] The connection object to which to print errors.
|
||||
\item[hFil] The handle of the NeXus file to write.
|
||||
\item[pDict] The handle of the NeXus dictionary to use.
|
||||
\item[pAlias] The alias name to use for writing.
|
||||
\item[pName] The name of the motor.
|
||||
\end{description}
|
||||
\item[SNXSPutMotorNULL] writes the motor zero point. Same parameters
|
||||
as above.
|
||||
\item[int SNXSPutVariable(SicsInterp *pSics, SConnection *pCon,\\
|
||||
NXHandle hFil, NXdict pDict, char *pAlias,\\
|
||||
char *pName)] writes a SICS variable to a NeXus file
|
||||
using the dictionary. Parameters similar to SNXSPutMotor.
|
||||
\item[SNXSPutEVVar(NXhandle hfil,NXdict pDict,char *pName, SConnection
|
||||
*pCon,\\ char *pValAlias, char *pStddevAlias)]
|
||||
This writes an environment variable pName to the file described by hfil,
|
||||
using the dictionary pDict. A warning is printed if the variable is
|
||||
not configured. If a variable is found its value and standard
|
||||
deviation are written to file using the aliases given as parameters.
|
||||
\item[SNXSPutGlobals] writes global data to the file.
|
||||
\item[SNXSFormatTime] returns the current time formatted according to
|
||||
the NeXus specification in buffer. Max iLen characters will be copied
|
||||
to buffer.
|
||||
\item[SNXSMakeFileName] returns a pointer to a buffer containing a new
|
||||
file name for a data file. This function assembles the filename from
|
||||
the DataNUmber and various SICS variables. The caller has to free the
|
||||
buffer containg the name.
|
||||
\item[SNXSPutDrivable] writes any variable adhering to the drivable
|
||||
interface.
|
||||
\end{description}
|
||||
|
||||
|
||||
|
42
doc/programmer/o2t.tex
Normal file
42
doc/programmer/o2t.tex
Normal file
@ -0,0 +1,42 @@
|
||||
\subsection{Omega 2Theta}
|
||||
This is an example for a simple virtual motor. It uses two motors and runs
|
||||
the second one to exactly the double value of the first one. It can be used
|
||||
to implement omega--two--theta (o2t) scans at reflectometers of four circle
|
||||
diffractometers using the normal scan command.
|
||||
|
||||
The o2t module uses the following data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct __SicsO2T {
|
||||
pObjectDescriptor pDes;
|
||||
pIDrivable pDrivInt;
|
||||
pMotor pOmega;
|
||||
pMotor pTheta;
|
||||
} SicsO2T;
|
||||
|
||||
\end{verbatim}
|
||||
The fields:
|
||||
\begin{description}
|
||||
\item[pDes] A pointer to the usual SICS object descriptor.
|
||||
\item[pDrivInt] A pointer to the drivable interface implemented by this
|
||||
variable.
|
||||
\item[pOmega] A pointer to the first motor to use.
|
||||
\item[pTheta] A pointer to the motor data structure of the second (double)
|
||||
motor to use.
|
||||
\end{description}
|
||||
|
||||
|
||||
Most of this modules action lives in the drivable interface. The rest is
|
||||
achieved through the following functions:
|
||||
\begin{description}
|
||||
\item[pSicsO2T MakeO2T(char *omega, char *theta, SicsInterp *pSics)] creates
|
||||
a new o2t object from motors omega and theta. Returns NULL on failure and a
|
||||
pointer to an o2t data structure on success.
|
||||
\item[void DeleteO2T(void *pData)] deletes an o2t object.
|
||||
\item[int CreateO2T(SConnection *pCon, SicsInterp *pSics, void *pData,\\
|
||||
int argc, char *argv[])] The object factory function for o2t
|
||||
objects.
|
||||
\end{description}
|
||||
|
||||
Please note, that o2t is just a helper variable and can not be manipualted
|
||||
from the SICS interpreter.
|
||||
|
44
doc/programmer/obpar.tex
Normal file
44
doc/programmer/obpar.tex
Normal file
@ -0,0 +1,44 @@
|
||||
\subsection{SICS Parameter Array}
|
||||
This thing holds an array of floating point numbers, their names and their access codes.
|
||||
It is used in SICS object implementations to hold larger amounts of
|
||||
configurable parameters. It provides functions for simplifying the
|
||||
management of such parameters.
|
||||
|
||||
Each parameter is described by a structure shown below:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
char *name;
|
||||
float fVal;
|
||||
int iCode;
|
||||
} ObPar;
|
||||
\end{verbatim}
|
||||
The fields are: \begin{description}
|
||||
\item[name] The name of the parameter.
|
||||
\item[fVal] The parameters value.
|
||||
\item[iCode] The access code necessary to modify the parameter.
|
||||
\end{description}
|
||||
|
||||
Parameter arrays are maintained by the functions described below:
|
||||
\begin{description}
|
||||
\item[ float ObVal(ObPar *self, int i)] gets the value of parameter i from
|
||||
the array self. This call is for module internal usage.
|
||||
\item[int ObParLength(ObPar *self)]
|
||||
finds the length of an ObPar array.
|
||||
\item[ObPar *ObParFind(ObPar *self, char *name)]
|
||||
finds a ObPar struct for a name, return NULL if none.
|
||||
\item[int ObParInit(ObPar *self,int i, char *name, float fVal, int iCode)]
|
||||
sets a ObPar entry. self is a pointer to the array.
|
||||
\item[int ObParSet(ObPar *self, char *obname,char *name, float fVal, SConnection
|
||||
*pCon)]
|
||||
checks if the connections permissions are alright and changes value
|
||||
if so. Returns 1 on success, 0 on failure. Prints errors directly to
|
||||
pCon. The parameter obname is the name of the object the parameters belong
|
||||
to. Needed for error printing. name is the parameter name, fVal the new
|
||||
value.
|
||||
\item[void ObParDelete(ObPar *self)]
|
||||
Deletes an ObPar array.
|
||||
\item[ObPar *ObParCreate(int iArrayLong)]
|
||||
creates an array with iASrrayLong entries. Returns NULL on failure, else
|
||||
a pointer to the array.
|
||||
\end{description}
|
||||
|
24
doc/programmer/ofac.tex
Normal file
24
doc/programmer/ofac.tex
Normal file
@ -0,0 +1,24 @@
|
||||
\subsection{The Object Factory}
|
||||
SICS is a highly configurable system. This module implements
|
||||
the configurable. Configuration is meant to happen via a Tcl-
|
||||
configuration script. This module will initialize commands which
|
||||
create SICS-objects. Than an initialization file is evaluated
|
||||
via the macro facility. As most of the initialization commands
|
||||
will no longer be needed after this, they will be deleted.
|
||||
All this will be run with a higly privileged connection which
|
||||
prints to stdout/stdin. This module contains the file static functions:
|
||||
InitIniCommands and KillIniCommands. {\bf InitIniCommands}
|
||||
intializes all SICS common commands plus the object creation
|
||||
commands. Once a new class has been devised its object
|
||||
creation function needs to be entered into this
|
||||
function. {\bf KillIniCommands} removes all the initialization
|
||||
commands no longer needed after the initialization file has
|
||||
been evaluated. Make sure to add an entry for your new
|
||||
classes creation command here as well.
|
||||
|
||||
The interface consists of a single function: \begin{verbatim}
|
||||
int InitObjectCommands(pServer pServ, char *file);
|
||||
\end{verbatim}
|
||||
Commands will be initialized for the server pServ from the file file.
|
||||
|
||||
|
804
doc/programmer/oguide.tex
Normal file
804
doc/programmer/oguide.tex
Normal file
@ -0,0 +1,804 @@
|
||||
\chapter{Guide To SICS Object Writers}
|
||||
This chapter describes the necessary steps for adding new objects to the SICS server. In order to live
|
||||
happily within SICS an object is obliged to stick to a set of rules and interfaces already defined. Such
|
||||
interfaces will be described here as well. For the following text it is assumed, that the reader has studied
|
||||
the SICS overview and kernel guide.
|
||||
|
||||
In general the following steps will be necessary in order to introduce a new object into SICS:
|
||||
\begin{enumerate}
|
||||
\item Define a new object data structure.
|
||||
\item Define a function capable of deleting the object from memory.
|
||||
\item Define a set of functions which define the operations on this object.
|
||||
\item Create an object wrapper function which defines the user commands
|
||||
the object can handle.
|
||||
\item Create an object creation function, which is capable of initializing
|
||||
the object and creates a new command in the SICS interpreter.
|
||||
\item Add the new objects creation command into the IniInitCommand and
|
||||
KillIniCommands functions defined in ofac.c.
|
||||
\item Document the new object.
|
||||
\end{enumerate}
|
||||
All these steps will now be discussed together with some additional SICS
|
||||
concepts applicable to writing new objects. Not all of the above mentioned
|
||||
steps will be necessary in all cases. If a new general SICS object is defined,
|
||||
no object creation function may be needed. Then it is sufficient to register
|
||||
the new object/command with the SICS interpreter in IniInitCommands, file ofac.c.
|
||||
In the rare cases where an object needs no data structure, the system will provide a dumb
|
||||
default which will not harm the system. Some objects may have more then one
|
||||
command associated with them. Some more care has to be taken when adding a
|
||||
new piece of hardware into the system. If it is just a variant of an already
|
||||
known type (for instance a new type of motor) it will be sufficient to introduce
|
||||
a new driver into the system. The procedures for doing this will be described
|
||||
in the reference sections for the appropriate device. Otherwise the SICS rule
|
||||
to divide a hardware object into a logical object and a driver should be
|
||||
observed. At minimum two drivers are necessary anyway in the first place:
|
||||
the driver for the actual device and a simulation driver which permits some
|
||||
debugging to take place while the hardware is still unavailable.
|
||||
|
||||
\section{Mapping Object Oriented Concepts into ANSI--C}
|
||||
SICS is in principle an object oriented system. However, it is implemented
|
||||
in ANSI--C. Therefore object oriented concepts must be mapped into C. The
|
||||
three object oriented concepts which need to be mapped are:
|
||||
\begin{itemize}
|
||||
\item Data Encapsulation.
|
||||
\item Polymorphism.
|
||||
\item Inheritance.
|
||||
\end{itemize}
|
||||
|
||||
Of these, data encapsulation is by far the most important concept. Objects
|
||||
in computer science can be understood as little boxes which contain some
|
||||
data describing their state and which understand messages sent by other
|
||||
objects. If such a message comes in, the object performs some action,
|
||||
perhaps changes its internal state or sends new messages to other objects.
|
||||
It is understood that changes to the internal data of the object can be
|
||||
achieved only through messages to the object and not by directly manipulating
|
||||
variables from the outside. In ANSI--C an object maps to a structure holding
|
||||
the objects data and the messages map to functions which act upon the data
|
||||
structure. In order to do this, the functions must take a pointer to the
|
||||
objects data structure as first parameter. In order to prevent messing with
|
||||
an objects data structure, only a pointer to a structure is declared in the
|
||||
header file. The actual definition of the data structure happens only in
|
||||
the implementation file. All functions belonging to an object are defined in that
|
||||
implementation file and have full access to the data structure.
|
||||
Users of the object see only the header file and thus only a pointer to the
|
||||
objects data structure which prevents
|
||||
them from messing with the objects data directly.
|
||||
In order to illustrate the concepts lets look at
|
||||
a primitive integer object defined in such a way.
|
||||
\begin{verbatim}
|
||||
/*-----------------------------------------------------------------------
|
||||
ExampleInt.h
|
||||
------------------------------------------------------------------------*/
|
||||
typedef struct __ExampleInt *pExampleInt;
|
||||
|
||||
int GetInt(pExampleInt self);
|
||||
void SetInt(pExampleInt self, int iNew);
|
||||
/*------------------- EOF ExampleInt.h---------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
ExampleInt.c, Implementation file
|
||||
-----------------------------------------------------------------------*/
|
||||
typedef struct __ExampleInt {
|
||||
int iExample;
|
||||
} ExampleInt;
|
||||
/*--------------------------------------------------------------------*/
|
||||
int GetInt(pExampleInt self)
|
||||
{
|
||||
return self->iExample;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
void SetInt(pExampleInt self, int iNew)
|
||||
{
|
||||
self->iExample = iNew;
|
||||
}
|
||||
\end{verbatim}
|
||||
Using this scheme all code changing the internal state of an object lives
|
||||
in one file. Changes to the objects data structure affect only the
|
||||
implementation file and no other files.
|
||||
This scheme is used for almost all SICS objects. A few system objects and
|
||||
older SICS objects define their data structures in header files. This is
|
||||
either a relic or had to be done for performance reasons.
|
||||
|
||||
The next concept is polymorphism. This describes the situation when a group
|
||||
of objects respond to the same message but doing different things. For
|
||||
instance a whole set of objects would implement a write functionality
|
||||
which writes the objects state to a file. Higher level would then not need
|
||||
to know of which type the actual object is, it just can send the write message
|
||||
and the rest is taken care of by the object. This concept is used for all
|
||||
hardware drivers in SICS. Mapping this to C requires to expose the objects
|
||||
data structure and let the data structure include a pointer to that polymorphic
|
||||
function. As an example, the ExampleInteger with a write function:
|
||||
\begin{verbatim}
|
||||
/*-----------------------------------------------------------------------
|
||||
ExampleInt.h
|
||||
------------------------------------------------------------------------*/
|
||||
typedef struct __ExampleInt{
|
||||
int iExample;
|
||||
void (*write)(struct __ExampleInt *self, FILE *fd);
|
||||
} *pExampleInt, ExampleInt;
|
||||
|
||||
pExampleInt MakeInt(int iNew);
|
||||
|
||||
int GetInt(pExampleInt self);
|
||||
void SetInt(pExampleInt self, int iNew);
|
||||
/*------------------- EOF ExampleInt.h---------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
ExampleInt.c, Implementation file
|
||||
-----------------------------------------------------------------------*/
|
||||
static void ExampleWrite(struct _-ExampleInt *self, FILE *fd)
|
||||
{
|
||||
fprintf(fd,"INT = %d",self->iExample);
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
pExampleInt MakeInt(int iNew)
|
||||
{
|
||||
pExampleInt pNew = NULL;
|
||||
|
||||
pNew = (pExampleInt)malloc(sizeof(ExampleInt));
|
||||
pNew->iExample = iNew;
|
||||
pNew->write = ExampleWrite;
|
||||
return pNew;
|
||||
}
|
||||
.
|
||||
.
|
||||
.
|
||||
\end{verbatim}
|
||||
This can then be called:
|
||||
\begin{verbatim}
|
||||
void SomeFunc()
|
||||
{
|
||||
pExampleInt pTest;
|
||||
|
||||
pTest = MakeInt(25);
|
||||
.
|
||||
.
|
||||
.
|
||||
pTest->write(pTest,fd);
|
||||
}
|
||||
\end{verbatim}
|
||||
This example also illustrates the concept of a special function which creates
|
||||
a new object of the appropriate type and initializes its data structure
|
||||
properly.
|
||||
|
||||
The last concept to discuss is inheritance. Inheritance can be used when
|
||||
an object is a derivative of another object. For instance a truck is a
|
||||
derivative of a motor car. Much of the behavior of a motor car will be the
|
||||
same as for a truck. In order to prevent rewriting of code, the truck
|
||||
should use the same data structures and code as the motor car. And add
|
||||
or modify only what is special. Inheritance is not much used in SICS. It can
|
||||
be implemented by overlaying data structures. This means the derived
|
||||
classes data structure has the same fields in the same order as the parent
|
||||
class and adds its specials at the end. For example:
|
||||
\begin{verbatim}
|
||||
typedef struct __MotorCar {
|
||||
int iWheels;
|
||||
float fSpeed;
|
||||
} *pMotorCar, MotorCar;
|
||||
|
||||
|
||||
typedef struct __Truck {
|
||||
int iWheels;
|
||||
float fSpeed; /* same as MotorCar */
|
||||
double dPayLoad; /* special for Truck */
|
||||
} *pTruck, Truck;
|
||||
|
||||
\end{verbatim}
|
||||
Thus functions defined for motor car can operate on trucks as well.
|
||||
For more details study the relationship between the ITC4 controller and
|
||||
general environment controllers. This is the only place where SICS
|
||||
currently uses inheritance.
|
||||
|
||||
|
||||
\section{The Object Data Structure}
|
||||
Nearly all SICS objects require some data. This data is collected in a
|
||||
C structure typical for the object. This is just a normal C struct with one
|
||||
exception:
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 1}}
|
||||
The first item in a SICS object data structure MUST be a pointer to a
|
||||
ObjectDescriptor data structure. This looks like:
|
||||
\begin{verbatim}
|
||||
typedef struct __MyObject {
|
||||
pObjectDescriptor pDes;
|
||||
int iMyExtremlyImportantInt;
|
||||
.
|
||||
.
|
||||
.
|
||||
} MyObject;
|
||||
\end{verbatim}
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
|
||||
Otherwise the SICS server will crash on you sooner or later. The reason for
|
||||
this is that SICS needs a means to identify a object and its capabilities
|
||||
from inside its code. For example a user has typed: {\em drive mot1 26} into
|
||||
the server. Now drive needs to verify that mot1 is really a motor or
|
||||
something else which can be driven. This can be done in the following way:
|
||||
\begin{enumerate}
|
||||
\item First find the object in the SICS interpreter
|
||||
(function FindCommand, SCinter.h).
|
||||
\item Get the pointer to the objects data structure.
|
||||
\item Assign this pointer to a dummy data structure (defined in obdes.h)
|
||||
which has a pointer to the ObjectDescriptor as single element.
|
||||
\item Ask the ObjectDescriptor if the object can be driven.
|
||||
\end{enumerate}
|
||||
In object speak this is called run time type information (RTTI).
|
||||
|
||||
It is interesting to look at the object descriptor in more detail. It is
|
||||
again a data structure and a good example for polymorphism:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
char *name;
|
||||
int (*SaveStatus)(void *self, char *name,FILE *fd);
|
||||
void *(*GetInterface)(void *self, int iInterfaceID);
|
||||
} ObjectDescriptor, *pObjectDescriptor;
|
||||
|
||||
\end{verbatim}
|
||||
The first field contains a string defining a type name. The next field is a
|
||||
pointer to a save function. This function is automatically called for all objects
|
||||
in the SICS interpreter when the server shuts down. This function is supposed to
|
||||
write all SICS commands necessary to reconfigure the object back into its current state
|
||||
into file fd. The middle parameter is the name of the object in the interpreter
|
||||
which must not necessarily be known to the object.
|
||||
|
||||
The next field, a pointer to a function GetInterface is used in order to inquire
|
||||
the capabilities of an object. Object capabilities in SICS are defined in terms of
|
||||
{\bf {\Large Interfaces}}. An Interface in the SICS sense is again a data structure
|
||||
which contains data fields and pointers to functions implementing the capability. As
|
||||
an example see the Drivable interface which is implemented by motors, environment
|
||||
devices and variables such as lambda which can be driven to a new value:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
int ID;
|
||||
int (*Halt)(void *self);
|
||||
int (*CheckLimits)(void *self, float fVal,
|
||||
char *error, int iErrLen);
|
||||
long (*SetValue)(void *self, SConnection *pCon,
|
||||
float fVal);
|
||||
int (*CheckStatus)(void *self, SConnection *pCon);
|
||||
float (*GetValue)(void *self, SConnection *pCon);
|
||||
} IDrivable, *pIDrivable;
|
||||
|
||||
\end{verbatim}
|
||||
Each SICS interface is identified by an integer ID number (defined in interface.h).
|
||||
GetInterface returns a pointer to an interface data structure for an ID if the object
|
||||
implements that interface. If not a NULL is returned.
|
||||
|
||||
\section{SICS Interfaces}\label{gow}
|
||||
Thus SICS interfaces define the capabilities of an object. The concept of
|
||||
Interfaces is similar to interfaces in the Java programming language
|
||||
or abstract base classes in C++ or other object oriented languages.
|
||||
As can be seen from the example
|
||||
given above, the interface implements the most common operations on an object with
|
||||
capabilities as defined by the interface. Currently, SICS knows four different kinds of
|
||||
Interfaces:
|
||||
\begin{description}
|
||||
\item[Drivable] The Drivable interface for objects such as motors, adjustable parameters
|
||||
and the like. Anything which can be driven to a value.
|
||||
\item[Countable] The Countable interface used for everything which can count: single
|
||||
counters, histogram memories or whatever may creep up.
|
||||
\item[CallBack] The CallBack interface introduces some component programming techniques
|
||||
into SICS. This technique lets an object, name it object A, issue events when its internal
|
||||
state changes. For example if object A is a motor, any time it drives to a new value
|
||||
an event is issued. Then another object, name it object B, can register an interest in
|
||||
such events with object A. It does so by giving A the address of a function to call
|
||||
when such an event occurs. A now calls all functions thus registered when the event
|
||||
occurs. Object B thus gets automatically notified when A changes its state. Currently
|
||||
this scheme is only used for implementing automatic notifications of clients when a
|
||||
SICS object changes its state. But there is a lot of potential in this scheme.
|
||||
\item[Environment] The Environment device is a interface implemented by all devices which
|
||||
need to be regularly monitored by the environment monitor.
|
||||
\end{description}
|
||||
For more details about the SICS interfaces see the reference section: \ref{interref}.
|
||||
The list of SICS interfaces can be extended when a novel abstract capability of an object
|
||||
is needed. This is also the main reason why this sophisticated scheme was chosen.
|
||||
|
||||
The question may arise how to use SICS interfaces. For example consider an object defining
|
||||
a drivable variable. The following steps are necessary:
|
||||
\begin{enumerate}
|
||||
\item Define functions with matching parameters to the ones requested by the interface.
|
||||
Tip: the first parameter, the pointer to void, is always the pointer to the object data
|
||||
structure to operate on. These functions must implement appropriate actions. What these
|
||||
are: see the documentation of the interface.
|
||||
\item Define a GetInterface function which returns a suitable interface
|
||||
data structure when asked for an interface with the Drivable ID. The fields of the interface
|
||||
structure returned must be set to the addresses of the functions you defined in step 1.
|
||||
\item Create an object initialization function.
|
||||
\item In this object initialization function: assign the object descriptors filed GetInterface
|
||||
to the address of your GetInterface function.
|
||||
\end{enumerate}
|
||||
Usually, the interfaces an object implements are made a field in the objects data
|
||||
structure. This interface is then initialized with appropriate function pointers when
|
||||
creating the object. GetInterface then returns this pointer when the interface is
|
||||
requested. Due to this usage a rule exits:
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 2}}
|
||||
Any interface data structure provided by an object belongs to the object providing
|
||||
it. The owner object is responsible for deleting it. Never free an interface data structure
|
||||
provided by another object.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
|
||||
Note, that the SICS interfaces are not the only interfaces to take care of. As SICS uses
|
||||
this duality between logical hardware objects and hardware drivers, the interfaces defined
|
||||
by the logical hardware devices can been seen as yet another internal interface. This leads to:
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Recommendation}}
|
||||
Watch your neighbors! Use the interfaces provided by the logical hardware objects for
|
||||
your objects business, when applicable.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
|
||||
\section{The Object Deletion Function}
|
||||
When the SICS server exits or when a command is removed from the SICS
|
||||
interpreter the interpreter will call a function which should free the memory
|
||||
associated with the deleted object. This is absolutely necessary in order to
|
||||
prevent memory leakage. Such a function has the form:
|
||||
\begin{verbatim}
|
||||
void ObjectKiller(void *pData);
|
||||
\end{verbatim}
|
||||
with pData being the pointer to the object to delete.
|
||||
|
||||
|
||||
\section{Writing Object Functions}
|
||||
The rules specified in this section apply to all kinds of object functions:
|
||||
those which implement functionality as well as the object wrapper
|
||||
functions. Please note, that any SICS object has two interfaces: an internal
|
||||
C--language interface and a user visible interface defined by the object
|
||||
wrapper functions. There are reasons why those two interfaces might not
|
||||
provide equivalent functionality.
|
||||
|
||||
\subsection{Input and OutPut}
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 3}}
|
||||
All input and output to the client executing the command must go through the
|
||||
connection object functions SCWrite and SCPrompt.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
These function will now be inspected in more detail:
|
||||
\begin{verbatim}
|
||||
int SCWrite(SConnection *pCon, char *pText, int eCode);
|
||||
int SCPrompt(SConnection *pCon, char *pPrompt, char *pBuffer, int iBufLen);
|
||||
\end{verbatim}
|
||||
SCWrite writes the data pText to the connection specified by pCon. The
|
||||
parameter eCode denotes the output code of the data in pText. SICS clients
|
||||
can choose to suppress some I/O from the SICS server. For instance a
|
||||
GUI--client might chooses not to receive scan status reports. For this
|
||||
purpose it was necessary to stick an output code onto each message to the
|
||||
client. Possible output codes are: eError, eWarning, eValue, eStatus and
|
||||
some internal codes. The names are self explaining. eValue denotes a value
|
||||
which has been explicitly asked for by the client. The rule specified above
|
||||
becomes understandable and thus bearable when looking at all the things
|
||||
SCWrite does with the message:
|
||||
\begin{itemize}
|
||||
\item It is written to the client connection socket, subject to the output
|
||||
code specified.
|
||||
\item The message is written to all log files configured for the client
|
||||
connection.
|
||||
\item The message is written to the server log together with the socket
|
||||
number of the connection.
|
||||
\item SCWrite stores the message into the Tcl macro interpreter in order to
|
||||
enable processing of data from SICS commands in Tcl scripts.
|
||||
\item SCWrite suppresses all messages to the client while executing a macro.
|
||||
This stops spurious output to appear at the client connection when running a
|
||||
command defined in the macro language. The exception are messages of type
|
||||
eError and eWarning. Such messages are always sent to the client.
|
||||
\end{itemize}
|
||||
|
||||
SCPrompt prompts the user at the client connection for data. The prompt
|
||||
string pPrompt is sent. Data entered by the user is returned in buffer
|
||||
pBuffer. Maximum iBufLen character are returned. While waiting for client to
|
||||
provide data, the SICS task switcher runs.
|
||||
|
||||
There is another convenience function SCSendOK(SConnection *pCon) which is
|
||||
just a wrapper around SCWrite. SCSendOk sends an 'OK' to the client. It is good
|
||||
practice to let the user know that the operation requested had been
|
||||
performed.
|
||||
|
||||
Given the rule stated above, it follows that connection objects have to
|
||||
be passed through the system to nearly everywhere. Especially where
|
||||
reportable errors are found.
|
||||
|
||||
All other I/O, for instance to files sitting at the computer running the
|
||||
SICS server, is not subjected to Rule 3.
|
||||
|
||||
|
||||
\subsection{Error Handling}
|
||||
Error handling is two thirds of the code written. Errors can be caused by
|
||||
faulty users or faulty hardware. In any case, the first thing to do is:
|
||||
report it using SCWrite! The next thing is to get the system into a state
|
||||
that it can continue execution. This is particularly important for a server
|
||||
program which might run for months on end. This means, free all memory used
|
||||
before the error occurred, get system variables into safe values and the
|
||||
like.
|
||||
|
||||
Sometimes error conditions arise in lower level code which should cause all
|
||||
upper level code to finish execution. Such conditions may be the result of a
|
||||
critical hardware fault or may even be requested by a user who wants to
|
||||
abort an operation. A standard method for communicating such conditions
|
||||
through the system is necessary. SICS uses interrupts for such conditions.
|
||||
The current interrupt active interrupt is located at the connection object
|
||||
and can be retrieved with {\bf SCGetInterrupt} and set with {\bf
|
||||
SCSetInterrupt}. Interrupt codes are defined in interrupt.h and are ordered
|
||||
into a hierarchy:
|
||||
\begin{description}
|
||||
\item[eContinue] Everything is just fine.
|
||||
\item[eAbortOperation] Stop the current scan point or whatever is done,
|
||||
but do not stop altogether.
|
||||
\item[eAbortScan] Abort the current scan, but continue processing of further
|
||||
commands in R\"unbuffers or command files.
|
||||
\item[eAbortBatch] Aborts everything, operations, scans and batch processing
|
||||
and leaves the system ready to enter new commands.
|
||||
\item[eHaltSystem] As eAbortBatch, but lock the system.
|
||||
\item[eFreeSystem] Unlocks a system halted with eHaltSystem.
|
||||
\item[eEndServer] Makes the SICS server run down and exit.
|
||||
For internal usage only.
|
||||
\end{description}
|
||||
|
||||
In most cases interrupts shall only effect the client connection executing
|
||||
the command. In such cases user code should use SCSetInterrupt in order to
|
||||
set an interrupt at the connection executing the command only. Very rarely
|
||||
conditions occur when an interrupt should affect the whole system. Then
|
||||
SetInterrupt (defined in intserv.h) should be used. SetInterrupt forwards
|
||||
the interrupt to all running tasks.
|
||||
|
||||
Objects implementing higher level commands such as scan commands might be
|
||||
able to handle interrupt conditions and thus consume an interrupt. Then the
|
||||
interrupt must be released with SCSetInterrupt and setting the interrupt to
|
||||
eContinue. The interrupt on a connection will automatically be set to
|
||||
eContinue when executing a new command from the command stack.
|
||||
|
||||
Objects are responsible for checking for interrupt conditions when
|
||||
applicable. This is specially true for objects performing complex or
|
||||
lengthy
|
||||
operations with hardware. Whenever a hardware operation finishes, the
|
||||
interrupt must be checked for and handled. The called hardware object or
|
||||
the user might have set an interrupt which needs to be honored.
|
||||
|
||||
Thus two new rules can be defined:
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 4}}
|
||||
Signal critical error conditions with interrupts.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 5}}
|
||||
Check for pending interrupts wherever applicable.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
|
||||
\subsection{Authorisation}
|
||||
Objects are also responsible for checking if the client requesting an
|
||||
operation may actually perform the operation. There are two cases when an
|
||||
operation may be forbidden:
|
||||
\begin{itemize}
|
||||
\item The user is not suitably authorized.
|
||||
\item The user is about to change critical parameters affecting a running
|
||||
measurement.
|
||||
\end{itemize}
|
||||
Both conditions must be checked for by the objects code. Where else then at
|
||||
the object can be known which operations are critical or not? This gives a
|
||||
new rule:
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 6}}
|
||||
Objects have to check authorisation!
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
|
||||
The user rights code for a client connection can be retrieved with
|
||||
SCGetRights. SCGetGrab finds out if a connection has the control token.
|
||||
A match with a value can be checked for with SCMatchRights which
|
||||
returns true (1) if the connection has a user rights equal or higher then the
|
||||
one necessary. SCMatchRights also checks for the status of the control token
|
||||
and prints messages. SCMatchRights is the recommended function for checking
|
||||
access rights in SICS.
|
||||
|
||||
An object can find out if some hardware operation is running by calling
|
||||
the function isInRunMode prototyped in devexec.h.
|
||||
|
||||
An object can find out, if it is executing in a macro by calling SCinMacro.
|
||||
Might be useful if the code is dependent on this condition. Usually all
|
||||
details associated with running in a macro are dealt with by the system.
|
||||
|
||||
\subsection{Driving Hardware}
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 7}}
|
||||
Use the device executor!
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
With respect to hardware, there are two different kinds of objects in SICS:
|
||||
some objects represent hardware. Examples are motors, counters. This group
|
||||
also includes drivable variables which implement coordinated movements of
|
||||
hardware. Such objects have to implement the necessary interfaces: either
|
||||
the drivable or the countable interface. The second class are objects which
|
||||
implement commands which use the hardware. For instance a drive command.
|
||||
This second class of commands has to find the necessary hardware objects and
|
||||
then run the actual hardware through the device executor. The function to
|
||||
use is StartDevice or its derivatives, prototyped in devexec.h. After this
|
||||
is done, there are tow options. In a scan command it might be needed to wait for
|
||||
the hardware to finish before continuing your code. In this case use
|
||||
function TaskWait, prototyped in tasker.h.
|
||||
In other cases execution of the function may just
|
||||
continue. The device executor will the take care of the task of monitoring
|
||||
the hardware operation. The following code snippet gives an example how to
|
||||
start a counter properly and wait for it to finish:
|
||||
\begin{verbatim}
|
||||
/*-------------- count */
|
||||
pDum = (pDummy)self->pCounterData;
|
||||
iRet = StartDevice(pServ->pExecutor, /* the executor, from global pServ */
|
||||
"ScanCounter", /* a name */
|
||||
pDum->pDescriptor, /* the descriptor of the cter */
|
||||
self->pCounterData, /* pointer to counter data */
|
||||
self->pCon, /* pointer to connection object */
|
||||
self->fPreset); /* count preset */
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(self->pCon,"ERROR: Cannot Count, Scan aborted",eError);
|
||||
return 0;
|
||||
}
|
||||
/* wait for finish */
|
||||
lTask = GetDevexecID(pServ->pExecutor); /* get ID of device
|
||||
executor task */
|
||||
if(lTask > 0);
|
||||
{
|
||||
TaskWait(pServ->pTasker,lTask);
|
||||
}
|
||||
|
||||
/* finished, check for interrupts. Whatever happened, user
|
||||
interrupt or HW interrupt, it will be on our connection
|
||||
*/
|
||||
iInt = SCGetInterrupt(self->pCon);
|
||||
switch(iInt)
|
||||
{
|
||||
case eContinue:
|
||||
break;
|
||||
case eAbortOperation:
|
||||
continue;
|
||||
break;
|
||||
case eAbortScan:
|
||||
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
|
||||
/* eat the interrupt, the requested op has been
|
||||
done
|
||||
*/
|
||||
SCSetInterrupt(self->pCon,eContinue);
|
||||
return 0;
|
||||
break;
|
||||
default: /* all others */
|
||||
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
\end{verbatim}
|
||||
The above code (taken from the implementation of the scan command) also
|
||||
shows an example for handling interrupts as a followup to running hardware.
|
||||
Such a procedure is highly recommended.
|
||||
|
||||
\subsection{Working with the CallBack Interface}
|
||||
Working with the callback interface is usually simple: just use the
|
||||
functions as defined in interface.h. Add new event codes to event.h, in
|
||||
order to make them known. A problem arises if an object which has callbacks
|
||||
registered with other objects gets deleted. For the following discussion:
|
||||
let us denote the object registering the callback as the client object and
|
||||
the object which generates the event (where the callback was registered) as
|
||||
source object. A typical example for a client is a
|
||||
connection object which had configured itself to be automatically notified
|
||||
of motor movements, variable changes and the like. Typically this is a
|
||||
status display client. In such cases the client object has to keep
|
||||
track of the callbacks it registered and delete them when the client objects gets
|
||||
deleted. Otherwise the source object would invoke a callback on an non
|
||||
existing client object. This usually results in a lovely core dump. For the
|
||||
connection object this is taken care of automatically. The only thing needed
|
||||
to be done, is to register the callback on the connection object with
|
||||
SCRegister prototyped in conman.h. If user codes removes a callback later on,
|
||||
it may call SCUnregister on the connection object to remove it from the
|
||||
connection objects callback database as well. All registered callback will
|
||||
be properly removed when the connection object is deleted.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 8}}
|
||||
Remove registered callbacks when deleting an object. For connection objects:
|
||||
register your callbacks!
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
|
||||
|
||||
\section{The Object Wrapper Function}
|
||||
The object wrapper function makes the SICS object visible as a command in
|
||||
the interpreter. It has to analyze parameters given to the command and act
|
||||
accordingly. The object wrapper function has the following form:
|
||||
\begin{verbatim}
|
||||
int ObjectWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
\end{verbatim}
|
||||
The parameters are:
|
||||
\begin{itemize}
|
||||
\item A pointer to the connection object and the client invoking the command.
|
||||
\item A pointer to the SICS interpreter in which the command was executed.
|
||||
As the interpreter also doubles as a database for objects it is often needed
|
||||
to locate other objects.
|
||||
\item A pointer to the objects data structure (pData).
|
||||
\item The number of arguments specified to the command.
|
||||
\item The text of the arguments specified. \verb+argv[0]+ is the name of the
|
||||
command invoked. The argc, \verb+argv[]+ are almost the same as the argc,
|
||||
\verb+argv[]+ pair given to a C main program.
|
||||
\end{itemize}
|
||||
In order to give the macro interpreter a hint if things are okay, the object
|
||||
wrapper function has to return 1 for success and 0 if it fails. The rules
|
||||
stated above for normal object functions apply.
|
||||
|
||||
\section{The Object Creation Function}
|
||||
The object creation function has the same form as the object wrapper
|
||||
function. Its purpose is to analyze parameters and to create the requested
|
||||
object from them. In the end the object creation function will probably
|
||||
create a new command in the SICS interpreter. The function to do this is the
|
||||
AddCommand function. The prototype for AddCommand looks like this:
|
||||
\begin{verbatim}
|
||||
int AddCommand(SicsInterp *pSics,
|
||||
char *name,
|
||||
ObjectFunc pObFunc,
|
||||
KillFunc pKill,
|
||||
void *pData);
|
||||
\end{verbatim}
|
||||
The parameters are:
|
||||
\begin{itemize}
|
||||
\item A pointer to the SICS interpreter into which the new command shall be
|
||||
installed.
|
||||
\item The name of the new command.
|
||||
\item The object function implementing the command.
|
||||
\item An optional function which is able to remove the object data structure
|
||||
given as last parameter from memory. This is mandatory for any object with
|
||||
an own data structure.
|
||||
\item A pointer to the object data structure.
|
||||
\end{itemize}
|
||||
|
||||
\section{Writing Data}
|
||||
For simple ASCII files at instruments doing scans, see the SICS manager
|
||||
documentation for the template file description. Other instruments should
|
||||
use the NeXus data format. Especially the NXDICT implementation. For more
|
||||
documentation see the napi and nxdict documents. An example for using NXDICT
|
||||
is given in the file nxsans.c.
|
||||
|
||||
\section{Hardware Objects}
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
\leftline{{\huge Rule 9}}
|
||||
Obey the division between driver code and logical object for hardware
|
||||
objects.
|
||||
\begin{center}
|
||||
\rule{9cm}{2mm}
|
||||
\end{center}
|
||||
The concept of separating a hardware object in two components: a driver
|
||||
which implements primitive operations and a logical object with which SICS
|
||||
interacts internally has proven very valuable. First of all two drivers are
|
||||
needed anyway: a simulation driver for simulating hardware and a
|
||||
driver for the real hardware. Simulating hardware proved invaluable for
|
||||
debugging of higher level code and can be used later on for testing command
|
||||
files.
|
||||
|
||||
Please note that sample environment devices are handled slightly
|
||||
differently. There exists a more general sample environment object which
|
||||
handles many aspects of such a device. If the logical interface provided by
|
||||
this general sample environment objects suffices, a new sample environment
|
||||
device requires just a new driver. If the sample environment needs some
|
||||
specials the study the relationship between the itc4 object and the general sample
|
||||
environment object. Basically such a derived object implements in its
|
||||
functions just the specials and calls the appropriate functions of the
|
||||
general environment device object at the end. This is a simple form of
|
||||
inheritance by delegation. This scheme has been devised in order to reduce
|
||||
the need for code duplication when introducing new environment devices. For
|
||||
more details see the reference section on environment devices.
|
||||
|
||||
\section{Examples}
|
||||
For a deeper understanding of the concepts explained above it may help to
|
||||
look at some source code. A nice example for the whole SICS object setup
|
||||
including a callback interface is the implementation of the SICS variables
|
||||
in files sicsvar.h and sicvar.c. For the implementation of a hardware object
|
||||
including a drivable interface, the code in motor.h, motor.c and the motor
|
||||
drivers: simdriv.c, el734dc.c and el734driv.c may be a suitable example. The
|
||||
motor object creation function also shows how to handle multiple drivers for
|
||||
a logical object.
|
||||
SICS knows a omega-two-theta variable o2t. This variable coordinates two
|
||||
motors in a way that the second motor has exactly the double value of the
|
||||
first. This was meant to implement a omega-two-theta scan. Anyway, o2t is
|
||||
a good example for implementing a drivable interface and how to handle such
|
||||
coordinated movements. An example for the implementation of a countable
|
||||
interface can be found in counter.h, counter.c for a single counter.
|
||||
|
||||
\section{Documentation}
|
||||
If a new object has been defined two documentation files should be provided:
|
||||
\begin{itemize}
|
||||
\item A html file which describes the user interface to the object.
|
||||
\item A latex file which describes the data structures used to implement the
|
||||
object, the interface to the object and as much internal knowledge about the
|
||||
working of the object as you care to provide. Being generous with
|
||||
information helps maintaining the code later on!
|
||||
\end{itemize}
|
||||
Furthermore it is required to update the SICS managers documentation so that
|
||||
the object creation function is known.
|
||||
|
||||
\section{Introducing a new Hardware Driver}
|
||||
A new hardware driver for an existing objects can be introduced into the
|
||||
system with the following two steps:
|
||||
\begin{itemize}
|
||||
\item Write the new driver. Use an existing driver as template.
|
||||
\item Locate the objects factory function. Modify it so that it knows about
|
||||
the new driver and how to initialise it.
|
||||
\item Depending of the implementation of the object, the object deletion
|
||||
function may need to know about the new driver as well in order to delete it
|
||||
properly.
|
||||
\end{itemize}
|
||||
Do not forget to update the SICS manager documentation to include the new
|
||||
driver!
|
||||
|
||||
\section{Coding Considerations}
|
||||
The header file {\em sics.h} includes all the SICS kernel header files in
|
||||
the right order. It is recommended to include sics.h at the top of
|
||||
your implementation file.
|
||||
|
||||
A server program has to run for times on end. Thus a server program is more
|
||||
sensitive than any other program to memory leakage or memory overwrites.
|
||||
Therefore the current SICS implementation utilizes a memory debugging tool
|
||||
called fortify. It is highly recommended to include fortify.h into your
|
||||
implementation file in order to enable memory debugging. More information
|
||||
about the inner working and usage of fortify can be found in the file fortify.doc in
|
||||
the sics source code directory. Fortify has given some false alarms already
|
||||
but it also helped to eliminate a couple of nasty problems at a very early
|
||||
stage. A nasty feature of fortify is that its header file, fortify.h, has
|
||||
to be included in ALL relevant source files. Otherwise nasty pseudo bugs
|
||||
creep up when fortify is enabled. Please note, that fortify is only enabled
|
||||
when all source files have been compiled with the flag -DFORTIFY. Otherwise
|
||||
fortify compiles to nothing. More information about fortify can be found in
|
||||
file fortify.h.
|
||||
|
||||
Names in the SICS source code are often made up along the following pattern:
|
||||
\begin{itemize}
|
||||
\item Use the full name of the thing or sensible and command abbreviations.
|
||||
Write the variable as one word, with word boundaries being marked by capital
|
||||
letters.
|
||||
\item Most variables are prefixed with a letter denoting type. Letters used
|
||||
are:
|
||||
\begin{itemize}
|
||||
\item p for pointer.
|
||||
\item i for integer.
|
||||
\item f for float.
|
||||
\item d for double.
|
||||
\item l for long.
|
||||
\item s for struct.
|
||||
\end{itemize}
|
||||
Combinations of letters are also possible.
|
||||
\end{itemize}
|
||||
|
||||
Some more general data structure implementations are used in SICS: There is
|
||||
a general linked list package from a dutch men documented in lld.h. There is
|
||||
a dynamical array in dynar.* and a parameter array in obpar.*.
|
||||
|
||||
|
||||
|
194
doc/programmer/optimise.tex
Normal file
194
doc/programmer/optimise.tex
Normal file
@ -0,0 +1,194 @@
|
||||
\subsection{Optimise}
|
||||
In instrument control the need arises to optimise a peak with respect to
|
||||
several variables. This is usually the case during instrument calibration.
|
||||
Four circle diffractometers however use this facility on a day to day basis
|
||||
for finding and verifying the exact position of reflections. In order to
|
||||
support both usages a more general module has been implemented. The way of
|
||||
operation is like this:
|
||||
\begin{verbatim}
|
||||
while errors > precision and cycles < maxcycles
|
||||
for all variables treated
|
||||
do a scan
|
||||
Try find the maximum, two halfwidth points and the peak center.
|
||||
if failure extend the scan.
|
||||
if success shift the variable, remember last shift.
|
||||
If shift < precicison mark this variable as done
|
||||
end for
|
||||
end while
|
||||
\end{verbatim}
|
||||
Possible outcomes of this procedure are: success, the peak was lost or the
|
||||
maximum number of cycles was reached. This routine requires that the
|
||||
instrument is currently placed somewhere on the peak and not miles away.
|
||||
|
||||
In order to use this scheme some general control variables are required:
|
||||
\begin{description}
|
||||
\item[iMaxCycles] The maximum number of cycles to run.
|
||||
\item[lThreshold] A threshold value used when determining if the peak was
|
||||
lost.
|
||||
\item[eMode] The counter mode to count in.
|
||||
\item[fPreset] The preset to use when counting.
|
||||
\item[iChannel] The channel to use as signal when counting. This is to
|
||||
support this technique on a monitor rather then with a counter. Useful for
|
||||
calibration.
|
||||
\end{description}
|
||||
|
||||
For each variable to optimise we have to hold the following items:
|
||||
\begin{description}
|
||||
\item[name] Variable name.
|
||||
\item[fStep] The step size to use for scanning
|
||||
\item[nStep] The number of steps to go in each direction by default. This
|
||||
parameter and the step size should together encompass somewhat more then the
|
||||
width of the peak.
|
||||
\item[fPrecision] The precision required or expected for this variable.
|
||||
\item[fShift] The shift necessary for the last variable.
|
||||
\end{description}
|
||||
Of this the user is required to enter: name, fStep, nStep and fPrecision.
|
||||
|
||||
For some of its work, this module relies on the scan object (scan.*) and the
|
||||
fitcenter object (fitcenter.*).
|
||||
|
||||
Internally the optimiser uses the following data structures:
|
||||
\begin{verbatim}
|
||||
typedef struct {
|
||||
char *pName;
|
||||
float fStep;
|
||||
int iStep;
|
||||
float fPrecision;
|
||||
float fCenter;
|
||||
float fShift;
|
||||
pIDrivable pDriv;
|
||||
void *pData;
|
||||
int iLost;
|
||||
} OVarEntry, *pOVarEntry;
|
||||
\end{verbatim}
|
||||
This is the data structure for each variable to optimise during an
|
||||
optimser run. The fields are:
|
||||
\begin{description}
|
||||
\item[pName] the name of the variable.
|
||||
\item[fStep] The step width to use for scanning the variable.
|
||||
\item[fPrecision] The precision required for this variable. Used to
|
||||
mark this variable OK if the last shift is less then this precision
|
||||
value.
|
||||
\item[fCenter] The calculated center of this variable.
|
||||
\item[fShift] The last shift calculated for this variable.
|
||||
\item[pDriv] A pointer to the drivable interface of this variable.
|
||||
\item[pData] A pointer to this variables data structure.
|
||||
\item[iLost] A flag which marks if the peak has been lost with respect
|
||||
to this variable.
|
||||
\end{description}
|
||||
|
||||
|
||||
The optimiser itself uses the following data structure:
|
||||
\begin{verbatim}
|
||||
typedef struct __OptimiseStruct {
|
||||
pObjectDescriptor pDes;
|
||||
int iMaxCycles;
|
||||
CounterMode eCount;
|
||||
float fPreset;
|
||||
int iChannel;
|
||||
float fThreshold;
|
||||
int iVar;
|
||||
pDynar pVariables;
|
||||
pScanData pScanner;
|
||||
pFit pPeakFitter;
|
||||
} Optimiser;
|
||||
\end{verbatim}
|
||||
The fields are:
|
||||
\begin{description}
|
||||
\item[pDes]The usual object descriptor.
|
||||
\item[iMaxCycles] The maximum number of cycles to perform.
|
||||
\item[eCount] The countmode to use for scanning.
|
||||
\item[fPreset] The preset to use for scanning.
|
||||
\item[iChannel] The channel to use for scanning.
|
||||
\item[fThreshold] The threshold to use for identifying lost peaks.
|
||||
\item[iVar] The number of variables to optimise.
|
||||
\item[pVariables] A dynamic array of variables to optimise.
|
||||
\item[pScanner] The scan object to use for scanning.
|
||||
\item[pFit] The peak center determination object to use.
|
||||
\end{description}
|
||||
|
||||
|
||||
The interface to this object looks like this:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
\verb@"optimise.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ O P T I M I S E@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Optimise a peak with respect to several variables.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, March 1998-1999@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSOPTIMISE@\\
|
||||
\mbox{}\verb@#define SICSOPTIMISE@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __OptimiseStruct *pOptimise;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------- live & death -----------------------------------------*/@\\
|
||||
\mbox{}\verb@ pOptimise CreateOptimiser(pCounter pCount);@\\
|
||||
\mbox{}\verb@ void DeleteOptimiser(void *pData);@\\
|
||||
\mbox{}\verb@ int MakeOptimiser(SConnection *pCon, SicsInterp *pSics,@\\
|
||||
\mbox{}\verb@ void *pData, int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@/*------------------- operation -------------------------------------------*/@\\
|
||||
\mbox{}\verb@#define PEAKLOST -1@\\
|
||||
\mbox{}\verb@#define MAXCYCLE -2@\\
|
||||
\mbox{}\verb@#define SCANERROR -3@\\
|
||||
\mbox{}\verb@#define SCANABORT -4@\\
|
||||
\mbox{}\verb@#define SYSERROR -5@\\
|
||||
\mbox{}\verb@#define DRIVEERROR -6@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ void OptimiserClear(pOptimise self);@\\
|
||||
\mbox{}\verb@ int OptimiserAdd(pOptimise self,@\\
|
||||
\mbox{}\verb@ char *pVarName, @\\
|
||||
\mbox{}\verb@ float fStep, @\\
|
||||
\mbox{}\verb@ int nStep, @\\
|
||||
\mbox{}\verb@ float fPrecision);@\\
|
||||
\mbox{}\verb@ int OptimiserSetPar(pOptimise self, char *name, float fVal);@\\
|
||||
\mbox{}\verb@ int OptimiserGetPar(pOptimise self, char *name, float *fVal);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int OptimiserRun(pOptimise self, SConnection *pCon); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int OptimiserAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
All functions except the installation functions take a pointer to the
|
||||
optimiser structure as first parameter. The function reference:
|
||||
\begin{description}
|
||||
\item[CreateOptimiser] creates an optimiser object. Takes a pointer to
|
||||
a counter object as a parameter. Returns a pointer to a nice and good
|
||||
optimiser object on return. Or NULL, if there was some sort of
|
||||
problem.
|
||||
\item[DeleteOptimiser] is the deletion function used in the
|
||||
interpreter for properly removing the optimiser object from the
|
||||
system.
|
||||
\item[MakeOptimiser] is the installation function which configures an
|
||||
optimiser into SICS.
|
||||
\item[OptimiserClear] removes all configured optimisation variables
|
||||
and all remnants of a previous optimiser run.
|
||||
\item[OptimiserAdd] adds a variable to be optimised. Parameter to this
|
||||
call are: pVarName, the name of the variable to optimise, fStep, the
|
||||
step width to use for scanning, nStep, the initial number of steps to
|
||||
use for scanning, fPrecision, the precision to achive for this
|
||||
variable.
|
||||
\item[OptimiserSetPar] sets the configuration parameters for the
|
||||
optimiser. The parameter name is the same name as stated in the
|
||||
command reference.
|
||||
\item[OptimiserGetPar] retrieves the value of a configuration
|
||||
parameters for the
|
||||
optimiser. The parameter name is the same name as stated in the
|
||||
command reference.
|
||||
\item[OptimiserRun] starts the optimser run with the current
|
||||
parameters. Output is sent to the connection pCon.
|
||||
\item[OptimiserAction] is the interpreter interface function for the
|
||||
optimiser.
|
||||
\end{description}
|
437
doc/programmer/overview.tex
Normal file
437
doc/programmer/overview.tex
Normal file
@ -0,0 +1,437 @@
|
||||
\chapter{SICS Overview}
|
||||
\section{Introduction}
|
||||
At the new spallation source SINQ at PSI a whole set of new neutron
|
||||
scattering instruments are being installed. All these new instruments need a
|
||||
computer instrument control control system. After a review of similar systems
|
||||
out in the market it was found that none fully met the requirements defined
|
||||
for SINQ or could easily be extended to do so. Therefore it was decided to
|
||||
design a new system. This new system SICS, the SINQ Instrument Control
|
||||
System, had to meet the following specifications:
|
||||
\begin{itemize}
|
||||
\item Control the instrument reliably.
|
||||
\item Good remote access to the instrument via the internet.
|
||||
\item Portability across operating system platforms.
|
||||
\item Enhanced portability across instrument hardware. This means that it
|
||||
should be easy to add other types of motors, counters or other hardware to
|
||||
the system.
|
||||
\item Support authorization on the command and variable level. This means
|
||||
that certain instrument settings can be protected against random changes by
|
||||
less knowledgable users.
|
||||
\item Good maintainability and extendability.
|
||||
\item Be capable to acomodate graphical user interfaces (GUI).
|
||||
\item One code base for all instruments.
|
||||
\item Powerful macro language.
|
||||
\end{itemize}
|
||||
A suitable new system was implemented using an object oriented design which
|
||||
matches the above criteria.
|
||||
|
||||
\section{The SINQ Hardware Setup}
|
||||
SICS had to take in account the SINQ hardware setup which had been decided
|
||||
upon earlier on. Most hardware such as motors and counters is controlled via
|
||||
RS--232 interfaces. These devices connect to a Macintosh PC which has a
|
||||
terminal server program running on it. This terminal server program collects
|
||||
request to the hardware from a TCP/IP port and forwards them to the serial
|
||||
device. The instrument control program runs on a workstation running
|
||||
DigitalUnix. Communication with the hardware happens via TCP/IP through the
|
||||
terminal server. Some hardware devices, such as the histogram memory, can handle
|
||||
TCP/IP themselves. With such devices the instrument control program
|
||||
communicates directly through TCP/IP, without a terminal server. All
|
||||
hardware devices take care of their real time needs themselves. Thus the
|
||||
only task of the instrument control program is to orchestrate the hardware
|
||||
devices. SICS is designed with this setup up in mind, but is not restricted
|
||||
to this setup. A schematic view of this setup is given in picture
|
||||
\ref{hard}.
|
||||
\begin{figure}
|
||||
%% \epsfxsize=0.65\textwidth
|
||||
\epsfxsize=160mm
|
||||
\epsffile{hart.eps}
|
||||
\caption{Instrument control hardware setup at SINQ}\label{hard}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\section{SICS Overall Design}
|
||||
In order to achieve the design goals stated above it was decided to divide
|
||||
the system into a client server system. This means that there are at least
|
||||
two programs necessary to run an instrument: a client program and a server
|
||||
program. The server program, the SICS server, does all the work and
|
||||
implements the actual instrument control. The SICS server usually runs on
|
||||
the DAQ computer. The client program may run on any computer on the world
|
||||
and implements the user interface to the instrument. Any numbers of clients
|
||||
can communicate with one SICS server. The SICS server and the clients
|
||||
communicate via a simple ASCII command protocol through TCP/IP sockets.
|
||||
With this design good remote control through the network is easily achieved.
|
||||
As clients can be implemented in any language or system capable of handling
|
||||
TCP/IP the user interface and the functional aspect are well separated. This
|
||||
allows for easy exchange of user interfaces by writing new clients.
|
||||
|
||||
|
||||
\section{SICS Clients}
|
||||
SICS Clients implement the SICS user interface. Current client
|
||||
programs are mostly implemented in Java for platform independence.
|
||||
This is a real concern at SINQ where VMS,
|
||||
Intel-PC, Macintosh and Unix users have to be satisfied.
|
||||
As many instrument scientists still prefer
|
||||
the command line for interacting with instruments, the most used client is a
|
||||
visual command line client. Status displays are another sort of specialized
|
||||
client programs. Graphical user interfaces are under consideration for some
|
||||
instruments. As an example for a client a screen shot of the status display
|
||||
client for a powder diffractometer is given in picture \ref{dmc}
|
||||
\ref{hard}.
|
||||
\begin{figure}
|
||||
%% \epsfxsize=0.65\textwidth
|
||||
\epsfxsize=160mm
|
||||
%% \epsffile{dmc.eps}
|
||||
\caption{Example for a SICS client: Powder Diffractometer Status Display}\label{dmc}
|
||||
\end{figure}
|
||||
|
||||
|
||||
|
||||
\section{The SICS Server}
|
||||
The SICS server is the core component of the SICS system. The SICS server is
|
||||
responsible for doing all the work in instrument control. Additionally the
|
||||
server has to answer the requests of possibly multiple clients.
|
||||
The SICS server can be subdivided into three subsystems: The kernel, a database
|
||||
of SICS objects and an interpreter. The SICS server kernel takes care of
|
||||
client multitasking and the preservation of the proper I/O and error context
|
||||
for each client command executing.
|
||||
SICS objects are software modules which represent all aspects
|
||||
of an instrument: hardware devices, commands, measurement strategies
|
||||
and data storage. This database of objects is initialized at server startup
|
||||
time from an initialization script. The third SICS server component is an
|
||||
interpreter which allows to issue commands to the objects in the objects database.
|
||||
The schematic drawing of the SICS server's structure is given in picture
|
||||
\ref{newsics}.
|
||||
\begin{figure}
|
||||
%% \epsfxsize=0.65\textwidth
|
||||
\epsfxsize=160mm
|
||||
\epsffile{newsics.eps}
|
||||
\caption{Schematic Representation of the SICS server's structure}\label{sicsnew}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\subsection{The SICS Server Kernel}
|
||||
In more detail the SICS server kernel has the following tasks:
|
||||
\begin{itemize}
|
||||
\item Accept and verify client connection requests.
|
||||
\item Read and execute client commands.
|
||||
\item Maintain the I/O and error context for each client connection.
|
||||
\item Serialize data access.
|
||||
\item Serialize hardware access.
|
||||
\item Monitor HW--operations.
|
||||
\item Monitor environment devices.
|
||||
\end{itemize}
|
||||
Any server serving multiple clients has the problem how to organize multiple
|
||||
clients accessing the same server and how to stop one client reading data,
|
||||
which another client is just writing. The approach used for the SICS server
|
||||
is a combination of polling and cooperative multitasking. This scheme is
|
||||
simple and can be implemented in an operating system independent manner. One
|
||||
way to look at the SICS server is as a series of tasks in a circular queue
|
||||
executing one after another. The servers main loop does nothing but
|
||||
executing the tasks in this circular buffer in an endless loop.
|
||||
There are several system tasks and one such
|
||||
task for each living client connection. Thus only one task executes at any
|
||||
given time and data access is efficiently serialized. One of the main system
|
||||
tasks (and the one which will be always there) is the network reader. The
|
||||
network reader has a list of open network connections and checks each of
|
||||
them for pending requests. What happens when a data is pending on an open
|
||||
network port depends on the type of port: If it is the servers main
|
||||
connection port, the network reader will try to accept and verify a new
|
||||
client connection and create the associated data structures. If the port
|
||||
belongs to an open client connection the network reader will read the
|
||||
command pending and put it onto a command stack existing for each client
|
||||
connection. When it is time for a client task to execute, it will fetch a
|
||||
command from its very own command stack and execute it. When the net reader
|
||||
finds an user interrupt pending, the interrupt is executed.
|
||||
This is how the SICS server deals with client requests.
|
||||
|
||||
The scheme described above relies on the fact that most SICS command need
|
||||
only very little time to execute. A command needing time extensive
|
||||
calculations may effectively block the server. Implementations of such
|
||||
commands have to take care that control passes back to the task switching
|
||||
loop at regular intervalls in order to prevent the server from blocking.
|
||||
|
||||
Another problem in a server handling multiple client requests is how to
|
||||
maintain the proper execution context for each client. This includes the
|
||||
clients I/O-context (socket), the authorisation of the client and possible
|
||||
error conditions pending for a
|
||||
client connection. SICS does this via a connection object, a special
|
||||
data structure holding all the above information plus a set of functions
|
||||
operating on this data structure. This connection object is passed along
|
||||
with many calls throughout the whole system.
|
||||
|
||||
Multiple clients issuing commands to the SICS server may mean that multiple
|
||||
clients might try to move motors or access other hardware in conflicting
|
||||
ways. As there is only one set of instrument hardware this needs to be
|
||||
prevented. This is achieved by a convention. No SICS object drives hardware
|
||||
directly but registers it's request with a special object, the device
|
||||
executor. This device executor starts the requested operation and reserves
|
||||
the hardware for the length of the operation. During the execution of such
|
||||
an hardware request all other clients requests to drive the hardware will
|
||||
return an error. The device executor is also responsible for monitoring the
|
||||
progress of an hardware operation. It does so by adding a special task into
|
||||
the system which checks the status of the operation each time this tasks
|
||||
executes. When the hardware operation is finished (one way or another) this
|
||||
device executor task will end. A special system facility allows a client
|
||||
task to wait for the device executor task to end while the rest of the task
|
||||
queue is still executing. In this way time intensive hardware operations can
|
||||
be performed by drive, count or scan commands without blocking the whole
|
||||
system for other clients. \label{devexec}
|
||||
|
||||
The SICS server can be configured to support another security feature, the
|
||||
token system. In this scheme a client can grab control of the instrument.
|
||||
With the control token grabbed, only the client which has the token may
|
||||
control the instrument. Any other client may look at things in the SICS server
|
||||
but does not have permission to change anything. Passing the control token
|
||||
requires that the client which has the token releases the token so that
|
||||
another client may grab it. There exists a password protected back door for
|
||||
SICS managers which allows to force the release of a control token.
|
||||
|
||||
Most experiments do not happen at ambient room conditions but
|
||||
require some special environment for the sample. Mostly this is temperature
|
||||
but it can also be magnetic of electric fields etc. Most of such devices
|
||||
can regulate themselves but the data acquisition program needs to monitor
|
||||
such devices. Within SICS this is done via a special system object, the
|
||||
environment monitor. A environment device, for example a temperature
|
||||
controller, registers it's presence with this object. Then an special system
|
||||
task will control this device when it is executing, check for possible out
|
||||
of range errors and initiates the proper error handling if such a problem is
|
||||
encountered.
|
||||
|
||||
\subsection{The SICS Interpreter}
|
||||
When a task belonging to a client connection executes a command it will pass
|
||||
the command along with the connection object to the SICS interpreter. The
|
||||
SICS interpreter will then analyze the command and forward it to the
|
||||
appropriate SICS object in the object database for further action. The SICS
|
||||
interpreter is very much modeled after the Tcl interpreter as devised by
|
||||
John Ousterhout$^{1}$. For each SICS object visible from the interpreter there is
|
||||
a wrapper function. Using the first word of the command as a key, the
|
||||
interpreter will locate the objects wrapper function. If such a function is
|
||||
found it is passed the command parameters, the interpreter object and the
|
||||
connection object for further processing. An interface exists to add and
|
||||
remove commands to this interpreter very easily. Thus the actual command
|
||||
list can be configured easily to match the instrument in question, sometimes
|
||||
even at run time. Given the closeness of the design of the SICS interpreter
|
||||
to the Tcl interpreter, the reader may not be surprised to learn that the
|
||||
SICS server incorporates Tcl as its internal macro language. The internal
|
||||
macro language may use Tcl commands as well as SICS commands.
|
||||
|
||||
\subsection{SICS Objects}
|
||||
As already said, SICS objects implement the true functionality of SICS
|
||||
instrument control. All hardware, all commands and procedures, all data
|
||||
handling strategies are implemented as SICS objects. Hardware objects, for
|
||||
instance motors deserve some special attention. Such objects are divided
|
||||
into two objects in the SICS system: A logical hardware object and a driver
|
||||
object. The logical object is responsible for implementing all the nuts and
|
||||
bolts of the hardware device, whereas the driver defines a set of primitive
|
||||
operations on the device. The benefit of this scheme is twofold:
|
||||
switching to new hardware, for instance a new type of motor, just requires
|
||||
to incorporate a new driver into the system. Internally, independent from
|
||||
the actual hardware, all hardware object of the same type (for example
|
||||
motors) look the same and can be treated the same by higher level objects.
|
||||
No need to rewrite a scan command because a motor changed.
|
||||
|
||||
In order to live happily within the SICS system SICS object have to adhere
|
||||
to a system of protocols. There are protocols for:
|
||||
\begin{itemize}
|
||||
\item Input/Output to the client.
|
||||
\item Error handling.
|
||||
\item Interaction with the interpreter.
|
||||
\item For identification of the object to the system at run time.
|
||||
\item For interacting with hardware (see device executor above).
|
||||
\item For checking the authorisation of the client who wants to execute the
|
||||
command.
|
||||
\end{itemize}
|
||||
|
||||
SICS uses NeXus$^{2}$, the upcoming standard for data exchange for neutron
|
||||
and x\_ray scattering as its raw data format.
|
||||
|
||||
SICS objects have the ability to notify clients and other objects of
|
||||
internal state changes. For example when a motor is driven, the motor object
|
||||
can be configured to tell SICS clients or other SICS objects about his new
|
||||
position.
|
||||
|
||||
\section{SICS Working Examples}
|
||||
In order to get a better feeling for the internal working of SICS the course
|
||||
of a few different requests through the SICS system is traced in this
|
||||
section. The examples traced will be:
|
||||
\begin{itemize}
|
||||
\item A request for a new client connection.
|
||||
\item A simple command.
|
||||
\item A command to drive a motor in blocking mode.
|
||||
\item A command to drive a motor which got interrupted by the user.
|
||||
\item A command to drive a motor in non blocking mode.
|
||||
\end{itemize}
|
||||
For the whole discussion it is assumed that the main loop is running,
|
||||
executing cyclically each single task registered in the server. Task switching is
|
||||
done by a special system component, the task switcher.
|
||||
|
||||
\subsection{The Request for a new Client Connection}
|
||||
\begin{itemize}
|
||||
\item The network reader recognizes pending data on its main server port.
|
||||
\item The network reader accepts the connection and tries to read a
|
||||
username/password pair.
|
||||
\item If such a username/password pair comes within a suitable time
|
||||
intervals it is checked for validity. On failure the connection is closed
|
||||
again.
|
||||
\item If a valid connection has been found: A new connection object is
|
||||
created, a new task for this client connection is introduced into the
|
||||
system and the network reader registers a new client port to check for
|
||||
pending commands.
|
||||
\item Control is passed back to the task switcher.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{A Simple Command}
|
||||
\begin{itemize}
|
||||
\item The network reader finds data pending at one of the client ports.
|
||||
\item The network reader reads the command, splits it into single lines and
|
||||
put those on the top of the client connections command stack. The network
|
||||
reader passes control to the task switcher.
|
||||
\item In due time the client connection task executes, inspects its command
|
||||
stack, pops the command pending and forwards it together with a pointer to
|
||||
itself to the SICS interpreter.
|
||||
\item The SICS interpreter inspects the first word of the command. Using
|
||||
this key the interpreter finds the objects wrapper function and passes
|
||||
control to that function.
|
||||
\item The object wrapper function will check further arguments, checks the
|
||||
clients authorisation if appropriate for the action requested. Depending on
|
||||
the checks, the wrapper function will create an error message or do its
|
||||
work.
|
||||
\item This done, control passes back through the interpreter and the connection
|
||||
task to the task switcher.
|
||||
\item The next task executes.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{A Drive Command in Blocking Mode}
|
||||
\begin{itemize}
|
||||
\item The network reader finds data pending at one of the client ports.
|
||||
\item The network reader reads the command, splits it into single lines and
|
||||
put those on the top of the client connections command stack. The network
|
||||
reader passes control to the task switcher.
|
||||
\item In due time the client connection task executes, inspects its command
|
||||
stack, pops the command pending and forwards it together with a pointer to
|
||||
itself to the SICS interpreter.
|
||||
\item The SICS interpreter inspects the first word of the command. Using
|
||||
this key the interpreter finds the drive command wrapper function and passes
|
||||
control to that function.
|
||||
\item The drive command wrapper function will check further arguments,
|
||||
checks the
|
||||
clients authorisation if appropriate for the action requested. Depending on
|
||||
the checks, the wrapper function will create an error message or do its
|
||||
work.
|
||||
\item Assuming everything is OK, the motor is located in the system.
|
||||
\item The drive command wrapper function asks the device executor to run the
|
||||
motor.
|
||||
\item The device executor verifies that nobody else is driving, then starts
|
||||
the motor and grabs hardware control. The device executor also starts a task
|
||||
monitoring the activity of the motor.
|
||||
\item The drive command wrapper function now enters a wait state. This means
|
||||
the task switcher will execute other tasks, except the connection task
|
||||
requesting the wait state. The client connection and task executing the drive command
|
||||
will not be able to process further commands.
|
||||
\item The device executor task will keep on monitoring the progress of the motor
|
||||
driving whenever the task switcher allows it to execute.
|
||||
\item In due time the device executor task will find that the motor finished
|
||||
driving. The task will then die. The clients grab of the hardware driving
|
||||
permission will be released.
|
||||
\item At this stage the drive command wrapper function will awake and
|
||||
continue execution. This means inspecting errors and reporting to the client
|
||||
how things worked out.
|
||||
\item This done, control passes back through the interpreter and the connection
|
||||
task to the task switcher. The client connection is free to execute
|
||||
other commands.
|
||||
\item The next task executes.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{A Drive Command Interrupted}
|
||||
\begin{itemize}
|
||||
\item The network reader finds data pending at one of the client ports.
|
||||
\item The network reader reads the command, splits it into single lines and
|
||||
put those on the top of the client connections command stack. The network
|
||||
reader passes control to the task switcher.
|
||||
\item In due time the client connection task executes, inspects its command
|
||||
stack, pops the command pending and forwards it together with a pointer to
|
||||
itself to the SICS interpreter.
|
||||
\item The SICS interpreter inspects the first word of the command. Using
|
||||
this key the interpreter finds the drive command wrapper function and passes
|
||||
control to that function.
|
||||
\item The drive command wrapper function will check further arguments,
|
||||
checks the
|
||||
clients authorisation if appropriate for the action requested. Depending on
|
||||
the checks, the wrapper function will create an error message or do its
|
||||
work.
|
||||
\item Assuming everything is OK, the motor is located in the system.
|
||||
\item The drive command wrapper function asks the device executor to run the
|
||||
motor.
|
||||
\item The device executor verifies that nobody else is driving, then starts
|
||||
the motor and grabs hardware control. The device executor also starts a task
|
||||
monitoring the activity of the motor.
|
||||
\item The drive command wrapper function now enters a wait state. This means
|
||||
the task switcher will execute other tasks, except the connection task
|
||||
requesting the wait state.
|
||||
\item The device executor task will keep on monitoring the progress of the
|
||||
driving of the motor when it is its turn to execute.
|
||||
\item The network reader finds a user interrupt pending. The interrupt will
|
||||
be forwarded to all tasks in the system.
|
||||
\item In due time the device executor task will try to check on the progress
|
||||
of the motor. It will recognize the interrupt. If appropriate the motor will
|
||||
get a halt command. The task will then die.
|
||||
The clients grab of the hardware driving permission will be released.
|
||||
\item At this stage the drive command wrapper function will awake and
|
||||
continue execution. This means it finds the interrupt, tells the user what he
|
||||
already knows: an interrupt was issued.
|
||||
\item This done, control passes back through drive command wrapper,
|
||||
the interpreter and the connection
|
||||
task to the task switcher.
|
||||
\item The next task executes.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{A Run Command in Non Blocking Mode}
|
||||
\begin{itemize}
|
||||
\item The network reader finds data pending at one of the client ports.
|
||||
\item The network reader reads the command, splits it into single lines and
|
||||
put those on the top of the client connections command stack. The network
|
||||
reader passes control to the task switcher.
|
||||
\item In due time the client connection task executes, inspects its command
|
||||
stack, pops the command pending and forwards it together with a pointer to
|
||||
itself to the SICS interpreter.
|
||||
\item The SICS interpreter inspects the first word of the command. Using
|
||||
this key the interpreter finds the drive command wrapper function and passes
|
||||
control to that function.
|
||||
\item The run command wrapper function will check further arguments,
|
||||
checks the
|
||||
clients authorisation if appropriate for the action requested. Depending on
|
||||
the checks, the wrapper function will create an error message or do its
|
||||
work.
|
||||
\item Assuming everything is OK, the motor is located in the system.
|
||||
\item The drive command wrapper function asks the device executor to run the
|
||||
motor.
|
||||
\item The device executor verifies that nobody else is driving, then starts
|
||||
the motor and grabs hardware control. The device executor also starts a task
|
||||
monitoring the activity of the motor.
|
||||
\item The run command wrapper function passes control through the interpreter and
|
||||
the clients task function back to the task switcher. The client connection can handle
|
||||
new commands.
|
||||
\item The device executor task will keep on monitoring the progress of the motor
|
||||
driving whenever the task switcher allows it to execute.
|
||||
\item In due time the device executor task will find that the motor finished
|
||||
driving. The task will then die silently. The clients grab of the hardware driving
|
||||
permission will be released. If errors occurred, however a they will be reported.
|
||||
\item At this stage the drive command wrapper function will awake and
|
||||
continue execution. This means inspecting errors and reporting to the client
|
||||
how things worked out.
|
||||
\item This done, control passes back through the interpreter and the connection
|
||||
task to the task switcher. The client connection is free to execute
|
||||
other commands.
|
||||
\item The next task executes.
|
||||
\end{itemize}
|
||||
|
||||
All this seems to be pretty complex and time consuming. But it is the complexity needed to
|
||||
do so many things, especially the non blocking mode of operation requested
|
||||
by users. Tests have shown that the task switcher manages +900 cycles per second
|
||||
through
|
||||
the task list on a DigitalUnix machine and 50 cycles per second on a pentium 133mhz
|
||||
machine running linux. Both data were obtained with software simulation of
|
||||
hardware devices. With real SINQ hardware these numbers drop 4 cycles per
|
||||
second. This shows clearly that the communication with the hardware is the
|
||||
systems bottleneck and not the task switching scheme.
|
||||
|
20
doc/programmer/passwd.tex
Normal file
20
doc/programmer/passwd.tex
Normal file
@ -0,0 +1,20 @@
|
||||
\subsection{The Password Database}
|
||||
This is just a simple password database. It keeps for each user an
|
||||
record containing username, password and an integer code. The code
|
||||
is meant to encode the users rights within the system. On
|
||||
initialisation the information is read from a file. Currently there
|
||||
is no encryption in this. Rely on the filesytem protection mechanisms
|
||||
for protecting passwords. Though SICS will have only a limited number
|
||||
of different user levels, the password class is designed to cope with
|
||||
more and stores its data in a linked list. Currently user names and
|
||||
passwords are entered into the database through the SicsUser
|
||||
initialization command.
|
||||
|
||||
The interface:\begin{itemize}
|
||||
\item {\bf int InitPasswd(char *filename) } reads user data from the file specified. Returns True on success, false else.
|
||||
\item {\bf void AddUser(char *name, char *passwd, int iCode) }, adds a new user to the database.
|
||||
\item {\bf int IsValidUser(char *name, char *passwd) }, checks a users authorisation information. Returns a negative value if the user is invalid, the users rights code if he is valid.
|
||||
\item {\bf void KillPasswd(void) }, deletes the password data structures, when it is no longer needed. Omission of this call will result in wasted memory.
|
||||
\end{itemize}
|
||||
|
||||
|
119
doc/programmer/perfmon.tex
Normal file
119
doc/programmer/perfmon.tex
Normal file
@ -0,0 +1,119 @@
|
||||
\subsection{Performance Monitor}
|
||||
This object implements a performance monitor for SICS. Please note that SICS
|
||||
performance is determined not only by processor speed but by a whole range
|
||||
of factors:
|
||||
\begin{itemize}
|
||||
\item Processor speed and memory.
|
||||
\item Speed of network connctions to hardware devices.
|
||||
\item Number of clients connected.
|
||||
\end{itemize}
|
||||
|
||||
The PerfMonTask is called from the SICS task modules main loop. It will then
|
||||
increment a cycle counter and check if a predefined intergration time has
|
||||
passed. If so a new
|
||||
value for cycle per seconds will be calculated. This is also the main
|
||||
output of PerfMon. PerfMon implements a callback interface in order to allow
|
||||
automatical notification about system performance.
|
||||
|
||||
PerfMon has a little datastructure:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$pdata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __PerfMon {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pICallBack pCall;@\\
|
||||
\mbox{}\verb@ int iLog; /* flag for@\\
|
||||
\mbox{}\verb@ serverlog writing */ @\\
|
||||
\mbox{}\verb@ float fCPS; /* cycles per seconds */@\\
|
||||
\mbox{}\verb@ int iInteg; /* integration time */@\\
|
||||
\mbox{}\verb@ int iCount;@\\
|
||||
\mbox{}\verb@ time_t tLast; /* last time calculated */@\\
|
||||
\mbox{}\verb@ time_t tTarget; /* next target time */@\\
|
||||
\mbox{}\verb@ int iEnd;@\\
|
||||
\mbox{}\verb@ }PerfMon;@\\
|
||||
\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 interface consists of the following functions:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$pInter {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __PerfMon *pPerfMon;@\\
|
||||
\mbox{}\verb@/*---------------------- live and death ----------------------------------*/@\\
|
||||
\mbox{}\verb@ pPerfMon CreatePerfMon(int iInteg);@\\
|
||||
\mbox{}\verb@ void DeletePerfMon(void *pData);@\\
|
||||
\mbox{}\verb@/*---------------------- increment ---------------------------------------*/@\\
|
||||
\mbox{}\verb@ int IncrementPerfMon(pPerfMon self);@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ float GetPerformance(pPerfMon self);@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int PerfMonWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@/*-----------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int PerfMonTask(void *pPerf);@\\
|
||||
\mbox{}\verb@ void PerfMonSignal(void *pPerf, int iSignal, void *pSigData); @\\
|
||||
\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}
|
||||
There is really not much to this.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"perfmon.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ P E R F M O N@\\
|
||||
\mbox{}\verb@ A performance monitor for SICS. Maintains and calculates a value for@\\
|
||||
\mbox{}\verb@ cycles per seconds. @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see implementation file@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSPERFMON@\\
|
||||
\mbox{}\verb@#define SICSPERFMON@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$pInter {\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{scrap4}
|
||||
\verb@"perfmon.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ The P E R F M O N datastructure.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\
|
||||
\mbox{}\verb@---------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@@$\langle$pdata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
67
doc/programmer/pimotor.tex
Normal file
67
doc/programmer/pimotor.tex
Normal file
@ -0,0 +1,67 @@
|
||||
\subsubsection{Physik Instrumente DC-Motor Controller}
|
||||
This is a mainly a driver for a C-804 DC-motor Controller as produced by the
|
||||
Company Physik Instrumente. This controller drives up to four high precision
|
||||
motors. These motors do not have reference points and have variable speeds.
|
||||
Therefore some additional code is needed to handle motor specific commands.
|
||||
This problem is solved by handling these specific additional commands in a
|
||||
new wrapper routine which finally calls the main motor wrapper routine for
|
||||
all the other commands. Of course, a special factory method is needed for
|
||||
this device as well.
|
||||
|
||||
The public interface for this motor includes the following functions:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$pimoti {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int PIMotorWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@ int PIMotorFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int PISetSpeed(pMotor self, SConnection *pCon, float fNew);@\\
|
||||
\mbox{}\verb@ int PIGetSpeed(pMotor self, SConnection *pCon, float *fVal);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int PIHome(pMotor self, SConnection *pCon);@\\
|
||||
\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{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
\verb@"pimotor.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ P I M O T O R@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Driver and add on code for the Physik Instrument Motor Controller C-804.@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1998@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef PIMOTOR@\\
|
||||
\mbox{}\verb@#define PIMOTOR@\\
|
||||
\mbox{}\verb@@$\langle$pimoti {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\subsubsection{Physik Instrument Piezo Controller E-255}
|
||||
This is piezo translator. A voltage is set and it elongates. It is
|
||||
handled as a motor because it is going to be scanned. A driver has
|
||||
been implemented in the file pipiezo.c. For
|
||||
the command protocoll, see the documentation coming with the gadget.
|
||||
|
||||
|
47
doc/programmer/progold.data
Normal file
47
doc/programmer/progold.data
Normal file
@ -0,0 +1,47 @@
|
||||
\chapter{SICS Programmers Reference}
|
||||
This chapter is a boring listing of the interfaces and functions provided by
|
||||
the SICS modules.
|
||||
|
||||
\section{Kernel Objects and Modules}
|
||||
This section describes the objects and modules defining the SICS kernel.
|
||||
\include{nserver}
|
||||
\include{nread}
|
||||
\include{nconman}
|
||||
\include{emonitor}
|
||||
\include{event}
|
||||
\include{interface}
|
||||
\include{devexec}
|
||||
\include{perfmon}
|
||||
\include{ini}
|
||||
\include{inter}
|
||||
\include{macro}
|
||||
\include{network}
|
||||
\include{passwd}
|
||||
|
||||
|
||||
\section{SICS Objects}
|
||||
This section describes the SICS objects implementing commands and hardware
|
||||
objects.
|
||||
\include{velo}
|
||||
\include{velodorn}
|
||||
\include{scan}
|
||||
\include{evcontroller}
|
||||
\include{center}
|
||||
\include{danu}
|
||||
\include{evcontroller}
|
||||
\include{itc4}
|
||||
\include{histogram}
|
||||
\include{histsim}
|
||||
\include{sinqhmdriv}
|
||||
\include{nxdata}
|
||||
|
||||
|
||||
|
||||
\section{Helper Objects}
|
||||
This section describes helper objects which implement useful data
|
||||
structures or utilities.
|
||||
\include{varlog}
|
||||
\include{dynar}
|
||||
\include{costa}
|
||||
\include{stringdict}
|
||||
\include{splitter}
|
37
doc/programmer/programmer.tex
Normal file
37
doc/programmer/programmer.tex
Normal file
@ -0,0 +1,37 @@
|
||||
% Copyleft (c) 1997-2000 by Mark Koennecke at PSI, Switzerland.
|
||||
%
|
||||
%
|
||||
%
|
||||
|
||||
\documentclass[12pt]{report}
|
||||
\usepackage{epsf}
|
||||
\setlength{\oddsidemargin}{-.1in}
|
||||
\setlength{\evensidemargin}{0in}
|
||||
\setlength{\topmargin}{0in}
|
||||
\addtolength{\topmargin}{-\headheight}
|
||||
\addtolength{\topmargin}{-\headsep}
|
||||
\setlength{\textheight}{8.9in}
|
||||
\setlength{\textwidth}{6.2in}
|
||||
\setlength{\marginparwidth}{0.5in}
|
||||
|
||||
\begin{document}
|
||||
\title{The SICS Programmers Reference}
|
||||
|
||||
\author{Mark K\"onnecke\\
|
||||
Labor f\"ur Neutronenstreuung\\
|
||||
Paul Scherrer Institut\\
|
||||
CH-5232 Villigen PSI\\
|
||||
Switzerland\\
|
||||
Mark.Koennecke@psi.ch \\
|
||||
}
|
||||
|
||||
|
||||
\maketitle
|
||||
\tableofcontents
|
||||
\include{overview}
|
||||
\include{proto}
|
||||
\include{kernelguide}
|
||||
\include{oguide}
|
||||
|
||||
|
||||
\end{document}
|
61
doc/programmer/proto.tex
Normal file
61
doc/programmer/proto.tex
Normal file
@ -0,0 +1,61 @@
|
||||
\chapter{The SICS Server Client Protocol}
|
||||
This short chapter describes the command protocol between the SICS server
|
||||
and possible SICS clients. All this is very simple.
|
||||
|
||||
\section{Logging in to the SICS Server}
|
||||
In order to log in to the SICS server it needs to be known on which
|
||||
machine the server runs and at which port number the server listens for
|
||||
connection requests. Also needed is a valid username/ password pair for the
|
||||
SICS server in question. Given that the procedure for connecting to a SICS
|
||||
server requires the following steps:
|
||||
\begin{enumerate}
|
||||
\item Open a TCP/IP connection to the SICS server port at the machine
|
||||
where it is running.
|
||||
\item Immediately after opening the connection send the username/password
|
||||
pair. If everything is OK, a string OK is sent. Else the server will break
|
||||
the connection again.
|
||||
\end{enumerate}
|
||||
|
||||
\section{Sending Commands}
|
||||
After login, two means of communications exist. The communication
|
||||
protocoll is choosen through the server port the client connects too.
|
||||
The recommended way is
|
||||
to adhere to the telnet protocoll as described in RFC-854. Just a
|
||||
basic NVT (Network Virtual Terminal) with no options is
|
||||
implemented. Binary communication is not possible on a telnet port.
|
||||
|
||||
The older way of communication is to send commands directly on the
|
||||
TCP/IP port. Commands are strings terminated by a \verb+\n+. Return
|
||||
messages from the server have the same format. This scheme is
|
||||
obsolete but it has been left in because the need for a binary
|
||||
communication may arise and this would help implement such a thing.
|
||||
|
||||
|
||||
|
||||
For a list of possible commands consult the
|
||||
user documentation.
|
||||
|
||||
\section{Issuing Interrupts}
|
||||
In some cases a user might want to stop the operation of the server. In
|
||||
order to do this the client must send an interrupt to the SICS server. There
|
||||
are two ways to do this: through the normal connection socket and through
|
||||
the a special UDP message to the server. Let us first discuss the first
|
||||
method, which uses the normal command socket for sending an interrupt.
|
||||
|
||||
In order to send an interrupt through the normal command socket a special
|
||||
message must be sent, consisting of a special command string. The command
|
||||
string is again all ASCII. The first part of this command string must read:
|
||||
INT1712, followed by a number denoting the interrupt. The meaning of these
|
||||
numbers is resolved in file interrupt.h. For example, the string 'INT1712 2'
|
||||
will abort the current scan. The presence of an interrupt string will be
|
||||
checked for already by the network reader. This means that such interrupts
|
||||
will even be honored when the client connection is waiting for some hardware
|
||||
to finish its job and would not accept normal commands. \label{prot1}
|
||||
|
||||
The SICS server also checks a special TCP/IP port for UDP messages which
|
||||
denote an interrupt. In order to send an interrupt through this channel, a
|
||||
UDP connection to the SICS servers UDP port must be opened. Then an special
|
||||
ASCII string of the form: {\bf SICSINT num} must be sent. num must be
|
||||
replaced by the number of the interrupt to issue. Again interrupt codes are
|
||||
resolved in file interrupt.h.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user