User-defined Devices

From dmon2
Jump to navigationJump to search

Introduction

The target system to which DMON is connected may include special purpose devices developed by the user. An example is an SOC implemented on an FPGA, which is likely to contain user defined devices. In what follows we will refer to such devices as ‘user defined devices‘, ‘user defined Intellectual property’, ‘user defined IP’, or sometimes just ‘IP’. Using standard DMON commands the user can interact with these devices, and can provide support for them by creating batch files of DMON commands or scripts in TCL or Python. It is also possible for a user to add support for a user defined device to DMON itself, extending DMON’s built-in commands and other features.

DMON API will allow user to add Custom Devices and Commands associated with these devices to DMON. This feature applies only to SPARC based systems which comply with the convention of Vendor and Device ID, and where the required address and IRQ information is available either in a configuration file or in the plug and play memory of the device.

Note on matching devices to drivers: Devices found in the Plug and Play area are matched based on the triplet of Vendor ID, Device Id and core revision. If no exact match is found but Vendor ID and Device ID is matched, the driver loaded will be that for the next lowest core revision; if no lower match is found the next highest revision will be matched.

Use Cases:

• Developer is adding a completely new IP core with a possibly new Vendor
• Developer is adding a new revision of an existing core
• Developer is adding a new IP core which is a customisation of an existing IP core, but where the Vendor ID is going to be changed to reflect this fact.

In each case the developer must provide all required driver functionality.

Note: the Developer will not be able to add a GUI element for the device; instead a basic GUI Device element will be created with limited functionality.

Technical background

DMON is written in Java, and adding an extension to it requires knowledge of the Java programming language.

Each type of device on the target is represented by a Java class. This provides constants such as register offsets, device specific command definitions and associated methods, symbol definitions, and information about this device class for display purposes.

There may be many devices of the same type on a target. Each one corresponds to a Java object, an instance of the Java class for that device type. Each device instance involves one or more addresses on the internal target bus (typically some version of the AMBA bus).

When DMON connects to the target SOC it determines the devices present either by reading the plug and play data on the target or by reading a configuration file on the host. Only the classes needed to support the devices present and the associated symbols and commands are loaded. If a device is not present, the symbols and commands specific to it will not be available.

At present DMON only supports the LEON plug and play form of device type identifier, three numbers that give the Vendor Id, Device Id, and Version Number followed by numbers giving the device’s base address or addresses. It is possible to register meaningful names corresponding to the Vendor, Device and Version numbers.

If the target does not contain a plug and play area, or it is desired to add support for devices not recorded in the plug and play, a target configuration file on the host is used. Each record in the file corresponds to a device and gives the device type identifier and the base address or addresses for the device. DMON only accepts a record format similar to that used in the plug and play.

Getting Started

Follow the steps below to add support to DMON for a user-defined device:

1. Modify sample MyVendor_MyNewDevice.java file located in ThirdParty folder in DMON install directory.
2. This class must extend UdipDevice.java. If java IDE is used then ThirdParty.jar should be added to this project class path. In other scenario -cp thirdpartyapi.jar should be passed to java compiler.
3. A class following the template of MyVendor_MyNewDevice.java must be created for each different device type.
4. If the THIRD_PARTY.jar is to be created in the DMON installation directory then the doUDIP batch file or shell script must be run with the correct privilege level. If the code is independently compiled it is important that the java compiler (javac) and archiver (jar) supplied with DMON is used in order to ensure byte code compatability.
5. The batch file will create THIRD_PARTY.jar using the same java compiler as was used to compile DMON.
6. Start DMON with –udip switch. This will force DMON to load THIRD_PARTY.jar. DMON will look first in the directory in which DMON was started (shown as initialisation directory on start-up) and then in the “ThirdParty” directory of the DMON installation.

API

The third party API provides the methods below to be used in the java code for a device driver. Methods are available either in the API class or in the UdipDevice class which the third party device must extend.

Each device class in the ThirdParty jar MUST extend the UdipDevice class and MUST provide a static “register” method which handles registering the device, and the Vendor if necessary. If the “register” method is missing the class will not be loaded.

Method Description
boolean Api.registerVendor(int VendorId, String Name) Register a name for the vendor represented by Vendor ID and add to the list of known Vendors. This will replace any existing entry for this Vendor ID. Should be called from the register method of the device class. This method returns true if the Vendor name could be registered. It will return false and no Vendor will be registered if Vendor ID is outside the range [1,255].
boolean Api.registerDevice(int vendorId, int deviceId, int revision,String className, String descriptiveName) Register a device handler. Should be called from the register method of the device class. This method returns true if the device could be registered. It will return false and no device will be registered if (1) Vendor ID is outside the range [1,255] or does not correspond to a known Vendor ID (2) Device ID is outside the range [1,4095] (3)Revision is outside the range [0,255] (4)Class name or descriptive name is NULL. (5)Note that while class name is not checked at this point, if it is invalid then it will not be possible to load when needed, leading to an error message at that point. This method is called by DMON start up before establishing the target configuration. Any errors which occur during start-up will be printed to the DMON console and are also logged in the internal log file.
boolean Api.registerCommand(String commandName,String commandMethodName,Class<?> className,String helpString) Register a command. The method commandMethodName in the Class className will be called if a string starting with commandName is entered at the console or in a script. The string helpString will be added to the online help. This method returns true if the command could be registered. It will return false and no command will be registered if (1)commandName is in use already (2)either className is null or the method commandMethodName cannot be invoked on className This method should only be called in the “addCommand” method of a Third Party device. This method is called by DMON start up while establishing the target configuration. Any errors which occur during start-up will be printed to the DMON console and are also logged in the internal log file.
void Api.display(String message) Display message on the DMON console, is the console is active. If logging is active the message will also be logged.
void Api.log(String message) Print message to the internal log with level WARN


There are a number of methods to read and write memory; these methods vary as to whether the arguments are long/int or Strings. Methods which take String arguments allow these arguments to be expressions which can be evaluated, see 7.1.1. Such expressions might be passed in from a command on the console to a User Defined command handler. Note also that long is used for target word values because Java int is always signed but target data may be interpreted as signed or unsigned; using long values allows calculations to be carried out in Java without unintended sign extension.

Method Description
byte[] Api.readBytes(

long address, long count)

byte[] Api.readBytes( String address, String count)

Read count bytes starting from address

Returns NULL if there was an error either in reading the target or in evaluating string expressions. The cause of the error will be logged in the internal log and an error message will be displayed in the console. Returns an array of bytes if successful.

long[] Api.readWords(

long address, long count)

long[] Api.readWords( String address, String count)

Read count 32 bit words starting from address

Returns NULL if there was an error either in reading the target or in evaluating string expressions.

The cause of the error will be logged in the internal log and an error message will be displayed in the console.

Returns an array of longs if successful – but note that it is the low 32 bits of these longs that represent the target data.

long Api.readWord(

long address)

long Api.readWord( String address)

Read one 32 bit word at address

Returns -1 if there was an error either in reading the target or in evaluating string expressions.

The cause of the error will be logged in the internal log and an error message will be displayed in the console.

Returns a long if successful – but note that it is the low 32 bits of this long that represents the target data.

boolean Api.writeWord(

long address, long data)

boolean Api.writeWord( String address, String data)

Write the low 32 bits of data to address

Returns false if there was an error either in writing the target or in evaluating string expressions.

The cause of the error will be logged in the internal log.

Returns true if successful

boolean Api.writeBytes(

long address, byte[] data)

boolean Api.writeBytes( String address, byte[] data)

Write data to the target starting at address.

Note: the debug link is usually 32 bits wide; non-aligned addresses will be modified using read-modify-write.

Returns false if there was an error either in writing the target or in evaluating string expressions.

The cause of the error will be logged in the internal log.

Returns true if successful.

boolean Api.writeWords(

long address, long[] data)

boolean Api.writeWords( String address, long[] data)

Write data to the target starting at address.

The low 32 bits of each long will be written.

Returns false if there was an error either in writing the target or in evaluating string expressions.

The cause of the error will be logged in the internal log.

Returns true if successful.

void Api.showInfoReg(

long address, String name)

Utility method which will display the contents of address on the console using name as a description.

Format will be the same as that used for “printreg” command.


Data and methods provided by UdipDevice superclass

The Third party device driver extends the UdipDevice class and therefore has access to some data and methods in that class.
Method / Item Description Default
long baseAPBAddress Convenience variable, used in example to hold the base address on the APB bus. Not Initialised
long baseAHBAddress Convenience variable, used in example to hold the base address on the AHB bus. Not Initialised
public UdipDevice(String className) Super constructor. Must be called with the same string as was used to register the driver in Api.registerDevice; otherwise the methods described here will not be available. This is used to retrieve the device configuration. It will call the addCommand method – this method should be implemented to register commands using Api.registerCommand. N/A
void initialise() Called by DMON main code when target is being initialised on start-up or due to “init” command. Override if it is necessary to reset registers in the device. Empty method
void addCommand() Called by super constructor. Override if adding commands. Empty method
int getNumberOfInstances() Not used by DMON code, exists for compatibility with similar code in DMON, where it returns the number of instances of a particular device. Returns zero.
ArrayList<String> getDefaultInfoSys() Returns formatted strings representing basic information about the device which has been read from the Plug and Play or configuration – Vendor ID, Device ID, Version, Description, IRQ and addresses used if appropriate. N/A
ArrayList<String> getInfoSys() Called by DMON to display information about a device, for example when the “info sys” command is galled, or the “info” button on the widget is pressed. The array of strings returned will be displayed. See also getDefaultInfoSys. Returns getDefaultInfoSys()
void getInfoReg() Called by DMON to display the registers in a device on the console. See also Api.showInfoReg. That method should be used to ensure consistent formatting. Empty method
ArrayList<?> getDeviceList() Not used by DMON code, exists for compatibility with similar code in DMON, where it returns the array of instances of a particular device. Returns null
Long getAhbStartAddress(int index) Returns the start address on the AHB read from the plug and play area/configuration. Each device can have up to three banks on the AHB; unused banks will have start and end addresses 0. Index must be in the range [0,2] or NULL will be returned. N/A
Long getAhbEndAddress(int index) Returns the end address on the AHB read from the plug and play area/configuration. Each device can have up to three banks on the AHB; unused banks will have start and end addresses 0. Index must be in the range [0,2] or NULL will be returned. N/A
long getApbStartAddress() Returns the start address on the APB read from the plug and play area/configuration. Each device can have one banks on the APB; unused banks will have start and end addresses 0. N/A
long getApbEndAddress() Returns the end address on the APB read from the plug and play area/configuration. Each device can have one banks on the APB; unused banks will have start and end addresses 0. N/A

Example code

There is a commented example of how to construct a Third Party device class in <DMON installation directory>/ThirdParty.