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 on board. This can be achieved by using the [Perl Inline::Java module](https://metacpan.org/pod/Inline::Java).
### 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.
Prerequisites
---
### Software
* [Code Composer Studio (CCS)](https://www.ti.com/tool/CCSTUDIO)
* Installation of [Java 2 Software Development Kit (JDK)](https://java.sun.com/javase/downloads/index.jsp).
Depending on your version of CCS, you will need a 32-bit or 64-bit version of the JDK.
OS |
Requires 32-bit JDK |
Requires 64-bit JDK |
Windows |
Up to CCS v8.x |
CCS v9 and above |
MacOS |
None |
All |
Linux |
Up to CCS v6.1.3 |
CCS v6.2.0 and above |
{{b You likely already have a Java Runtime Environment (JRE) installed (one comes bundled with CCS), but you need the JDK to get the Java compiler (javac).}}
* Installation of Perl. [ActivePerl](https://www.activestate.com/Products/ActivePerl/?tn=1) and [StrawberryPerl](http://strawberryperl.com/) are two of the more popular ones on Windows.
* Installation of Inline::Java. Note that you will need to have both the JDK and Perl installed to install Inline::Java.
You can install Inline::Java from CPAN. You can find more details on installing CPAN modules [here](https://www.cpan.org/modules/INSTALL.html). For example, to install Inline::Java via CPAN from the command line using StrawberryPerl (assuming proxy configuration is set or unneeded), run cpan and type `install Inline::Java` at the prompt.
```diff
> cpan
cpan> install Inline::Java
```
This may take a while as it will bring in all the dependent modules.
[[y Problems installing Inline::Java?
* You might need to set the `JAVA_HOME` environment variable to the install location of the JDK. For example `set JAVA_HOME=C:\Java\jdk1.8.0_202`.
* If you use a proxy server or firewall, you may need to set the `HTTP_PROXY` environment variable (for example `set HTTP_PROXY=http://proxy.company.com:8008`, this will vary based on your setup).
* If the command above doesn't work, you can also try the more direct
```
> cpan
cpan> install ETJ/Inline-Java-0.66.tag.gz
```
]]
[[b What about Cygwin? Linux? Unix?
Also works fine. In addition, Cygwin JNI support got added in 0.52.]]
### Environment Setup
The dss.jar file must be added the the `CLASSPATH`. The file can be found in
<CSS_DIR>/ccs_base/DebugServer/packages/ti/dss/java/dss.jar
where <CSS_DIR> refers to the location of your version of CCS. (For example in CCS 8 on Windows it might be C:\ti\ccsv8).
You may also want to set the `PERL_INLINE_JAVA_J2SDK` environment variable as the location of the JDK you want Inline::Java to use. If this variable is not set, Inline::Java will default to the JDK that was used when it was installed.
This can be done manually, or it can be automated by a batch or shell script. An example batch file (setpath.bat) is provided in the perl_inlinejava example folder (found in <CCS_DIR>/ccs_base/scripting/examples/DebugServerExamples/perl_inlinejava). Simply update the paths for `DSS_ROOT` and `PERL_INLINE_JAVA_J2SDK`.
[[+g setpath.bat (expand)
```diff
@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:\ti\ccsv8
REM Root JDK install location
REM If omitted, Inline::Java will default to the JDK used when it was installed
set PERL_INLINE_JAVA_J2SDK=C:\Program Files\Java\jdk1.8.0_202
REM ============================================================================
REM Set CLASSPATH
set CLASSPATH=%CLASSPATH%;%DSS_ROOT%\ccs_base\DebugServer\packages\ti\dss\java\dss.jar
```
+]]
Creating a Script
---
### Using Inline::Java
To use Inline::Java with DSS you must:
* tell Inline::Java to explicitly `STUDY` the main DSS class (`ScriptingEnvironment`) so it can be used 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, the steps described above have been added to a Perl module (DSS_SCRIPTING.pm) which is provided with DSS (in the perl_inlinejava example folder).
[[+g DSS_SCRIPTING.pm (expand)
```perl
#=============================================================================
# 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
# /scripting/lib/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,
);
#
# 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;
```
+]]
To ensure Perl can find the DSS_SCRIPTING package, you can add the file to you package path. One way is to add the containing folder to the `PERL5LIB` environment variable. DSS_SCRIPTING.pm can then be leveraged in a Perl script by
```perl
# 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();
```
With the main scripting object, the rest of the DSS APIs are available for use:
```perl
# 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 the perl_inlinejava examples folder. The script takes a \*.out file and a *.ccxml setup file as its parameters.
```diff
> perl dss_simple.pl my_out.out my_target_config.ccmxl
```
### Error Handling
Starting in version 0.31, Inline::Java 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.
```perl
#
# 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 "Failed to load $out_file $!";
}
```
### 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. The bottom line is that there is an initial 1-2sec hit but then calls to the methods are near identical to calls from Javascript directly.
{{b 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 CCS is installed in a path with spaces in it (like 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.