XIL Device Porting and Extensibility Guide
この本のみを検索
PDF 文書ファイルをダウンロードする

More on Writing Device Handlers

2

How XIL Device Handlers Work

Each type of device in the XIL library handles a different aspect of imaging device dependence. The inner workings of each type of device are detailed in the following chapters along with an example of each device handler. However, the overall concept behind providing a device handler is similar among different kinds of devices.
To implement a specific device, you must define a derived class from the appropriate XilDeviceType class that represents the device. Only one derived class can exist for each device, and therefore only one for each handler. The purpose of the derived class is to:
  • initialize the device
  • create the derived XilDevice class

Note - If you are writing a device handler, be aware that not all XIL application programs call xil_close() before exiting. Therefore you should make sure, if possible, that your device handler frees all system resources if an application dies abnormally.

As an example, consider the case of an I/O device called camera, which represents the combination of a frame grabber and camera (as shown in Figure 2-1). This example demonstrates the flow of creating an XIL handler, as follows:
  1. The subclass XilDeviceInputOutputTypeCamera is created by a call to the global function XilCreateInputOutputType(), which must exist in the loadable library that contains the handler.

  2. The XilCreateInputOutputTypeCamera subclass initializes the frame grabber, and holds all the global information that is shared among different instances of the actual device. The XilCreateInputOutputType() function is called when the handler is loaded. In this example of an I/O device, this happens the first time the API function xil_create_from_device() is called with the Camera handler name as the device-name parameter.

  3. After initializing, the XIL core code calls code in XilDeviceInputOutputTypeCamera that creates an instance of the derived class XilDeviceInputOutputCamera. This class contains all the code needed to perform the image acquisition. The second time the application calls xil_create_from_device() with the same device name, the second instance of XilDeviceInputOutputCamera is created. To the application, this appears as a second device image. The two device images can exist in sequence or simultaneously.

グラフィック

Figure 2-1

The flow of creating a device handler is essentially the same for I/O, storage, and compression handlers (Figure 2-2), but not identical for compute devices.

グラフィック

Figure 2-2

Compute devices have only a single instantiation, which is controlled by the XIL core code. Thus, there is no derived class called XilDeviceCompute; only the XilDeviceComputeType class exists. Like the other device classes, the XilDeviceComputeType class must be subclassed, this time to represent the XIL functions that are being accelerated. The mechanism for allowing the XIL core code to instantiate the compute class is described in detail in Chapter 4, "Compute Devices."

The Development Environment

The porting interface for the XIL library is written in C++. Due to the lack of a stable binary interface for C++ compilers, it is important that device handler code be written with the same compiler as the interface part of the library. Two compilers are supported: SPARCompiler(TM) C++ v2.0 (or 2.0.1) and ProCompiler(TM) C++ 2.0.1.

SPARC - Although the XIL Programmer's Guide recommends the SPARCompiler C 3.0 or later compiler for building XIL applications, the SPARCompiler C++ 3.0 compiler cannot be used for writing device handler code.

The XIL library contains the XIL Test Suite. It enables you to perform regression tests against proven reference signatures. The XIL Test Suite is described in XIL Test Suite User's Guide, which is part of this software release.
The environment variable XIL_DEBUG can be useful in development situations. The options for XIL_DEBUG are described in Table 2-1.
Table 2-1 XIL_DEBUG
XIL_DEBUG OptionDefinition
linkxxAdd the two characters following the option link to the base name of the loadable handlers. This option is especially useful when you want to load a debug version of a handler. For example, link_g causes xilioxlib_g.so.1 to be loaded. If this version does not exist, then the handler with the standard name (xilioxlib.so.1) is loaded.
show_actionPrint XIL_ACTION, the name of the device (e.g., XilDeviceComputeMemory) and the name of the function being called to execute each XIL operation (e.g., setvalue8()). For example,

XIL_ACTION[XilDeviceComputeMemory]:setvalue8()

set_synchronizeDisable deferred execution.
verbose_cleanupPrint the name and class of each XIL object that you were responsible for destroying but did not. If an object that you were responsible for destroying is still on the list of active XIL objects at xil_close(), then the object's destroy function is invoked. An example of output for this option is Cleaning up an XIL_IMAGE object this object has no assigned name
no_cleanupDo not destroy extra XIL objects at xil_close(). By default, if an object that you were responsible for destroying is still on the list of active XIL objects at xil_close(), then the object's destroy function is invoked.
Multiple variables may be set at once. For example, you could set XIL_DEBUG to "show_action:set_synchronize."

Installing XIL Device Handlers

By default, XIL looks for the device handlers in the directory
/opt/SUNWits/Graphics-sw/xil/lib/pipelines

This location is the default installation point for the Driver Developers Kit (DDK) packages. If XIL does not find the device handlers in this location, it will look in the directory
/usr/openwin/etc/devhandlers

The environment variable XILHOME overrides where XIL looks for the device handlers. If you set this environment variable, XIL looks for the device handlers only in
$XILHOME/lib/pipelines

The file xil.compute is a configuration file for handlers and their dependencies. This file resides in the same directory as the XIL runtime libraries (assuming default installation of the Software Developers Kit (SDK) packages):
/opt/SUNWits/Graphics-sw/xil/lib

If you have set the environment variable XILHOME, the library uses the xil.compute file in $XILHOME/lib.
Each of the following chapters that discuss I/O, storage, and compute drivers reference the xil.compute file and the changes you must make to it to add a new device handler.

Note - Be sure not to overwrite any existing files when you write your device handlers to the pipelines directory.

Error Reporting for XIL Device Handlers

All the possible error messages in the XIL library are listed in a file xil.po. This file is located in the directory
/opt/SUNWddk/ddk_2.4/xil/src/doc

As part of the release process, this file is compiled into another file, called xil.mo, which is used to localize error messages for different languages. In the system programmer release, the xil.po file is included. Where possible, you should make use of the currently existing error messages.
When you need to use device-specific error messages that are to included in the standard XIL release, you should create a new error file. The current xil.po file contains the device-independent error message IDs. These IDs are numbered and prefixed with the string di- (for example, di-312).
For device-dependent errors, the prefix for the error ID should be the device name for the handler. For example, for a handler with the device name MYCAMERA, the error IDs should have the form MYCAMERA-123. In this example, the XIL library looks for the device-specific error message number 123 in the directory
/opt/SUNWits/Graphics-sw/xil/lib/locale/current_locale\
/LC_MESSAGES/MYCAMERA.mo

The XIL library is internationalized; that is, it uses functions to extract error messages for a given locale. For information on localization of error messages and the creation of the .mo files, see the document Developer's Guide to Internationalization (available in AnswerBook).

What Kinds of Ports Are Possible in the XIL Library?

The mechanism for porting in the XIL library allows you to decide which functions would provide the maximum benefit for your customers. If an add-on card is only good at geometric operators, only those functions need to be ported; the memory versions of the remaining functions are called automatically. If the device is a general-purpose imaging accelerator, you may find it reasonable to provide a compute handler for most or all of the possible XIL atomic functions.
If only a compute handler is written, the XIL library expects that an image ends up residing in the CPU memory after each operation. If an accelerator has its own memory, it is often an advantage to allow the image data to reside on the device between operations. This avoids the overhead of having to copy the data back to the CPU after each operation. The XIL library has the concept of a storage handler, which is a set of functions which implements a copy to and from the specific device. If a storage handler is written, the XIL core code
allows the image to reside in accelerator memory until another function requests that it be moved somewhere else. Writing a storage handler can greatly speed up a port for certain types of accelerator devices.
Additional molecules may be implemented by combining atomic functions in ways that accelerate specific application areas. Faster implementations of atomic functions can be used in place of the default implementation. While not properly a device port, molecules can greatly improve the performance of groups of operations.
For devices that act as either a source or destination image in an operation, the XIL library has the concept of an I/O handler. Once the handler is written, the application programmer can use the I/O device as a source or destination through the device image mechanism.
A single device may be represented by more than one handler. For example, an input frame grabber that has integrated processing support can be described by an I/O handler and an associated compute handler. If it appears as though multiple processing operations will be done often on the grabbed images, a storage handler can be written for the frame-grabber board as well.
Compression devices must implement the compression but may be associated with other compute, storage, or I/O handlers as well.
The following chapters will describe each type of handler in detail.

What Kinds of Ports Are Not Possible in the XIL Library?

The major constraint on porting in the XIL library is that the set of atomic functions may not be extended by the user. All molecules, including those going to I/O hardware, must be made up of groups of the atomic functions that the XIL library defines and implements. The list of available atomic functions is given in Appendix B, "XIL Atomic Functions."
In addition, the IHV should not change the meaning of existing atomic functions; a new implementation should do exactly what the original version does. The correctness of a new function can be tested using the XIL Test Suite.
Porting of functions not defined by the XIL library must be performed using the mechanism defined by xil_export().

Version Control for XIL Handlers

The XIL core contains a global function:
xilVersionPtr* XilGetVersion()

This function returns a pointer to a structure that contains 16-bit unsigned integers containing the major and minor release numbers of the current XIL library. The structure looks like this:

  typedef struct {  
       Xil_unsigned16 majorVersion;  
       Xil_unsigned16 minorVersion;  
  } *xilVersionPtr;  

The rules for loading handlers are fairly simple:
  • The library will not load a module with a majorVersion greater than its own. An attempt to load a module greater than the current library version results in an error.
  • Currently, the allowable (earlier) module versions that are supported are versions 1.1 and 1.2. Thus, majorVersion can only equal 1, and minorVersion can equal either 1 or 2.
  • The library loads and executes any module with the same majorVersion number.
Similar version control rules exist for all of the OGI foundation libraries, including the port for the OpenWindows(TM) software.
These rules have implications for writers of XIL device handlers. You should write your handler with the earliest version of the Solaris OS that you wish to support. Upgrading to a new OS version by the end user will, in general, not require a new release of XIL device handlers. If you wish to write a handler that requires functionality only available after a specific library release, you must check the majorVersion and minorVersion numbers to make sure the handler has been loaded by an appropriate version of the library.
In order for the library to properly load handlers, the name of the handler must contain its major version number as a suffix. For example, the standard XIL I/O handler for X11 support is called xilioxlib.so.1. For the 1.x release of the XIL library, it is sufficient to ensure that each handler name includes the suffix .1.