Apex Standalone C/C++ for Tornado
Getting StartedCreate a Working View For Your Application
See "Create a Working View for Your Application" in the Getting Started section of this document for a detailed description.
When you select a model, choose one from $APEX_BASE/c++ /model.ss, included in this installation.
Create and Link a Hello World Program
In your view, create the file Hello.C with this text:
#include <iostream.h> main() { cout << "Hello" << endl; }
You can create the file with File > New > New C++ from the GUI or using your favorite editor. If using File > New > New C++, change the buttons to Class and Header. The NAME field should be set to main and the Filename field to Hello.C.
If you use the GUI, your program is automatically registered as a main program.
If not, select your Hello.C program in a view browser and select Compile > Maintenance > Register Main Program.
Link your program with Compile > Link.
The program needs to be compiled before it can be linked. Apex automatically invokes the compiler.
Note: One very useful feature of Apex is the ability to navigate your source using the semantic knowledge that Apex stores about the program. In the Apex editor, select the string iostream.h in your Hello.C file and click the Visit button to navigate to that file. You can also visit cout to have Apex show you where it is declared.
Starting the Tornado Target Server
Before running your program, make sure your Tornado target is running VxWorks. Refer to "Set Up the Target to Run/Debug Your Application" for detailed instructions.
If using Tornado 2.0, start the Tornado Launcher to create the target server (and possibly start wind shells to interact with the target). If using Tornado 3.0 AE, start Tornado. You can start either from Apex by invoking Tools > Tornado Launch from the GUI or by typing apex_tornado_launch from within an Apex shell.
Select Your Target
- In your working view, select File > Run.
Determine the Logical Target
The Logical Target field
When you created a view, you obtained a Policy/Switches file based on the model you used. All Apex Embedded models include a LOGICAL_TARGET_NAME switch. The value of this switch is used to initialize the Logical Target field.
For example, if you chose the PowerPC "board" model when creating your view, the Logical Target field will contain "power.vw_ppc.board".
You may change the value of the Logical Target field if you wish. The string "power.vw_ppc.board" is provided as a default to help you identify the kind of target you are using. But you could change the name to "my_testing_board", or even "fred" if you wished.
Changing the Logical Target value will make visible a toggle enabling you to make your newly specified Logical Target the default for your current view.
- To change the value permanently for the view, edit the Switches file in the Policy directory. Change the value for the switch LOGICAL_TARGET_NAME.
- To change the value for this immediate execution only, change the Logical Target: field in the Run dialog.
- Click OK or Apply.
- Since the logical target has not been mapped, a popup asks if you would like to map it? Click Yes.
In the Map your_logical target to Physical Target dialog, the mapping dialog, the value for your Logical Target: is supplied.
- If physical targets have been created, double click on the physical target in the List of Physical Targets: field.
- If you need to create a new physical target, click the Create New Physical Target button. This will bring up the New Physical Target dialog. The new physical target name appears in the Physical Target: field.
- Click OK to return to the Run dialog.
Supply Logical Target Data:
Note: Under Physical Target Kind:, the VxWorks Tab is selected.
Usually the defaults of the Debug, Set I/O Redirection, Set Cross Run Options, and Collect Trace Data options are adequate. These buttons are covered under File > Run in the online Reference Guide.
- Click OK to run the program. Output is displayed in an Apex output window.
After running the program, the mapping from logical target (and the information you entered about the physical target) remains valid from one session to the next. Since a default value for the logical target is obtained from your view's LOGICAL_TARGET_NAME switch, you can simply visit the view, and select File > Run.
Running a Program
From the view browser, select your executable, Hello, and invoke File > Run. Check to make sure the field labeled entry point contains main, the start symbol of your program.
Note: If you do not specify the entry point, the Run tool will choose __start and your program will not run. (This is a bug and should be fixed in a future release).
You can click OK to finish the dialog and run your program. An output window appears with Hello in it. You can also see Hello echoed in the wind shell if you have one running.
Debugging a Program
To start the debugger on your program, select your executable, Hello, and invoke File > Debug.
Note: If you do not specify the entry point, the Debug tool will choose __start and your program will not run. (This is a bug and should be fixed in a future release).
"Run and Debug Your Application," provides an overview of using the debugger.
Running a Program From the Wind Shell
If you want to run your program directly from the wind shell, make sure that you have the correct file format for download.
The Hello executable produced by the Apex linker is in VOX format, but the Tornado target uses a different module format. See Table 4 below for the conversion format for your target. If you've used Apex to run or debug your program already, you have a file called Hello.omf which is Hello converted to the correct object module format. See Executable Format for information about producing converted objects directly.
Download your module in the wind shell:
-> ld < "hello.omf"
Make sure your target is looking at the directory where your file is located (or use the absolute path name). Run the program using the Tornado spawn command:
-> sp main
Table 4 Processor Conversion Formats
M68000 Family VOX to A_OUT
PowerPC, MIPS VOX to ELF
i386 Family with Tornado 2.0 VOX to A_OUT
i386 Family with Tornado 3.0 AE VOX to ELF
Running Apex Tools From the Command LineYou can work from the Apex GUI or from an Apex shell. Below is a brief list of commands to repeat the exercise from the shell:
% apex link Hello.C % apex_execute -e main Hello
Note: -e specifies the entry point
% apex_debug -e main Hello
There are shell versions of the operations performed in Tools > Targets and Tools > Tornado Launch and most other GUI.
Executable FormatPrograms are linked in relocatable VOX format. This format is not understood by the Tornado loader. The Apex debugger and Apex run commands perform an implicit conversion to the correct object module format and place the result in file_name.omf.
You can explicitly convert the file. Select Tools >Convert and specify an output file and format. Or, from the command-line execute:
% apex_convert -format <format
> hello hello.omf
Where <format> is one of the formats listed in Table 4 .
Note: The Apex tools use the extension .omf.
Main ProgramsAt this time, Apex Standalone C/C++ for Tornado has the same constraints and rules as Apex Native with respect to naming, registering and linking main programs. The key points are as follows:
- A file of any name can be registered as a main program provided it has the proper extension -- .c or .C. For instance, you could register file main.c as a main program and you could also register file Hello.C as a main program and you could have them both registered in the same Apex view.
- Files registered as main programs must have a function named main which is used as the entry point of the program.
The second point is not a concern for native programs, but programs linked for Tornado and downloaded to a Tornado system live in a single shared namespace. The following illustrates what can happen when loading two programs on the Tornado target from the wind shell:
-> ld < Hello.omf value = 664248 = 0xa22b8 = tcp_output + 0x184 -> ld < Goodbye.omf value = 666168 = 0xa2a38 = tcp_output + 0x904 -> lkup "main" ... main 0x0012053c text (Goodbye.omf) main 0x0012e70c text (Hello.omf) ...
-> sp main [Goodbye runs because it was the last one loaded] -> sp 0x0012e70c [can run Hello by using its load address like this]
Static Constructors and DestructorsApex Standalone C/C++ for Tornado follows the standard Tornado conventions for handling static constructors and destructors. These conventions are described fully in the VxWorks Programmer's Guide. Here is a brief summary along with the relevant details that apply to Apex.
- The Vxworks system can be configured in Manual or Automatic mode.
- In Manual mode calls to cplusCtors() and cplusDtors() (only available through the Wind Shell) must be made to run the static constructors and destructors respectively.
- In Automatic mode the VxWorks system automatically calls the static constructors when a program is loaded and calls the destructors when the program is unloaded from memory.
Programs built with Apex will work with either mode in the same way as programs built with GNU tools.
- Tornado assumes the constructors and destructors of a module will be present in the module under the names _ctors and _dtors respectively.
To create the _ctors and _dtors structures, the GNU tools require that you link your program, run the munch program on it and follow this with another compile and link step.
Apex takes care of doing this all for you when you link your program. After this single link step, you are ready to run.
- The _ctors and _dtors structures are each simply a list of functions that are called, in order, by VxWorks when it is time to process constructors/destructors for a module. Using the GNU munch tool, these structures have an entry for each constructor and destructor required by the module. However with Apex _ctors and _dtors will each have a single entry. This single routine (called _vx_cinit_ for _ctors and _sw_atexit_ for _dtors) will in turn call each of the necessary constructors and destructors.
Debugging Static Constructors and DestructorsIf you need to debug your static constructors and/or destructors, switch your target to Manual mode. See Static Constructors and Destructors for an explanation of Automatic vs. Manual modes. You cannot debug the constructors in Automatic mode. They are run as the module is loaded and there is no way for the debugger to intervene in this process. Below is an approach to running the main program and debugging the constructors/destructors.
Rename your main routine to something like old_main and add a new main which could look like this:
extern "C" void _vx_cinit_(); extern "C" void _sw_atexit_(); int main() { int ret_val; _vx_cinit_(); /* call constructors */ ret_val = old_main(); /* call main */ _sw_atexit_(); /* call destructors */ return ret_val; }
Note: You will not have source to the routines _vx_cinit_() and _sw_atexit_() so do not step into them in the debugger. Instead set breakpoints on the constructors or destructors that you want to debug and run to the breakpoints.
Library IssuesThere are two basic approaches to accessing a library of code from a program on a Tornado system.
- 1 . The library can be linked together with the program.
- 2 . The library can be downloaded in a separate step. This approach would allow the library code to be shared by multiple programs that need it.
Currently Apex Standalone C/C++ for Tornado only supports the first model for linking programs. All referenced units from the link view's imports and from standard archive libraries are bundled into the executable program.
You can, however, load individual object files using File > Download (or apex_download from the command line) and start tasks using the VxWorks spawn command as shown in Running a Program From the Wind Shell.
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |