ADS Intro Tutorial v06
ADS Intro Tutorial v06
2
Introductory
Tutorial
Pre-requisites
The student should be familiar with Microsoft DOS/Windows, and have a basic
knowledge of the C programming language. The ARM Developer Suite (version 1.2)
should be available.
Note: Explanation of File Extensions:
.c C source file.
.h C header file.
.o object file.
.s ARM or Thumb assembly language source file.
.mcp ARM Project file, as used by the CodeWarrior IDE.
.axf ARM Executable file, as produced by armlink.
.txt ASCII text file.
Additional information
This tutorial is not designed to provide detailed documentation of ADS, as full on-line
documentation is available. To access the on-line documentation:
From the Start menu select Programs → ARM Developer Suite
v1.2 → Online Books.
This opens a new window split into two panels. The left panel displays a ‘Table of
Contents’ for the current level of documentation. The right panel shows the titles
available within the collection selected in the left panel. Double click on any book
topic to view more information. To search for a specific topic enter a search string in
the Find field and press carriage return. This will then display the number of entries
that each book contains. Select the book (by double clicking on the book name) and a
new window will open with the left hand column now displaying the chapters and
listing the number of entries per chapter. Scroll through each chapter to view each
specific result found.
Further help can be accessed from the on-line documentation by pressing F1 when
running CodeWarrior or AXD, from the help menu, or by using the -help switch for a
command line tool. The documentation is also available in PDF format in the PDF
directory located within the ADS installation directory.
Alternatively click on the Notepad icon on the ‘Start menu’ and open
the required file using the File→ Open command.
Help is available from the command line for all of the tools covered in
this session by typing the name of the tool followed by -help.
All the tools covered in this session are documented in the online text
found under ARM Developer Suite → Compiler, Linker and Utilities
Guide.
Consider the following simple C program which calls a subroutine. This file is
provided as hello.c in c:\ads_tutorial\intro\session1\
/* hello.c Example code */
#include <stdio.h>
#include <stdlib.h> /*for size_t*/
int main(void)
{
const char *greeting = "Hello from subroutine\n";
printf("Hello World from main\n");
subroutine(greeting);
printf("And Goodbye from main\n\n");
return 0;
}
armcc -g hello.c
The C source code is compiled and an ARM ELF object file, hello.o, is created.
The compiler also automatically invokes the linker to produce an executable with the
default executable filename __image.axf.
Thus this command will compile the C code, link with the default C library and
produce an ARM ELF format executable called __image.axf.
This command informs the debugger to execute the image and then terminate.
Different arguments can be passed to the compiler from the command line to
customize the output generated. A list of the more common options, together with
their effects, can be viewed by entering armcc -help at the command line. Some of
these options are listed below:
When the compiler is asked to generate a non-object output file, for example when
using –c or -S, the linker is not invoked, and an executable image will not be created.
These arguments apply to both the ARM and Thumb C compilers.
Use the compiler options with armcc or tcc to generate the following
output files from hello.c:
Run the Thumb executable image using armsd, the output generated
should be the same as before.
Note the sections of assembly source that correspond to the interleaved C source code.
In previous exercises we have seen how the compiler can be used to automatically
invoke the linker to produce an executable image. armlink can be invoked explicitly
to create an executable image by linking object files with the required library files.
This exercise will use the files, main.c and sub.c which can be linked to produce a
similar executable to the one seen in the previous exercises.
Use the compiler to produce ARM object code files from each of the
two source files.
Run the executable using armsd and check that the output is similar to
before.
The ability to link files in this way is particularly useful when link order is important,
or when different C source modules have different compilation requirements It is also
useful when linking with assembler object files.
ARM ELF format objects and ARM ELF executable images that are produced by the
compilers, assembler and/or linker can be decoded using the fromelf utility, and the
output examined. Shown below is an example using the –text option with the /c
switch to produce decoded output, showing disassembled code areas, from the file
hello.o that was produced in Exercise 1.1:
Alternatively re-direct the output to another file to enable viewing with a text editor:
Use the fromelf utility to produce and view disassembled code listings from the
main.o and sub.o object files.
A complete list of options available for ‘fromelf’ can be found from the
command line using fromelf –help, or by consulting the on-line
documentation.
We have now seen how the command line tools can be used to
compile, link and execute simple projects.
armcc The compiler can be called with many different options. The -g option
is required to enable source level debugging. The compiler can be used
to generate executable images, object files and assembly listings.
tcc The Thumb compiler can be used in the same way as armcc.
armasm The assembler can be used to construct object files directly from
assembly source code.
armlink The linker can be used to produce executable images from ARM or
Thumb object files.
In this exercise, we will create a new header file using CodeWarrior’s built-in editor.
/* Struct definition */
struct DateType
{
int day;
int month;
int year;
};
You have now created a very simple header file. This will be used later by the
example program supplied: month.c.
Leave the editor window open for use later in the exercise.
We will now create a new project and add our files month.c and datetype.h to it
The project window, calendar.mcp appears. The Files tab is highlighted and
DebugRel is selected as the build target by default. Other build targets can be selected
by clicking on the drop-down box.
The three default target variants available refer to the level of debug information
contained in the resultant image.
Debug Contains full debug table information and very limited optimization.
Release No source level debug information, but full optimization.
DebugRel A trade-off between the two.
It is the DebugRel variant that we shall use for the remainder of this tutorial.
Navigate to c:\ads_tutorial\intro\session2\
From the menu select Project → Add datetype.h to Project. Click OK.
If the editor window has been closed use Project → Add Files… again
to locate datetype.h.
The Files tab of the project window now shows that datetype.h and month.c
have been added to the project. Source files in the project window can be edited by
double clicking on their icons. The Code and Data columns for month.c both
contain 0 as no object code or executable image exists for the project as yet.
An Errors & Warnings window appears with the several messages, the first two of
which are shown below:
The lower section of the window contains a section of the code that caused the first
error message.
The IDE opens the editor and sets the focus on the line of code associated with the
error. There is something wrong with the code; a close bracket is missing. The line
should read:
Correct the error by adding the missing bracket and then save the
updated source file.
The Errors & Warnings window appears again. The first error message is:
The editor window is opened, with focus placed on the problem line. You will find
that there is nothing wrong with the code on this line!
Towards the top of the file, the preprocessor directives contain a reference to the
macro DATETYPE, which has not been defined in any of the source files. Normally a
command line parameter would have to be supplied to the C compiler, armcc, to
specify:
-DDATETYPE
Tools are configured graphically with CodeWarrior. We must edit the command line
arguments for this target’s settings:
DATETYPE
The project window Code column now indicates that some code has been generated
for our source file.
The project has been successfully built. The disassembled code for this file can be
examined in CodeWarrior, via the fromelf decoding utility. CodeWarrior calls the
utility and prints the output to the screen.
If you wish to do a forced rebuild of all of the source files then select
‘Project→Remove Object Code...’. Select ‘All Targets’ or ‘Current
Target’ to delete the relevant object files.
This will open AXD and run the image that the IDE has built in the instruction set
simulator, ‘ARMulator’. You will see a window similar to the one shown below:
In the center is the Console Window where program input and output takes place.
Execution has already begun and the program is now awaiting user input.
The program will display the dates for the following calendar month and then
terminate.
You can have multiple instances of AXD open, but each time it is
launched from the IDE a new instance is opened; hence you can end up
with a previous instance of AXD still running. It is therefore good
practice to close down AXD after each debug session is complete.
Select Project→ Debug from the IDE menu (or press F5).
AXD will load the image ready for debugging, and will have set a breakpoint on
main. The disassembled project code is visible in the Disassembly window.
The program will terminate after it has output the set of dates for the following month.
Use the scroll bar at the edge of the Console Window to view the dates
at the end of November. You will find that there is an extra day!
A Variables window appears. Ensure the Local tab is selected. The window contains
our variables: daysInMonth. Its value has not been determined yet and it is currently
set to 0:
The display is updated. The global variables, including the date struct are now
visible.
Click on the cross to the left of date to view the struct’s fields.
Select Execute→ Step (F10) to perform the next step in the program.
You will note that the case statements have been skipped and that the
default path will be taken.
As the default path assumes the month has 31 days. This is not correct for
November. There is a fragment of code, case 11:, missing from line 51. To rectify
this permanently we would have to edit the source file. For the purposes of this
example we will modify the variable daysInMonth to produce the desired result.
Set a new breakpoint on line 58 after the block of code containing the
switch statement.
Double click on the value to edit it and change the value to 30, then
press enter.
AXD will load the image ready for debugging, and will have set a breakpoint on
main. The disassembled project code is visible in the Disassembly window.
Open the Low-Level Symbols window from the Processor Views menu.
Locate the date entry in the Symbol column.
Right click on the date entry and select Locate using Address from the
context menu to view the variable in memory.
Right click on the highlighted values in the Memory window and select
Format → Other → Size 32 → Decimal
Note how the highlighted word and the two successive words in
memory correspond to the three fields in the date struct
(26/12/2000). See image below.
Open the Registers window from the Processor Views menu and click
on the cross to the left of current to expand the view.
At this point in the program r3 holds the value stored in the day field of the date
variable in the Memory window (The value of day is now 27 as the nextday
function has been called.):
Use the Go button (or press F5) to pass through the while loop until
the program ends.
Note how the value entered in memory affects the value in the register r3 and the
program output.
It is often useful to see interleaved code, i.e. the high level C code, and the low level
assembled code together. This is easily achieved in AXD.
The program will run to the first breakpoint at main and the source code for month.c
will come into view.
Step through the code until you have passed the date entry point and the next
two days have been output. (F10).
In this exercise we will see how the tasks performed using the graphical interface can
be replicated using the command line.
Debug > go
Once again execution halts on entry to main before the first instruction to be
executed.
Set another breakpoint on line 40 of the source file by using the break command
with month.c as the file context qualifier, then resume program execution:
Execution will stop at the breakpoint. Now check the values of the program variables:
Remove the breakpoint on line 40 using the unbreak command (you can find the
reference for the breakpoint you need using the break command which will print a
list of current breakpoints):
Set another breakpoint immediately after the switch statement then resume program
execution:
Use the go command to pass through the while loop until the output displays the date
2000 12 3
Debug > go
Note how the values in r0 and r1 correspond to the variables that were used to
evaluate the if statement in the previous instruction.
Check the output is correct in the Console window then quit the
debugger to finish the exercise.
In this exercise we will see how multiple commands can be combined in a script file
to control execution within the debugger.
go
break month.c|40
go
print daysInMonth dec
format dec
print date.day
print date.month
print date.year
unbreak #2
break month.c|58
go
print daysInMonth
let daysInMonth 30
go
memory @date +0xc 32
step
registers current
unbreak #2
go
The file consists of a simple selection of commands which will perform the same task
that was performed in the previous exercise.
Select Project→ Debug (F5) from the IDE menu to launch AXD.
When the program has terminated use the scroll bar on the right hand side of the
Command Line window to view the values of the variables displayed by the script file.
Check the output is correct in the Console window then quit the
debugger to finish the exercise.
We have now seen how the IDE can be used to create source files and
create projects and also how to add source files to projects.