5.8   The Shell Architecture

5.8.1   Controlling the Target from the Host

Tornado integrates host and target resources so well that it creates the illusion of executing entirely on the target itself. In reality, however, most interactions with any Tornado tool exploit the resources of both host and target. For example, Table 5-17 shows how the shell distributes the interpretation and execution of the following simple expression:

-> dir = opendir ("/myDev/myFile") 

Parsing the expression is the activity that controls overall execution, and dispatches the other execution activities. This takes place on the host, in the shell's C interpreter, and continues until the entire expression is evaluated and the shell displays its result.

To avoid repetitive clutter, Table 5-17 omits the following important steps, which must be carried out to link the activities in the three contexts (and two systems) shown in each column of the table:

The first access to server and agent is to allocate storage for the string "/myDev/myFile" on the target and store it there, so that VxWorks subroutines (notably opendir( ) in this case) have access to it. There is a pool of target memory reserved for host interactions. Because this pool is reserved, it can be managed from the host system. The server allocates the required memory, and informs the shell of its location; the shell then issues the requests to actually copy the string to that memory. This request reaches the agent on the target, and it writes the 14 bytes (including the terminating null) there.

The shell's C-expression interpreter must now determine what the name opendir represents. Because opendir( ) is not one of the shell's own commands, the shell looks up the symbol (through the target server) in the symbol table.

The C interpreter now needs to evaluate the function call to opendir( ) with the particular argument specified, now represented by a memory location on the target. It instructs the agent (through the server) to spawn a task on the target for that purpose, and awaits the result.

As before, the C interpreter looks up a symbol name (dir) through the target server; when the name turns out to be undefined, it instructs the target server to allocate storage for a new int and to make an entry pointing to it with the name dir in the symbol table. Again these symbol-table manipulations take place entirely on the host.

The interpreter now has an address (in target memory) corresponding to dir, on the left of the assignment statement; and it has the value returned by opendir( ), on the right of the assignment statement. It instructs the agent (again, through the server) to record the result at the dir address, and evaluation of the statement is complete.

5.8.2   Shell Components

The Tornado shell includes two interpreters, a common front end for command entry and history, and a back end that connects the shell to the global Tornado environment to communicate with the target server. Figure 5-3 illustrates these components:

Line Editing
The line-editing and command history facilities are designed to be unobtrusive, and support your access to the interpreters. 5.5 Shell Line Editing describes the vi-like editing and history front end.

C-Expression Interpreter
The most visible component is the C-expression interpreter, because it is the interface that most closely resembles the application programming environment. The bulk of this chapter describes that interpreter.

Tcl Interpreter
An interface for extending the shell or automating shell interactions, described in 5.7 Tcl: Shell Interpretation.

WTX Tcl
The back-end mechanism that ties together all of Tornado; the Wind River Systems Tool Exchange protocol, implemented as a set of Tcl extensions.

5.8.3   Layers of Interpretation

In daily use, the shell seems to be a seamless environment; but in fact, the characters you type in WindSh go through several layers of interpretation, as illustrated by Figure 5-4. First, input is examined for special editing keystrokes (described in 5.5 Shell Line Editing). Then as much interpretation as possible is done in WindSh itself. In particular, execution of any subroutine is first attempted in the shell itself; if a shell built-in (also called a primitive) with that name exists, the built-in runs without any further checking. Only when a subroutine call does not match any shell built-ins does WindSh call a target routine. See 5.2.3 Invoking Built-In Shell Routines for more information. For a list of all WindSh primitives, see Table 5-13List of WindSh Commands.