DMON facilities
Tcl/Python Scripts
DMON allows scripts to be used to run a sequence of commands. If only DMON commands are used, then no logic structures are available; however if commands which run an application on the board are included in the script then the next command will not be executed until the target has stopped.
Tcl
Tcl support has been added to DMON by integrating the jTcl interpreter version 2.7.0. This supports Tcl commands. Further information on jTCl is available from https://jtcl-project.github.io/jtcl/
Tcl commands can be entered in several ways
• At the DMON console
• Using the DMON script command: commands in the file will be interpreted line by line
• Using the Tcl source command to read in a whole file of Tcl code.
• Using the Tcl edit window in the GUI.
DMON can be started in tcl mode using the –tcl command line option, or the command tcl can be entered at the console to enter Tcl mode. Any symbols previously available to DMON scripts are available as Tcl variables. That is, the symbol should be prefixed with “$” to identify it as a variable.
DMON commands can be used as usual in a tcl script – however some commands may be shadowed by Tcl procedures or keywords. Prefixing these commands with “d.” forces them to be interpreted as DMON commands.
There are a number of DMON commands for interacting with the target which are specific to Tcl/Python mode and return objects rather than outputting to the console:
Option | Description |
---|---|
getb [Address] [count] | read [count] bytes from address. |
getb [Address] | read a byte from address. |
getw [Address] [count] | read [count] 32 bit words starting from address. |
getw [Address] | read a 32 bit word from address. |
getstate | returns 1 if the target is running and 0 if it is stopped |
-tcl | Set console language to Tcl |
dmon | Use only DMON commands. Ignored if already in DMON mode |
shell | In a startup script activate the language specified by command line option. Otherwise, display the language in use. |
tcl | Interpret command input as Tcl commands. Ignored if in Tcl mode |
The STDOUT, STDERR and STDIN streams of the Tcl interpreter are attached to the DMON console. STDIN will be used for Tcl commands such as “get” and “read”. If the Tcl interpreter is waiting for input on STDIN an “Input” prompt as shown below is shown. If the command is entered on multiple lines (as determined by the Tcl interpreter) a continuation prompt will be shown while more input is expected for the command.
Python
Python support has been added to DMON by integrating the jython interpreter version 2.7.0 which supports Python 2.7. Further information on Jython is available from http://www.jython.org/.
Python commands can be entered in several ways
• At the DMON console
- o DMON commands entered at the console work as before.
- o Prefixing a command with “d.” forces it to be evaluated as a DMON command.
• By importing a python script.
- o execfile('./python/PythonScript.py')
• Using the Python edit window in the GUI.
Because Python is a block oriented language and cannot be processed line by line as DMON and Tcl are, the DMON script command is not available in python mode. The python method to process a script must be used; and the API which is provided to run DMON commands must be used for DMON commands. The API provides a run method for the DMON command; the method returns an object corresponding to the returned object; for most DMON commands this is a Boolean which is true for success; the side effects of the commands will normally be information printed on the console. There are some dedicated commands which return a specific value.
Command | Description | Return type |
---|---|---|
getb [Address] [count] | read [count] bytes from address. | List of integers |
getb [Address] | read a byte from address. | Integer |
getw [Address] [count] | read [count] 32 bit words starting from address. | List of integers |
getw [Address] | read a 32 bit word from address. | Integer |
getstate | returns 1 if the target is running and 0 if it is stopped | Integer |
The example shown uses the getb command to read 10 bytes and print them.
Note: The python interpreter loads some libraries at start up, and this can be a slow process. The libraries can be preloaded in parallel to DMON start up using the –preload switch. This is not required if DMON is started in –python mode.
Option | Description |
---|---|
-preload | Load python libraries before first use |
-python | Set console language to python |
dmon | Use only DMON commands. Ignored if already in DMON mode |
python | Interpret command input as Python commands. Ignored if in Python mode |
shell | In a startup script activate the language specified by command line option. Otherwise, display the language in use. |
The Python builtin function “raw_input” can be used to read a string from the DMON console.
When the “raw_input” function is encountered, the prompt – if specified – is printed to the DMON console and the Input: prompt shown. return causes the string to be read into the specified variable.
Scripts run on particular events
Scripts while running programs
Multiple scripts can be specified to be run during execution of the run/go command to start a program or during the continue/step command. Only one script can be specified to be run during execution of a program.
Note that the scripts files are read once when added to the lists and stored as an array of strings. This means that if the file is changed on disk it must be removed and added again to the list.
precont [filename] | append a script to the user scripts executed before continuing/stepping a program |
precont insert [index] [filename] | insert a script at [index] in the user scripts executed before continuing/stepping a program |
precont list | list the user scripts executed before continuing/stepping a program |
all] | remove the script at [index] in the user scripts or all scripts executed before continuing/stepping a program |
prerun [filename] | append a script to the user scripts executed before starting a program |
prerun insert [index] [filename] | insert a script at [index] in the user scripts executed before starting a program |
prerun list | list the user scripts executed before starting a program |
all] | remove the script at [index] in the user scripts or all scripts executed before starting a program |
runscript [filename] | set the user script executed during program execution |
runscript list | list the user script executed during program execution |
runscript remove | clear the user script executed during program execution |
Scripts may be DMON, Tcl or Python. Note that scripts are executed one line at a time; if Tcl or Python scripting is required it would be better to use the source <file> command in Tcl to load a script, or the exec <file> command in Python. Note however that these are atomic commands from DMONs point of view (so the script will not be stopped by DMON).
The script being run during program execution will be stopped when the program stops (for example at a breakpoint). If the script ends while the program is still running it will be started again.
CAUTION: if the script contains a command which cannot be interrupted, it will not be stopped until that command completes. This is especially the case for Python and Tcl scripts.
Triggered Scripts
DMON provides a function which allows the user to monitor an address and to run a script when that address changes. The foreseen scenario is for use with interrupt processors; therefore a bit can be monitored and the facility to clear and mask the monitored bit is provided.
It is the user’s responsibility, if an application is running on the board, to ensure that the application does not handle the interrupt, or at least does not clear it, as this will interfere with the handling of it by DMON.
The flowchart above summarises the operation.
mon [addr] [script] <bit> | Runs script every time addr value changes. If a bit is specified, runs the script when that bit has changed, and clears it. |
mon [pen][clr][msk][script][b] | pen, clr and msk are addresses; b is a bit offset. (1)Bit b in msk is set (2) Bit b in pen is polled, If it is set, script is run (3) Bit b in clr is set (4) Polling resumes (Ctrl-C or mon stop will stop the operation). |
mon stop | stops monitoring if running |
As well as the commands described above, there is a GUI element to set up the scripts. Select the tasks option from the top menu to manage triggered scripts. Similar GUI elements exist for tracing and other scripts.
Data Monitor
Overview
Use this link if problems with youtube above
DMON allows the user to monitor addresses on the board by periodically sampling them. The user can configure a start condition, a stop condition and a number of addresses to poll. The user can also choose to display the data as it is polled in several formats. The data can also be stored in a file.
The top level menu shown in the figure above offers a number of options
- Configure Variable Set: opens a dialog window to configure the current variable set which is being prepared.
- Load Variable Set: load a variable set from an XML file which describes a Variable Set to be monitored. Performs validation and reports any errors to the user.
- Save Variable Set: save the current variable set to an XML file.
- Export XML schema: exports the XML Schema which is used to define the legal XML for a variable set.
- Start Monitoring: Start monitoring the data set. This first performs some additional validity checks on the data set and then starts the polling of data at 100 ms. Start and Stop Conditions are applied.
Monitoring Operation
Once start monitoring is chosen the monitoring state machine shown below becomes operational after the variable set has been validated. Variable set validation ensures that all required items are defined, and that any program symbols used can be resolved. There are a number of options which affect the polling:
- pollWhenNotRunning: If this flag is set, polling starts immediately, otherwise data will only be polled when an application program is running and is being monitored by DMON.
- The optional start and stop triggers must be enabled. Start and Stop trigger are independent.
- Once started polling continues until it is stopped by
- The “Stop Monitoring” item on the menu which replaces the “Start Monitoring”
- The user interrupts DMON operation using the stop command or Ctrl-C
- CAUTION: closing a display window will stop that window displaying data but does not affect polling.
Data Configuration Menu
Dialog Elements
- Name: a name for the data set. This is for documentation purposes in the XML.
- Start Trigger: see below
- Stop Trigger: see below
- Store in file: Boolean flag. If set data will be stored as sampled in the file specified. The format is Date, Time, Subsecond time, Item name, Value(s) as 32 bit hex. For examples see below.
- Filename: name of file in which to store data
- pollWhenNotRunning: If this flag is set, polling starts immediately, otherwise data will only be polled when an application program is running and is being monitored by DMON.
- Configure Display Sets: see below
- Configure Data Items: see below
Start/Stop Trigger
The following items may be configured for the start or stop trigger. Either trigger is optional and will be ignored if not defined or if it is not enabled.
Item | Type | Description |
---|---|---|
Address | String | Address to poll; may use an expression using ELF symbols. This will be evaluated when polling is started by the user and must be valid at that point. |
Mask | 32 bit integer | Value read from address will be compared with the mask using the condition operator described below. Note: Mask will be stored as a string in XML but must be a valid Long integer in Hex, Decimal or Octal format. It is entered as a hex value in the dialog. |
Condition | enumeration | Condition applied to value read and mask to determine whether the condition is met. For bitwise conditions the condition is met if the result of applying it to the value read and the mask is non zero. All comparisons are on the basis of unsigned integers. One of Bitwise And, Bitwise Or, Bitwise XOR, Less than, Greater than, Less than or equal, Greater than or equal, Exactly equal. |
enabled | Boolean | Whether to apply the trigger |
Configure Display Sets
Each Data Item may belong to a Display set. If a display set is in used by a Data Item it is not possible to remove it.
The configure dialog permit setting the parameters for each graph type. The “max samples” option is the upper limit for the number of samples displayed on the graph. Older samples are discarded.
Other parameters govern the scaling and labelling of axes. The screenshots below show how to configure data items and display sets.
Data Item Configuration
Data Items are defined by
- A name; must be unique in the Data Set
- An Address; may use ELF symbols and expressions. If a program has been loaded symbols will be presented in a drop down list for selection.
- Data Type can be SIGNED_INT, UNSIGNED_INT, SIGNED_SHORT, UNSIGNED_SHORT.
- Length is number of data types to sample starting at address above.
- Whether to display the item. If the display option is chosen a drop down list of available display sets is shown.
- The “Parameters” button is used to further configure display, by assigning a colour for example. It depends on the display set chosen.
Output File Examples
This shows several data items being polled, with 5 values being polled from one of the addresses:
2015-06-02, 15:31:50,756000000,x,0x00000219, 2015-06-02, 15:31:50,803000000,beat,0x00000327, 2015-06-02, 15:31:50,804000000,y,0x00000373,0x000003e8,0x00000327,0x400921fb,0x54442d18, 2015-06-02, 15:31:50,868000000,y2,0x000003e8, 2015-06-02, 15:31:50,884000000,x,0x00000219, 2015-06-02, 15:31:50,980000000,beat,0x00000327, 2015-06-02, 15:31:50,981000000,y,0x00000373,0x000003e8,0x00000327,0x400921fb,0x54442d18, 2015-06-02, 15:31:51,39000000,y2,0x000003e8,
Console commands
There are console commands which allow some of the functionality above to be used.
datamon load [filename] | load a DataSet from an xml file |
datamon save [filename] | save the current DataSet to an xml file |
datamon start | Validate the current DataSet. If successful, start monitoring |
datamon stop | stop monitoring |
datamon xsd [filename] | save schema for DataSet to the specified file |
User-defined Devices
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.
Other Features
RTEMS Thread Support
DMON will poll on request the thread table of RTEMS, parsing the structures described below. This functionality requires that some ELF symbols are defined for the program loaded:
• RTEMS Version is read from _RTEMS_version
• Threads tables are searched for in the following locations:
- o _RTEMS_tasks_Information
- o _Thread_Internal_information
• The currently Executing thread control block is read from *_Thread_Executing
• The start and end of ram determined during memory probing are used to sanity check the values read from the tables in order to avoid attempting to read invalid memory addresses.
NOTE: loading an RTEMS application may not initialise the memory for the thread tables. In that case running the RTEMS command from the console or GUI before starting the program will give incorrect results.
This functionality is only supported for RTEMS versions which are identified in the version string as compiled for SPARC. The version string found is shown on starting monitoring (GUI) or when the command is run. If the version is not one of the supported versions polling will be attempted anyway with the defined structures; the user is warned.
There are two commands available from the console:
rtems Read current RTEMS thread information (if available)
rtems dump Dump structures used to read RTEMS thread information
Once an RTEMS application has been loaded at least once during the session, and the GUI is active, a GUI menu is available:
If “Start Monitoring” is selected, the Thread tables will be polled at the specified interval – by default once per second. The results are shown in a GUI window. This window cannot be closed while polling is active, regardless of whether the application is running or not. Polling can be stopped from the menu. Once started, the “Start Monitoring” menu point becomes a “Stop Monitoring” menu point.
The following are read from each thread structure:
Name | C variable | Type | Offset : Size |
---|---|---|---|
API | the_api | Objects_APIs | 0 : 4 |
Max. Index | maximum | unsigned short int | 16 : 2 |
Table | local_table | Objects_Control ** | 28 : 4 |
Each Thread control block has the following data read from it:
Name | C variable | Type | Offset : Size |
---|---|---|---|
Name | Object.name | Objects_Name | 12 : 4 |
ID | Object.id | Objects_Id | 8 : 4 |
Priority | current_priority | Priority_Control | 20 : 4 |
Entry Point | Start.entry_point | Thread_Entry | 156 : 4 |
Current PC | Registers.o7 | uint32_t | 340 : 4 |
Running time | cpu_time_used | struct timespec | 132 : 8 |
State | current_state | long unsigned int | 16 : 4 |
Example output for console command:
rtems-4.10.1(SPARC/w/FPU/leon3)
TA1 CLASSIC 0x0a010002 1 0x40001420 (Test_task) 0x40016bfc (_Thread_Dispatch + 0xd8) 0:00:00,960459000 0x00000008 (Delaying)
* TA2 CLASSIC 0x0a010003 1 0x40001420 (Test_task) 0x4000a194 (apbuart_outbyte_polled + 0xc) 0:00:00,374664000 0x00000000 (Ready)
TA3 CLASSIC 0x0a010004 1 0x40001420 (Test_task) 0x40016bfc (_Thread_Dispatch + 0xd8) 0:00:00,254531000 0x00000008 (Delaying)
IDLE INTERNAL 0x09010001 255 0x40009e10 (bsp_idle_thread) 0x40016bfc (_Thread_Dispatch + 0xd8) 0:04:38,710598000 0x00000000 (Ready)
GDB Remote Target
GDB is a standard command line debugger. It needs to be ported to a particular gcc tool chain and also needs to be aware of the operating system (if any). Programmes compiled as a Bare-C or using RTEMS use sparc-rtems-gdb. Programmes compiled using sparc-elf-gcc will use sparc-elf-gdb.
For complete details on GDB functionality, refer to the GDB Manual, available online at the following URL https://sourceware.org/gdb/current/onlinedocs/gdb/ (Note that this is for the latest version, and the versions used are typically older
GDB provides a remote protocol for communication between GDB and a target. The GDB server component of DMON supports this protocol.
DMON must be listening for GDB connections. This is done by issuing the “gdb” command at the DMON console. This takes a TCP port as an optional argument. The default port is 1234.
GDB needs to connect to DMON. This is done by issuing the following command at the gdb prompt.
- target extended-remote <ip address/hostname of machine running DMON>:<port>
If both DMON and GDB are run on the same machine “localhost” or simply “:port” can be used.
GDB operation is then as normal. It is possible to issue any DMON command through GDB and the output of these commands is visible on the GDB console. These commands need to be prefixed with the keyword “monitor”. Note that using commands which start or stop the program will interfere with GDB knowledge of the program and will lead to errors. Break and watchpoints should only be set using GDB and run and continue should only be issued through GDB.
After loading the program, it should be started with the “run” command to ensure correct initialisation, “continue” should only be used after a breakpoint has been hit.
Note that is typically necessary to reload an RTEMS application that has been run already before running it again – this is because loading the program correctly initialises data tables used by RTEMS.
Note that GDB will timeout after about 2 seconds if it does not receive any input from DMON. To avoid this happening an empty string is sent to GDB every 1.5 seconds when a long running command is running. This prevents the timeout but does not affect what a human user sees. It may affect what is seen in a GDB scripted session.
The user can modify the GDB Timeout by issuing the following GDB cli option or command before connecting to DMON:
- -l timeout Sets the timeout (in seconds) of any communication used by GDB for remote debugging.
At the GDB prompt it is possible to issue the command “set remotetimeout num” which sets the timeout limit to wait for the remote target to respond to num seconds. The default is 2 seconds. If connections are causing problems it is recommended to increase this timeout.
DMON supports setting Software Breakpoints, Hardware Breakpoints and Read/Write and Access Watchpoints through GDB. There are several limitations on this; see below.
The DMON GDB Server only allows one GDB connection at a time. It will continue listening for GDB connections and serving them until either the “gdb detach” command is executed or CTRL-C is pressed for DMON. CTRL-C works as though the GDB detach command had been issued first.
There are limitations around the use of data watchpoints and hardware breakpoints:
- 1. HW Breakpoints and watchpoints are set on all CPUs in a multiple cpu system if requested by GDB.
- 2. If GDB requests more than the number of watchpoints/hardware breakpoints that are supported by the board, DMON will return an error code. The behaviour seen by the GDB user is that GDB reports a message such as “Cannot remove breakpoints because program is no longer writable.”
If a problem is observed in conjunction with the GDB tool additional helpful information can be gained from the communications log in GDB. To get such a log, issue the command “set remotelogfile <filename>” before connecting to DMON with “target extended-remote”
Trace Buffer and Call Graph Support
DMON allows a complete instruction trace to be obtained from a running application. Profile information is presented graphically and a file with each executed instruction is produced for offline analysis. This is in addition to the profile command, which samples the program counter periodically and therefore is only an estimate.
The itrace enable command initiates the instruction trace capture. This command will only work on processors with an instruction trace capability, and the command will not be available unless the hardware support is. It will significantly slow down operation as the instruction trace buffer can only be read when the processor is stopped – therefore the processor is stopped each time the buffer is full. Note also that this feature uses the hardware breakpoint functionality, and may conflict with hardware breakpoints set by the user. It is recommended not to use HW breakpoints when using itrace.
Part of a sample profile is shown below. The vertical axis shows the function names executed, taken from the ELF symbols. The horizontal axis shows the number of times the function has been called. Different colours on the bars indicate which CPUs executed the function.
Note that the graph functionality requires ELF symbols. If there are none available then the instructions will be logged but the graph will be empty.
The detailed instruction trace data is written into the folder C:\Users\<username>\DMON\UserData on Windows or /home/<username>/DMON/UserData on Linux with the name iTraceLogDD-MM-YYYY_HHMMSS.txt. A new log file is started once 50 MB of data has been accumulated; the files from the same program run are labelled with the same time stamp but part_0, part_1 etc. in sequence. The file initially created will be renamed to part_0. An example of the start of a trace file is shown below. These files contains every instruction executed during the run and may be used for offline analysis.
## LOGGING STARTED 10-05-2016_143029 00470298310 cpu0 40002AD8 sethi %hi(0xa5a5a400), %g2 [A5A5A400] 00470298310 cpu3 40002278 cmp %g2, 0xc [FFFFFFF9] 00470298311 cpu0 40002ADC bset 0x1a5, %g2 [A5A5A5A5] 00470298311 cpu3 4000227C ld [%fp + 0x68], %g2 [13483119] 00470298319 cpu0 40002ADC bset 0x1a5, %g2 [A5A5A5A5] 00470298320 cpu0 40002AE0 st %g2, [%l0 + 0x3c] [410800BC] 00470298321 cpu0 40002AE4 mov 0x1, %g2 [00000001] 00470298327 cpu0 40002AE8 st %g2, [%l0 + %g0] [41080080] 00470298328 cpu0 40002AEC cmp %g1, 0x0 [00000002] 00470298329 cpu0 40002AF0 be giveToCpu + 0x104 [00000000] 00470298330 cpu0 40002AF4 sethi %hi(0x380b0000), %g1 [380B0000] 00470298333 cpu0 40002AF8 bset %g1, %i0 [380B0004] 00470298334 cpu0 40002AFC sethi %hi(0x80000000), %g1 [80000000] 00470298335 cpu0 40002B00 bset 0x210, %g1 [80000210] 00470298339 cpu3 4000227C ld [%fp + 0x68], %g2 [00000000] 00470298341 cpu0 40002B04 st %i0, [%g1 + %g0] [80000210] 00470298341 cpu3 40002280 st %g2, [%fp - 0x8] [67FFFE98] 00470298342 cpu0 40002B08 ret [40002B08] 00470298343 cpu0 40002B0C restore [00000000] 00470298343 cpu3 40002284 ld [%fp + 0x70], %g2 [00000000] 00470298349 cpu3 40002288 st %g2, [%fp - 0x4] [67FFFE9C] 00470298350 cpu3 4000228C mov %i1, %g1 [0000000A]
The video below gives a brief demo of the callgraph command.
Use this link if problems with youtube above
If trace buffer is enabled and a program has been executed, you can issue the callgraph command. The callgraph command allows you to see graph of each function found during itrace and its call hierarchy. The callgraph command can accept as its first argument the root node which sets the graph root to that function and anything not called from here is discarded. Here is example of issuing the “callgraph” command on its own
callgraph
If we issue “callgraph main”, you will see that the root node is the main function and anything before this function call or not called from main isn’t visible
callgraph main
Another feature of the callgraph command is filtering. The filtering argument (which is used with “filter:”) can accept multiple regular expressions so that any functions matching those filters are excluded from the graph. This image shows the exclusion of any function that begins with “__” with the root still being main
callgraph main filter: __
As mentioned before we can include many different expressions to filtering, here is an example of having the root as main and filtering with “__” and “fflush”
callgraph main filter: __ fflush
There are also a few built in expressions that can be used for convince
callgraph filter: rtems rtems functions prefixed with rtems_ are removed callgraph filter: ecos ecos functions called prefixed with cyg_ are removed callgraph filter: _ functions prefixed with _ are removed callgraph filter stdlib standard stdlib function calls removed
LEON4/LEON3 Statistics Module
If the Leon 4/3 statistics module is present on the target it can be configured either graphically or using commands. It is outside the scope of this document to give a full description of the LEON4 Statistics module; the user should consult the document supplied with their particular hardware.
It should however be noted that a single device will be present on two buses, and the user should choose the interface through which the device is controlled to minimize impact on their testing. If more than one device is present on the target, the command for second device has underscore and index (l3stat_1).
DMON > l3stat events datawritebuffhold : Data write buffer hold : 0x10 totalinscount : Total instruction count : 0x11 intins : Integer instructions : 0x12 fpunitinscount : Floating-point unit instruction count : 0x13 branchpremiss : Branch prediction miss : 0x14 exectime : Execution time, excluding debug mode : 0x15 ahbutilper : AHB utilization (per AHB master) : 0x17 hbutiltotal : AHB utilization(total) : 0x18 .........
DMON > l3stat status CPU0 Total instruction count 0 CPU0 Branch prediction miss 0 CPU0 Execution time, excluding debug mode 0 CPU0 Branch prediction miss 0
DMON > l3stat display workers all Worker 0: CurrentRead :0 Hold :false Time :0.0 Interval :1000 TotalRead :0 Counter :0 Running :false RunPoll :true EventID :Data write buffer hold CleanOnRead :true Enabled :true Worker 0: CurrentRead :0 Hold :false Time :0.0 Interval :1000 TotalRead :0 Counter :1 Running :false RunPoll :true EventID :Integer instructions CleanOnRead :true Enabled :true
DMON > l3stat display workers 3 Worker 3: CurrentRead :0 Hold :false Time :99.74 Interval :1000 TotalRead :0 Counter :3 Running :true RunPoll :false EventID :Branch prediction miss CleanOnRead :true Enabled :true
DMON > l3stat display counters all Counter 0 : EventID :Data write buffer hold CleanOnRead :true Enabled :true Counter :0 CPU :0 CounterValue :0 EventLevel :false Counter 1 : EventID :Integer instructions CleanOnRead :true Enabled :true Counter :1 CPU :0 CounterValue :0 EventLevel :false
DMON > l3stat set 0 cpu=0 event=0x15 cl=1 su=0 en=1 // Set in counter 0 CPU/AHB index to 0, event to 0x15( or abbreviation can be used "exectime") event=0x15 ,clear on read en=1, Supervisor/User mode filter su=0 and Enable counter (EN) en=1 Warning. Parameter event cannot be evaluated. Using as it is : 0x15 Command l3stat set executed successfully.
DMON > l3stat duration 3 enable lvl // Enable duration on counter 3 and set Level
DMON > l3stat poll 2 1000 save // Start polling counter 2 at 1000ms interval and save data to the csv file
DMON > l3stat poll 2 1000 hold save // Start polling enable bit in control register of counter 2 at 1000ms interval till software or user enables counter and only then DMON will start to poll value register and save data to the csv file
DMON > l3stat runpoll 1 1000 save // DMON will start polling counter 1 when program starts running on the board at interval 1000ms and save data to csv file
DMON > l3stat stop 3 // Stop polling counter 3. The counter will be disabled. If started with save option, then data will be available in csv file located in DMON installation directory and file name l3stat_Counter_3-07-17-2019 16-40-38.csv The polling worker for counter 3 was stopped Disabled counter: 3 Device: 0
DMON > l3stat stop all // Disable all the polling workers The polling worker for counter 0 was stopped The polling worker for counter 1 was stopped The polling worker for counter 2 was stopped The polling worker for counter 3 was stopped Disabled counter: 3 Device: 0 Disabled counter: 2 Device: 0 Disabled counter: 1 Device: 0 Disabled counter: 0 Device: 0
DMON Statistic Module Menu :
Statistic Viewer Panel. User can load previously generated csv file by statistic module
Statistic Jobs Status View per device. All Created jobs are displayed in this view. User can cancel job by clicking in "Remove" column.
Create New Job Dialog. Hover all the fields to get more information. Optional settings will set Counter Control Register. This register can be configured before and left empty except job configurations like save to file, hold or Poll when running, functionality of which are described above.
Create New Event Dialog. If DMON is missing event that supported by Hardware, than user can add this event and use in commands
Statistics Graph. Shows data as Line Graph per counter.
Statistics Graph. Shows data as table per counter.
Video Tutorial:
Use this link if problems with youtube above
Command | Command Description |
---|---|
l4stat events | Show all events that can be selected/counted |
l4stat events [hex][abbr][descr] | Add new event to DMON (hardware must support this code). hex->code value, abbr->abbreviation, descr->description |
l4stat clear [cnt] | Clear the counter cnt. |
l4stat status | Display status of all available counters. |
l4stat display [workers|counters] <all|n> | Display information on workers or counters |
l4stat set [cnt][flag=value] | Count the event using counter cnt on processor cpu. Use enable flag(en) the last. Available flags: cpu=val, event=val, cl=1|0, su=0|1|2, en=1|0 |
l4stat duration [cnt][enable|disable]<lvl> | If Enabled the core will save the maximum time the selected event has been at the level specified by the EL field. If level(lvl) is present the counter will count the cycles, otherwise will count the time between event assertions |
l4stat poll [cnt][int]<hold><save> | Continuously poll counter(cnt) at interval(int)(min value 100 ms).If hold parameter is passed, DMON will poll for Counter control register till software enables the counter and only then will start to poll for counter value. If save parameter is used, DMON will save data to csv file |
l4stat runpoll [cnt][int]<save> | Poll counter(cnt) at interval(int)(min value 100 ms) while application is running. DMON will start polling, when program starts running on the board. If breakpoint is hit, DMON will pause polling and resume after program will continue. If save parameter is used, DMON will save data to csv file |
l4stat stop [cnt|all] | Stop polling of Counter Register for counter(cnt) or all and disable counter |
l3stat events | Show all events that can be selected/counted |
l3stat events [hex][abbr][descr] | Add new event to DMON (hardware must support this code). hex->code value, abbr->abbreviation, descr->description |
l3stat clear [cnt] | Clear the counter cnt. |
l3stat status | Display status of all available counters. |
l3stat display [workers|counters] <all|n> | Display information on workers or counters |
l3stat set [cnt][flag=value] | Count the event using counter cnt on processor cpu. Use enable flag(en) the last. Available flags: cpu=val, event=val, cl=1|0, su=0|1|2, en=1|0 |
l3stat duration [cnt][enable|disable]<lvl> | If Enabled the core will save the maximum time the selected event has been at the level specified by the EL field. If level(lvl) is present the counter will count the cycles, otherwise will count the time between event assertions |
l3stat poll [cnt][int]<hold><save> | Continuously poll counter(cnt) at interval(int)(min value 100 ms).If hold parameter is passed, DMON will poll for Counter control register till software enables the counter and only then will start to poll for counter value. If save parameter is used, DMON will save data to csv file |
l3stat runpoll [cnt][int]<save> | Poll counter(cnt) at interval(int)(min value 100 ms) while application is running. DMON will start polling, when program starts running on the board. If breakpoint is hit, DMON will pause polling and resume after program will continue. If save parameter is used, DMON will save data to csv file |
l3stat stop [cnt|all] | Stop polling of Counter Register for counter(cnt) or all and disable counter |
Remote Access using DMON
The target system may need to be shared by different developers, some of whom are working remotely, or be in an environment not suitable for software debugging activities.
To help address these types of issues, DMON can be used in a client-server configuration, with the target system connected directly to a DMON server, and a client DMON linked to the server over the Internet. The link between them is secured using SSL.
The user on the DMON client is able to carry out all the functions available when connected directly to the target.
In addition the user can ask for a session to be kept alive, and shut down the client only. Any client can re-connect to this session later by giving the session-id.
Commands are provided also to allow a client download program files to a designated area on the server. These can then be loaded into target memory by any client.
In the client-server configuration a license is not required on the client DMON.
Define alias for DMON command
DMON provides a mechanism to define an alias for any of its commands. The DMON installation folder (e.g. C:\Program Files (x86)\DMON\Local) contains a text file called local_commands.txt. This file contains a mapping for commands. The first word is the alias and the second word is the DMON command. For example if the line "reset init" is added to the file, the user can use the command reset to execute the DMON init command.
Elf File Image information
This is primarily metadata such as the sources of the files containing the loaded program images and parameters such as creation and modification dates and times.
By default, when a program is loaded DMON's information about previously loaded programs is deleted and only that for the program just loaded is kept.
The optional add[] parameter of the load and rload commands causes the previous information to be retained.
When an image is loaded, a unique image identifier string is created. By default this is the first part of the filename with internal whitespaces removed. The user can create an identifier using the add[] parameter. (The image identifier is used also as a source identifier when evaluating symbols).
Image information commands:
iminfo <imageidentifier> show metadata on specified image or on all images iminfodel delete all metadata and symbol information
Note that these commands relate only to DMON’s knowledge of what is present on the target and have no effect on the contents of target memory. Program images may be present in target memory but not known to DMON. Target memory areas may be cleared using DMON’s write command if required. DMON only knows about the images that have been loaded in the current DMON session.
Expressions and symbols
A DMON parameter that is an integer number can be given as an expression involving numerals, symbols and operators, e.g. examine 0x40000000, examine main, examine main + 0x1000 * (count + 1). Operators are
+,-,*,/,%,>>,<<,&,^,|, (, ),
with the standard precedence, so evaluation order may differ from that in which operators appear, e.g. examine 2+3*4 evaluates to examine 14, not to examine 20.
Binary numerals start with ‘0b’ or ’0B’, hexadecimal with ‘0x’ or ‘0X’, other numerals that start with 0 are octal (N.B.), and numerals that do not start with 0 are denary (base ten).
Symbols begin with an alphabetic character or underscore ‘_’. They do not contain white space, control characters, the character ‘:’ nor the characters ‘[‘ or ‘]’.
Expressions can include white space, and evaluate to 64 bit long integers. Some commands may reject parameters outside a 32 bit range, making it necessary to 'and' a result with 0xffffffff. In particular this may be needed when results have negative values.
Parameters are separated by white space or a comma(,). If a parameter begins with a unary plus or minus a comma is used to separate it from earlier parameters, e.g. write 0x40000000 + offset , -20 & 0xffffffff 10 writes the value 0xffffffec to 10 words starting at address 0x40000000+offset.
Symbols may be user defined or come from one or more loaded program images. There are also internal DMON symbols generally not used after DMON startup.
The same symbol may be defined in different sources. The instance to use can be specified by prefixing the symbol with a source identifier, e.g. myfile3:main, _user:a.
When a source identifier is used, the symbol is looked for in that source only. Evaluation fails if the symbol does not exist in that source, even though it exists elsewhere.
When no source identifier is used, a symbol is looked for first in DMON’s internal symbols, then in user defined symbols, and finally in the program images. If it cannot be found, or exists only in program images but with differing values, evaluation fails.
A warning is given if a user creates a symbol that conflicts with an existing symbol. The definition takes place and will shadow that symbol in loaded images unless a source identifier is used.
The value associated with a symbol can be found in a number of ways:
lookup <symbolname> returns the value currently associated with symbolname. find <symbolname> finds all occurrences of the symbol unless symbolname includes a source identifier (e.g. myimage:sym), in which case only the specified source is searched.
All symbols that occur in the currently loaded images can be displayed in value order:
symbols <file> show all symbols in currently loaded images or adds symbols from a file.
Further commands are provided for dealing with user defined symbols.
User Defined Symbols
In client-server mode, user defined symbols are known only on the client.
User defined symbols can be constants or variables.
Constant symbols are assigned a value calculated when the symbol is defined. This only changes when the symbol is redefined Variable symbols are assigned an expression. This is re-evaluated each time the symbol is used Commands:
setv symbolname expression create a constant symbol, the expression is evaluated when the ‘setv’ command is executed, and a 64 bit signed long integer value assigned to the symbol. Any language in use has its symbol table updated. set symbolname expression create a variable symbol, the expression is re-evaluated each time the symbol is used. Any language in use has its symbol table updated with the initial value only. show <symbolname> shows the expression or value corresponding to the given symbolname, or show all user defined symbols in alphabetical order. delv [symbolname|#] delete the user defined symbol or delete all user defined symbols
Examples :
setv a 5 a now has the value 5 setv b a + 7 b now has the value 12 set c a*b c will evaluate to 60 when next used setv a 3 a now has the value 3, b is still 12, unchanged c will evaluate to 36 when next used
Lookup can be restricted to user defined symbols only using the source identifier “_USER:” or “_user:” .
If no source identifier is given, user defined symbols are shadowed by DMON’s internal symbols as these are looked up first. User defined symbols themselves take precedence over symbols defined in the loaded program images.
Load command add[] parameter
This causes DMON's information about the image being loaded to be added to that for the images already present. If not used, DMON’s internal information on images previously loaded is deleted when a program is loaded.
The add[] parameter has a number of optional sub-parameters, allowing the user identify which CPU is to be used with this image, and to define an image identifier to use instead of the default.
When no add[] parameter is used, the load and rload commands set the PCs of all CPUs on the target to the starting address of the image.
If the add[] parameter is used, the user can select the CPU to use with the image. If this is not selected the image start address is not transferred to any CPU’s PC.
Add parameter options (in all cases the information on previously loaded images is kept):
add[] PC is not set, image’s default identifier is used add[cpu,identifier] PC of cpu is set to image start address, identifier is used instead of the default add[CPUx] PC of CPU x is set to image start address, 'CPUx' used as identifier add[cpu], add[cpu,], add[cpu,””] PC of cpu is set to image start address, default identifier is used add[identifier], add[,identifier] PC not set, identifier used instead of default
The cpu and x above must evaluate to an integer 0,1,2,... that corresponds to one of the CPUs on the target. If not it is ignored and a warning given to the user.
The identifier above must begin with an alphabetic character or underscore ‘_’. It should not contain control characters or the characters ‘,’ ‘:’, ‘[‘ or ‘]’. If it is illegal or not present the default identifier for the image is used.
Note: the iminfodel command can be used to remove all internal DMON information on previously loaded images.