Perl Scripting with DSS

From Texas Instruments Embedded Processors Wiki

Jump to: navigation, search


  • Image:Google-16x16.png Search for an article here:


Contents

Motivation/Overview

JavaScript is very rich and programmer-friendly, but Perl is probably still the most pervasive scripting language in use today. Giving programmers the ability to use DSS from Perl brings more customers onboard. This can be achieved by using the Perl Inline::Java module.

How does it work?

The perl Inline module has been around for many years. It lets perl developers write/leverage C code from within a perl environment. In the last several years, more language support has been added to the Inline module. Inline::Java was developed in 2001. With this we can access DSS Java classes in perl. A Java compiler is launched and the Java code is compiled. Then Perl asks the Java classes what public methods have been defined. These classes and methods are available to the Perl program as if they had been written in Perl. Is it efficient? Yes, the process of interrogating the Java classes for public methods occurs the first time you run your Java code. The namespace is cached, and subsequent calls use the cached version

Installation

The following are pre-requisites before installation of Inline::Java

Ex: Running PPM from the command line with ActiveState Perl 5.8 (assuming proxy configuration set or not needed):

[>] ppm install http://theoryx5.uwinnipeg.ca/ppms/Inline-Java.ppd

If you are using ActiveState Perl 5.10:

[>] ppm install http://cpan.uwinnipeg.ca/PPMPackages/10xx/Inline-Java.ppd

This brings in all the dependent modules (so be patient!)

What about Cygwin? Linux? Unix?

Uninstallation

  • The JDK and Activeperl have straightforward uninstallers like all Windows/Linux products.
  • Uninstall Inline::Java via PPM
[>] ppm uninstall Inline-Java

Environment Setup

NOTE: The follow steps are applicable for Windows. Linux steps will be added shortly...

Additional paths must be added to the PATH and CLASSPATH environment variables.

PATH: The following must be added to the PATH:

  • <INSTALL DIR>\ccsv4\DebugServer\packages\ti\dss\java
  • <INSTALL DIR>\ccsv4\DebugServer\bin\win32
  • <INSTALL DIR>\ccsv4\common\bin
  • <INSTALL DIR>\ccsv4\common\uscif
  • <INSTALL DIR>\ccsv4\eclipse\plugins\com.ti.dvt.ofssymbolmanager_1.0.0
  • <INSTALL DIR>\ccsv4\eclipse\plugins\com.ti.dvt.tidisassembly_1.0.0\os\win32

CLASSPATH: The following needs to be added to CLASSPATH

  • <INSTALL DIR>\ccsv4\DebugServer\packages\ti\dss\java\dss.jar
  • <INSTALL DIR>\ccsv4\dvt\scripting\dvt_scripting.jar

This can be done manually or automated by a batch file. An example batch file (setpath.bat) is provided in the 'perl_inlinejava' example folder (found in '<INSTALL DIR\ccsv4\scripting\examples\DebugServerExamples\perl_inlinejava'). Simply update the paths for DSS_ROOT and PERL_INLINE_JAVA_J2SDK.

@echo off
REM
REM File: setpath.bat
REM
REM This batch file will set up the environment to run DSS with Perl 
REM Inline::Java. Contents of this batch file must be modified to match the 
REM user's environment
REM

REM ============================================================================
REM Modify these paths to match the user's environment.

REM Root DSS install location
set DSS_ROOT=C:\Program Files\Texas Instruments\ccsv4

REM Root JDK install location
set PERL_INLINE_JAVA_J2SDK=C:\Program Files\Java\jdk1.5.0_08

REM ============================================================================

REM Set PATH
set PATH=%PATH%;%DSS_ROOT%\DebugServer\packages\ti\dss\java;%DSS_ROOT%\DebugServer\bin\win32;%DSS_ROOT%\common\bin;%DSS_ROOT%\common\uscif
set PATH=%DSS_ROOT%\eclipse\plugins\com.ti.dvt.ofssymbolmanager_1.0.0;%PATH%
set PATH=%DSS_ROOT%\eclipse\plugins\com.ti.dvt.tidisassembly_1.0.0\os\win32;%PATH%

REM Set CLASSPATH
set CLASSPATH=%CLASSPATH%;%DSS_ROOT%\DebugServer\packages\ti\dss\java\dss.jar;%DSS_ROOT%\dvt\scripting\dvt_scripting.jar

Using Inline::Java

To use Inline::Java with DSS:

  • Tell Inline::Java to explicitly ‘STUDY’ main DSS class (ScriptingEnvironment) so we can use it from Perl
  • Turn on AUTOSTUDY which makes Inline::Java automatically study unknown classes as it encounters them
  • Proxy Java's importPackage() by assigning a new namespace TraceLevel to the fully scoped package name so we can then use the shorter namespace $TraceLevel::ALL instead of $DSS_SCRIPTING::com::ti::ccstudio::scripting::environment::TraceLevel::ALL
  • Enable access to the ScriptingEnvironment Java class constructor

For reuse and usability purposes, this functionality has been added to a Perl module (DSS_SCRIPTING.pm) which is provided with DSS (in the 'perl_inlinejava' example folder).

#=============================================================================
# POD Documentation First ...
#=============================================================================
 
=head1 NAME
 
DSS_SCRIPTING.pm
 
=head1 SYNOPSIS
 
Perl module for using Debug Server Scripting. Leverages Inline::Java to
interface with DSS's Java classes
 
=head1 USAGE
 
   use DSS_SCRIPTING; 
 
=head1 DESCRIPTION
 
Perl module for using Debug Server Scripting. Leverages Inline::Java to
interface with DSS's Java classes
 
Main purpose is to hide the funky details of 'STUDY' and 'CLASSPATH'
that perl users dont need to know.
 
This module lets perl users leverage the Scripting package to call the core
APIs. In addition we also use config option 'AUTOSTUDY' which brings in all
other DSS Java classes we need to work with.
 
=head1 FUNCTIONS DEFINED
 
Nothing - no 'wrappers' required at present
 
=cut
 
#=============================================================================
# Code starts here ...
#=============================================================================
 
package DSS_SCRIPTING;
 
use strict;
use warnings;
 
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw();
 
#
# Base Java CLASSPATH is set as an environment variable and must have at least
# <myDssdir>/DebugServer/packages/ti/dss/java/dss.jar in it
#
 
#
# Bring in the Java classes from DSS that we need.
# AUTOSTUDY helps in not requiring us to list out all classes we need
# individually. For example openSession() returns a DebugSession class
# which Inline::Java automatically 'studies' by virtue of AUTOSTUDY.
#
# Note, however that we *must* (a) STUDY 1 class to guide AUTOSTUDY's
# context (b) explicitly specify the TraceLevel class since we
# explicitly use its member data (ie its context is not returned by
# a TraceLevel() API like the other classes)
#
use Inline (
             Java  => 'STUDY',
             STUDY => ['com.ti.ccstudio.scripting.environment.ScriptingEnvironment',
                       'com.ti.ccstudio.scripting.environment.TraceLevel',
                       'java.lang.System',
                      ],
             AUTOSTUDY => 1,
#             DEBUG => 5,
           );
 
# Set XPCOM.RUNTIME property
my $dss_root = DSS_SCRIPTING::java::lang::System->getenv("DSS_ROOT");
DSS_SCRIPTING::java::lang::System->setProperty("XPCOM.RUNTIME", "$dss_root/DebugServer/win32");  
 
#
# Our perl proxy for Java's importPackage(). We assign a new namespace TraceLevel
# to the fully scoped package name so we can then use the shorter namespace
# $TraceLevel::ALL instead of
# $DSS_SCRIPTING::com::ti::ccstudio::scripting::environment::TraceLevel::ALL
# Internally this creates a TraceLevel symbol table which holds typeglobs
# to each of the class fields.
# 
BEGIN {
    %{TraceLevel::} = %{DSS_SCRIPTING::com::ti::ccstudio::scripting::environment::TraceLevel::};
}
 
# enable access to the DebugserverEnvironment Java class constructor
sub new {
    my $class = shift;
    return DSS_SCRIPTING::com::ti::ccstudio::scripting::environment::ScriptingEnvironment->instance();
}
 
1;

Users can add the path to DSS_Scripting.pm to their package path so it can be referenced for anywhere (can add the below to the end of the setpath.bat file).

set PERL5LIB=%PERL5LIB%;%DSS_ROOT%\ccsv4\scripting\examples\DebugServerExamples\perl_inlinejava

DSS_Scripting.pm then can be leveraged in the Perl script by:

# import module abstracting the DSS class details
use DSS_SCRIPTING;
 
# call the DSS class constructor(s) we need to create our scripting environment object
my $dss = new DSS_SCRIPTING();

And with the main scripting object, the rest of the DSS APIs are available for use:

# Create a log file to log script execution
$dss->traceBegin("dssScriptLog.xml", "DefaultStylesheet.xsl");
 
# The default timeout is 'infinite'.  Set ours to something shorter, 10s
$dss->setScriptTimeout(10000);
 
# Make the log and console file really verbose
$dss->traceSetConsoleLevel($TraceLevel::INFO);
$dss->traceSetFileLevel($TraceLevel::ALL);
 
# Open a debug session
my $debugServer = $dss->getServer("DebugServer.1");
...

Example

An example perl script (dss_simple.pl) is provided in 'perl_inlinejava' examples folder. The script takes an outfile to run and ccxml setup file as its parameters:

> perl dss_simple.pl ..\..\C64\interpreter\Debug\interpreter.out ..\..\C64\tisim_c64xple.ccxml

Error Handling

  • Inline::Java >= v0.31 lets you catch exceptions in perl as objects when they are thrown from Java, using the regular Perl exception tools: eval and $@.
  • There are many good reasons for using exception handling. One reason might be in running 1000 tests on 1000 different .out files - if one of the .out files is misspelled or passed incorrectly, you might not want to kill the entire script. Instead you might want to catch the exception and simply warn the user indicating which file was problematic.
#
# Load the program from the out file.
# Example of how to handle Java exceptions in perl with Inline::Java
# This is Perl's equivalent of Java try-catch
#
eval { $tgt->{memory}->loadProgram($out_file); };
if ($@) {                  
     die "$out_file does not exist! $!";
}

Performance

When you use Inline::Java, the Java compiler (javac) is launched and the DSS Java code is compiled. Then Perl asks the Java classes what public methods have been defined. The process of interrogating the Java classes for public methods occurs the first time you run your Java code. The namespace is cached, and subsequent calls use the cached version - bottom line is there's an initial 1-2sec hit but then calls to the methods are near identical to calls from Javascript directly.

  • Inline::Java now also provides a JNI extension that allows you to load the JVM as shared object instead of running it as a separate process

Known Issues

  • If CCS4/DSS is installed in a path with spaces in it (like the default "C:\Program Files\Texas Instruments"), there may be an issue running the perl example (dss_simple.pl) from within the directory. This can be worked around by changing the working directory to a path without spaces.

References

Intrigued? Read more at: -


For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Perl Scripting with DSS here.
Leave a Comment

Comments

Comments on Perl Scripting with DSS


Csghone said ...

How do you run a perl DSS script from within CCSv4?

This was possible in CCS3.3 and seems like a very serious limitation since you can do much more in perl than you can do in JS.


--Csghone 03:26, 31 May 2010 (CDT)

Personal tools