camp_addInterface.html
CAMP Software Manager Note: Adding a New Interface Type to the CAMP Server
Ted Whidden, Dec. 23, 1999A 12 Step Program
1. Define the definition string
All CAMP instrument types have an associated definition string. The string has a different format for each, and contains all of the parameters necessary for configuration of the run-time use of an interface. A character string was chosen as the internal representation of the definition for maximum parallelism between interface types (rather than having a separate data structure for each). The definition strings for the current implemented interface types are as follows:
- RS232 interface definition:
"port baud databits parity stopbits readTerm writeTerm timeout"
, for example"/tyCo/1 9600 8 none 1 CRLF CRLF 3"
- GPIB interface definition:
"address readTerminator writeTerminator"
, for example"12 LF LF"
- CAMAC interface definition:
"B C N"
, for example"0 0 0"
The interface definition string for a new interface type must describe everything necessary for defining and differentiating instances of an interface. Note that in the present implementation the parameters are delimited by spaces.
2. Routines to parse the definition string
Various CAMP routines, in the server and client programs, will need to regularly
parse the definition string for its component parameters. These routines are
localized in the file camp_if_utils.c
. The routines are very short,
each one locating a parameter in the definition string and returning its value,
either as an integer as the function return value, or in a string that is passed
to the function (as appropriate). Create a routine for extracting each parameter
in the new definition string, following the examples for RS232, GPIB and CAMAC.
3. Make the Tcl interpreter aware of the new type
In camp_tcl.c
in the routine camp_tcl_sys
there is
a case statement SYS_ADDIFTYPE
. This processes the Tcl command
sysAddIfType
which is used to add all of the available interface
types at system startup. The information about interface types is stored in
the CAMP server system database.
This command must be aware of your new interface type.
In the "if( streq( argv[1],"
statement in SYS_ADDIFTYPE
,
add a new "else if"
statement for your new instrument, making it
similar to the entries for RS232, GPIB and CAMAC. You must choose a string identifier
for your type (e.g., camac
) an integer identifier for the type
(e.g., CAMP_IF_TYPE_CAMAC
), names of the four interface processing
routines (e.g., if_camac_online
, etc.), and the name of the initialization
routine (e.g., if_camac_init
).
4. Add the integer identifier to camp.h
The integer identifier chosen in Step 3 must be given a value in the camp.h
include file. Find the definition enum CAMP_IF_TYPE
and add an
entry for your new interface type (e.g., CAMP_IF_TYPE_CAMAC
). Give it
a unique value and be careful of the placement of commas in the enum.
5. Write the interface processing routines
Create a new file to define the interface processing routines. You can
start with one of the files for another instrument type (camp_if_rs232*.c
,
camp_if_gpib*.c
, camp_if_camac*.c
) as a template.
Name the following using the same string identifier chosen in Step 3 for consistency.
You must define the routines already referred to in Step 3 here. These include:
if_*_init
Routine to process when an instrument with this interface is newly added. Be sure to use the same interface type identifier string in the call tocamp_ifGetpIF_t
as you chose in Step 3.if_*_online
Routine to process when an interface is turned online at the hardware level. This will be called, for example, by the CAMP Tcl commandinsIfOn
. Note that this routine does not call the "-onlineProc" in the instrument's Tcl driver. Instead, it should do direct hardware related tasks only.if_*_offline
Routine to process when an interface is turned offline at the hardware level. This will be called, for example, by the CAMP Tcl commandinsIfOff
. Note that this routine does not call the "-offlineProc" in the instrument's Tcl driver. Instead, it should do direct hardware related tasks only.if_*_read
Routine to process when an interface is requested for perform a read operation. This will be called, for example, by the CAMP Tcl commandinsIfRead
. Note that this routine does not call a variable's "-readProc" in the instrument's Tcl driver. Instead, it should do direct hardware related tasks only.if_*_write
Routine to process when an interface is requested for perform a write operation. This will be called, for example, by the CAMP Tcl commandinsIfWrite
. Note that this routine does not call a variable's "-writeProc" in the instrument's Tcl driver. Instead, it should do direct hardware related tasks only.
Notes:
- You must use the same calling parameters as in the example routines. The
routines are called generically in
camp_if_priv.c
and are expected to have the same calling parameters. - You must return a valid CAMP status integer from all routines:
CAMP_SUCCESS
on success andCAMP_FAILURE
(or others) on failure. - All of these routines are called with the CAMP global lock (mutual exclusion
semaphore) ON. It is often efficient for the CAMP server to release the global
lock during operations that involve relatively long waiting periods. Otherwise,
the CAMP server will be completely locked during the processing of one single
device I/O.
In some of the
camp_if_rs232*.c
andcamp_if_gpib*.c
files there are examples of how to release the lock using the combination ofthread_unlock_global_np()
andthread_lock_global_np()
. Be careful that the global lock is only released when it is safe (i.e., library calls made with the global lock OFF must be re-entrant). And, be sure to always use the two calls in combination, and always return from these routines with the global lock ON (as it was when it was called).
6. Optionally add Tcl commands to access interface parameters
It may be useful for a Tcl instrument driver to have easy access to interface
definition parameters. To do this, follow the example of other interface types
in camp_tcl.c
as follows.
- Find the
VAR_GETIFPROCS
enum incamp_tcl.c
and add values for each of your new routines. - Add the command names to the interpreter in
campTcl_CreateInterp
, for example,Tcl_CreateCommand( interp, "insGetIfCamacB", camp_tcl_varGetIfCamac, (ClientData)INS_CAMP_IF_CAMAC_B, NULL );
- Add a Tcl processing routine to process the commands
(e.g.,
camp_tcl_varGetIfCamac
) - In the processing routine use a
switch
case statement to determine which command has been called, and return the appropriate string parameter using the parsing routines written in Step 2.
7. Make the Tcl command "insIfSet -if" aware of the new type
In camp_tcl.c
in the routine camp_tcl_ins
there is
a case statement TOK_OPT_IF_SET
. This processes the command
insIfSet -if
.
Add an entry in the "switch( pIF_t->typeID )"
statement for your
new interface type, following the examples. Since interfaces are defined by
a single string, the only thing unique about your interface type here is the
number of space-delimited parameters within the string (e.g., 8 for RS232, 3
for GPIB and 3 for CAMAC).
8. Make the Tcl command "insIfSet -if_mod" aware of the new type
In camp_tcl.c
in the routine camp_tcl_ins
there is
a case statement TOK_OPT_IF_MOD
. This processes the command
insIfSet -if_mod
.
Add an entry in the "switch( pIF_t->typeID )"
statement for your
new interface type, following the examples. The insIfSet -if_mod
if intended to allow the dynamic change of a subset of the definition string.
You may decide to add something meaningful here, but in practice this command
is seldom used.
9. Make the CAMP CUI aware of the new type
The CAMP CUI needs interface specific information to be able to prompt users for
input and display the current settings.
There are three files for the CAMP CUI that contain interface specific
information: camp_cui_data.c
, camp_cui_varinfo.c
,
and camp_cui_if.c
.
- In
camp_cui_data.c
, find the statement"switch( pIns->pIF->typeID )"
in the routinedisplayVar
. This routine displays interface definition information in a full screen information page for an instrument. Add an entry for your new interface type. Display the appropriate information using the curses library calls following the other examples. - In
camp_cui_varinfo.c
, find the statement"switch( pIns->pIF->typeID )"
in the routinedisplayVarInfoWin
. This routine displays interface definition information in the variable infomation window (the window on the right side of the CUI) for an instrument. Add an entry for your new interface type. Display the appropriate information using the curses library calls following the other examples. - In
camp_cui_if.c
, find the statement"switch( pIF_t->typeID )"
in the routineinputIf
. Add an entry for your new interface type which calls a new routine namedinputIf_*
with two string parameters. The two string parameters are a default definition string (defined with thesysAddIfType
command in the server at startup) and a string to return the newly defined interface definition. Add the routineinputIf_*
tocamp_cui_if.c
, following the examples for the other interface types. This routine must prompt for all interface parameters.
10. Optionally add prototypes
You may like to add prototypes for the newly created routines. Prototypes
for the routines added to camp_if_utils.c
in Step 2
go in camp.h
.
Prototypes for routines added to camp_if_*.c
in Step 5
go in camp_srv.h
.
Prototypes for routines added to camp_cui_if.c
in Step 9 go in
camp_clnt.h
.
11. Update the Makefile/descrip.mms
Update the Unix and VMS makefiles to include the new file created in Step 5.
12. Update the camp.ini
initialization file
Add appropriate sysAddIfType
entries for your new interface
type in the CAMP initialization file camp.ini
.
The first parameter is the string identifier for the interface type chosen in Step 3.
The second parameter is a configuration parameter which may be used as
needed. For instance, for RS232 interfaces this configuration parameter
is a list of available ports that is used by the CAMP CUI to prompt users
for a selection (see camp_cui_if.c
for how this is done -
look for the variable pIF_t->conf
).
In the GPIB DELTAT implementation it is a list of
interface specific parameters. This configuration string may be used
in the if_*_init
routine to define interface specific settings
(see the example in camp_if_gpib_deltat.c
to see how this
might be done - look for the variable pIF_t->conf
).
The third parameter is a default interface definition string. This is used mainly so that users can be prompted with meaningful information in the CAMP CUI when adding an instrument. It is, however, usually superseded by a default definition in the Tcl instrument driver when the instrument is added.
That's all folks!
whidden@tao.ca, Consultant to TRIUMF Data Acquisition Group