For the January 2006 meeting, Paul Archer presented a new project he was working on. The idea was to provide Perl access to the USB Visual Signal Indicator from Delcom Engineering. This project was based on a set of articles in the Linux Journal. For more information on the origin of the project, see the notes on the first presentation.
Since the Delcom VSI is a USB device, controlling it from Perl requires a Perl interface to USB. At the time Paul began working on this there was a minimal module on CPAN for access to USB, but nothing complete. There is a C library for accessing USB devices libusb. In order to use this library, we need to be able to call C code from Perl. Paul decided to use the Inline::C module to provide this access.
The February meeting continued the group development of some prototype code that was able to exercise the device. Some work was accomplished to clean up the code for accessing the libusb library, but the main focus was on the VSI itself. Since that time, Wade has been adding some time and potential help to the project, focusing mostly on the LibUSB interface and a possible language-based interface to the VSI library. We have also elicited interface design help from the group at large.
The March meeting concluded
the sessions on this project. There is still development to do, but as the project
moves from a prototyping phase into more traditional development, it appears to
be less interesting in a meeting setting. We did a few new experiments and had a
bit more discussion about issues relating to getting the LibUSB
module ready to be released.
Project Code
This is the latest version of the code developed for this project. Since it is a work in progress, don't be surprised if it is not complete.
- Device::USB::LibUSB module, version 0.02
Lessons Learned
The Delcom documentation is mostly useful. But it did contain a few discrepancies that made life more difficult. In many cases, the text would contain a description of parameters to be passed and then an example to clarify. These two often did not match. In general, the text seems to be right and the example is wrong.
The Delcom documentation is also quite specific about the request type in
being 0x08
when making a usb_control_msg
call.
Unfortunately, not only does that value not work, but example code that does
work uses a value of 0xc8
. It turns out that the request type
actually encodes three pieces of information, not just an address. In our
case, the value should be 0x48
for sending data to the device
and 0xc8
when requesting data from the device. When just using
the function to set control parameters (which is most of what we do) either
parameter appears to work.
Although the Inline::C
module has been extremely helpful in
accessing libusb
from Perl, it has also been the source of some
difficulty. Since the Inline::C
parser is not a full parser, we
have seen some cases where function prototypes did not act as expected. In
particular, a function with no parameters cannot be declared with
void
as the parameter list.
Also the "DATA"
approach to declaring the C code inline works
great in a script, but it does not work so well in a module. The names of
functions declared in the inline portion will not be available in the module.
This problem can be solved either by moving the code to a here
document or directly calling the Inline->init()
method after
your use Inline
call.
References
- Delcom Engineering
- USB Visual Signal Indicator
- Linux Journal articles by Greg Kroah-Hartman:
- libusb
- USB.org: source for specifications and such on the USB.
- Device::USB module providing partial libusb implementation
- Inline::C module for accessing C code from Perl
- Parse::RecDescent module parsing an input language for controlling the VSI
- inline@perl.org mailing list archive