From: <ro...@us...> - 2013-04-29 19:23:49
|
Revision: 3077 http://sourceforge.net/p/nscldaq/code/3077 Author: ron-fox Date: 2013-04-29 19:23:43 +0000 (Mon, 29 Apr 2013) Log Message: ----------- Get the docs to match the current data. Modified Paths: -------------- branches/nscldaq-11.0-development/sbs/readout/SBSReadout.xml branches/nscldaq-11.0-development/usb/ccusb/ccusb.xml branches/nscldaq-11.0-development/usb/vmusb/vmusbReadout.xml Modified: branches/nscldaq-11.0-development/sbs/readout/SBSReadout.xml =================================================================== --- branches/nscldaq-11.0-development/sbs/readout/SBSReadout.xml 2013-04-29 17:21:58 UTC (rev 3076) +++ branches/nscldaq-11.0-development/sbs/readout/SBSReadout.xml 2013-04-29 19:23:43 UTC (rev 3077) @@ -157,6 +157,15 @@ available. On return, the actual number of 16 bit words read should be returned. </para> + <para> + If your Readout is participating in distributed event + building your <methodname>read</methodname> method + must provide the event timestamp and, may optionally, + provide the source id associated with the event. + If not provided, the source id is taken from + value of othe <option>--sourceid</option> command + line option. + </para> </listitem> </varlistentry> </variablelist> @@ -2068,8 +2077,8 @@ <type>size_t</type> <parameter>maxwords</parameter> </methodparam> </methodsynopsis> + - </classsynopsis> </refsynopsisdiv> <refsect1> @@ -2174,6 +2183,8 @@ </programlisting> <synopsis> class <ooclass><classname>CEventSegment</classname></ooclass> { + </synopsis> + <programlisting> <methodsynopsis> <modifier>virtual</modifier> <type>void</type> <methodname>initialize</methodname> @@ -2222,8 +2233,21 @@ <type>CEventSegment::AcceptState</type><methodname>getAcceptState</methodname> <void /> <modifier>const</modifier> </methodsynopsis> + <methodsynopsis> + <type>void</type><methodname>setTimestamp</methodname> + <methodparam> + <type>uint64_t</type><parameter>stamp</parameter> + </methodparam> + </methodsynopsis> + <methodsynopsis> + <type>void</type><methodname>setSourceId</methodname> + <methodparam> + <type>uint32_tr</type><parameter>id</parameter> + </methodparam> + </methodsynopsis> + }; - </synopsis> + </programlisting> </refsynopsisdiv> <refsect1> <title>DESCRIPTION</title> @@ -2344,6 +2368,29 @@ to determine if the event has been marked for rejection by another event segment. </para> + <methodsynopsis> + <type>void</type><methodname>setTimestamp</methodname> + <methodparam> + <type>uint64_t</type><parameter>stamp</parameter> + </methodparam> + </methodsynopsis> + <para> + This should be called from the <methodname>read</methodname> method + of at least one event segmetn when Readout is a data source for + event building. The method sets the event timestamp. If called + more than once, the last call in the event readout specifies the time. + </para> + <methodsynopsis> + <type>void</type><methodname>setSourceId</methodname> + <methodparam> + <type>uint32_tr</type><parameter>id</parameter> + </methodparam> + </methodsynopsis> + <para> + Called by an event segment to set the source id. Normally + this is set at the command line via the <option>--sourceid</option> + option. + </para> </refsect1> <refsect1> <title>PUBLIC TYPES AND VARIABLES</title> @@ -4118,10 +4165,22 @@ </listitem> </varlistentry> <varlistentry> + <term><option>--sourceid</option>=<replaceable>value</replaceable></term> + <listitem> + <para> + Sets the default source id for events that have timestamps. + Events without timestamp have an abbreviated body header. + A call to <methodname>setSourceId</methodname> from within the + event processor overrides the value of this switch for this + event only. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>--help</option></term> <listitem> <para> - Outputs a summary of the command lineo ptions and exits without + Outputs a summary of the command line options and exits without doing anything else useful. </para> </listitem> Modified: branches/nscldaq-11.0-development/usb/ccusb/ccusb.xml =================================================================== --- branches/nscldaq-11.0-development/usb/ccusb/ccusb.xml 2013-04-29 17:21:58 UTC (rev 3076) +++ branches/nscldaq-11.0-development/usb/ccusb/ccusb.xml 2013-04-29 19:23:43 UTC (rev 3077) @@ -1,11447 +1,11484 @@ -<!-- chapter frameworks --> -<chapter> - <title>CCUSB Readout framework</title> - <para> - The CCUSB Readout framework provides support for the Wiener-JTec - CC-USB CAMAC controller. The CC-USB is a USB CAMAC controller that - uses a Xilinx gate array to implement a CAMAC list processor. - The CCUSB Readout framework provides: - </para> - <itemizedlist> - <listitem><para> - A high level approach to the problem of data taking with the CC-USB - </para></listitem> - <listitem><para> - Support for user written device support without any need to - understand the format of list operations supported by the CC-USB. - Drivers can be written in either C++ or in object oriented extensions - to Tcl. - </para></listitem> - <listitem> - <para> - Direct insertion of data taken to an arbitrary destination - ringbuffer. - </para> - </listitem> - </itemizedlist> - <para> - This Chapter provides overview information that describes - </para> - <itemizedlist> - <listitem> - <para> - The philosophy behind the CCUSB readout framework. - </para> - </listitem> - <listitem> - <para> - How to write configuration files for the CCUSB readout - framework. - </para> - </listitem> - <listitem> - <para> - How to write device support modules in in C++ and incorpoprate - those modules into the - CCUSB readout framework - </para> - </listitem> - <listitem> - <para> - How to write device support moduels in Tcl and incorporate - those modules in the CCUSB readout framework. - </para> - </listitem> - <listitem> - <para> - How the slow controls framework operates. - </para> - </listitem> - </itemizedlist> - <para> - Reference information is available in the <literal>3ccusb</literal> - section of the referencae material. - </para> - <section> - <title>How the CCUSB readout framework works</title> - <para> - The CCUSB readout framework provides a high level approach to - configuring devices supported by the system. A plugin architecture - allows user written device support to be incorporated into - the framework at run-time. - </para> - <para> - The framework supports both data taking devices and slow control - devices that may require a control panel. Naturally you can - support relatively static slow control devices by using the - data taking device support as well. - </para> - <para> - The recurring concepts for both the data taking device support - and slow controls device support are: - </para> - <itemizedlist> - <listitem> - <para> - A Tcl configuration file describes the devices used - by the experiment. - </para> - </listitem> - <listitem> - <para> - Each supported device class is represented in the - configuration file by a Tcl command ensemble. The - command ensemble provides subcommands that allow you to - create, configure and query the configuration of - physical devices (device instances). - </para> - </listitem> - <listitem> - <para> - The device configuration is represented in the configuration - file in manner analagous to the state of a Tk widget. - That is, you never actually program the device directly, - you simply specify the desired configuration. The actual - programming is done by the device class's device support - software. - </para> - </listitem> - <listitem> - <para> - In accordance with the way the CC-USB operates, you can create - two lists or <firstterm>stack</firstterm>s in CC-USB parlance. - One stack is an event stack and is intended to be used - to handle event triggers. The second stack is a scaler stack - and typically is set to readout periodically. - </para> - <para> - Each stack has, configuration properties as well. One - configuration property is the set of modules managed - by that stack. Modules managed by that stack are initialized - by the software, in accordance with their configuration, - and contribute to the readout list that executes in response - to that stack's trigger. - </para> - </listitem> - </itemizedlist> - - </section> - <section> - <title>Writing DAQ configuration files</title> - <para> - The DAQ configuration file is processed at the beginning of each run. - The configuration file is processed in a fresh interpreter each time. - You therefore cannot maintain any state across runs via your configuration - file. - </para> - <para> - To illustrate module creation and configuration, - this let's look at a fragment from a configuration - file: - </para> - <example> - <title>Creating and configuring devices</title> - <programlisting> -ph7xxx create tdc -slot 13 -id 0x7186 -sparse false -ph7xxx config tdc -readhits true -usellt false -usehlt false - </programlisting> - </example> - <para> - The ph7xxx driver supports the Phillips 7xxx series - CAMAC 16 channel digitizers. The <command>ph7xxx</command> command is the Tcl - command this driver recognizes. The <command>create</command> - subcommand creates a new device instance and names it <literal>tdc</literal>. - When you create a module any addition command words following the - device name are interpreted as configuration options. - In this case, the module is configured to be in slot 13, - the driver is configured to emit a literal value (<option>-id</option>) - <literal>0x7186</literal> prior to data from the device. - The module is also configured to read all channels - (<option>-sparse</option> <literal>false</literal>). - </para> - <para> - The <command>config</command> subcommand allows you to further - configure the options of a device instance. The second line - of the example continues specifying the configuration of the - device named <literal>tdc</literal>. The configuration parameters - on that line request the driver to read the hit pattern register - (<option>-readhits</option> <literal>true</literal>), to not - enable either the lower level threshold or the upler level threshold - (<option>-usellt</option> and <option>usehlt</option>). - </para> - <para> - The reference section <literal>3ccusb</literal> provides detailed - information that describes each supported device and the - configuration options it supports. - </para> - <para> - Configuration files must also specify at least one stack and, if - scaler modules are to be read periodically, a second scaler stack. - See the <xref linkend="ccusb3-stack" /> command - in the reference material for detailed information about how - to create and configure stacks. - </para> - <para> - To continue with the previous example: - </para> - <example> - <title>Configuring an event stack</title> - <programlisting> -stack create events -stack config events -modules [list tdc] -type event -delay 108 - </programlisting> - </example> - <para> - Stacks are created and configured exactly like any other module. - In this configuration file fragment, a stack named - <literal>events</literal> is created. It is configured to - manage the <literal>tdc</literal> module (<option>-modules</option>). - It is configured as the event stack (<option>-type</option>) which, - by default is triggered by a nim pulse in the <literal>IN1</literal> - input of the module. The <option>-delay </option> parameter - specifies a delay of 108usec between the trigger input and stack - execution. This capability is provided to allow the digitizers - in the stack time to convert. - </para> - <para> - Finally here's a configuration file fragment that sets up an - LRS 2551 scaler and the scaler stack: - </para> - <example> - <title>Setting up a scaler stack</title> - <programlisting> - -lrs2551 create counters -slot 5 -stack create scaler -stack config scaler -type scaler -period 2 -modules [list counters] - - </programlisting> - </example> - </section> - <section> - <title>Writing device support software</title> - <para> - 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 <command>load</command> command. - </para> - <para> - 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: - </para> - <example> - <title>Obtaining the ccusb driver development kit</title> - <programlisting> -<command>cp $DAQROOT/ccusbdriver/drivertemplate.cpp .</command> -<command>cp $DAQROOT/ccusbdriver/Makefile .</command> - </programlisting> - </example> - <para> - The example below shows how to load a user written driver - and use the driver that is created by an unmodified driver template: - </para> - <example> - <title>Using a user written CCUSB driver</title> - <programlisting> -set here [file nativename [file dirname [info script]]] -load [file join $here libtemplatedriver.so] -changeme create testing -value 0x1234 - </programlisting> - </example> - <para> - 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 - <command>load</command> command will claim the file cannot be located. - The final command creates and configures a device instance - named <literal>testing</literal> using the <command>changeme</command> - command the unmodified driver creates. - </para> - <para> - Let's look at the template driver you copied. - The template consists of two main chunks. The first chunk is a - class derived from <classname>CReadoutHardware</classname> that is - responsible for managing the driver itself. You will normally - need to modify the <methodname>onAttach</methodname>, - <methodname>Initialize</methodname> and <methodname>addReadoutList</methodname> - methods of this class, as well as changing the class name to something - more reasonable than <classname>CTemplateDriver</classname>. - </para> - <para> - The second chunk is a Tcl package initialization function that - must define the Tcl command that is associated twith the driver. - </para> - <para> - 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. - </para> - <section> - <title>The driver onAttach method</title> - <para> - 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. - </para> - <para> - The template driver's code is (comments removed for brevity: - </para> - <informalexample> - <programlisting> -void -CTemplateDriver::onAttach(CReadoutModule& configuration) -{ - m_pConfiguration = &configuration; <co id='ccusb-dtemplate-saveconfig' /> - m_pConfiguration->addIntegerParameter("-slot", 1, 23, 1); <co id='ccusb-dtemplate-slotparam' /> - - m_pConfiguration->addIntegerParameter("-value"); // default is 0. <co id='ccusb-dtemplate-valueparam' /> -} - </programlisting> - </informalexample> - <calloutlist> - <callout arearefs='ccusb-dtemplate-saveconfig'> - <para> - <methodname>onAttach</methodname> needs to be able - to access its configuration in other methods. - The <parameter>configuration</parameter> parameter is - a reference to that configuration. This line - saves a pointer to that configuration in the - <varname>m_pConfiguration</varname> member variable. - Note that a <classname>CReadoutModule</classname> - is derived from a <classname>CConfigurableObject</classname> - and that base class holds the configuration. - </para> - <para> - This code is provided by the driver template. - </para> - </callout> - <callout arearefs='ccusb-dtemplate-slotparam'> - <para> - Virtually all of the device support you write will - need to know which slot in the CAMAC crate contains - your module. This line creates an integer - parameter constrained to lie in the range - <literal>[1..23]</literal> named <literal>-slot</literal>. - The default value (if the user does not configure - this item) is <literal>1</literal> (the last parameter - of the <methodname>addIntegerParameter</methodname> call). - </para> - <para> - This code is provided by the driver template. - </para> - </callout> - <callout arearefs='ccusb-dtemplate-valueparam'> - <para> - This sample line shows how to create an unconstrained - integer parameter named <literal>-value</literal>. - The configuration subsystem will ensure the value - is a valid integer but will not contrain the range - of that integer. - </para> - <para> - 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. - </para> - </callout> - </calloutlist> - <para> - Normally the <methodname>onAttach</methodname> 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. - </para> - <para> - Parameter values can have constraints placed on them (the - range of <option>-slot</option> 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. - </para> - <para> - See <xref linkend='ccusb3-CConfigurableObject' /> for - detailed information about how to define configuration - parameters. - </para> - </section> - <section> - <title>The driver Initialize method</title> - <para> - The <methodname>Initialize</methodname> 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 - CC-USB. - </para> - <para> - Typically in <methodname>Initialize</methodname> you must: - <orderedlist> - <listitem> - <para> - Fetch the configuration parameters you need - to know how to initialize the device and prepare - it for data taking. - </para> - </listitem> - <listitem> - <para> - Issue method calls to the <parameter>controller</parameter> - <classname>CCCUSB</classname> object passed in to the - method. Note that if your device requires a lot of - initialization, you can speed up that process - by creating <classname>CCCUSBReadoutList</classname> - objects, which are lists of instructions, using - its methods to create a list of operatinos and then - asking the controller to execute that list. - </para> - </listitem> - </orderedlist> - </para> - <para> - For detailed information about the methods supported by - the <classname>CCCUSB</classname> and <classname>CCCUSBReadoutList</classname>, - see <xref linkend='ccusb3-CCCUSB' /> and <xref linkend='ccusb3-CCCUSBReadoutList' /> - </para> - <para> - The template driver provides the following code (most - comments removed for brevity). - </para> - <informalexample> - <programlisting> -void -CTemplateDriver::Initialize(CCCUSB& controller) -{ - - int slot = m_pConfiguration->getIntegerParameter("-slot"); <co id='ccusb-dtemplate-init1' /> - - /* MODIFY ME HERE */ - <co id='ccusb-dtemplate-init2' /> - /* END MODIFICATIONS */ - -} - - - </programlisting> - </informalexample> - <calloutlist> - <callout arearefs='ccusb-dtemplate-init1'> - <para> - In most cases you need the slot number of the module - to initialize it. This call obtains the value of the - <option>-slot</option> configuration parameter - from the configuration database for this module. - </para> - </callout> - <callout arearefs='ccusb-dtemplate-init2'> - <para> - You would add code here to fetch parameter values - as well as method calls for the <parameter>controller</parameter> - object to manipulate the CAMAC crate. If initialization - requires a large number of CAMAC operations you could - also create a <classname>CCCUSBReadoutList</classname>, - manipulate it to store a set of operatiuons and then - use <parameter>controller.executeList(3ccusb)</parameter> to - execute that list. - </para> - </callout> - </calloutlist> - </section> - <section> - <title>The driver addReadoutList method</title> - <para> - <methodname>addReadoutList</methodname> is called as a run is - being intialized. This method is expected to contribute items - to the <classname>CCCUSBRedoutList</classname> 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 <parameter>list</parameter> parameter to - add CAMAC operations to the stack. - </para> - <para> - The template driver implements a marker 'device'. The marker - device ignores its <option>-slot</option> configuration parameter - (a production quality marker driver would probably not define - a <option>-slot</option> parameter). It adds an instrution - to the <parameter>list</parameter> that inserts a literal - value into the event. The value inserted is determined by - the <option>-value</option> parameter. - </para> - <para> - Here's the sample driver code for the <methodname>addReadoutList</methodname> - method: - </para> - <informalexample> - <programlisting> -void -CTemplateDriver::addReadoutList(CCCUSBReadoutList& list) -{ - int slot = m_pConfiguration->getIntegerParameter("-slot"); - - /* MODIFY ME HERE */ - - int value = m_pConfiguration->getIntegerParameter("-value"); <co id='ccusb-dtemplate-read1' /> - list.addMarker(value); // This is a longword marker. <co id='ccusb-dtemplate-read2' /> - - /* END MODIFICATIONS */ -} - - </programlisting> - </informalexample> - <calloutlist> - <callout arearefs='ccusb-dtemplate-read1'> - <para> - This line fetches the <option>-value</option> - cofiguration parameter. This is the value - that we are going to insert into the event buffer - </para> - </callout> - <callout arearefs='ccusb-dtemplate-read2'> - <para> - The <methodname>addMarker</methodname> method 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 - <option>-value</option> configuration parameter. - </para> - <para> - Naturally a real device would add NAF instructions or - Q-Stop/C-Scan operations to the list via other - <classname>CCCUSBReadoutList</classname> methods. - </para> - </callout> - </calloutlist> - </section> - <section> - <title>Initializing the driver with the framework.</title> - <para> - The Tcl <command>load</command> 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. - </para> - <para> - The initialization entry point must be the name of the - resulting library with the <literal>lib</literal> prefix stripped - off and the first letter capitalized suffixed by <literal>_Init</literal>. - Thus if you are building - <filename>libmydriver.so</filename>, the initialation function - must be called <function>Mydriver_Init</function>. - </para> - <para> - The template driver provides the following code: - </para> - <informalexample> - <programlisting> -extern "C" { <co id='ccusb-dtemplate-dinit1' /> - int Templatedriver_Init(Tcl_Interp* pInterp) <co id='ccusb-dtemplate-dinit2' /> - { - Tcl_PkgProvide(pInterp, "Templatedriver", "1.0"); <co id='ccusb-dtemplate-dinit3' /> - - CUserCommand::addDriver("changeme", new CTemplateDriver); <co id='ccusb-dtemplate-dinit4' /> - - return TCL_OK; <co id='ccusb-dtemplate-dinit5' /> - - } -} - </programlisting> - </informalexample> - <calloutlist> - <callout arearefs='ccusb-dtemplate-dinit1' > - <para> - Since C++ <firstterm>decorates</firstterm> function names - with an encoding of the call signature, to support function - overloading, you must declare the initialization - functino using C linkage conventions. The - <literal>extern "C" {}</literal> creates a block of - code whose externally visible symbols will use C - linkage conventions. - </para> - </callout> - <callout arearefs='ccusb-dtemplate-dinit2'> - <para> - In general you will need to modify the name of this - to work with the name of the library file you - create. The discussion prior to this example - describes the naming conventions that are required. - </para> - </callout> - <callout arearefs='ccusb-dtemplate-dinit3'> - <para> - In our examples we used the Tcl <command>load</command> - command to load the driver. This statement registers - the library as providing a Tcl loadable package. - You can use the Tcl command <command>pkg_mkIndex</command> - to build an auto load index file for loadable packages - including those in shared libraries. This allows you - to collect several drivers into a directory added to the - auto load path, and use the <command>package require</command> - command to load them by package name. You must - change the name of the package in this call - to be something unique and descriptive of your driver. - </para> - </callout> - <callout arearefs='ccusb-dtemplate-dinit4'> - <para> - The <classname>CUserCommand</classname>::<methodname>addDriver</methodname> - function associates a template device driver object - with its Tcl command ensemble name. The template device driver - object is cloned for each <command>create</command> subcommand - issued for this driver in the configuration script. - You should change both the name of the driver command - from <literal>changeme</literal> and you should have - previously changted the class name of the - driver class from <classname>CTemplateDriverM</classname> - </para> - </callout> - <callout arearefs='ccusb-dtemplate-dinit5'> - <para> - If the library initialization was successful it - should return <literal>TCL_OK</literal> on failure - it shouild return <literal>TCL_ERROR</literal>. - In this case it is also customary to use - e.g. Tcl_SetResult or a similar function to set the - result of the load command to a descriptive error - message. - </para> - </callout> - </calloutlist> - </section> - </section> - <section> - <title>Tcl device driver support</title> - <para> - This section describes how to provide support for device drivers - as Tcl modules. The first subsection will describe in general - terms how to do this. The second and third subsections will show - sample drivers written in the snit and Incr-Tcl object oriented - extensions of Tcl along with sample fragments of DAQ configuration - files that show how to use these drivers. Note that while snit and - Incr-Tcl drivers are shown any Tcl object oriented extension can - probably be used as could a carefully crafted set of - <command>namespace ensemble</command> commands. - </para> - <section> - <title>Conceptual background</title> - <para> - If you have not read the section on writing C++ device drivers - you should at least skim it. Several of the concepts - are important. Specifically: - </para> - <itemizedlist> - <listitem> - <para> - A device support module provides a command that - generates device instances. - </para> - </listitem> - <listitem> - <para> - Device instances have to provide an - <methodname>Initialize</methodname> method that - initializes the device according to some configuration - of the instance. - </para> - </listitem> - <listitem> - <para> - Device instances have to provide a - <methodname>addReadoutList</methodname> method that - adds elements to the list of CAMAC operations - that are executed when the stack they live in - is triggered. - </para> - </listitem> - </itemizedlist> - <para> - All of this is a natural match to the way all of the object - oriented extensions to Tcl work. Specifically you write a - class like thing. Creating an instance of the class creates - a new Tcl command <firstterm>ensemble</firstterm>. The - public methods of the instance become sub commands of the - new Tcl command. - </para> - <para> - The CCUSB framework therefore provides a - mechanism, the <command>addtcldriver</command> command to - add an object instance command to the set of devices that - can be added to a stack. The <command>addtcldriver</command> - command registers the command name as a name of a device - that can be put in a stack. The command ensemble is also - wrapped in an actual driver that invokes - <methodname>Initialize</methodname>, and - <methodname>addReadoutList</methodname> - methods at the appropriate times. - </para> - <para> - The final piece of the puzzle is providing access to the - CCUSB and CCUSBReadout list capabilities to Tcl drivers. - This has been done by wrapping Tcl command ensembles around both - of those classes using SWIG - (see <ulink url='http://www.swig.org'>http://www.swig.org</ulink>). - </para> - <para> - As we will see when we work our way through sample drivers, - the C++ wrappers are not able to actually pass a SWIG wrapped - object to the driver methods. The driver must take the - swig pointer like parameter and turn it into a SWIG object - before it can be used. A Tcl fragment that shows how to - turn the CCCUSB pointer into a SWIG CCCUSB object is shown - below: - </para> - <informalexample> - <programlisting> -... -method Initialize ccusbPointer { - cccusb::CCCUSB c -this $ccusbPointer - ... -} -... - </programlisting> - </informalexample> - <para> - The example takes the <varname>ccusbPointer</varname> parameter - which must be a swig like pointer to a CCCUSB object and - turns it in to a swig object named <literal>c</literal> - which is a SWIG object representing the underlying CCCUSB - passed in to the <methodname>Initialize</methodname> method. - </para> - </section> - <section> - <title>A sample snit Tcl CCUSB framework driver</title> - <para> - This section will go through a sample snit driver describing - how it works. To see this driver incorporated in a DAQ - configuration file see - <xref linkend='ccusb-general-tcldriver-usage' />. - </para> - <para> - First a word or two about snit. Snit is a pure Tcl object - oriented framework for Tcl written by Will Duquette from - the Jet Propulsion Laboratory in Pasadena. - <ulink url='http://wiki.tcl.tk/3963'> - http://wiki.tcl.tk/3963</ulink> - provides access to documentation and examples of snit in action. - </para> - <para> - snit is part of the <literal>TclLib</literal> which is installed - on all systems at the NSCL. - </para> - <para> - Snit classes are created via the <command>snit::type</command> - command. Snit classes feature <command>method</command>s - which are analagous to member functions in C++ classes. - </para> - <para> - snit also - provides all types with a <command>configure</command> and - <command>cget</command> command and a mechanism for declaring - options that can be manipulated by these commands. Using this - capability allows you to configure snit device driver instances - in a manner analagous to the C++ driver instances supported - by the CCUSB framework. - </para> - <para> - Below is a complete implementation of a snit driver that, - at initialization time turns on the yellow LED and adds - a marker to the readout list. The marker value can be configured - via the instances built in configure subcommand. - </para> - <example> - <title>A snit CCUSB device driver module</title> - <programlisting> -lappend auto_path /usr/opt/daq/10.1/lib <co id='ccusb-snit-auto_path' /> - -package require snit -package require cccusb <co id='ccusb-snit-packages' /> -package require cccusbreadoutlist - - -snit::type marker-snit { <co id='ccusb-snit-type' /> - option -value 0 <co id='ccusb-snit-option' /> - - # - # Called when the run is being started. - # - # @param driverPtr - 'pointer' to the CCUSB object. - # - method Initialize driverPtr { <co id='ccusb-snit-Initializemethod' /> - - - cccusb::CCCUSB c -this $driverPtr; <co id='ccusb-snit-ccusbswigwrap' /> - - # Get the led programming now - # Yellow is the mask of FF0000 - # Clear out those bits and set that field to be 110000 which is source I3 and - # inverted. - - set leds [c readLedSelector] <co id='ccusb-snit-readleds' /> - set leds [expr {$leds & 0xffff}] - set leds [expr {$leds | 0x110000}] - c writeLedSelector $leds <co id='ccusb-snit-writeleds' /> - - } - # Called to contribute to the readout list - # - # @param list - 'pointer' to the CCCUSBReadoutList which will be wrapped in a - # swig wrapper. - # - method addReadoutList list { <co id='ccusb-snit-addReadoutListmethod' /> - - # - # Wrap the list so we can use it: - # - cccusbreadoutlist::CCCUSBReadoutList l -this $list; <co id='ccusb-snit-ccusbreadoutlist-swigwrap' /> - - l addMarker $options(-value) <co id='ccusb-snit-addmarker' /> - - } -} - - </programlisting> - </example> - <para> - The numbers in the explanations below refer to the corresponding - numbers in the example text. - </para> - <calloutlist> - <callout arearefs='ccusb-snit-auto_path'> - <para> - The SWIG Tcl wrappers for the CCUSB and CCUSBReadoutList - classes are installed in the <filename>lib</filename> - subdirectory of the NSCLDAQ installation. This - adds that directory for the 10.1 verssion of nslcdaq - to the package loads search path. This allows those - packages to be loaded via the <command>package require</command> - package. - </para> - </callout> - <callout arearefs='ccusb-snit-packages'> - <para> - Incorporates the following packages into the - driver, if they have not been loaded elsewhere: - </para> - <variablelist> - <varlistentry> - <term>snit</term> - <listitem><para> - The snit package. This implements the - object oriented framework this example uses. - </para></listitem> - </varlistentry> - <varlistentry> - <term>cccusb</term> - <listitem> - <para> - The swig wrapper for the - CCUSB C++ class. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>cccusbreadoutlist</term> - <listitem> - <para> - The swig wrapper for the CCCUSBReadoutList - C++ class. - </para> - </listitem> - </varlistentry> - </variablelist> - </callout> - <callout arearefs='ccusb-snit-type'> - <para> - The <command>snit::type</command> command - creates a new snit class like entity. The - type is named <command>marker-snit</command> and - the list of commands that follow define the - body of the class. This creates a new command - <command>marker-snit</command> primarly used to - construct instances of the type. - </para> - </callout> - <callout arearefs='ccusb-snit-option'> - <para> - Snit objects all have a set of options that are - modified via their built in - <command>configure</command> sub command and accessed - externally via their <command>cget</command> - built in sub command. - </para> - <para> - The <command>option</command> command within a snit - type body defines a configurable option - (<option>-value</option> in this case), and optionally - provides an initial value. - </para> - </callout> - <callout arearefs='ccusb-snit-Initializemethod'> - <para> - Instance subcommands are created via the - snit <command>method</command> command. This command - looks exactly like the <command>pro</command> command - except that methods generate subcommands. - </para> - <para> - The <methodname>Initialize</methodname> method must - be implemented by all device driver objecgt (do-nothing - implementations are fine). The parameter to this method - is a pointer like entity which points to a - <classname>CCCUSB</classname> object that communuicates - with the selected CAMAC crate. - </para> - <para> - The <methodname>Initialize</methodname> method is - invoke for all object instances that are added to stacks. - It is suposed to look at the configuration items and - do what is necessary to program the module it supports - to prepare to take data in the specified configuration. - </para> - </callout> - <callout arearefs='ccusb-snit-ccusbswigwrap'> - <para> - Creates a swig wrapping of the <classname>CCCUSB</classname> - class whose underlying class is the class 'pointed to' - by the <parameter>driverPtr</parameter> parameter. - </para> - <para> - The wrapping creats a command <command>c</command> - Subcommands of that command are mapped to methods in the - <classname>CCCUSB</classname> C++ class. - </para> - <para> - You can also get Swig to name the new object after - the pointer that was passed in: - <informalexample> - <programlisting> -... -cccusb::CCCUSB -this $driverPtr -... - </programlisting> - </informalexample> - Where $driverPtr can be used as the CCCUSB object - command. - </para> - </callout> - <callout arearefs='ccusb-snit-readleds'> - <para> - This is an example of invoking a CCCUSB method. - The subcommand <methodname>readLedSelector</methodname> - reads the CC-USB LED selector register. The subsequent - code makes changes the fields that control the yellow - LED so that it's input is the NIM IN3 inpout and is lit - when there is no input (inverted state). This should - normally light the yellow LED. - </para> - </callout> - <callout arearefs='ccusb-snit-writeleds'> - <para> - Invokes the CCCUSB <methodname>writeLedSelector</methodname> - so that the new value of the LED selector register - takes effect. - </para> - </callout> - <callout arearefs='ccusb-snit-addReadoutListmethod'> - <para> - The <methodname>addReadoutList</methodname> - is invoked for each driver instance that is in a stack - as the run is started. It is is expected to contribute - elements to a <classname>CCCUSBReadoutList</classname> - object that read the supported module in the manner - defined by the object's configuration. - </para> - <para> - The <parameter>list</parameter> parameter is a pointer - like value to a <classname>CCCUSBReadoutList</classname> - object. - </para> - </callout> - <callout arearefs='ccusb-snit-ccusbreadoutlist-swigwrap'> - <para> - Wraps the pointer in a SWIG object analagous to what - was done for the ccusb pointer passed to - <methodname>Initialize</methodname>. - </para> - </callout> - <callout arearefs='ccusb-snit-addmarker'> - <para> - Adds a marker to the list. - The marker value will be value of the - <option>-value</option> option. In snit, options - are put in an array named <varname>options</varname> - indexed by the option name. - </para> - </callout> - - </calloutlist> - </section> - <section> - <title>A sample Incr-Tcl Tcl CCUSB framework driver</title> - <para> - Incr Tcl is an object oriented extension for Tcl. It is installed - on all NSCL systems. It provides the ability to define - <firstterm>classes</firstterm>. As with snit, creating a class - instance (object) creates a new command. The public class - methods are then subcommands for the object command. - </para> - <para> - As with snit, objects can have configurations that are manipulated - and queried via built in <command>config</command> and - <command>cget</command> object subcommands. Unlike snit, - all public member variables are considered to be - configurable objects to Incr Tcl. - </para> - <para> - The properties above make Incr Tcl a viable option for - implementing driver support. - </para> - <para> - <ulink url='http://incrtcl.sourceforge.net/itcl/'> - http://incrtcl.sourceforge.net/itcl/</ulink> - provides information about Incr Tcl. - </para> - <para> - The example below shows a marker driver identical in functionality - to the snit driver shown in the previous section, but written - with Incr Tcl. - </para> - <example> - <title>CCUSB device support example writtin in Incr Tcl</title> - <programlisting> -lappend auto_path /usr/opt/daq/10.1/lib -puts $auto_path -package require Itcl <co id='ccusb-itcl-header' /> -package require cccusb -package require cccusbreadoutlist - -itcl::class marker-itcl { <co id='ccusb-itcl-class' /> - public variable value 0 <co id='ccusb-itcl-options' /> - - # - # Called when the run is being started. - # - # @param driverPtr - 'pointer' to the CCUSB object. - # - public method Initialize driverPtr { <co id='ccusb-itcl-initialize' /> - - # This turns the driver pointer into a CCUSB object which - # can make use of the SWIG wrappers for the CCUSB code: - - cccusb::CCCUSB c -this $driverPtr; # c is a CAMAC controller object. - - # Get the led programming now - # Yellow is the mask of FF0000 - # Clear out those bits and set that field to be 110000 which is source I3 and - # inverted. - - set leds [c readLedSelector] - set leds [expr {$leds & 0xffff}] - set leds [expr {$leds | 0x110000}] - c writeLedSelector $leds - - } - # Called to contribute to the readout list - # - # @param list - 'pointer' to the CCCUSBReadoutList which will be wrapped in a - # swig wrapper. - # - public method addReadoutList list { <co id='ccusb-itcl-addreadoutlist' /> - - # - # Wrap the list so we can use it: - # - cccusbreadoutlist::CCCUSBReadoutList l -this $list; # l is now a swig wrapper over the list. - - l addMarker $value <co id='ccusb-itcl-addmarker' /> - - } - - </programlisting> - </example> - <para> - The numbers in the explanations below refer to the numbers - in the example above. - </para> - <calloutlist> - <callout arearefs='ccusb-itcl-header'> - <para> - This heading is easily understandable from the - example in the previous section. The only difference - is that the Itcl package is loaded instead of snit. - </para> - </callout> - <callout arearefs='ccusb-itcl-class'> - <para> - The <command>class</command> command creates an Incr - Tcl class. The class name <command>marker-itcl</command> - becomes the command name for creating class instances - (objects). - </para> - </callout> - <callout arearefs='ccusb-itcl-options'> - <para> - Unlike snit Incr Tcl does not have a separate facility - for creating options. Any instance variable that is - declared <literal>public</literal> is treated as - a configuration parameter. - </para> - <para> - Therefore this line creates the - <option>-value</option>. Configuring - <option>-value</option> will modify this variable. - Cgetting <option>-value</option> will read this - variable. - </para> - </callout> - <callout arearefs='ccusb-itcl-initialize'> - <para> - The <methodname>Initialize</methodname> method - has been described previously. The body of this - method is identical to the body of the - correpondig <literal>snit::type</literal>. - method. - </para> - </callout> - <callout arearefs='ccusb-itcl-addreadoutlist'> - <para> - Creates a method to be called when the software - is building readout lists. With the exception - shown below... [truncated message content] |