In the Tornado development environment, application modules for the target system are created and maintained on a separate development host. First, the source code, generally in C or C++, is edited and compiled to produce a relocatable object module. Application modules use VxWorks facilities by virtue of including header files that define operating-system interfaces and data structures. The resulting object modules can then be loaded and dynamically linked into a running VxWorks system over the network.
The following sections describe in detail the procedures for carrying out cross-development manually (without using the project facility).
Many application modules make use of VxWorks operating system facilities or utility libraries. This usually requires that the source module refer to VxWorks header files. The following sections discuss the use of VxWorks header files.
VxWorks header files supply ANSI C function prototype declarations for all global VxWorks routines. The ANSI C prototypes are conditionally compiled; to use them, the preprocessor constant __STDC__ must be defined. ANSI C compilers define this constant by default. VxWorks provides all header files specified by the ANSI X3.159-1989 standard.
VxWorks system header files are in the directory installDir/target/h and its subdirectories.
![]() |
NOTE: The notation $(WIND_BASE) is used in makefiles to refer to the Tornado installation directory. This chapter uses that notation because makefiles are the most convenient way to run the Tornado compilation tools. If you run the compiler from the Windows command prompt, write %WIND_BASE% instead.
|
||||||||||||||||||
The header file vxWorks.h contains many basic definitions and types that are used extensively by other VxWorks modules. Many other VxWorks header files require these definitions. Thus, this file must be included first by every application module that uses VxWorks facilities. Include vxWorks.h with the following line:
#include "vxWorks.h"
Application modules can include other VxWorks header files as needed to access VxWorks facilities. For example, an application module that uses the VxWorks linked-list subroutine library must include the lstLib.h file with the following line:
#include "lstLib.h"
The manual entry for each library lists all header files necessary to use that library.
All ANSI-specified header files are included in VxWorks. (UNIX)
This implies that many familiar UNIX header files are available under VxWorks as well. There are two file names that differ from the usual UNIX names: a_out.h (which corresponds to the UNIX a.out.h) and stdlib.h (which corresponds to the UNIX malloc.h)
By default, the compiler searches for header files first in the directory of the source module and then in directories that apply only to the development host. With the GNU compiler, you can avoid these host-system include directories with the compilation flag -nostdinc. To access the VxWorks header files, the compiler must also be directed to search $(WIND_BASE)/target/h. Thus, the following option flag is standard for VxWorks compilation:
-I $(WIND_BASE)/target/h
Some header files are located in subdirectories. To refer to header files in these subdirectories, be sure to specify the subdirectory name in the include statement, so that the files can be located with a single -I specifier. For example:
#include "vxWorks.h" #include "sys/stat.h"
Some VxWorks facilities make use of other, lower-level VxWorks facilities. For example, the tty management facility uses the ring buffer subroutine library. The tty header file tyLib.h uses definitions that are supplied by the ring buffer header file rngLib.h.
It would be inconvenient to require you to be aware of such include-file interdependencies and ordering. Instead, all VxWorks header files explicitly include all prerequisite header files. Thus, tyLib.h itself contains an include of rngLib.h. (The exception to this is the basic VxWorks header file vxWorks.h, which all other header files assume is already included.)
This, in turn, might lead to a problem: a header file could get included more than once, if one were included by several other header files, or if it were also included directly by the application module. Normally, including a header file more than once generates fatal compilation errors, because the C preprocessor regards duplicate definitions as potential sources of conflict. To avoid this problem, all VxWorks header files contain conditional compilation statements and definitions that ensure that their text is included only once, no matter how many times they are specified by include statements. Thus, an application module can include just those header files it needs directly, without regard for interdependencies or ordering, and no conflicts arise.
Table 8-2 lists the subdirectories of installDir/target/h used by VxWorks for internal header files. These header files are, for the most part, not intended for applications. The following subdirectories are exceptions, and are sometimes required by application programs:
|
|||||||||||||||||||
|
|||||||||||||||||||
|
|||||||||||||||||||
VxWorks modules are designed so that you never need to know or reference the modules' internal data structures. In general, all legitimate access to a facility is provided by a module's subroutine interfaces. The internal details should be thought of as "hidden" from application developers. This means that the internal implementations can change without affecting your use of the corresponding facilities.
Internal details in VxWorks are hidden using two conventions. Some header files mark hidden code using the following comments:
/* HIDDEN */ ... /* END HIDDEN */
Internal details are also hidden with private header files: files that are stored in the directory installDir/target/h/private. The naming conventions for these files parallel those in installDir/target/h with the library name followed by P.h. For example, the private header file for semLib is installDir/target/h/private/semLibP.h.
![]() |
CAUTION: Never make references to any of the hidden definitions, or base any assumptions on those definitions. The only supported uses of a module's facilities are through the public definitions in the header file, and through the module's subroutine interfaces. Although this rule is not currently enforced in any way, it is in your interest to observe it. Your adherence ensures that your application code is not affected by internal changes in the implementation of a VxWorks module.
|
||||||||||||||||||
Tornado includes a full-featured C and C++ compiler and associated tools, collectively called the GNU ToolKit. Extensive documentation for this set of tools is printed in a separate manual: the GNU ToolKit User's Guide. This section provides some general orientation about the source of these tools, and describes how the tools are integrated into the Tornado development environment.
GNU ("GNU's Not UNIX!") is a project of the Free Software Foundation started by Richard Stallman and others to promote free software. To the FSF, free software is software whose source code can be copied, modified, and redistributed without restriction. GNU software is not in the public domain; it is protected by copyright and subject to the terms of the GNU General Public License, a legal document designed to ensure that the software remains free--for example, by prohibiting proprietary modifications and concomitant restrictions on its use. The General Public License can be found in the file COPYING that accompanies the source code for the GNU tools, and in the section titled Free Software at the back of the GNU ToolKit User's Guide.
It is important to be aware that the terms under which the GNU tools are distributed do not apply to the software you create with them. In fact, the General Public License makes no requirements of you as a software developer at all, as long as you do not modify or redistribute the tools themselves. On the other hand, it gives you the right to do both of these things, provided you comply with its terms and conditions. It also permits you to make unrestricted copies for your own use.
The Wind River GNU distribution consists of the GNU ToolKit, which contains GNU tools modified and configured for use with your VxWorks target architecture. The source code for these tools is included.
The GNU cross-development tools in Tornado have names that clearly indicate the target architecture. This allows you to install and use tools for more than one architecture, and to avoid confusion with corresponding host native tools. A suffix identifying the target architecture is appended to each tool name. For example, the cross-compiler for the 68K processor family is called cc68k, and the assembler as68k. The suffixes used are shown in Table 8-3. Note that the text in the GNU ToolKit User's Guide refers to these tools by their generic names (without a suffix).
|
|||||||||||||||||||
|
|||||||||||||||||||
|
|||||||||||||||||||
1: See C. Intel i960. |
Tornado can support multiple target architectures in a single development tree. To accommodate this, several VxWorks header files contain conditional compilation directives based on the definition of the variable CPU. When using these header files, the variable CPU must be defined in one of the following places:
To define CPU in the source modules or header files, add the following line:
#define CPU cputype
To define CPU on the compilation command line, add the following flag:
-DCPU=cputype
The constants shown in Table 8-4 are supported values for cputype.
With makefiles, the CPU definition can be added to the definition of the flags passed to the compiler (usually CFLAGS).
In the source code, the file vxWorks.h must be included before any other files with dependencies on the CPU flag.
As well as specifying the CPU value, you must usually run the compiler with one or more option flags to generate object code optimally for the particular architecture variant. These option flags usually begin with -m; see Compiling C Modules.
The following is an example command to compile an application module for a VxWorks MC68020 system:
% cc68k -fno-builtin -I %WIND_BASE%\target\h -nostdinc -O \ -c -DCPU=MC68020 applic.c
This compiles the module applic.c into an object file applic.o. Table 8-5 shows a similar example compiler invocation for each CPU architecture family.
|
|||||||||||||||||||
|
|||||||||||||||||||
See your i960 toolkit documentation and C. Intel i960.
|
|||||||||||||||||||
|
|||||||||||||||||||
The following list gives summary descriptions of the compiler flags in Table 8-5. For more information, see the GNU ToolKit User's Guide, or the architecture appendices.
Tornado supports the GNU compiler, a standard part of the cross-compilation tools distributed for Tornado, compiles source programs in either C or C++. To use this compiler for C++, invoke ccarch on any source file with a C++ suffix (such as .cpp). For complete information on using C++, including a detailed discussion of compiling C++ modules, see 5. C++ Development.
Compiling C++ applications in the VxWorks environment involves the following steps:
After you compile an application module, you can load it directly into the target with the Tornado dynamic loader (through the shell or through the debugger).
In general, application modules do not need to be linked with the linker from the GNU ToolKit, ldarch. However, using ldarch may be required when several application modules cross-reference each other. The following example is a command to link several application modules, using the GNU linker for the MC680x0 family of processors.
C:\devt> ld68k -o applic.o -r applic1.o applic2.o applic3.o
This creates the object module applic.o from the object modules applic1.o, applic2.o, and applic3.o. The -r option is required, because the object-module output must be left in relocatable form so that it can be downloaded and linked to the target VxWorks image.
Any VxWorks facilities called by the application modules are reported by ldarch as unresolved externals. These are resolved by the Tornado loader when the module is loaded into VxWorks memory.
![]() |
WARNING: Do not link each application module with the VxWorks libraries. Doing this defeats the load-time linking feature of Tornado, and wastes space by writing multiple copies of VxWorks system modules on the target.
|
||||||||||||||||||
After application object modules are compiled (and possibly linked by the host ldarch command), they can be dynamically loaded into a running VxWorks system by invoking the Tornado module loader. You can do this either from the Tornado shell using the built-in command ld( ), or from the debugger using the Debug menu or the load command.
The following is a typical load command from the Tornado shell:
-> ld <applic.o
This relocates the code from the host file applic.o, linking to previously loaded modules, and loads the object module into the target's memory. Once an application module is loaded into target memory, any subroutine in the module can be invoked directly from the shell, spawned as a task, connected to an interrupt, and so on.
The shell ld( ) command, by default, adds only global symbols to the symbol table. During debugging, you may want local symbols as well. To get all symbols loaded (including local symbols), you can use the GDB command load from the debugger. Because this command is meant for debugging, it always loads all symbols. Alternately, you can load all symbols by calling the shell command ld( ) with a full argument list instead of the shell-redirection syntax shown above. When you use an argument list, you can get all symbols loaded by specifying a 1 as the first argument, as in the following example:
-> ld 1,0,"applic.o"
In the foregoing examples, the object module applic.o comes from the shell's current working directory. Normally, you can use either relative path names or absolute path names to identify object modules to ld( ). If you use a relative path name, the shell converts it to an absolute path (using its current working directory) before passing the download request to the target server. In order to avoid trouble when the shell where you call ld( ) is not running on the same host as its target server, Tornado supplies the LD_SEND_MODULES facility; see the Tornado User's Guide: Shell. If you are using a remote target server and ld( ) fails with a "no such file" message, be sure that LD_SEND_MODULES is set to "on."
![]() |
CAUTION: (Windows) If you call ld( ) with an explicit argument list, any backslash characters in the module-name argument must be doubled. If you supply the module name with the redirection symbol, as in the earlier example in this section, no double backslashes are needed. See the Tornado User's Guide: Shell for more discussion of this issue.
|
||||||||||||||||||
When a module is loaded, it is assigned a module ID and a group number. Both the module ID and the group number are used to reference the module. The module ID is returned by ld( ) as well as by the target-resident loader routines. When symbols are added to the symbol table, the associated module is identified by the group number (a small integer). (Due to limitations on the size of the symbol table, the module ID is inappropriate for this purpose.) All symbols with the same group number are from the same module. When a module is unloaded, the group number is used to identify and remove all the module's symbols from the symbol table.
Whenever you load a particular object module more than once, using the target server (from either the shell or the debugger), the older version is unloaded automatically. You can also unload a module explicitly: both the Tornado shell and the target-resident VxWorks libraries include an unloader. To remove a module from the shell, use the shell routine unld( ); see the reference entry for windsh.
For information about the target-resident version of the unloader (which also requires the target-resident symbol table and loader), see the VxWorks reference entry for unldLib.
After a module has been unloaded, any calls to routines in that module fail with unpredictable results. Take care to avoid unloading any modules that are required by other modules. One solution is to link interdependent files using the static linker ldarch as described in 8.4.3 Static Linking (Optional), so that they can only be loaded and unloaded as a unit.