This section describes how to write a device support module. Device support modules are built into shared object libraries that can be dynamically loaded into the readout software via the load command.
The device support package is provided as a template driver source file and a Makefile that builds the shared object. If the DAQ software is installed in $DAQROOT, the following commands copy the template driver and its makefile:
Example 5-4. Obtaining the ccusb driver development kit
cp $DAQROOT/ccusbdriver/drivertemplate.cpp . cp $DAQROOT/ccusbdriver/Makefile .
The example below shows how to load a user written driver and use the driver that is created by an unmodified driver template:
Example 5-5. Using a user written CCUSB driver
set here [file nativename [file dirname [info script]]] load [file join $here libtemplatedriver.so] changeme create testing -value 0x1234
The example assumes that you have built the driver in the same directory as your configuration file. The first example line computes the full file path to the configuration file's directory. The second loads the driver, joining that path to the name of the shared object created by the Makefile. Note that you typically will need to provide a full path to the driver shared object or the load command will claim the file cannot be located. The final command creates and configures a device instance named testing using the changeme command the unmodified driver creates.
Let's look at the template driver you copied.
The template consists of two main chunks. The first chunk is a
class derived from
CReadoutHardware that is
responsible for managing the driver itself. You will normally
need to modify the
methods of this class, as well as changing the class name to something
more reasonable than
The second chunk is a Tcl package initialization function that must define the Tcl command that is associated twith the driver.
While the driver template is heavily commented, and modification points are indicated, the next few sections are a guided tour of the main sections you will need to modify.
Each driver instance has a configuration database attached to it when it is created. The configuration database holds configuration parameter definitions and their current values. The framework takes care of managing the values for you, however you must define the set of configuration parameters supported by your driver.
The template driver's code is (comments removed for brevity:
onAttachneeds to be able to access its configuration in other methods. The
configurationparameter is a reference to that configuration. This line saves a pointer to that configuration in the
m_pConfigurationmember variable. Note that a
CReadoutModuleis derived from a
CConfigurableObjectand that base class holds the configuration.
This code is provided by the driver template.
This code is provided by the driver template.
This line is provided by the template driver but normally is removed as you edit the code to define the configuration options you actually need.
onAttach method is simply
defining the set of configuration parameters it needs to know
how to initialize and read the device it manages. Configuration
parameters are named items (by convention the names start with the
dash character) and are strongly typed. Integer, real, string,
enumerated, and boolean simple parameters are supported. In
addtion collection (Tcl lists) are supported.
Parameter values can have constraints placed on them (the
-slot parameter values e.g.) which
are checked by the configuration subsystem without any intervention
by you. Several pre-defined constraint checkers are available,
as are convenience functions for defining configuration parameters.
You can also define custom constraint checkers and register them
with the configuration subsystem.
See CConfigurableObject(3ccusb) for detailed information about how to define configuration parameters.
Initialize method of each
device instance that has been put in a stack is called
after the configuration file is processed prior to loading
the stack and prior to turning on data taking mode in the
Initialize you must:
Fetch the configuration parameters you need to know how to initialize the device and prepare it for data taking.
Issue method calls to the
CCCUSB object passed in to the
method. Note that if your device requires a lot of
initialization, you can speed up that process
objects, which are lists of instructions, using
its methods to create a list of operatinos and then
asking the controller to execute that list.
The template driver provides the following code (most comments removed for brevity).
-slotconfiguration parameter from the configuration database for this module.
controllerobject to manipulate the CAMAC crate. If initialization requires a large number of CAMAC operations you could also create a
CCCUSBReadoutList, manipulate it to store a set of operatiuons and then use
controller.executeList(3ccusb)to execute that list.
addReadoutList is called as a run is
being intialized. This method is expected to contribute items
CCCUSBRedoutList that will be
loaded into either a scaler or event stack. Usuall this is done
by fetching the set of configuration parameters that are required
to know how to read the device and then invoking appropriate
methods on the
list parameter to
add CAMAC operations to the stack.
The template driver implements a marker 'device'. The marker
device ignores its
-slot configuration parameter
(a production quality marker driver would probably not define
-slot parameter). It adds an instrution
list that inserts a literal
value into the event. The value inserted is determined by
Here's the sample driver code for the
-valuecofiguration parameter. This is the value that we are going to insert into the event buffer
addMarkermethod adds the CCUSB instructions to insert a literal value in the output buffer to the list being built up. This therefore instructs the CCUSB that the readout of this 'device' consists of inserting the value of the
Naturally a real device would add NAF instructions or
Q-Stop/C-Scan operations to the list via other
The Tcl load command searches the shared object for a specific function entry point that it will call to initialize the library. The initialization function must follow the correct naming conventions or Tcl will complain about not being able to find the library's initialization function.
The initialization entry point must be the name of the
resulting library with the lib prefix stripped
off and the first letter capitalized suffixed by _Init.
Thus if you are building
libmydriver.so, the initialation function
must be called
The template driver provides the following code:
addDriverfunction associates a template device driver object with its Tcl command ensemble name. The template device driver object is cloned for each create subcommand issued for this driver in the configuration script. You should change both the name of the driver command from changeme and you should have previously changted the class name of the driver class from