# Overview
The Debug Server Scripting (DSS) Test Server example creates a [**Debug Server Scripting**](https://software-dl.ti.com/ccs/esd/documents/users_guide/sdto_dss_handbook.html) (DSS) instance for a [target configuration](https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html#target-configuration-files) and starts a debug session for all debuggable cores on the target in its own Java thread. Each thread will then listen for commands on an open TCP/IP socket. Remote clients can communicate to the active debug session by connecting to the socket and sending appropriate commands.
# Dependencies and Setup
DSS and the DSS Test Server example come bundled with Code Composer Studio (CCS). Hence an installation of CCS is required.
[[+y If you are using CCSv9.0.x or earlier (expand)
The DSS Test Server example has been updated in CCSv9.1.0. To use the updated example with older CCS versions, please download the [latest example](./files/TestServer.zip) and use it to replace the existing obsolete example found in [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer. You can rename the existing **TestServer** folder and then extract the newly downloaded **TestServer.zip** in [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples to replace it.
+]]
The scripts that configure and start the DSS Test Server are written in [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) (the native scripting language supported by DSS).
Three remote client script examples have been provided to send commands to toe DSS Test Server, written in:
* [Perl](https://www.perl.org/): **perl_client.pl**
An installation of Perl is needed to use the Perl script "as-is". The [JSON (JavaScript Object Notation) encoder/decoder Perl module](https://metacpan.org/pod/JSON) also needs to be installed.
The associated module **DSSClient.pm** is needed.
* [Python](https://www.python.org/): **python_client.py**
An installation of Python is needed to use the Python script "as-is".
The associated module **DSSClient.py** is needed.
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript): **js_client.js**
JavaScript is the native scripting language supported by DSS, so no additional installations are needed.
The associated module **DSSClient.js** is needed.
For this example you may choose any of the three client scripts.
[[b NOTE
Older CCS installations only comes with a Perl client script example. If you do not wish to update your CCS version, you can separately download the JavaScript and Python client script example files from [here](https://software-dl.ti.com/ccs/esd/documents/files/py_js_client_examples.zip).
]]
[[b NOTE
Any language of choice can be used to communicate to the remote server and send the desired debug commands to the target. See the [Format](#format) section for more details on how the commands should be formatted.
]]
The client scripts and DSS server JavaScript (**test_server.js**) are configured to run the [SYS/BIOS **hello** example](https://dev.ti.com/tirex/content/simplelink_cc2640r2_sdk_2_40_00_32/examples/rtos/CC2640R2_LAUNCHXL/sysbios/hello/README.html) for the [CC2640R2 LaunchPad](https://www.ti.com/tool/LAUNCHXL-CC2640R2).
To configure the example to use a different target/example:
1. Open the **test_server.js** script (located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer) in your text editor.
2. Modify the **configFile** field on **line 6** of the JavaScript by replacing **CC2640R2F.ccxml** with the name and path of the [target configuration file](https://software-dl.ti.com/ccs/esd/documents/users_guide/sdto_dss_handbook.html#target-configuration) for your target.
3. Modify the **name** field on **line 11** of the JavaScript by replacing **Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0** with the unique name for the connection/CPUName for your target configuration. For more example on unique names, please see the **openSession()** API examples mentioned in the [DSS guide](https://software-dl.ti.com/ccs/esd/documents/users_guide/sdto_dss_handbook.html#multiple-debug-sessions-for-multi-core-debug). To open a debug session for additional CPUs of a multi-core device, add an entry for each desired session under the **sessions** field.
**For Perl**:
- Open the **perl_client.pl** script (located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer) in your text editor.
- Modify **line 84** of the perl script by replacing **hello_CC2640R2_LAUNCHXL_tirtos_ccs.out** with the name and path of the program to be used.
- Save all files.
**For Python**:
- Open the **python_client.py** script (located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer) in your text editor.
- Modify **line 96** of the python script by replacing **hello_CC2640R2_LAUNCHXL_tirtos_ccs.out** with the name and path of the program to be used.
- Save all files.
**For JavaScript**:
- Open the **js_client.js** script (located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer) in your text editor.
- Modify **line 113** of the script by replacing **hello_CC2640R2_LAUNCHXL_tirtos_ccs.out** with the name and path of the program to be used.
- Save all files.
## Start the Test Server:
Open a command window by running the **setenv.bat** file located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer
Start the Test Server example by running the **test_server.js** script:
```text
> dss test_server.js
```
The Test Server will take a few moments to start up. You will know it is fully up when you are notified that the *TestServer is ready*.
![](./images/dss_testserver01.png)
[[y NOTE
Linux/MacOS users will not be able to set up the environment with the Windows specific **setenv.bat** file. Please refer to the batch file and then configure your environment accordingly.
]]
## Run the Test Server Client example:
Open a command window by running the **setenv.bat** file located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer
Run the Client example by running the **perl_client.pl**, **python_client.py** or **js_client.js** script (located at: [CCS_INSTALL_DIR]/ccsv[x]/ccs_base/scripting/examples/TestServer) and passing in the host and port of the Test Server debug session you wish to connect to. For this example, use **localhost** for the host and port number **4444**.
**For Perl**:
```text
> perl perl_client.pl "localhost" 4444
```
**For Python**:
```text
> python python_client.py "localhost" 4444
```
**For JavaScript**:
```text
> dss js_client.js "localhost" 4444
```
This will run the Client example for the specified debug session. A series of messages will appear in both consoles as messages are being passed between the client and server. The client script will open a connection to specified host and port number, and then send a series of commands that the server will receive and attempt to execute on the associated debug session. The status of the command will be sent back to the client (**OK** or **FAIL**). Any failure will also have an associated message describing the cause of the failure. Note that the client script *intentionally* has some invalid commands to demonstrate how failures are handled.
[[y NOTE
The client script sends the [**stop**](#stop) command towards the end of the script. This will remotely shutdown the test server, preventing any future remote connections, and requiring a restart of the test server. Do not send the **stop** command if your wish to have the test server running and available for future connections.
]]
# Commands
## Format
The format of the data communicated between the host and client are JSON objects. [JSON (JavaScript Object Notation)](https://www.json.org) is a lightweight computer data interchange format based of JavaScript.
JSON objects are a set of name/value pairs. An object begins with "{" and ends with "}". Each name is followed by ":" and the name/value pairs are separated by ",".
Example:
```json
{"name":"timeout","timeout":10000}
```
### Using the DSSClient Perl Module
The **DSSClient** Perl module provides an **execute** function that can take a Perl data structure and encode it to JSON format. Hence one simply needs to format the command they wish to send to the Test Server in a data structure and use the execute command to encode it to the JSON format and send the command. For example, the **halt** command (to halt the target) has no parameters. The element in the data structure would be the name of the command:
```perl
# Halt the target
$cmd = {
"name" => "halt",
};
```
The first element is always the name of the command.
Let's take a look at a command with many parameters... like the **loadRawFromFile** command (load a binary file from the PC to target):
```perl
# Load binary file to memory.
$cmd = {
"name" => "loadRawFromFile",
"page" => 0,
"address" => 0x10000,
"file" => "loadRawFromFile.bin",
"wordSize" => 32,
"byteSwap" => 0,
};
```
### Using the DSSClient Python Module
The **DSSClient** Python module provides an **execute** function that can take a Python dictionary and encode it to JSON format. Hence one simply needs to format the command they wish to send to the Test Server in a dictionary and use the execute command to encode it to the JSON format and send the command. For example, the **halt** command (to halt the target) has no parameters. The element in the data structure would be the name of the command:
```python
# Halt the target
cmd = {
"name": "halt",
}
```
The first element is always the name of the command.
Let's take a look at a command with many parameters... like the **loadRawFromFile** command (load a binary file from the PC to target):
```python
# Load binary file to memory.
cmd = {
"name": "loadRawFromFile",
"page": 0,
"address": 0x10000,
"file": "loadRawFromFile.bin",
"wordSize": 32,
"byteSwap": 0,
}
```
### Using the DSSClient JavaScript Module
The **DSSClient** JavaScript module provides an **execute** function that can take a JSON object. Hence one simply needs to format the command they wish to send to the Test Server in a JSON object and use the execute command to send the command. For example, the **halt** command (to halt the target) has no parameters. The element in the data structure would be the name of the command:
```javascript
// Halt the target
cmd = {
"name": "halt",
}
```
The first element is always the name of the command.
Let's take a look at a command with many parameters... like the **loadRawFromFile** command (load a binary file from the PC to target):
```javascript
// Load binary file to memory.
cmd = {
"name": "loadRawFromFile",
"page": 0,
"address": 0x10000,
"file": "loadRawFromFile.bin",
"wordSize": 32,
"byteSwap": 0,
}
```
---
All commands return a status to indicate if the command succeeded (**OK**) or failed (**FAIL**). In JSON format, it would be status":"OK" or status":"FAIL". The command can also return additional values, usually a failure message if the command failed, or data if it is a command requesting data (such as **readData**).
## List of Commands
The following commands are currently supported. Since many of the commands call an equivalent [DSS API](https://software-dl.ti.com/ccs/esd/documents/users_guide/sdto_dss_handbook.html#dss-api), it is recommended to get familiar with the DSS API documentation for a better understanding of the commands.
---
### stop
Close the socket
**Format**
{"name":"stop"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### connect
Connect to the target
**Format**
{"name":"connect"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### disconnect
Disconnect from the target
**Format**
{"name":"disconnect"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### load
Loads a program on the target
**Format**
{"name":"load","program":[file name]}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### run
Synchronous run command. This command will block until the program is halted or a script timeout occurs
**Format**
{"name":"run"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### runAsynch
Asynchronous run command. This command will run the target and return
**Format**
{"name":"asynch"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### halt
Halt the target
**Format**
{"name":"halt"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### reset
Reset the target
**Format**
{"name":"reset"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### timeout
Set the DSS timout value for synchronous APIs
**Format**
{"name":"timeout","timeout":[value]}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### redirectCIO
Redirect CIO messages to a file
**Format**
{"name":"redirectCIO","file":[file name]}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### setBreakpoint
Set a breakpoint on an address or symbol
**Format**
{"name":"setBreakpoint","address":[address value (int) or symbol name (string)]}
**Returns**
status (OK or FAIL), message (breakpoint ID or failure message)
---
### removeAllBreakpoints
Remove all set breakpoints
**Format**
{"name":"removeAllBreakpoints"}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### loadRawFromFile
Load a binary file to writable target memory. This command will not work with flash memory.
**Format**
```text
{
"name":"loadRawFromFile",
"page":[memory page],
"address":[address value],
"file":[file name],
"wordSize":[size of word (in bits)],
"byteSwap":[byte swap enable ('0' = false, '1' = true)]
}
```
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### saveRawToFile
Save target memory contents to a binary file
**Format**
```text
{
"name":"saveRawToFile",
"page":[memory page],
"address":[address value],
"file":[file name],
"length":[number of bytes],
"wordSize":[size of word (in bits)],
"byteSwap":[byte swap enable ('0' = false, '1' = true)]
}
```
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### loadDataFromFile
Load a *.dat file to writable target memory. This command will not work with flash memory.
**Format**
```text
{
"name":"saveRawToFile",
"page":,
"address":,
"file":,
"length":
}
```
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### saveDataToFile
Save target memory contents to a *.dat file
**Format**
```text
{
"name":"saveRawToFile",
"page":[memory page],
"address":[address value],
"file":[file name],
"length":[number of bytes],
"ioFormat":[see DSS API documentation for ioFormat values],
"append":[enable append to file ('0' = false, '1' = true)]
}
```
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### loadGel
Load a GEL file
**Format**
{"name":"loadGel","file":[file name]}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### runGel
Run a GEL expression
**Format**
{"name":"runGel","expression":[GEL expression]}
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### readData
Read one integer value from memory
**Format**
```text
{
"name":"readData",
"page":[memory page],
"address":[address value],
"typeSize":[bit size of value to read],
"signed":[return value is signed ('0' = false, '1' = true)]
}
```
**Returns**
status (OK or FAIL), value (if status is OK), message (if status is FAIL)
---
### writeData
Write one integer value to writable target memory. This command will not work with flash memory.
**Format**
```text
{
"name":"writeData",
"page":[memory page],
"address":[address value],
"value":[value to write],
"typeSize":[bit size of value to write]
}
```
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
### readDataArray
Read multiple values from memory
**Format**
```text
{
"name":"readDataArray",
"page":[memory page],
"address":[address value],
"typeSize":[bit size of the values to read],
"numValues":[number of values to read],
"signed":[return value is signed ('0' = false, '1' = true)]
}
```
**Returns**
status (OK or FAIL), value (if status is OK), message (if status is FAIL)
---
### writeDataArray
Write multiple values to writable memory. The values parameter takes a string of values delimited by a comma ("1,2,3,4"). This command will not work with flash memory.
**Format**
```text
{
"name":"writeData",
"page":[memory page],
"address":[address value],
"values":[values to write to memory],
"typeSize":[bit size of values to write]
}
```
**Returns**
status (OK or FAIL), message (if status is FAIL)
---
## Custom Commands
Additional custom commands can be created. Simply create them in your server side script and add them using the **addHandlers()** API. See **test_server.js** for an example.
# Files
The following files are the core files that the examples depend on.
* **DSSClient.pm** - Perl module that enable customers to talk over a TCP/IP socket to a DSS TestServer as implemented in **TestServer.js**. Requires a version of Perl with JSON support. This file is only needed by Perl based client scripts.
* **DSSClient.py** - Python module that enable customers to talk over a TCP/IP socket to a DSS TestServer as implemented in **TestServer.js**. Requires a version of Python. This file is only needed by Python based client scripts.
* **DSSClient.js** - JavaScript module that enable customers to talk over a TCP/IP socket to a DSS TestServer as implemented in **TestServer.js**. This file is only needed by JavaScript based client scripts.
* **json2.js** - JSON utility JavaScript file that creates a global JSON object containing two methods: **stringify** and **parse**.
* **TestServer.js** - JavaScript file where the bulk of the functionality is found, implemented in JavaScript/DSS. Starts a DSS instance for a specified target configuration, and then starts a debug sessions for all debuggable cores, each in its own Java Thread and waits for connections/commands on a TCP/IP socket per session.
* **readme.txt** - Link to this document.
The rest of the files are example files that would vary between users and is provided as an example on how to use the above (minus **readme.txt**) core scripts. The key files to be aware of are:
* **perl_client.pl** - Example client script. Demonstrates the use of **DSSClient.pm** by creating a **DSSClient** instance and sending scripting commands to an active DSS Test Server debug session.
* **python_client.py** - Example client script. Demonstrates the use of **DSSClient.py** by creating a **DSSClient** instance and sending scripting commands to an active DSS Test Server debug session.
* **js_client.js** - Example client script. Demonstrates the use of **DSSClient.js** by creating a **DSSClient** instance and sending scripting commands to an active DSS Test Server debug session.
* **test_server.js** - Example server script. Demonstrates the use of **TestServer.js**. By default, it will start a the DSS Test Server for a CC2640R2 LaunchPad. Also defines some additional custom commands that can be called from the remote client.
* **setpath.bat** - Windows batch file that configures the environment **PATH** and **PERL5LIB** variables needed to run the Test Server and examples.