ARM Software Development Toolkit User Guide

Version 2.50

Table of Contents

About this book
Further reading
ARM publications
Other publications
Typographical conventions
Feedback on this book
Feedback on the ARM Software Development Toolkit
1. Introduction
1.1. About the ARM Software Development Toolkit
1.1.1. Components of the SDT
1.1.2. Components of C++ version 1.10
1.2. Supported platforms
1.3. What is new?
1.3.1. Functionality enhancements and new functionality
1.3.2. Changes in default behavior
1.3.3. Obsolete and deprecated features
2. ARM Project Manager
2.1. About the ARM Project Manager
2.1.1. Online help
2.2. Getting started
2.2.1. Starting and stopping APM
2.2.2. Projects and sub-projects
2.2.3. Build
2.2.4. Correcting problems
2.2.5. Project output
2.3. The APM desktop
2.3.1. Project window
2.3.2. Changing the way a project is displayed
2.3.3. Edit window
2.3.4. View window
2.4. Additional APM functions
2.4.1. Configuring tools
2.4.2. Partitions
2.4.3. Project templates
2.4.4. Project hierarchy
2.4.5. Variables
2.4.6. Variants
2.4.7. Changing a project name
2.4.8. Converting old projects
2.5. Setting preferences
2.5.1. APM preferences
2.5.2. Editor preferences
2.6. Working with source files
2.6.1. Creating a new source file with APM
2.6.2. When a file type is associated with multiple partitions
2.6.3. Performing a single build step
2.7. Viewing object and executable files
2.7.1. decaof
2.7.2. decaxf
2.8. Working with project templates
2.8.1. General information
2.8.2. Blank templates supplied with APM
2.8.3. Editing a variable
2.8.4. Editing a path
2.8.5. Editing a project template
2.8.6. Creating a new template
2.8.7. Editing project template details
2.9. Build step patterns
2.9.1. Specifying input and output patterns in a build step pattern
2.9.2. Editing a build step pattern
2.9.3. Adding a build step pattern
2.10. Using APM with C++
2.10.1. APM templates for C++
2.10.2. Using the ARM Project Manager C++ Templates
3. ARM Debuggers for Windows and UNIX
3.1. About the ARM Debuggers
3.1.1. Online help
3.1.2. Debugging an ARM application
3.1.3. Debugging systems
3.1.4. Debugger concepts
3.2. Getting started
3.2.1. The ARM Debugger desktop
3.2.2. Starting and closing the debugger
3.2.3. Loading, reloading, and executing a program image
3.2.4. Examining and setting variables, registers, and memory
3.3. ARM Debugger desktop windows
3.3.1. Main windows
3.3.2. Optional windows
3.4. Breakpoints, watchpoints, and stepping
3.4.1. Simple breakpoints
3.4.2. Simple watchpoints
3.4.3. Complex breakpoints
3.4.4. Complex watchpoints
3.4.5. Backtrace
3.4.6. Stepping through an image
3.5. Debugger further details
3.5.1. Working with source files
3.5.2. Working with variables
3.5.3. Displaying disassembled and interleaved code
3.5.4. Remote debug information
3.5.5. Using regular expressions
3.5.6. High level and low level symbols
3.5.7. Profiling
3.5.8. Saving or changing an area of memory
3.5.9. Specifying command-line arguments for your program
3.5.10. Using command-line debugger instructions
3.5.11. Changing the data width for reads and writes
3.5.12. Flash download
3.6. Channel viewers (Windows only)
3.6.1. ThumbCV channel viewer
3.7. Configurations
3.7.1. Debugger configuration
3.7.2. ARMulator configuration
3.7.3. Angel remote configuration
3.7.4. EmbeddedICE configuration
3.8. ARM Debugger with C++
3.8.1. About ADW for C++
3.8.2. Using the C++ debugging tools
3.8.3. Using the Class View window
3.8.4. Using the Watch window
3.8.5. Evaluating expressions
3.8.6. Debug Format Considerations
4. Command-Line Development
4.1. The hello world example
4.1.1. Create, compile, link, and run
4.1.2. Debugging hello.c
4.1.3. Separating the compile and link stages
4.1.4. Generating interleaved C and assembly language
4.1.5. For more information
4.2. armsd
4.2.1. Starting armsd and loading an image
4.2.2. Obtaining help on the armsd commands
4.2.3. Setting and removing simple breakpoints
4.2.4. Setting and removing simple watchpoints
4.2.5. Executing the program
4.2.6. Stepping through the program
4.2.7. Exiting the debugger
4.2.8. Viewing and setting program variables
4.2.9. Displaying source code
4.2.10. Viewing and setting debugger variables
5. Basic Assembly Language Programming
5.1. Introduction
5.1.1. Code examples
5.2. Overview of the ARM architecture
5.2.1. Architecture versions
5.2.2. ARM and Thumb state
5.2.3. Address space
5.2.4. Processor mode
5.2.5. Registers
5.2.6. ARM instruction set overview
5.2.7. Thumb instruction set overview
5.3. Structure of assembly language modules
5.3.1. Layout of assembly language source files
5.3.2. An example ARM assembly language module
5.3.3. Calling Subroutines
5.3.4. An example Thumb assembly language module
5.4. Conditional execution
5.4.1. The ALU status flags
5.4.2. Execution conditions
5.4.3. Using conditional execution in ARM state
5.5. Loading constants into registers
5.5.1. Direct loading with MOV and MVN
5.5.2. Loading with LDR Rd, =const
5.6. Loading addresses into registers
5.6.1. Direct loading with ADR and ADRL
5.6.2. Loading addresses with LDR Rd, = label
5.7. Load and store multiple register instructions
5.7.1. ARM LDM and STM Instructions
5.7.2. LDM and STM addressing modes
5.7.3. Implementing stacks with LDM and STM
5.7.4. Block copy with LDM and STM
5.7.5. Thumb LDM and STM instructions
5.8. Using macros
5.8.1. Test and branch macro example
5.8.2. Unsigned integer division macro example
5.9. Describing data structures with MAP and # directives
5.9.1. Absolute maps
5.9.2. Relative maps
5.9.3. Register based maps
5.9.4. Program-relative maps
5.9.5. Finding the end of the allocated data
5.9.6. Forcing correct alignment
5.9.7. Using register-based MAP and # directives
5.9.8. Using two register-based structures
5.9.9. Avoiding problems with MAP and # directives
6. Using the Procedure Call Standards
6.1. About the procedure call standards
6.2. Using the ARM Procedure Call Standard
6.2.1. APCS register names and usage
6.2.2. An example of APCS register usage: 64-bit integer addition
6.2.3. A more detailed look at APCS register usage
6.3. Using the Thumb Procedure Call Standard
6.3.1. TPCS register names and usage
6.4. Passing and returning structures
6.4.1. The default method
6.4.2. Returning integer-like structures
6.4.3. Returning non integer-like structures in registers
7. Interworking ARM and Thumb
7.1. About interworking
7.1.1. When to use interworking
7.2. Basic assembly language interworking
7.2.1. The Branch Exchange instruction
7.2.2. Implementing interworking assembly language subroutines
7.2.3. Data in Thumb code areas
7.3. C and C++ interworking and veneers
7.3.1. Specifying APCS options
7.3.2. Compiling code for Interworking
7.3.3. Simple rules for interworking
7.3.4. Detecting interworking calls
7.3.5. Using two copies of the same function
7.3.6. The C and C++ interworking libraries
7.4. Assembly language interworking using veneers
7.4.1. Assembly-only interworking using veneers
7.4.2. C, C++, and assembly language interworking using veneers
7.5. ARM-Thumb interworking with the ARM Project Manager
7.5.1. Choosing a template
7.5.2. Using the Thumb-ARM interworking image project
7.5.3. Modifying a project to support interworking
7.5.4. C library usage and the ARM Project Manager
8. Mixed Language Programming
8.1. Using the inline assemblers
8.1.1. Invoking the inline assembler
8.1.2. ARM and Thumb instruction sets
8.1.3. Differences between the inline assemblers and armasm
8.1.4. Restrictions
8.1.5. Usage
8.1.6. Examples
8.2. Accessing C global variables from assembly code
8.3. Using C header files from C++
8.3.1. Including system C header files
8.3.2. Including your own C header files
8.4. Calling between C, C++, and ARM assembly language
8.4.1. General rules for calling between languages
8.4.2. C++ specific information
8.4.3. Examples
9. Handling Processor Exceptions
9.1. Overview
9.1.1. The vector table
9.1.2. Use of modes and registers by exceptions
9.1.3. Exception priorities
9.2. Entering and leaving an exception
9.2.1. The processor response to an exception
9.2.2. Returning from an exception handler
9.2.3. The return address and return instruction
9.3. Installing an exception handler
9.3.1. Installing the handlers at reset
9.3.2. Installing the handlers from C
9.4. SWI handlers
9.4.1. SWI handlers in assembly language
9.4.2. SWI handlers in C and assembly language
9.4.3. Using SWIs in supervisor mode
9.4.4. Calling SWIs from an application
9.4.5. Calling SWIs dynamically from an application
9.5. Interrupt handlers
9.5.1. Simple interrupt handlers in C
9.5.2. Reentrant interrupt handlers
9.5.3. Example interrupt handlers in assembly language
9.6. Reset handlers
9.7. Undefined instruction handlers
9.8. Prefetch abort handler
9.9. Data abort handler
9.10. Chaining exception handlers
9.10.1. A single extended handler
9.10.2. Several chained handlers
9.11. Handling exceptions on Thumb-capable processors
9.11.1. Thumb processor response to an exception
9.11.2. The return address
9.11.3. Determining the processor state
9.12. System mode
10. Writing Code for ROM
10.1. About writing code for ROM
10.2. Memory map considerations
10.2.1. ROM at 0x0
10.2.2. RAM at 0x0
10.3. Initializing the system
10.3.1. Defining the entry point
10.3.2. Setting up exception vectors
10.3.3. Initializing the memory system
10.3.4. Initializing the stack pointers
10.3.5. Initializing any critical I/O devices
10.3.6. Initializing RAM variables required by the interrupt system
10.3.7. Initializing memory required by C code
10.3.8. Enabling interrupts
10.3.9. Changing processor mode
10.3.10. Changing processor state
10.3.11. Entering C code
10.4. Example 1: Building a ROM to be loaded at address 0
10.4.1. Area listing for the code
10.4.2. Output from -info Sizes option
10.4.3. Sample code
10.5. Example 2: Building a ROM to be entered at its base address
10.5.1. Building the ROM image
10.5.2. Sample disassembly
10.6. Example 3: Using the embedded C library
10.6.1. Initialization code
10.6.2. C code
10.6.3. Compiling, linking, and running the program
10.6.4. Code listings for example 3
10.7. Example 4: Simple scatter loading example
10.7.1. Memory map
10.7.2. Scatter load description file
10.7.3. Initialization code
10.7.4. Initializing execution regions
10.7.5. C code
10.7.6. Building the example
10.8. Example 5: Complex scatter load example
10.8.1. Memory map
10.8.2. Scatter load description file
10.8.3. Initialization code
10.8.4. Initializing execution regions
10.8.5. Building the example
10.8.6. Running the example
10.9. Scatter loading and long-distance branching
10.9.1. Range restrictions
10.10. Converting ARM linker ELF output to binary ROM formats
10.10.1. Multiple output formats
10.10.2. Configuration
10.11. Troubleshooting hints and tips
10.11.1. Replacing the Write0() SWI call
10.11.2. Linker errors
11. Benchmarking, Performance Analysis, and Profiling
11.1. About benchmarking and profiling
11.2. Measuring code and data size
11.2.1. Interpreting size information
11.2.2. Calculating ROM and RAM requirements
11.2.3. Code and data sizes example: Dhrystone
11.3. Performance benchmarking
11.3.1. Measuring performance
11.3.2. Cycle counting example: Dhrystone
11.3.3. Real-time simulation
11.3.4. Reading the simulated time
11.3.5. Map files
11.3.6. Real-time simulation example: Dhrystone
11.3.7. Reducing the time required for simulation
11.4. Improving performance and code size
11.4.1. Compiler options
11.4.2. Improving image size with the linker
11.4.3. Changing the source
11.5. Profiling
11.5.1. Availability of profiling
11.5.2. About armprof
11.5.3. Collecting profile data
11.5.4. Saving profile data
11.5.5. Generating the profile report
11.5.6. Profiling example: sorts
11.5.7. Profiling and instruction tracing with ARMulator
12. ARMulator
12.1. About the ARMulator
12.2. ARMulator models
12.2.1. Sample models
12.2.2. Model stub exports
12.3. Tracer
12.3.1. Configuring the Tracer
12.3.2. Debugger support for tracing
12.3.3. Interpreting trace file output
12.4. Profiler
12.4.1. Configuring the profiler
12.5. Windows Hourglass
12.6. Watchpoints
12.6.1. Enabling watchpoints
12.7. Page table manager
12.7.1. Controlling the MMU and cache
12.7.2. Controlling registers 2 and 3
12.7.3. Pagetable contents
12.8. armflat
12.8.1. Selecting the ARMflat memory model
12.9. armfast
12.9.1. Selecting the ARMfast memory model
12.10. armmap
12.10.1. Clock frequency
12.10.2. Selecting the ARMmap memory model
12.10.3. How ARMmap calculates wait-states
12.10.4. Configuring the ARMmap memory model
12.11. Dummy MMU
12.11.1. Configuring the Dummy MMU
12.12. Angel
12.12.1. Configuring Angel
12.12.2. ARMulator SWIs
12.13. Controlling the ARMulator using the debugger
12.13.1. About RDI
12.13.2. Using the armul.cnf configuration file
12.13.3. The File
12.14. A sample memory model
12.14.1. The memory map
12.14.2. Implementation
12.15. Rebuilding the ARMulator
12.15.1. Rebuilding on UNIX
12.15.2. Rebuilding on Windows
12.16. Configuring ARMulator to use the example
13. Angel
13.1. About Angel
13.1.1. Angel system features
13.1.2. Angel component overview
13.1.3. Angel system resource requirements
13.2. Developing applications with Angel
13.2.1. Full Angel debug agent
13.2.2. Minimal Angel
13.2.3. Overview of the development procedure
13.2.4. Developing an application under full Angel
13.2.5. Developing an application under minimal Angel
13.2.6. Application communications
13.2.7. Downloading new application versions
13.3. Angel in operation
13.3.1. Initialization
13.3.2. Waiting for debug communications
13.3.3. Angel debugger functions
13.3.4. Angel task management
13.3.5. Context switching
13.3.6. Example of Angel processing: a simple IRQ
13.4. Porting Angel to new hardware
13.4.1. Angel source code directory structure
13.4.2. Overview of porting steps and recommendations
13.4.3. Modifying the UNIX makefile
13.4.4. Modifying an APM project
13.4.5. Modifying target-specific files
13.4.6. Writing the device drivers
13.4.7. Downloading a new version of Angel
13.4.8. Debugging your Angel port
13.5. Configuring Angel
13.5.1. Configuring the memory map
13.5.2. Configuring timers and profiling
13.5.3. Configuring exception handlers
13.5.4. Configuring where Angel runs
13.5.5. Configuring SWI numbers
13.6. Angel communications architecture
13.6.1. Overview of the Angel communications layers
13.6.2. Boot support
13.6.3. Channels layer and buffer management
13.6.4. Device driver layer
13.7. Angel C library support SWIs
13.7.1. Angel task management and SWIs
13.7.2. SYS_OPEN (0x01)
13.7.3. SYS_CLOSE (0x02)
13.7.4. SYS_WRITEC (0x03)
13.7.5. SYS_WRITE0 (0x04)
13.7.6. SYS_WRITE (0x05)
13.7.7. SYS_READ (0x06)
13.7.8. SYS_READC (0x07)
13.7.9. SYS_ISERROR (0x08)
13.7.10. SYS_ISTTY (0x09)
13.7.11. SYS_SEEK (0x0a)
13.7.12. SYS_FLEN (0x0c)
13.7.13. SYS_TMPNAM (0x0d)
13.7.14. SYS_REMOVE (0x0e)
13.7.15. SYS_RENAME (0xf)
13.7.16. SYS_CLOCK (0x10)
13.7.17. SYS_TIME (0x11)
13.7.18. SYS_SYSTEM (0x12)
13.7.19. SYS_ERRNO (0x13)
13.7.20. SYS_GET_CMDLINE (0x15)
13.7.21. SYS_HEAPINFO (0x16)
13.7.22. SYS_ELAPSED (0x30)
13.7.23. SYS_TICKFREQ (0x31)
13.8. Angel debug agent interaction SWIs
13.8.1. angel_SWIreason_EnterSVC (0x17)
13.8.2. angel_SWIreason_ReportException (0x18)
13.8.3. angel_SWIreason_LateStartup (0x20)
13.9. The Fusion IP stack for Angel
13.9.1. How Angel, Fusion, and the PID hardware fit together
A. FlexLM License Manager
A.1. About license management
A.1.1. Installing FlexLM software
A.2. Obtaining your license file
A.3. What to do with your license file
A.4. Starting the server software
A.5. Running your licensed software
A.5.1. Setting the environment variable ARMLMD_LICENSE_FILE
A.5.2. Running your application
A.6. Customizing your license file
A.6.1. Server and Vendor lines
A.6.2. Feature lines
A.7. Finding a license
A.8. Using FlexLM with more than one product
A.8.1. All products use the same server
A.8.2. All products use different license servers
A.9. FlexLM license management utilities
A.9.1. License administration tools
A.10. Frequently asked questions about licensing

List of Figures

2.1. New dialog
2.2. New Project dialog
2.3. Expanded view
2.4. Built project with error in source
2.5. Successful project build
2.6. Project window
2.7. Edit window
2.8. View window
2.9. Compiler Configuration dialog
2.10. Add Variant dialog
2.11. Build Variants dialog
2.12. Edit Variables dialog
2.13. Project Conversion wizard
2.14. APM Preferences dialog
2.15. Editor Preferences dialog
2.16. New dialog
2.17. Files Matched Multiple Partitions dialog
2.18. Viewing dialog
2.19. View window
2.20. Edit Variables dialog
2.21. Edit Paths dialog
2.22. Project Template Editor dialog
2.23. Edit Template Details dialog
2.24. Edit Build Step Pattern dialog
2.25. The APM New dialog
2.26. The APM New Project dialog
3.1. A typical debugging set-up
3.2. A typical ARM Debugger desktop display
3.3. Execution window
3.4. Console window
3.5. Command window
3.6. Locals window
3.7. Set or Edit Breakpoint dialog
3.8. Set or Edit Watchpoint dialog
3.9. Variable Properties dialog
3.10. Put File dialog
3.11. Get File dialog
3.12. Command Line Arguments dialog
3.13. Flash Download dialog
3.14. Thumb Comms Channel Viewer
3.15. Configuration of target environment
3.16. Configuration of debugger
3.17. Configuration of ARM Debugger memory maps
3.18. Configuration of ARMulator
3.19. Configuration of remote connection
3.20. Configuration of EmbeddedICE target
3.21. The ARM Debugger C++ interface
3.22. The Class View window
3.23. The Class View window menu
3.24. The Watch window
3.25. The Watch window menu
3.26. The Watch Control window
3.27. The Display Format window
3.28. The Modify Item window
3.29. The Evaluate Expression window
3.30. Compiler configuration window
4.1. Compiling and linking C
6.1. Mixing C or C++ and assembly language
7.1. Total code sizes
7.2. Interworking veneer sizes
7.3. Interworking using direct calls
7.4. Interworking errors
7.5. Example veneer
9.1. ARM SWI instruction
9.2. Accessing the supervisor stack
9.3. PCB layout
9.4. Handling an exception in Thumb state
9.5. Thumb SWI instruction
10.1. Example of a system with ROM at 0x0
10.2. Example of a system with RAM at 0x0
10.3. Memory map for example 4
10.4. Memory map for example 5
12.1. Memory map
12.2. I/O area split
13.1. A typical Angel system
13.2. The Angel development process
13.3. Angel raw serial device
13.4. Processing a simple IRQ
13.5. Angel source directory structure
13.6. Edit variables
13.7. Project template editor
13.8. Edit Build Step Pattern
13.9. Edit makelo.c build step
13.10. Compiler Configuration
13.11. Replacing target-specific source files
13.12. Communications layers for Angel
13.13. Send buffer lifecycle
13.14. Angel, Fusion ,and PID hardware
A.1. Finding a license

Proprietary Notice

ARM, Thumb, StrongARM, and the ARM Powered logo are registered trademarks of ARM Limited.

Angel, ARMulator, EmbeddedICE, Multi-ICE, ARM7TDMI, ARM9TDMI, and TDMI are trademarks of ARM Limited.

All other products or services mentioned herein may be trademarks of their respective owners.

Neither the whole nor any part of the information contained in, or the product described in, this document may be adapted or reproduced in any material form except with the prior written permission of the copyright holder.

The product described in this document is subject to continuous developments and improvements. All particulars of the product and its use contained in this document are given by ARM in good faith. However, all warranties implied or expressed, including but not limited to implied warranties of merchantability, or fitness for purpose, are excluded.

This document is intended only to assist the reader in the use of the product. ARM Limited shall not be liable for any loss or damage arising from the use of any information in this document, or any error or omission in such information, or any incorrect use of the product.

Revision History
Revision ADec 1996Internal release
Revision BJan 1997First release for SDT 2.10
Revision CJune 1997Updated for SDT 2.11
Revision DNov 1998Updated for SDT 2.50
Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0040D