blueDonkey.org

Books.VxWorksCookbookTargetTools

Target Tools


Target Shell

Basics

Simple C interpreter
Shell commands
Editing & the command history
Extending the shell's capabilities
Limitations
There are perhaps two big limitations of the target shell:

  1. Only one instance can run at a time (hence when you telnet in, the serial console session is suspended)
  2. The line length is limited to just 128 characters, even when reading from a script file

Addressing the single instance limitation is almost impossible without completely rewriting the shell. The problem is caused by the yacc/lex generated parser that is used as the basis of the shell's expression handling. Those tools were designed for a process model world, where running multiple instances in a single address space never happened. One possible solution to this though would be to locate the variable(s) that cause the problem and make them use the taskVars mechanism. To make this change requires having the source to the target shell, and a significant amount of work to re-arrange the "global" variable (in quotes since most are actually statics, so are only really global within the scope of the affected file).

The second problem is also impossible to fix without the source code for the target shell, but can be worked around relatively easily in scripts at least. Given that any function you call from the target shell can have a maximum of 10 (ten) parameters, it is likely to be only commands involving long string literals, or those using mangled C++ symbol names that will exceed the 128 character limit.

For string literals, assign them to variables then pass those to the function you wish to call. If any one string exceeds the 128 character limit, then compose that string using malloc() to allocate some space and strcpy() and strcat() to build the string:

-> arg1=" ... "
-> arg2=malloc (500)
-> strcpy (arg2, " ... ")
-> strcat (arg2, " ... ")
-> strcat (arg2, " ... ")
-> myFunction (arg1, arg2)

For C++ names, I would recommend creating small C wrappers for them. This not only keeps the symbol lengths down, but also makes them easier to remember and type:

extern "C" {

    void myClassWrapper (char * arg1, char * arg2, int arg3)
    {
        myClass::staticFunction (arg1, arg2, arg3);
    }
}

Note that in the examples the names are probably not going to generate symbols that are that long, but in real world applications generating very long mangled C++ symbol names is not that difficult.

Telnet and Rlogin

  • Configuring for network connections to target shell

Security

  • Adding usernames and passwords

Deploying the Target Shell

  • Risks of leaving the target shell in a deployed system
  • Advantages of leaving the target shell in a deployed system
  • Adding basic authentication on the serial console

VxWorks AE Differences

  • Switching the current working domain
  • Calling functions in a user domain
  • vi vs emacs editing modes

Loader

Loading .o Files

  • Basic commands
  • More advanced usage

Dealing with Relocation Out of Range Errors

Most of the RISC style CPUs that VxWorks supports (e.g. PowerPC and ARM) have a limited relative branch range. That limit is usually ± 32MB. The Thumb mode available on many ARM CPUs has an even more restrictive range of just ± 4MB. On these systems, having more RAM fitted than this limit can cause relocation out of range errors when dynamically loading modules. There are a number of solutions to the problem:

  1. Compile your dynamically loaded code with -mlongcall (which will have an impact on both size and performance since it converts calls going outside of a module into the multi-instruction sequence necessary to make a full 32 bit address branch).
     
  2. Link your code with the kernel. As long as the size of the resulting text segment is less than relocation range limit, this will work well. Of course, it does remove the dynamic load capability making field upgrades more challenging, so this may not be a viable solution for some systems.
     
  3. Configure your system to have the full amount of memory available, but assign all but the first 32MB (or 4MB for Thumb systems) to the user reserved memory region (using the USER_RESERVED_MEM macro in the BSP). Boot, load any dynamically loaded modules necessary, and then add the user resevered memory region to the main system pool using memAddToPool(). A variant on this scheme, that is a little simpler to use when the autosizing feature is in use, is to simply allocate enough memory to force the loads under the 32MB/4MB boundary. Once the loads are complete, free the allocated block(s) to make the rest of the RAM available again.
     
  4. For each of the .o files that need to be downloaded dynamically, determine the external references that they need. Use the nm utility for your chosen architecture to get this list, e.g. nmppc --undefined-only module.o. Rename these undefineds in the module using the objcopy utility. Then, create a stub that defines these renamed symbols, and makes a 32 bit range call to the original. The most efficient way of doing this would be directly in assembler, but you could, if you are unsure of the assembler to use, write it in C and compile with the -mlongcall option mentioned in above.
     
  5. Replace the VxWorks memory allocation library (memPartLib) with an allocator that allocates from low addresses before high ones. VxWorks loads itself into low memory, but allocates memory for the ld command using malloc() which selects blocks starting at high addresses first. Changing this to start with the lower addresses would make the relocation problem much rarer. This is perhaps a little more complex because of the need to replace the VxWorks memory allocation library - not something that is documented by Wind River.
     
  6. Change the VxWorks memory layout so it loads itself into high memory rather than low memory - a similar solution to the above but it doesn't need a replacement for memPartLib.

Add Examples of Each of These

Target Debug Tools

Setting Breakpoints

  • Setting software breakpoints
  • Scope of a software breakpoint
  • Using hardware breakpoints

Obtaining Stack Traces

  • Using the tt command
  • What to do if it fails
  • Getting parameters for each frame

Understanding Exception Messages

  • Understanding the exception types
  • Locating the function that caused the crash
  • Decoding additional status information

Debugging Startup Problems

  • Using JTAG or similar tools
  • Using reboot() to pinpoint crashes in the startup sequence
  • Writing debug info to safe regions of memory

Alternate Target Shells

Vx-Scheme

Vx-Scheme is an alternative to the target shell that was written by Wind River's former Chief Technologist, Colin Smith, and is freely available (including the source code) under the Artistic License. Unlike the standard target shell, it is an interpreter for the Scheme language. The Vx-Scheme home page contains much more information about the history of the project, its design goals as well as examples of its use and the link to download it.


 
 
© 2003-5 blueDonkey.org, except where otherwise noted. All rights reserved.