Abstract
Automotive multimedia devices are verified against requirements by applying analog signals and Controller Area Network (CAN) commands to the devices and recording their responses. Perl, Tk, and C were used to write a test sequencer and an EEPROM configuration tool at Visteon. This software is used in the product verification process. A variety of programming methods, including late binding, object oriented and procedural modules, inter-process communication, and graphical user interfaces are used in the software. The usefulness of these methods is discussed. The measurement of speed sensitive volume using General Purpose Interface Bus based instruments and a CAN network interface is described.
Introduction
Visteon designs and manufactures automotive multimedia devices such as radio head units, satellite radio receivers, and DVD players. One phase of the design process is product verification, which acts to ensure that the devices to be manufactured are compliant to requirements. This happens before manufacturing begins. Automation aids in product verification by applying repeated test vectors to the devices and measuring their response against the applicable requirements. To facilitate this activity, the author wrote a test sequencer with a graphical user interface (GUI) in Perl, Tk (a graphical package), and C. This package is collectively called the Perlizer, because previous coding of test cases in C++ is replaced by Perl scripting. Scripting saves time and effort in the development effort as it allows for the immediate execution of developed tests, unlike languages such as C, which require compiling and linking. Perl also saves time over C++ as Perl generally requires fewer statements to accomplish a given task. Perl facilitates the construction of scripts from reusable software components (modules and scripts) that are assembled together at run time to form complete programs.
Many vehicles, including cars and some motorcycles, use the Controller Area Network (CAN) body network to communicate between devices. A technical necessity in the creation of the Perlizer was to allow the testing of multimedia modules using General Purpose Interface Bus (GPIB) instruments synchronized with CAN message sequences. This is necessary to test the next generation of distributed modules that will run in vehicles. A business requirement was added to the effect that the test sequencer must not quickly become obsolete. To that end, the test sequencer was written so that software components are loaded into it at run time, rather than being permanently bound to it. The test sequencer can then be adapted to whatever tests are needed at that moment in the product verification cycle by simply loading different components and tests. The software components are used via their public interface, which can remain consistent even if the underlying methods change. The test programmer writes only the Perl scripts needed for a test, using software components that receive simple instructions expressed in the language of the test domain and its instruments. He or she then plugs these scripts into the Perlizer, whose implementation remains unchanged.
Instrument control libraries are typically written in C, necessitating that C and Perl interoperate. These C libraries cannot be directly executed in Perl. C executables are used to access the C libraries used to control the instruments. The C executables control the instruments through the libraries. Perl controls the C executables via inter-process communication (IPC) methods. One of the main goals of the Perlizer is to allow test scripts to be written without knowledge of the details of instrument use. The Perl components that control the instruments abstract out the details of instrument use and provide high-level public interfaces to the test programmer. The test programmer does not need to have knowledge about the C executables or the details of use of the instruments to use the Perl modules that employ the C executables to control the instruments.
Radio features are set in EEPROM using bit configurations described by blocks of hexadecimal digits. Editing or interpreting hexadecimal files directly is difficult, time consuming, and error prone. Canfigure (Configures CAN) is a second Perl with Tk and C application. This software tool configures radio EEPROM settings using a Perl/Tk GUI that communicates with an external C program (ceeblock.exe) to read or load configuration blocks used to set radio features. Engineers can reprogram or examine radio features visually, rather than using a command line program that requires understanding a file specified with hexadecimal digits.
Why perl is appropriate for automation and tools
Perl is an interpreted scripting language that reads human-readable program text, the script, at run time and performs all needed steps to immediately execute the script. This process is called interpretation. The Perl language executable is an interpreter. This allows rapid and flexible development cycles because scripts can be written employing different solutions to an application problem, then executed and tested immediately. Normally an executable Perl interpreter and a set of modules are installed on every computer that needs to run a Perl script. Both the Perlizer and Canfigure are Perl scripts which use Perl modules and C executables via run time loading as described above.
Perl 1 started life in the middle of the 1980s as the mind child of Larry Wall, who created Perl to make it easier to search file hierarchies, hence the Perl acronym Practical Extraction and Report Language. An enthusiastic community contributed to Perl's development and growth, although Wall is still the central figure in Perl development activities, which are easily accessed at www.perl.org. A Perl interpreter is available for free on a variety of platforms, including Linux, Unix, OSX, and Windows. The Comprehensive Perl Archive Network (CPAN) at www.cpan.org provides additional modules covering many areas of interest. Learning Perl 2 by Schwartz and Phoenix is a good book for beginners. Perl users in the Microsoft environment can turn to ActiveState 3 for Perl use on Windows. ActivePerl V5.8.7 running on Windows XP was used for all discussion that follows.
Perl software can exist in several forms: as scripts, modules of reusable procedures, modules that represent object oriented (OO) classes and class hierarchies, inline statements in C or other languages, or as separately compiled modules written in C using the same methods used to implement Perl itself. Subroutines provide an abstraction mechanism for procedural operations. Data values are passed into a subroutine via an array. The subroutine then operates on the data and returns a value or values. The internal implementation of a subroutine is invisible to the subroutine's caller.
Groups of subroutines and associated data can be placed in modules, identified by having a ‘.pm’ extension, such as exist in CPAN. Modules can control what subroutine names they export, thereby hiding their implementation details and not filling the namespace of the user of the module with unwanted variable or subroutine names. Reducing the chance of name space clashes is a matter of reliability, as well as courtesy. An OO module encapsulates data and subroutines inside an abstraction called a class. An object is a software component that holds associated data and subroutines together in a private relationship. OO modules employ extra semantics to allow classes to be inherited, allowing class hierarchies.
Perl is often described as a glue language, owing to its ability to tie computational components, resources, and data together, often through a network. It is also a dynamic language; meaning that functions, variables, and even the executable image are created at run time. The actual association of values with variables in the symbol table(s) at run time is called late binding, as opposed to static binding, which occurs before the program is executed. Languages like C create functions, variables, and bindings when they are initially compiled and linked in separate steps prior to being run. Greater flexibility can be obtained in Perl compared to static languages at some performance cost by generating and binding data and subroutines at run time. This article provides methods that capitalize on Perl's support for the run time creation of both variables and subroutines that together can generate reusable components.
Each Perl variable is preceded by a character, called a sigil, which identifies the type of the variable. Sigils are a useful way to directly distinguish the type of the variable. A reference to a variable is a form of indirection. It allows the variable to be manipulated in an anonymous manner after its creation. Anonymous variables allow data structures to be built as needed at run time in whatever configuration is required at that moment. Anonymous subroutines can be created at run time and executed later.
A Perl array is a form of double-ended queue, often called a dequeue, pronounced ‘deck’. A dequeue is a linear data structure that allows data to be accessed from either end. Data can be accessed by array index, pushed and popped from the end; and shifted and unshifted from the front. It is quite versatile and useful, and can be made to act as a first in-first out (FIFO, pipe) data structure or a last in-first out (LIFO, stack) data structure. A Perl hash is an associative array, which binds scalar data values with matching keys in a manner such that the hash will return the matching value when presented with the key associated with the value.
Perl is a procedural language with block structure delimited by. Variable visibility based on the block structure of the program text is called lexical scoping, as variable visibility is only dependent on the program's text, not on run time considerations. This makes it easier to understand the program's behavior based on examining only the text without performing run time debugging to watch logical program flow as it assigns values to variables. Most of the common control structures from C and shell scripting are available. Program execution flow is controlled by logical operators ‘=’, ‘eq’, ‘and’, ‘not’, and others that compare variable values or the existence of pattern matches in regular expressions, which are text pattern matching operators.
Perl has the ability to reclaim memory from variables that are no longer usable. This ability to recycle memory at run time is called garbage collection. It happens invisibly to the user of the Perl interpreter, automating a programming task that is difficult and prone to error. Garbage collection introduces a level of unpredictability in the timing of execution due to the necessity of the interpreter pausing to perform the operation. This unpredictability makes it difficult to carry out actions that need precise timing, such as the periodic sending of messages.
Perl V5.8.7 supports threads, which are used by the Perlizer to have an active GUI while executing tests. When the Perlizer creates a new thread for test execution, the Perl interpreter duplicates itself and runs each interpreter in a separate thread. Thread safe queues 4 allow a data producer-consumer pair to safely exchange data. Thread safety protects the data from being read by one thread while another thread is writing to it, which would lead to the data reader obtaining a corrupt value. The producer puts data on the queue and the consumer takes the data off the queue. The queue handles all issues involving synchronizing the read-write accesses.
Several GUI packages have been adapted for use by Perl, including Tk, an adaptation of the Tcl language's Tk package. Tk is used in Perl by importing the Tk module 5 into the run time Perl script. Tk has been adapted to other dynamic programming languages, such as Python, Ruby, and R. Once Tk is understood, a GUI can be made in any language that has a Tk binding.
Serial port access on Linux and some Berkeley Software Distribution (BSD) variants is provided by Sys::PortIO. IO::Socket provides a socket interface. Sockets provide a two-way communication mechanism like a telephone line between a client and a server. Win32::OLE provides access to Object Linking and Embedding (OLE) 6 compliant programs or devices. OLE allows an application to be used as a server in a programmatic manner, rather than via stand alone execution. The OLE for Process Control Foundation 7 discusses the use of OLE with a variety of hardware automation devices. PerlNet 8 from ActiveState claims it supports the use of .NET 9 components in ActiveState Perl running in a Microsoft environment. Neither OLE or .NET were tried during the exercises under discussion.
Several error-handling methods are available in Perl. Subroutines can return an error value that is checked after a call is made. The resulting script tends to be a bit cluttered with checks which distract from understanding the mainline functionality. Perl has an idiom whereby the status is checked without visible checking statements using a logical ‘or’. An error return (undef) from a subroutine is trapped and the built-in Perl function ‘die’ is called. The ‘die’ function prints a programmer-supplied message to standard error and exits the program. In an alternate method of error handling, a given block of Perl script can be run as a separate Perl process using the ‘eval’ function. If a runtime error occurs, or a ‘die’ function is executed, the ‘eval’ function exits the Perl script block, and puts an error message in the Perl variable ‘$@’. The ‘$@’ variable can then be examined, and appropriate action taken, without the overall Perl executable being terminated. The ‘eval’ method can be used to reduce error check complexity or to provide a safety net in case of an unexpected error state being reached.
Applications
Perlizer
The Perlizer test sequencer executes a series of tests without knowledge of the interior details of the tests themselves. The tests use the Perlizer as a service provider via the interface that the Perlizer presents to the tests. A Perl script designed to run a specific sequence of tests creates test case objects for each individual test. The script then instantiates a driver object and loads the specific tests as anonymous objects into an array in the driver object. The value of using anonymous objects is that the Perlizer does not need to have hard coded test scripts, but rather has the flexibility to take as many tests as it is offered at run time and execute them. Bench initialization and shutdown subroutines are also loaded into the driver object. The driver object is started by invoking the Tk event loop (MainLoop) within the driver.
The Perlizer uses thread safe queues to carry out communication between its GUI and test execution threads. Tests execute in their own thread, separate from the Tk GUI, which executes in the main thread. This allows the GUI to continue to run while the tests execute, allowing a BREAK button to be active in the GUI. The initialization script and test objects are dynamically loaded into the test thread where they use the Perlizer GUI and instrument control modules without knowing their internal details. The Perlizer architecture is shown in Figure 1.

Perlizer architecture.
Bench initialization is protected by an ‘eval’ function as shown below. The script block inside the ‘eval’ function creates a CAN device object and connects to it. If this fails, the ‘Scan’ object is told to ‘quit’ and an error exception is thrown with a message by the ‘die’ function. The ‘$reply =∼ /error/’ regular expression match checks the ‘$reply’ variable for the ‘error’ string using regular expression (text pattern) matching. After the ‘eval’ function has terminated, the ‘$@’ variable is examined to see how it was set by ‘eval’. If ‘$@’ is undefined, no error happened. If ‘$@’ has a message, it came from either the ‘die’ function invocation, or from the Perl interpreter itself when it detected an error.
A key issue in using Perl for laboratory automation is that instrument control software is usually written in C, a language with which Perl does not readily communicate. It is critical that the Perlizer communicate with the CAN network device, whose MS Windows driver is a .dll (dynamically linked library) written using the C calling convention. There are a number of ways to make Perl interoperate with C, including inline C, Perl modules written in C, and IPCs which sew together applications that require separate processes to perform tasks. Timing sensitive tasks such as maintaining the CAN token-passing ring or sending periodic messages are delegated to a separate C executable, which runs with threads but without garbage collection, which is not natively offered in C. Peter van der Linden's Deep C Secrets 10 is a useful reference for C programmers who wish to use IPC methods.
The Perl module IPC::Open3 11 was used, because it proved to be easy to reliably use on XP to communicate with the external C executable that handles the CAN communication device via the device's .dll, which does not directly execute in Perl. IPC::Open3 uses pipes, which allow data to be transmitted from one process to another using the same Perl read/print operations that are used for files. A simple string-based request/response protocol was developed for the external C application. IPC::Open3 opens pipes between the Perl script and the external C executable, which maintains connection with the CAN bus and handles periodic message generation.
There are advantages to using a stand alone executable external to Perl. It can be implemented in any language as long as its I/O is consistent with the use of pipes. The external program can be unit tested independently of the Perl application, using nothing more complex than a command line interface, which was the method used in developing the network driver described above. An external executable can be reused with other applications, which may not be written in Perl. Previously written tools that have compliant I/O characteristics can be reused, although the IPC::Open3 documentation sternly warns of possible reliability issues. The exchange of character strings terminated by a newline ‘\n’ on the pipes is reliable, as long as only one string is passed per transaction.
There are disadvantages to using an external executable over pipes. One is that communication must be turned into character strings, pushed through the pipe, and interpreted at the other end. This involves writing software not directly related to solving the problem at hand, and the inherent latency of squeezing it through a pipe. There is also an issue with the way an operating system time-slices itself between processes. Execution transfers between multiple processes outside the control of the test tool. The test tool is one process among several to the operating system. This limits the ability of the test tool to control the exact timing of its own reads and writes to an instrument. Perl itself must also do memory reclamation of unused computational elements within its own environment, further reducing timing predictability. Perl is not inherently suitable to precisely timing events. External devices such as network cards or the sync line on an oscilloscope can help maintain and track timing.
Test Example Using the Perlizer—Speed Sensitive Volume Using CAN Simulation and GPIB
One of the audio system features supported by Visteon products is speed sensitive volume (SSV). A sensor in the wheel supplies signals to a CAN junction box, which converts the signals to CAN vehicle speed messages and sends them to the audio head unit. The audio head unit uses these messages and a user-selected SSV level to raise the audio output volume a controlled amount as the vehicle's speed increases. The Perlizer simulates the vehicle speed by sending a vehicle speed CAN message every 90 ms from the C executable to the radio. The Perl test script sends one instruction to the C executable to periodically send this message. The C executable creates a fresh thread with a Sleep timer to establish waits between message sends and begins sending the message periodically. The audio output volume is measured using GPIB from an audio analyzer, which also generates the original signal fed through a signal generator to the radio's antenna input. The speed range and SSV levels are swept using the Perlizer. A Hewlett Packard audio analyzer and a Panasonic AM/FM stereo signal generator are used, running an 800 Hz test tone on a 101.1-MHz FM, 10 mV signal with 22.5 KHz modulation to the radio's antenna. The resulting data read from the audio analyzer via GPIB and the speed corresponding to the CAN message sent to the radio are written to a text file and a plot is made with Excel called using the Perl ‘system’ procedure.
External GPIB 12 devices are accessible with a GPIB driver adapted for Perl. The Perlizer uses a National Instruments GPIB board running on XP. An example script which opens an audio analyzer at GPIB address 28, sets the frequency, and reads the signal strength from the radio follows. Note the use of embedded comments (beginning with ‘#’) that describe what each statement does. The $a variable is a reference to a GPIB object. The GPIB module was obtained from CPAN. The ‘ib …’ routines are methods used by the GPIB class object to access the GPIB bus via the National Instruments GPIB driver.
Canfigure
The main data structure in Canfigure is composed of anonymous hash functions and arrays, which are described in a separate module and are built at run time in the application to describe the radio's memory map. This descriptive module is completely independent of the Canfigure script, which loads the module at run time, and then creates its own interface using buttons, checklists, and layout management based on the contents of the configuration module. When Canfigure starts, it optionally reads the radio's memory contents and sets the values of the interface to reflect the actual state of the radio at that time. A new radio needs only a new Perl module that describes its memory map and features. Canfigure rebuilds or modifies its internal data structures every time EEPROM content is read from the device under test. Canfigure uses a ‘system’ call to run the C executable that reads and writes EEPROM data. Disc files are used to hold intermediate information.
Evaluation of methods
A number of Perl, Tk, and C methods have been discussed and are evaluated below:
Tk for Perl works reliably as long as Tk widgets are kept in one Perl thread. If Tk widget variables are shared between threads, the Perl interpreter will terminate due to garbage collection errors.
Perl threads work well, although a separate Perl interpreter is invoked for each thread. Perl's variable sharing mechanism for threads seemed inadequate on XP, requiring the use of thread safe queues, which are a better solution for data sharing between threads as they handle thread safety issues for the developer.
IPC communication using pipes is reliable if single new-line terminated strings are used. A string-based protocol must be developed.
Perl modules from CPAN, such as GPIB.pm, are a major benefit of using Perl. Perl procedural modules are successfully used by Canfigure to establish the main data structure. Perl OO modules are successfully used by the Perlizer to encapsulate tests and data.
The dynamic creation of data and subroutines allows applications to be written that do not have specific test or product data. The application is not burdened with implementation specifics, reducing maintenance effort. Anonymous test objects are used by the Perlizer to build test cases. The creation of new tests does not involve maintenance of the Perlizer. The ability to create and use anonymous data, subroutines, script blocks, and objects and bind them at run time is an important plus for Perl.
Regular expressions (text matching patterns) are used to parse (take apart) EEPROM maps in the file format used by the factory as well as for parsing IPC messages. The use of regular expressions is supported in the syntax of Perl itself.
Results
Both the Perlizer and Canfigure run effectively on a 3-GHz Intel Pentium 4 based Windows XP machine with 2 GB of RAM. The Perlizer's multiple threads and processes are executed without appearing burdened by performance issues. The Canfigure Tk interface updates immediately when an EEPROM option item is changed or when EEPROM blocks are imported.
The Perlizer has seen use as a test sequencer in verification and software development. The Perlizer is an improvement over the previous C++ test sequencer. The more flexible Perl syntax permits test scripts to be written at a higher level, with fewer statements needed to accomplish the same task. Putting test objects into a dequeue, then iterating across the dequeue to execute the tests is an example of how Perl makes test sequencing more efficient. The use of Tk from within Perl is much easier than the C++ GUI employed previously. The use of C executables from Perl via IPC methods allows all of Cs strengths to be available (indirectly) from Perl. The performance of Perl compared to C++ is not an issue. Overall, the Perlizer is simpler and more powerful than that of the previous C++ test sequencer. The following tests have been successfully implemented in the Perlizer:
Simple CAN tests such as volume change, dimming, delayed accessory, ignition, and reverse park aid.
CPM On/Off simulates CAN Phone Module (CPM) message sequencing.
CAN SSV Graph samples and plots the CAN SSV response.
Canfigure is a useful and reliable tool, not only to configure EEPROM maps, but also to quickly check the configuration status of a radio. Its use has been expanded, at user request, to read and write the factory file format so that production EEPROM files can be made using it. The enhanced ease of use of Canfigure over previous methods is appreciated by the user community. The previous methods to modify EEPROM data did not use a GUI that displayed the state of the system being defined. Canfigure is a solid example of why Perl with Tk and C executables has a place in the laboratory.
Discussion
For Perl to be of greater use to the laboratory community, it needs to allow device drivers not written in Perl to be more easily used. There are a number of ways that this could happen. One way is through use of tools such as Inline to facilitate direct use of a .dll or other sharable library. This was tried but failed to work on the development machine. Another way is the general adoption of something like the .NET model by instrument makers so that drivers can be directly brought into a Perl script through a language independent technology. An alternative test sequencer architecture would use the Perl Object Environment (POE), 13 a state machine with timing capabilities, running external devices through .NET drivers. A state machine is an execution sequencer based on an event-state/action-next state table. This was not employed because POE does not properly run in a second Perl thread on XP or on OSX, where it was also tested. Additionally, the use of explicit Perl interface modules, similar to those used by Bioperl, 14 to define the public interface to Perl modules would provide stability over extended maintenance.
This article does not explore all the potential virtues of Perl in a laboratory automation context. Database access and the provision of web server routines are Perl's strong points. A larger scale laboratory system with Perl as a glue language could provide for the gathering, interpretation, and recording of results, with virtually instant Web access to a results database via a suitable front end. This would be done through well-known modules available on CPAN, such as database interface (DBI) for database access, CGI to write Common Gateway Interface (CGI) scripts for Web requests, graphics draw (GD) for graphical images, strong text processing capabilities, and specialized packages such as Bioperl. Once the essentials of an instrument or device under test are captured in a Perl object, its manipulation by an application programmer can be simple, clear, and reliable. Perl also has the virtue of being implemented on many platforms.
Python, which is an interpreted language like Perl, would be similarly suitable for automation purposes. Python is stronger in OO capabilities and also supports the Tk extensions. Perl has the CPAN module library and corporate support at Visteon. The choice really depends on your taste, experience, and organizational culture. The author simply made a go-for-one choice on Perl at an earlier date, and selected it as the implementation language going forward.
Conclusion
Perl is used at Visteon in conjunction with Tk and C to perform tests that synchronize CAN network commands with GPIB instrument based measurements to control and monitor multimedia devices under test. Implementation time was the only cost. No incremental funds were expended. The ability of the Perlizer to simulate a CAN phone module and measure SSV using CAN messages and GPIB shows that Perl can be used for the automation of product verification tests. The Canfigure application has proven that Perl can be used to create high value add utilities in a laboratory setting. Canfigure's use of a GUI to directly display a radio configuration reduces the likelihood of someone making an error in a configuration file. Pluggable components made for the Perlizer to access external C executables using Perl's module and OO capabilities handle those functions that are not done well in Perl and provide abstract access to functions whose implementation details may grow and change.
Perl is a suitable laboratory automation and tool language. This is especially true if you are in a Perl-based group or have the desire to use Perl's database or other capabilities. The Perlizer and Canfigure each show the strengths of Perl for laboratory automation and software tools. When implemented using modules and objects for reuse and encapsulation, a Perl-based test environment allows a test developer to use the instruments and devices in the system without needing an understanding of their direct use, while taking advantage of such Perl features as double-ended arrays, hash functions, regular expressions integrated with Perl syntax, and the library of Perl modules at CPAN. Perl and Tk combined with C executables allow high quality visual tools that make work processes faster and less error prone to be created at low cost.
Acknowledgments
The author would like to thank Chuck Everhart for his editing insight and support of this project at Visteon, Tom Wendeln for teaching me how to write automation for software testing, Vaughn Daniels for the smart list suggestion and encouragement, Anne Marie Graham and Kevin Wagg for adoption and use of Canfigure and Perlizer, and Dr. Matthew Evett at Eastern Michigan University for the Perl-based class Computational Tools for Bio informatics.
