The tsctl command line client for direct access

From embeddedTS Manuals

To help you get up and running with Technologic Systems hardware as fast as possible we provide tsctl, a libtsctl client/server application.

First, download the latest pre-compiled tsctl binary for your platform.

For the TS-4500, TS-7552, TS-7553 or TS-7558, download the "cavium" binary here

For the TS-4200, TS-4700, or TS-4800, download the "noncavium" binary here

Install the binary anywhere in your PATH. Before installing, you may wish to make sure you do not already have an older version of tsctl by attempting to run the "tsctl" command. If the command is found, be sure to replace the existing binary with the newly downloaded one in order to ensure you are running the most up to date copy.

Now you can see immediate results. Locate the red and green LEDs on your board. For TS-SOCKET boards these LEDs are usually on the base board (e.g. the TS-8XXX series) while TS-75XX boards have the LEDs directly on the board. Type the following commands:

tsctl DIO SetAsync GREEN_LED LOW
tsctl DIO SetAsync RED_LED LOW
tsctl DIO SetAsync GREEN_LED HIGH
tsctl DIO SetAsync RED_LED HIGH

You should see the green and red LEDs go off and on. (If they are already off then the first two commands will have no effect.)

Now let's talk about how the above commands work. Unlike many Linux utilities, tsctl provides direct access to a number of different functions across several classes using a "generic to specific" way of invoking the functionality you want.

First, you specify the host that you want to invoke the functionality on. This part is optional. The host is specified as the @ symbol followed by an IP address or host name, and indicates that the TCP/IP protocol is to be used. If no host is specified (as in the examples above), localhost is used if the tsctl server is running on the board, otherwise direct access is used.

Second, you specify what class of functionality you want to use. The available classes, in alphabetical order, are AIO, Bus, CAN, DIO, DIORaw, EDIO, Mode, Pin, SPI, System, Time, and TWI. If you specify "?" instead of a class, the available classes will be shown.

Third, you specify which function in the given class you want to invoke. If you specify "?" the list of functions available for that class will be shown. Above, we specified the SetAsync function.

Fourth, you specify the parameters for the function. If you specify "?" the expected parameters will be shown. The format of any parameter is quite flexible: you can enter a numeric value in octal, decimal, hexadecimal, or using a special string name which has a mapping to a value in the System lookup table, which we will discuss later. The SetAsync function takes two parameters: the DIO number and the state to set the DIO to. We used a special string for each: GREEN_LED, for example, having an entry in the mapping that corresponds to the DIO number for the GREEN_LED, and LOW/HIGH being enumerated values for 0 and 1, respectively.

Note that the SetAsync function does not returned any data, so the above commands produce no output. For our next example, let's use the GetAsync function to obtain the current state of the green LED pin:

tsctl DIO GetAsync GREEN_LED

When you run the above command, what output will you get? The answer to this is that it depends on the current output mode. The default mode is to output a name=value pair for each function, where the name is the name of the function you invoked, with an underscore and a number after it, and where the value is formatted in hexadecimal for integers and as an escaped, quoted string for arrays of 8-bit integers, and colon separated hexadecimal integers for all other arrays. If the output is an enumerated value, the default is to print the string corresponding to the enum value if the enum is not a flags enum, and otherwise to print the string value for each flag set separated by a plus symbol. The output mode can be changed by calling functions in the Mode class.

In the case of GetAsync, the value returned is an ordinary (non-flags) enumerated value, which can be one of the following: HIGH,LOW, INPUT, INPUT_LOW, and INPUT_HIGH. So in the following example we see the default output if the green LED was on:

$ tsctl DIO GetAsync GREEN_LED
GetAsync_0=HIGH

You might be wondering why there is an underscore and a number after the function name in the output. The reason is that tsctl allows you to issue multiple commands in a single invocation of tsctl. Each output has a unique name (accomplished by appending a different number for each command) in order to allow the results to be read by a shell script and assigned to shell variables. There are two schemes that can be used. By default (for backward compatibility), each function has its own counter, starting at 0, and incrementing by 1 each time it is called. The second method that can be used is (for slightly better performance) to use a single counter for all functions, so that this counter will increment once each time any command is called.

There are several ways that you can issue multiple commands with only a single invocation of tsctl. The first is to string together multiple tsctl commands by separating each one with a semi-colon. Since most shells use the semi-colon to separate shell commands, usually you will need to quote the semi-colon. So for example you could get the value of both the red and green LED with only a single invocation of tsctl as follows:

tsctl DIO GetAsync GREEN_LED \; DIO GetAsync RED_LED

Depending on your shell, the following should also work:

tsctl "DIO GetAsync GREEN_LED;DIO GetAsync RED_LED"

Note that no space is necessary on either sides of the semi-colon. The only white-space required is to separate each argument, and this white-space can be in any amount. The only thing to be aware of is that the newline character both terminates a command and triggers an invocation of all commands on the current line, so it is a bit more efficient to separate commands with semi-colons rather than white space unless you need a given output before issuing the next command.

If the red LED is on and the green LED is off, the default output of either of the above commands will look like this:

GetAsync_0=LOW
GetAsync_1=HIGH

Another way to issue multiple commands to a single invocation of tsctl is by reading the commands directly from the standard input, or from a file.

To read commands directly from the standard input until end of file (e.g. CTRL+D is pressed) invoke tsctl as follows:

tsctl --

To read commands directly from a file, invoke tsctl as follows:

tsctl -f filename

The format of each command when reading from standard input or a file is identical to that of the command line. Every command always is of the form:

@host class command arguments...

where @host is optional.

The Command Stack

Sometimes you may want to issue several commands, and the first part of each command will be the same. As a simple example, consider reading the example of reading the red and green LEDs given above. If read from a file, these commands would look like this:

DIO GetAsync GREEN_LED
DIO GetAsync RED_LED

Each command starts with a common prefix, namely DIO GetAsync. To reduce the amount of typing (and length of the command) needed, tsctl provides a "command stack".

The tsctl command stack can be thought of as follows. When you specify a command, it consists of several words, separated by whitespace, starting with the (optional) host name and continuing until all the arguments have been specified. Conceptually, as each word is read, it is pushed onto a stack. Once a complete command is on the stack, it is executed. However, if the current command terminates without a complete command being present, then the current command stack is then saved as the context for future commands. Each future command will then be read with this context, this pre-initialized stack. Each time an empty command is encountered, the last element on the stack - if present - is popped off.

In the above example the result would look like this:

DIO GetAsync
GREEN_LED
RED_LED

The first line effectively selects the DIO class and the GetAsync function. Subsequent commands then operate in this context and only need to specify the arugments to the GetAsync function. If we wanted to use another DIO function we would enter a blank line to pop the "GetAsync" function, and if we were done with DIO we could enter another blank line to pop the "DIO" class from the stack. Any extra blank lines would be ignored.

If you wanted to issue both commands in the same server invocation you could simply the above set of commands to the following:

DIO GetAsync;GREEN_LED;RED_LED

This can be a very efficient method for calling the same function repeatedly with the same arguments. For instance, suppose you wanted to read the SYSCON registers at offset 0,2,4,6,8,and 10 of Bus 0, and then call System function ModelId you could do so as follows:

Bus Peek16;0;2;4;6;8;10;;;System Model

The empty commands are used to pop the command stack, two pops are necessary to remove first the "Peek16" functiom, and then the "Bus" class, so that the System class can be used.

Due to the command stack, it is not considered an error if there is a partial command left when tsctl exits. It is important to remember this to avoid confusion in case you accidentally specify a partial command. For instance, the following command will generate no output and no error, because it does not do anything.

tsctl Bus Peek16


The last way to issue multiple commands with a single invocation of tsctl is to start the tsctl shell, as follows:

tsctl

There are a few differences between running the tsctl shell versus providing commands directly from the command line or from a file. The readline library is used to allow command editing and history. Starting with version 0.91, output in shell mode is in decimal (Mode Dec) and the values from each command are printed without an an assigment (Mode NoAssign).

This will print a startup message and then give the tsctl shell prompt, "tsctl> ". To supress the startup message use the "--quiet" option:

tsctl --quiet

Note: UNIMPLEMENTED

The tsctl command shell displays "tsctl" plus the current command stack (if any) before the prompt. The above example of using the command stack has been extended (to show popping the stack) in the tsctl shell.

$ tsctl
tsctl 0.91-ts (Nov 30 2012 22:06:57)  
Type "?" to get context-sensitive help.
tsctl> DIO
tsctl DIO> GetAsync
tsctl DIO GetAsync> GREEN_LED
HIGH
tsctl DIO GetAsync> RED_LED
LOW
tsctl DIO GetAsync>
tsctl DIO>
tsctl>

You can also use semi-colons to put multiple commands or parts of a command on a single line.

To exit the tsctl shell, press CTRL+D, or enter the word "end" by itself on the current line with no extra whitespace.

You can control the format of the output of each command using the Mode class. The output mode is divided into two parts: the encoding and the base.

The output encoding is one of the following: Raw, Newline, Assign, and JSON.

Raw encoding outputs each value returned by the command in the current base, one after the other with no other characters in between each value. It is mainly intended for base -1 and base 0, as with all other bases it would be difficult or impossible to determine where one value ended and the next started.
Newline encoding outputs each value returned by the command in the current base, with a new-line character after each value.
Assign encoding outputs a "name=value" pair for each value returned by the command, where value is in the current base, and name is the name of the function, with an underscore and numeric count appended.
JSON encoding wraps each output in a "name":value format, and separates each element with a comma as well as wrapping arrays in brackets and the entire reply in braces.

Output base is one of the following: -1 (escaped binary), 0 (binary), 2 (ASCII binary), 8 (octal), 10 (decimal), or 16 (hexadecimal). Separate bases are active for character strings and other numbers. Note that for ASCII base output (2 and above) there are no identifying characters to tell what base it is. For instance, there is no "0x" preceding the hexadecimal value in base 16 mode.

Base 0 is the raw internal, little-endian "binary" representation of the value. Although it is the actual binary format of the value this should not be confused with base 2, which is the ASCII representation of the binary value, which consists of only '0' and '1' characters.
Base -1 is the same as Base 0, except that only 8-bit values in the range of 32 and 126 (excluding 92, which is the ASCII backslash character) are output as-is. All other values are output as a backslash followed by three octal digits representing the ASCII value of the byte.

In addition, there input modes, and is divided into two parts: the encoding and the base.

The input encoding is one of the following: HTTP and Command.

Command encoding indicates that the server immediately processes input as commands. This is the default and only mode available in client mode.
HTTP encoding is only available through the TCP port. In this mode, an HTTP POST header is assumed to occur before the start of any commands. Two empty newlines terminate the header and put the connection back into Command mode.

The input base is either Binary or Text.

The tsctl client, whether invoked as a command-line sequence of commands, as the tsctl client, or reading commands from the standard input or a file, defaults to input encoding Command, input base Text, output encoding Assign, output base 16.

You can find more information in the tsctl "Getting Started" guide for the hardware you are using.