15.9.3 Adding a new trace capture device

DS-5 Debugger has built in support for reading trace data from DSTREAM, ETB, TMC/ETM and TMC/ETR devices. Adding support for a new trace capture device is not very difficult, however, and can be done entirely with DTSL Jython scripts.

The DTSL trace capture objects class hierarchy shows that all DTSL trace capture objects are derived from the ConnectableTraceCaptureBase class. This base class implements two interfaces, ITraceCapture and IDeviceConnection. ITraceCapture defines all the methods that relate to controlling and reading trace data from a capture device, and IDeviceConnection defines the methods for a component that needs to be connected to. The ConnectableTraceCaptureBase class contains stub implementations for all the methods in both interfaces.

To create a new trace capture class:

  1. Create a new class derived from the ConnectableTraceCaptureBase class, or the TraceCaptureBase class if appropriate.
  2. Implement the class constructor, making sure to call the base class constructor in your implementation.
  3. Override the startTraceCapture() and stopTraceCapture() methods. The default implementations of these methods throw an exception when DTSL calls them, so you must override them to avoid this.
  4. Override the getCaptureSize() method to return the size of raw trace data in the device.
  5. Override the getSourceData() method to return trace data for a specified trace source.
  6. If your trace device requires a connection, override the connect(), disconnect(), and isConnected() methods.
  7. In your platform DTSL Jython script, create an instance of your new trace capture device class and add it to the DTSL configuration.

The following example Jython code implements a new trace capture device which reads its trace data from an ETB dump file (the raw content of an ETB buffer). It is assumed that this code is in FileBasedTraceCapture.py.

from java.lang import Math
from com.arm.debug.dtsl.impl import DataSink
from com.arm.debug.dtsl.impl import Deformatter
from com.arm.debug.dtsl.impl import SyncStripper
from com.arm.debug.dtsl.components import ConnectableTraceCaptureBase
from com.arm.debug.dtsl.configurations import ConfigurationBase
import sys
import os
import jarray

class FileBasedTraceCaptureDevice(ConnectableTraceCaptureBase):
    '''
    Base class for a trace capture device which just returns
    a fixed data set from a file. The amount of trace data captured
    is just the size of the file.
    '''
    def __init__(self, configuration, name):
        '''Construction
        Params: configuration
                    the top level DTSL configuration (the
                    class you derived from DTSLv1)
                name
                    the name for the trace capture device
        '''
        ConnectableTraceCaptureBase.__init__(self, configuration, name)
        self.filename = None
        self.fileOpened = False
        self.hasStarted = False
        self.trcFile = None

    def setTraceFile(self, filename):
        '''Sets the file to use as the trace data source
        Params: filename
                    the file containing the trace data
        '''
        self.filename = filename
        
    def connect(self):
        '''We interpret connect() as an opening of the trace data file
        '''
        self.trcFile = file(self.filename, 'rb')
        self.fileOpened = True
        self.fileSize = os.path.getsize(self.filename)

    def disconnect(self):
        '''We interpret disconnect() as a closing of the trace data file
        '''
        if self.trcFile != None:
            self.trcFile.close()
        self.fileOpened = False
        self.fileSize = 0

    def isConnected(self):
        return self.fileOpened

    def startTraceCapture(self):
        self.hasStarted = True

    def stopTraceCapture(self):
        self.hasStarted = False

    def getMaxCaptureSize(self):
        return self.fileSize

    def setMaxCaptureSize(self, size):
        return self.getMaxCaptureSize()

    def getCaptureSize(self):
        return self.fileSize

    def getNewCaptureSize(self):
        return self.getCaptureSize()

    def hasWrapped(self):
        return True

class ETBFileBasedTraceCaptureDevice(FileBasedTraceCaptureDevice):
    '''
    Creates a trace capture device which returns ETB trace
    data from a file.
    '''
    def __init__(self, configuration, name):
        '''Construction
        Params: configuration
                    the top level DTSL configuration (the
                    class you derived from DTSLv1)
                name
                    the name for the trace capture device
        '''
        FileBasedTraceCaptureDevice.__init__(self, configuration, name)

    def getSourceData(self, streamID, position, size, data, nextPos):
        '''Reads the ETB trace data from the file
        Params: streamID
                    for file formats which contain multiple
                    streams, this identifies the stream for which
                    data should be returned from
                position
                    the byte index position to read from
                size
                    the max size of data (in bytes) we should return
                data
                    where to write the extracted data
                nextPos
                    an array into which we set entry [0] to the
                    next position to read from i.e. the position parameter
                    value which will return data that immediately follows
                    the last entry written into data
        '''
        # We assume that size is small enough to allow to read an entire
        # data block in one operation
        self.trcFile.seek(position)
        rawdata = jarray.array(self.trcFile.read(size), 'b')
        nextPos[0] = position+size
        dest = DataSink(0, 0, size, data)
        # We assume the file contains TPIU frames with sync sequences
        # Se we set up a processing chain as follows:
        # file data -> strip syncs -> de formatter -> to our caller
        deformatter = Deformatter(dest, streamID)
        syncStripper = SyncStripper(deformatter)
        syncStripper.forceSync(True)
        syncStripper.push(rawdata)
        syncStripper.flush()
        return dest.size()

We can use the new trace capture device in the platform DTSL Jython code:

from FileBasedTraceCapture import ETBFileBasedTraceCaptureDevice
[snip]
        self.etbFileCaptureDevice = ETBFileBasedTraceCaptureDevice(self, 'ETB(FILE)')
        self.etbFileCaptureDevice.setTraceFile('c:\\etbdump.bin')
        self.addTraceCaptureInterface(self.etbFileCaptureDevice)

We can add it to the configuration as though it were an ETB or DSTREAM device.

Non-ConfidentialPDF file icon PDF versionARM DUI0446Z
Copyright © 2010-2016 ARM Limited or its affiliates. All rights reserved.