UrJTAG protocol (URFP)
This page describes the communication protocol to speak to a remote UrJTAG server, "URFP". The protocol can be used over any serial connection, from RS232 to TCP/IP streams.
URFP is an abbreviation of "Universal Remote Function Protocol". It allows to send commands with arguments to a remote device and retrieve the results. So far that's nothing new, but in addition, URFP allows to send more than one command at once, before the results are expected; and URFP allows to pass data and debug information "in parallel" to the command requests and responses.
URFP servers can be chained, so a server 1 might provide basic functions to server 2, which adds some more functions, and another server 3 that adds even more functions, and all together could be used by a client (communicating with server 3) like a single server with a real lot of functions.
URFP is not dedicated to JTAG operation, but at this time it is used only for UrJTAG (beside some ancestor versions, which are in use in various measurement devices).
The protocol core implementation could make use of SWIG for the description of the extended API. In other words, it could be applied to any software package that exports its API via SWIG, and on the client end be useful in any programming language for which SWIG can generate code (with some restrictions imposed on the language features used in the API)
Simple adapters (well, "simple" like parallel port cables or USB cables with no or only small programmable logic embedded) won't be able to speak this protocol but rather will be connected through some cable server running on the host. It is, however, simple enough so that basic support for it could be implemented in a small CPLD.
Note that this is only a draft and hasn't been implemented anywhere yet...
The "server" is the device with interfaces where targets are attached to. The "client" is application software. A server might not support all functionality defined here. It is possible to add a third component, an "extender", which translates high level requests from the client into lower level requests to the server.
A server may have more than one interface with targets, and it may serve more than one client at the same time. An extender can also serve as a hub or aggregator that allows access to many servers during a single connection from one client. A locking and sharing mechanism assures that clients get their work done without interfering each other.
The differentiation between "Server" and "Client" just determines who asks for action. It is not necessarily the client who initiates the connection.
There are two protocol modes, "ASCII" and "Binary". ASCII mode allows interactive use over a terminal or telnet/SSH session. In Binary mode, the communicated content is exactly the same, but data is sent in a more compact form. Support for binary mode is required, ASCII mode is optional. A server might listen on two different TCP ports for binary and ASCII mode connections. "Extenders" can be used to translate.
The basic communication item is a "line" of limited length. The client (user) sends command lines, the server (UrJTAG) replies with echo and response lines. A command always consists of only one line, while a response may extend over multiple lines.
The basic communication cycle in ASCII mode is as follows:
- The server emits a prompt (an almost arbitrary string, e.g. "urfp>"; it just must not begin with a digit or asterisk "*")
- The client sends a command, consisting of the following components:
- Two letters specifying the command
- An optional digit (0..5) defining a tag (defaults to 0 if omitted) which will be echoed in the response
- Whitespace (ASCII 9,32,...) followed by a parameter for the command (Parameters may be numbers in a format understood by strtod, ASCII words, or UTF-8 strings enclosed in quotes).
- Optionally a tilda "~" to allow deferral of responses (see "Asynchronous operation", below)
- Optionally an asterisk "*" followed by checksum for the line
- LF, CR, or CR+LF
- The server responds with zero, one or more lines, each following this format specification:
- All but the last line start with a digit 0...9, increased for each line; the last line instead starts with an asterisk "*"
- The same two letters and tag as in the command from the client
- Zero or more times a space (ASCII 32) followed by a result of the command
- If the client sent a checksum, the server has to append a checksum too.
Command: cf0 33 argum "string" ~*3FC2
It depends on the particular command and function whether there is a response at all, but this has to be specified for the particular application and may not change dynamically (ie. a function may respond always or never, but not just sometimes).
Errors: In case of an error that prevented the command from producing a proper response, the server should emit a single line prefixed with a question mark "?" or exclamation mark "!" instead of the response. The "?" should be used in cases where retrying the query (with better arguments) would be reasonable (possibly followed an explanation how to improve the query), the "!" should be used when the server can't give any hints.
Echo/Line editing: By default, the server echoes all input. Emacs-style Ctrl-X combinations may be sent to edit the current line. The server will use spaces, Ctrl-M (CR) and Ctrl-H (BS) codes to rewrite the current line. Line editing may not be available in very simple servers. Telnet-style option processing may be used for negotiation, eventually.
Whether a line from the server is just an echo of your input or output from the server can be distinguished by looking at the first char after CR/LF: Output from the server always begins with a digit or an asterisk. For a prompt however, that's not allowed.
- Ctrl-A: Beginning of the line
- Ctrl-B: Move cursor to the left
- Ctrl-C: Abort - see below
- Ctrl-D: Delete char under cursor, or Exit - see below
- Ctrl-F: Move cursor to the right
- Ctrl-H or Del: Move cursor to the right, delete char under cursor
- Ctrl-K: Delete to end of line
- Ctrl-M (CR): Enter line / send command
- Ctrl-U: Delete whole line
Aborting/Exiting: Ctrl-D on an empty line or an appropriate command will immediately terminate the connection. There is no response. Ctrl-C should result in cancellation of all currently executing commands. If there are no other commands running, it should even remove all commands scheduled for automatic repetition. In other words, sending Ctrl-C and then sending Ctrl-C again after a prompt has been received will stop all activity on the server.
Timeout: The server must respond to a command within 0,5 seconds. If the server knows that more timeout is needed to compute a response to a command, it can send a "timeout extension request" response which is similar to the lines of the response, but prefixed with a "~". It may only occur before the first line of the actual response.
Checksums: Normally, CRC16 should be used (represented as exactly 4 hex digits). For memory or performance reasons, CRC8 may be used instead (represented as a hash sign "#" followed by two hex digits), or, even if requested, no CRC at all (represented as two hash signs "##"). If either end knows that a given communication media is "error-free" (e.g. a TCP/IP connection), it is also wise to omit checksumming. Checksums are computed over all bytes in a line, including the leading digit or asterisk (in responses) and trailing asterisk before the checksum or even the trailing hash sign before an 8-bit checksum.
Additionally, there are two mechanisms for transfer of large amounts of data (such as FPGA configuration or firmware binaries): Data can either be split into smaller chunks, so that every chunk fits into a command line on its own (see "DA" command). Second, optionally, servers that have the memory and CPU power should provide functions for transferring "files" using X/Y/ZModem protocol.
In binary mode, similar content like the lines described for ASCII mode is transmitted, but encoded in a more compact form. There is only light error checking, so this mode should be used only on connections where other mechanisms ensure error-free communication (e.g. TCP/IP). Transfer of large amounts of data can be implemented simply by transmitting the data as is.
When working out the binary mode details, the following constraints have to be considered:
- Avoid collisions with telnet protocol handling (commands started with IAC, 0xFF)
- Must allow to design a protocol decoder (server side) in logic (FPGA, CPLD) using only a few memory/register bits
- Must be translatable into ASCII data
- Keep in mind the maximum size of USB1.1 vendor requests (64 bytes)
- On the low end, stay close to similar binary JTAG protocols (e.g. FT2232 MPSSE commands, USB-Blaster, ... see Cables page in UrJTAG wiki)
- Gather some statistics about the actual usage of commands and typical amount of parameter data in ASCII mode before designing binary mode.
Proposal for binary mode:
- Transfer unit is 16 bit (which seems to be the most common physical data bus width of USB device chips such as Cypress FX2 or NXP ISP158x). That means if you want to make use of the 8 bit format you always have to send two commands/variables.
- 8, 16 or 32 Bit header is used. Same format for commands and responses.
- 8 bit format (only for commands, not for responses) - can be used to toggle variables quickly, for example JTAG TCK or TDI
- 3 bits tag, always "000" for very quick function call, "001" for very quick variable set/clear. The tag in the response will automatically use the tag used in the previous response to a command, increment by 1
- No "deferral" flag (always allowed)
- 5 bits function code or 4 bit variable number + 0 (clear variable to 0) or 1 (set variable to 1)
- No length -> no arguments / values follow.
- 16/32 bit format with optional arguments:
- 3 bit tag (010..111. In commands, 000 and 001 are used for the very quick 8 bit instead. In responses, 000 and 001 are used alternating for out-of-band responses)
- 4 bit command/response code (1111 reserved for telnet protocol collision avoidance)
- 1 bit flag "Allow deferral" (commands) or "Timeout extension request" (responses)
- 8 bit length (number of 16-bit words following), or QF function number, QV variable number, or QD channel 0..7 + length
- eventually 16 more bits of length, if previous 8 bit had MSB set
- X 16 bit words containing data
Proposal for data:
- 8 bit data type (e.g. array(nestable), ascii word, utf8 string, int, uint, ...)
- 8, or 24, or any other 8+Nx16 bit data, up to a total of the specified number of words
There is no concept of "multiple lines" in binary mode.
Furthermore, the server is allowed to send lines "Out Of Band" (OOB) at any time (but not within a multi-line response, only just between the query and the response or following the response).
The OOB lines are formatted like normal responses but use incrementing tags 8...F (not related to the tag used in the command that eventually caused the OOB line).
In order to minimize disturbance for humans who interactively enter commands to an UrJTAG server on a console, whenever an OOB line is emitted by the server, it tries to re-echo the input (if any) so that the OOB line actually appears above the user input.
In binary mode, when transferring large amounts of data, they should be packetized to allow insertion of OOB data between chunks of data.
In order to increase performance, the protocol doesn't require the communication to occur only in isolated pairs of commands each immediately followed by a response. A client may append a tilda to the command, indicating that the server doesn't have to respond immediately. It then may continue and send another command.
When given the tilda, the server is allowed to hold back the response(s) until either some implementation-dependent timeout passed, or the server doesn't have any more buffer space for further responses, or the client sent another command without the tilda. The client has to be prepared to receive deferred responses at any time, even immediately after issuing the command. The server is NOT allowed to send responses out-of-order (ie. to respond earlier to commands received later).
Commands can be scheduled for automatic repetition every T milliseconds. This could be used to periodically output variables etc.. The same mechanism as for Out-of-band information is used.
The proposal for the binary protocol allows for max 15 generic commands. Everything else has to be implemented using functions and variables.
- General actions:
- HE: get version and help
- EX: exit
- LF xx: list functions (xx=0) or just report if function xx is implemented
- QF xx: quick function call (xx < 256, no arguments, use in binary mode)
- CF xx ...: call numbered function xx (arguments follow on the same line)
- CF : (same code as CF xx, but with no function number and no arguments) - cancel running function (Ctrl-C may do the same)
- AF xx ...: alias function (define new function without args to call other function YY with saved arg list). Response contains an index to be used with CF.
- CD xx ...: channel data for xx (hex bytes follow on the same line - also allowed as OOB line from server)
- QD xx ...: quick data for channel 0..7, max 31 16-bit words
- LV xx: list variables (xx=0) or just report if variable xx is implemented
- QV xx: quick variable read (xx < 256, use in binary mode for reading scalars)
- RV xx .. : read variable (with possible offset and length for reading from arrays)
- WV xx ...: write variable
- Automatic repetition:
- AR y: add periodic repetition of previous command at frequency of y/1000 Hz. May not be used with function aliases. Response contains an index to be used with NR.
- LR xx: list scheduled repetitions or just report if there is one at index xx
- NR xx: stop repetition of command xx (cancels any running command xx)
ASCII-only commands (not passed to binary-mode servers):
- Rx: specify radix for output (from server to client)
- RB: radix binary (prefixed with #)
- RO: radix octal (prefixed with 0)
- RH: radix hex (prefixed with 0x)
- RD: radix decimal (signed)
- RU: radix decimal (unsigned)
The AF, AR, LF and LV commands may be available as simplified variants in some implementations, for example, if a CPLD is used.
AF and AR may not be available at all or with just a limited number of possible aliases/repetition list entries.
LF, LV and LR may not be able to return a list. In that case, the desired functionality has to be checked one-by-one by the client. The response when asked for a list should be an error message specifying the number of the highest-numbered function or variable.
The proposal for the binary protocol allows for max 15 response codes.
- NO: Error
- TO: Timeout extension request / progress indication
- OK xx: Command executed properly, xx are results.
- ER xx: Error during execution of automatic repetition, xx is the index of the repeated command
- CR xx yy: Output from automatic repetition, xx is the index of the repeated command, yy are results
- LG xx: Textual information (various severity levels, various modules)
- CD xx: Channel data from channel xx
- QD: Quick data
The extensibility of the protocol is based on the "CF" (call function) command. Its main argument is a function number, all further arguments are passed to the function. Function numbers are unique. Same holds true for variables.
There will be some mandatory functions (probably somewhat like SVF) and many optional. A client should call "LF" to get a list of supported functions before any other operation.
Some ideas about basic functions and variables, functions first:
- SVF functions
- Get/Release Lock on interface
- List interfaces, select interface (if there are many)
- Files or buffers (transfer to/from sandbox on server, e.g. SVF and STAPL files, or firmware, etc.)
- CD: change directory
- LS: list files and subdirectories in current directory
- AX: list all files and directories on server
- TX ...: send file (to server)
- RX ...: receive file (from server)
- GV xx xx: get variable values from file (file has to be uploaded with SX before)
- PV xx xx: put variable values into file (can be downloaded later using RX)
- Security (could be handled on another level, e.g. SSL)
- AU xx: Authentication
- EC xx: Encryption
And some basic variables:
- Signal state (TDI, TDO, TMS, TCK) for bit-banging (actual access to IO)
- Signal history (indicator whether a signal was changed externally, e.g. whether reset was activated externally)
- Server name, vendor, protocol revision, basic capabilities