No part of this document may be reproduced without the prior written consent of IAR
Systems. The software described in this document is furnished under a license and may
only be used or copied in accordance with the terms of such a license.
DISCLAIMER
The information in this document is subject to change without notice and does not
represent a commitment on any part of IAR Systems. While the information contained
herein is assumed to be accurate, IAR Systems assumes no responsibility for any errors
or omissions.
In no event shall IAR Systems, its employees, its contractors, or the authors of this
document be liable for special, direct, indirect, or consequential damage, losses, costs,
charges, claims, demands, claim for lost profits, fees, or expenses of any nature or kind.
TRADEMARKS
IAR Systems, From Idea to Target, IAR Embedded Workbench, visualSTATE, IAR
MakeApp and C-SPY are trademarks owned by IAR Systems AB.
Atmel is a registered trademark of Atmel Corporation. AVR is a registered trademark of
Atmel Corporation.
Microsoft and Windows are registered trademarks of Microsoft Corporation.
All other product names are trademarks or registered trademarks of their respective
owners.
EDITION NOTICE
Fourth edition: February 2005
Part number: CAVR-4
This guide applies to version
4.x of AVR IAR Embedded Workbench®.
Brief contents
Tables ...................................................................................................................... xv
Preface ................................................................................................................... xix
Part 1. Using the compiler ......................................................... 1
Getting started .................................................................................................... 3
Data storage ...................................................................................................... 15
73: Traditional standard C header files—DLIB ...................................................... 245
74: Embedded C++ header files .............................................................................. 246
75: Additional Embedded C++ header files—DLIB ............................................... 246
76: Standard template library header files ............................................................... 247
77: New standard C header files—DLIB ................................................................ 247
78: IAR CLIB Library header files ......................................................................... 249
79: Miscellaneous IAR CLIB Library header files ................................................. 249
80: Message returned by strerror()—IAR CLIB library ......................................... 265
81: Message returned by strerror()—IAR DLIB library ......................................... 268
xvii
AVR® IAR C/C++ Compiler
xviii
Reference Guide
Preface
Welcome to the AVR® IAR C/C++ Compiler Reference Guide. The purpose
of this guide is to provide you with detailed reference information that can
help you to use the AVR IAR C/C++ Compiler to best suit your application
requirements. This guide also gives you suggestions on coding techniques so
that you can develop applications with maximum efficiency.
Who should read this guide
You should read this guide if you plan to develop an application using the C or C++
language for the AVR microcontroller and need to get detailed reference information on
how to use the AVR IAR C/C++ Compiler. In addition, you should have a working
knowledge of the following:
● The architecture and instruction set of the AVR microcontroller. Refer to the
documentation from Atmel® Corporation for information about the AVR
microcontroller
● The C or C++ programming language
● Application development for embedded systems
● The operating system of your host machine.
How to use this guide
When you start using the AVR IAR C/C++ Compiler, you should read Part 1. Using the
compiler in this guide.
When you are familiar with the compiler and have already configured your project, you
can focus more on Part 2. Compiler reference.
If you are new to using the IAR toolkit, we recommend that you first study the AV R® IAR Embedded Workbench™ IDE User Guide. This guide contains a product overview,
tutorials that can help you get started, conceptual and user information about IAR
Embedded Workbench and the IAR C-SPY Debugger, and corresponding reference
information. The AVR® IAR Embedded Workbench™ IDE User Guide also contains a
glossary.
xix
What this guide contains
What this guide contains
Below is a brief outline and summary of the chapters in this guide.
Part 1. Using the compiler
● Getting started gives the information you need to get started using the AVR IAR
C/C++ Compiler for efficiently developing your application.
● Data storage describes how data can be stored in memory, with emphasis on the
different memory models and memory type attributes.
● Functions describes the special function types, such as interrupt functions and
monitor functions.
● Placing code and data describes the concept of segments, introduces the linker
command file, and describes how code and data are placed in memory.
● The DLIB runtime environment describes the runtime environment in which an
application executes. It covers how you can modify it by setting options, overriding
default library modules, or building your own library. The chapter also describes
system initialization and introduces the file
cstartup, as well as how to use
modules for locale, and file I/O.
● The CLIB runtime environment gives an overview of the runtime libraries and how
they can be customized. The chapter also describes system initialization and
introduces the file cstartup.
● Assembler language interface contains information required when parts of an
application are written in assembler language. This includes the calling convention.
● Using C++ gives an overview of the two levels of C++ support: The
industry-standard EC++ and IAR Extended EC++.
● Efficient coding for embedded applications gives hints about how to write code that
compiles to efficient code for an embedded application.
Part 2. Compiler reference
● Data representation describes the available data types, pointers, and structure types.
This chapter also gives information about type and object attributes.
● Segment reference gives reference information about the compiler’s use of
segments.
● Compiler options explains how to set the compiler options, gives a summary of the
options, and contains detailed reference information for each compiler option.
● Extended keywords gives reference information about each of the AVR-specific
keywords that are extensions to the standard C/C++ language.
● Pragma directives gives reference information about the pragma directives.
● The preprocessor gives a brief overview of the preprocessor, including reference
information about the different preprocessor directives, symbols, and other related
information.
● Intrinsic functions gives reference information about the functions that can be used
for accessing AVR-specific low-level features.
AVR® IAR C/C++ Compiler
xx
Reference Guide
Other documentation
Preface
● Library functions gives an introduction to the C or C++ library functions, and
summarizes the header files.
● Implementation-defined behavior describes how the AVR IAR C/C++ Compiler.
handles the implementation-defined areas of the C language standard.
● IAR language extensions describes the IAR extensions to the ISO/ANSI standard
for the C programming language.
● Diagnostics describes how the compiler’s diagnostic system works.
The complete set of IAR Systems development tools for the AVR microcontroller is
described in a series of guides. For information about:
● Using the IAR Embedded Workbench™ IDE with the IAR C-SPY™ Debugger,
refer to the AVR® IAR Embedded Workbench™ IDE User Guide
● Programming for the AVR IAR Assembler, refer to the AVR® IAR Assembler
Reference Guide
● Using the IAR XLINK Linker™, the IAR XAR Library Builder™, and the IAR
XLIB Librarian™, refer to the IAR Linker and Library Tools Reference Guide
● Using the IAR DLIB Library functions, refer to the online help system
● Using the IAR CLIB Library functions, refer to the IAR C Library Functions
Reference Guide, available from the online help system.
● Porting application code and projects created with a previous AVR IAR Embedded
Workbench IDE, refer to AVR® IAR Embedded Workbench Migration Guide.
All of these guides are delivered in hypertext PDF or HTML format on the installation
media. Some of them are also delivered as printed books.
FURTHER READING
The following books may be of interest to you when using the IAR Systems
development tools:
● Barr, Michael, and Andy Oram, ed. Programming Embedded Systems in C and
C++. O’Reilly & Associates.
● Harbison, Samuel P. and Guy L. Steele (contributor). C: A Reference Manual.
Prentice Hall.
● Kernighan, Brian W. and Dennis M. Ritchie. The C Programming Language.
Prentice Hall. [The later editions describe the ANSI C standard.]
● Labrosse, Jean J. Embedded Systems Building Blocks: Complete and Ready-To-Use
Modules in C. R&D Books.
● Lippman, Stanley B. and Josée Lajoie. C++ Primer. Addison-Wesley.
● Mann, Bernhard. C für Mikrocontroller. Franzis-Verlag. [Written in German.]
● Stroustrup, Bjarne. The C++ Programming Language. Addison-Wesley.
xxi
Document conventions
Document conventions
We recommend that you visit the following websites:
● The Atmel® Corporation website, www.atmel.com, contains information and news
about the AVR microcontrollers.
● The IAR website, www.iar.com, holds application notes and other product
information.
● Finally, the Embedded C++ Technical Committee website,
www.caravan.net/ec2plus, contains information about the Embedded C++
standard.
When, in this text, we refer to the programming language C, the text also applies to C++,
unless otherwise stated.
TYPOGRAPHIC CONVENTIONS
This guide uses the following typographic conventions:
StyleUsed for
computerText that you enter or that appears on the screen.
parameterA label representing the actual value you should enter as part of a
command.
[option]An optional part of a command.
{a | b | c}Alternatives in a command.
boldNames of menus, menu commands, buttons, and dialog boxes that
appear on the screen.
refe renceA cross-reference within this guide or to another guide.
…An ellipsis indicates that the previous item can be repeated an arbitrary
number of times.
Identifies instructions specific to the IAR Embedded Workbench
interface.
Identifies instructions specific to the command line interface.
Identifies helpful tips and programming hints.
AVR® IAR C/C++ Compiler
xxii
Reference Guide
Table 1: Typographic conventions used in this guide
Part 1. Using the compiler
This part of the AVR® IAR C/C++ Compiler Reference Guide includes the
following chapters:
● Getting started
● Data storage
● Functions
● Placing code and data
● The DLIB runtime environment
● The CLIB runtime environment
● Assembler language interface
● Using C++
● Efficient coding for embedded applications.
1
2
IAR language overview
Getting started
This chapter gives the information you need to get started using the AVR IAR
C/C++ Compiler for efficiently developing your application.
First you will get an overview of the supported programming languages,
followed by a description of the steps involved for compiling and linking an
application.
Next, the compiler is introduced. You will get an overview of the basic settings
needed for a project setup, including an overview of the techniques that enable
applications to take full advantage of the AVR microcontroller. In the following
chapters, these techniques will be studied in more detail.
There are two high-level programming languages available for use with the AVR IAR
C/C++ Compiler:
● C, the most widely used high-level programming language used in the embedded
systems industry. Using the AVR IAR C/C++ Compiler, you can build
freestanding applications that follow the standard ISO 9899:1990. This standard is
commonly known as ANSI C.
● C++, a modern object-oriented programming language with a full-featured library
well suited for modular programming. IAR Systems supports two levels of the
C++ language:
● Embedded C++ (EC++), a subset of the C++ programming standard, which is
intended for embedded systems programming. It is defined by an industry
consortium, the Embedded C++ Technical committee. See the chapter Using C++.
● IAR Extended EC++, with additional features such as full template support,
namespace support, the new cast operators, as well as the Standard Template
Library (STL).
Each of the supported languages can be used in strict or relaxed mode, or relaxed with
IAR extensions enabled. The strict mode adheres to the standard, whereas the relaxed
mode allows some deviations from the standard.
It is also possible to implement parts of the application, or the whole application, in
assembler language. See the AVR® IAR Assembler Reference Guide.
Part 1. Using the compiler
3
Building applications—an overview
For more information about the Embedded C++ language and IAR Extended Embedded
C++, see the chapter Using C++.
Building applications—an overview
A typical application is built from a number of source files and libraries. The source files
can be written in C, C++, or assembler language, and can be compiled into object files
by the AVR IAR C/C++ Compiler or the AVR IAR Assembler.
A library is a collection of object files. A typical example of a library is the compiler
library containing the runtime environment and the C/C++ standard library. Libraries
can also be built using the IAR XAR Library Builder, the IAR XLIB Librarian, or be
provided by external suppliers.
The IAR XLINK Linker is used for building the final application. XLINK normally uses
a linker command file, which describes the available resources of the target system.
Below, the process for building an application on the command line is described. For
information about how to build an application using the IAR Embedded Workbench
IDE, see the AVR® IAR Embedded Workbench™ IDE User Guide.
COMPILING
In the command line interface, the following line compiles the source file myfile.c
into the object file myfile.r90 using the default settings:
iccavr myfile.c
In addition, you need to specify some critical options, see Basic settings for project
configuration, page 5.
LINKING
The IAR XLINK Linker is used for building the final application. Normally, XLINK
requires the following information as input:
● A number of object files and possibly certain libraries
● The standard library containing the runtime environment and the standard language
functions
● A program start label
● A linker command file that describes the memory layout of the target system
● Information about the output format.
On the command line, the following line can be used for starting XLINK:
In this example, myfile.r90 and myfile2.r90 are object files, lnkm128s.xcl is the
linker command file, and
the label where the application starts. The option -o specifies the name of the output
file, and the option -F can be used for specifying the output format. (The default output
format is
Motorola.)
The IAR XLINK Linker produces output according to your specifications. Choose the
output format that suits your purpose. You might want to load the output to a
debugger—which means that you need output with debug information. Alternatively,
you might want to load the output to a flash loader—in which case you need output
without debug information, such as Intel-hex or Motorola S-records.
Basic settings for project configuration
This section gives an overview of the basic settings for the project setup that are needed
to make the compiler generate the best code for the AVR device you are using. You can
specify the options either from the command line interface or in the IAR Embedded
Workbench IDE. For details about how to set options, see Setting command line options,
page 167, and the AVR® IAR Embedded Workbench™ IDE User Guide, respectively.
The basic settings available for the AVR microcontroller are:
● Processor configuration
● Memory model
● Size of double floating-point type
● Optimization for speed and size
● Runtime environment.
In addition to these settings, there are many other options and settings available for
fine-tuning the result even further. See the chapter Compiler options for a list of all
available options.
Getting started
cl3s-ec.r90 is the runtime library. The option -s specifies
PROCESSOR CONFIGURATION
To make the compiler generate optimum code you should configure it for the AVR
microcontroller you are using.
The --cpu option versus the -v option
There are two processor options that can be used for configuring the processor support:
--cpu=derivative and -vn
Your program may use only one processor option at a time, and the same processor
option must be used by all user and library modules in order to maintain consistency.
Part 1. Using the compiler
5
Basic settings for project configuration
Both options set up default behavior—implicit assumptions—but note that the
--cpu
option is more precise because it contains more information about the intended target
than the more generic
-v option. The --cpu option knows, for example, how much flash
memory is available in the given target and allows the compiler to optimize accesses to
code memory in a way that the
-v option does not. See Mapping of processor options
--cpu and -v, page 6.
The
--cpu=derivative option implicitly sets up all internal compiler settings needed
to generate code for the processor variant you are using. The following options are
implicitly controlled when you use the
--eeprom_size, --enhanced_core, --spmcr_address, -v and --64k_flash.
Because these options are automatically set when you use the
--cpu option: --eecr_address,
--cpu option, you cannot
set them explicitly. For information about implicit assumptions when using the -v
option, see Summary of processor configuration, page 8. To read more about the
generated code, see -v, page 197.
See the AVR® IAR Embedded Workbench™ IDE User Guide for information about
setting project options in IAR Embedded Workbench.
Use the --cpu or -v option to specify the AVR derivative; see the chapter Compiler options for syntax information.
Mapping of processor options --cpu and -v
The following table shows the mapping of processor options and which AVR
microcontrollers they support:
The following table summarizes the memory characteristics for each -v option:
Generic processor
option
Available
memory models
-v0Tiny__nearfunc≤ 256 bytes≤ 8 Kbytes
-v1Tiny, Small__nearfunc≤ 64 Kbytes≤ 8 Kbytes
Table 3: Summary of processor configuration
Function
memory
attribute
Max addressable
data
Max module and/or
program size
Getting started
Generic processor
option
-v2Tiny__nearfunc≤ 256 bytes≤ 128 Kbytes
-v3Tiny, Small__nearfunc≤ 64 Kbytes≤ 128 Kbytes
-v4Small, Large__nearfunc≤ 16 Mbytes≤ 128 Kbytes
-v5Tiny, Small__farfunc
-v6Small, Large__farfunc
Table 3: Summary of processor configuration (Continued)
Available
memory models
Function
memory
attribute
Max addressable
data
*
≤ 64 Kbytes≤ 8 Mbytes
*
≤ 16 Mbytes≤ 8 Mbytes
Max module and/or
program size
Note:
*)
●
When using the -v5 or the -v6 option, it is possible, for individual functions,
to override the
● Pointers with function memory attributes have restrictions in implicit and
__farfunc attribute and instead use the __nearfunc attribute
explicit casts between pointers and between pointers and integer types. For
details about the restrictions, see Casting, page 142
● -v2 and -v4: There are currently no derivatives that match these processor
options, which have been added to support future derivatives
● All implicit assumptions for a given -v option are also true for corresponding
--cpu options.
It is important to be aware of the fact that the
-v option does not reflect the amount of
used data, but the maximum amount of addressable data. This means that, for example,
if you are using a microcontroller with 16 Mbyte addressable data, but you are not using
more than 256 bytes or 64 Kbytes of data, you must still use either the
-v4 or the -v6
option for 16 Mbyte data.
MEMORY MODEL
One of the characteristics of the AVR microcontroller is that there is a trade-off
regarding the way memory is accessed, ranging from cheap access limited to small
memory areas, up to more expensive access methods that can access any location in
memory.
In the AVR IAR C/C++ Compiler, you can set a default memory access method by
selecting a memory model. There are three memory models available—Tiny, Small, and
Large. Your choice of processor option determines which memory models are available.
If you do not specify a memory model option, the compiler will use the Tiny memory
model for all processor options, except for
model will be used.
-v4 and -v6, where the Small memory
Part 1. Using the compiler
9
Basic settings for project configuration
Your program may use only one memory model at a time, and the same model must be
used by all user modules and all library modules.
Summary of memory models
The following table summarizes the characteristics for each memory model:
Memory model
Tiny-v0, -v1, -v2,
Small-v1, -v3, -v4,
Large-v4, -v6__far__far≤ 16 Mbytes
Table 4: Summary of memory models
Generic processor
option
-v3, -v5
-v5, -v6
Default memory
attribute
__tiny__tiny≤ 256 bytes
__near__near≤ 64 Kbytes
Default data
pointer
Max. stack size
For more details about memory models, see Memory models, page 17.
SIZE OF DOUBLE FLOATING-POINT TYPE
Floating-point values are represented by 32- and 64-bit numbers in standard IEEE754
format. By enabling the compiler option --64bit_doubles, you can choose whether
data declared as
float is always represented using 32 bits.
double should be represented with 32 bits or 64 bits. The data type
OPTIMIZATION FOR SPEED AND SIZE
The AVR IAR C/C++ Compiler is a state-of-the-art compiler with an optimizer that
performs, among other things, dead-code elimination, constant propagation, inlining,
common sub-expression elimination, and precision reduction. It also performs loop
optimizations, such as induction variable elimination.
You can decide between several optimization levels and two optimization goals—size
and speed. Most optimizations will make the application both smaller and faster.
However, when this is not the case, the compiler uses the selected optimization goal to
decide how to perform the optimization.
The optimization level and goal can be specified for the entire application, for individual
files, and for individual functions. In addition, some individual optimizations, such as
function inlining, can be disabled.
For details about compiler optimizations, see Controlling compiler optimizations, page
122. For more information about efficient coding techniques, see the chapter Efficient coding for embedded applications.
AVR® IAR C/C++ Compiler
10
Reference Guide
Getting started
RUNTIME ENVIRONMENT
To create the required runtime environment you should choose a runtime library and set
library options. You may also need to override certain library modules with your own
customized versions.
There are two different sets of runtime libraries provided:
● The IAR DLIB Library, which supports ISO/ANSI C and C++. This library also
supports floating-point numbers in IEEE 754 format and it can be configured to
include different levels of support for locale, file descriptors, multibyte characters,
et cetera.
● The IAR CLIB Library is a light-weight library, which is not fully compliant with
ISO/ANSI C. Neither does it fully support floating-point numbers in IEEE 754
format or does it support Embedded C++. (This library is used by default).
The runtime library you choose can be one of the prebuilt libraries, or a library that you
have customized and built yourself. The IAR Embedded Workbench IDE provides a
library project template for both libraries, that you can use for building your own library
version. This gives you full control of the runtime environment. If your project only
contains assembler source code, there is no need to choose a runtime library.
For detailed information about the runtime environments, see the chapters The DLIB runtime environment and The CLIB runtime environment, respectively.
The way you set up a runtime environment and locate all the related files differs
depending on which build interface you are using—the IAR Embedded Workbench IDE
or the command line.
Choosing a runtime library in IAR Embedded Workbench
To choose a library, choose Project>Options, and click the Library Configuration tab
in the General Options category. Choose the appropriate library from the Library
drop-down menu.
Note that for the DLIB library there are two different configurations—Normal and
Full—which include different levels of support for locale, file descriptors, multibyte
characters, et cetera. See Library configurations, page 55, for more information.
Based on which library configuration you choose and your other project settings, the
correct library file is used automatically. For the device-specific include files, a correct
include path is set up.
Part 1. Using the compiler
11
Special support for embedded systems
Choosing a runtime library from the command line
Use the following command line options to specify the library and the dependency files:
Command lineDescription
-I\avr\incSpecifies the include paths
-I\avr\inc\{clib|dlib}Specifies the library-specific include path. Use clib or
dlib depending on which library you are using.
libraryfile.r90Specifies the library object file
--dlib_config
C:\...\configfile.h
Table 5: Command line options for specifying library and dependency files
For a list of all prebuilt library object files for the IAR DLIB Library, see Table 15,
Prebuilt libraries, page 57. The table also shows how the object files correspond to the
dependent project options, and the corresponding configuration files. Make sure to use
the object file that matches your other project options.
For a list of all prebuilt object files for the IAR CLIB Library, see Table 26, Prebuilt libraries, page 86. The table also shows how the object files correspond to the dependent
project options. Make sure to use the object file that matches your other project options.
Specifies the library configuration file (for the IAR DLIB
Library only)
Setting library and runtime environment options
You can set certain options to reduce the library and runtime environment size:
● The formatters used by the functions printf, scanf, and their variants, see
Choosing formatters for printf and scanf, page 59 (DLIB) and Input and output,
page 87 (CLIB).
● The size of the stack and the heap, see The data stack, page 41, and The return
address stack, page 43, respectively.
Special support for embedded systems
This section briefly describes the extensions provided by the AVR IAR C/C++ Compiler
to support specific features of the AVR microcontroller.
EXTENDED KEYWORDS
The AVR IAR C/C++ Compiler provides a set of keywords that can be used for
configuring how the code is generated. For example, there are keywords for controlling
the memory type for individual variables as well as for declaring special function types.
By default, language extensions are enabled in IAR Embedded Workbench.
AVR® IAR C/C++ Compiler
12
Reference Guide
Getting started
The command line option -e makes the extended keywords available, and reserves them
so that they cannot be used as variable names. See, -e, page 179 for additional
information.
For detailed descriptions of the extended keywords, see the chapter Extended keywords.
To read about special function types, see Special function types, page 29.
PRAGMA DIRECTIVES
The pragma directives control the behavior of the compiler, for example how it allocates
memory, whether it allows extended keywords, and whether it issues warning messages.
The pragma directives are always enabled in the AVR IAR C/C++ Compiler. They are
consistent with ISO/ANSI C, and are very useful when you want to make sure that the
source code is portable.
For detailed descriptions of the pragma directives, see the chapter Pragma directives.
PREDEFINED SYMBOLS
With the predefined preprocessor symbols, you can inspect your compile-time
environment, for example time of compilation, the processor variant, and memory
model in use.
For detailed descriptions of the predefined symbols, see the chapter The preprocessor.
HEADER FILES FOR I/O
Standard peripheral units are defined in device-specific I/O header files with the
filename extension h. The product package supplies I/O files for all devices that are
available at the time of the product release. You can find these files in the
directory. Make sure to include the appropriate include file in your application source
files. If you need additional I/O header files, they can easily be created using one of the
provided ones as a template.
For an example, see Accessing special function registers, page 133.
avr\inc
ACCESSING LOW-LEVEL FEATURES
For hardware-related parts of your application, accessing low-level features is essential.
The AVR IAR C/C++ Compiler supports several ways of doing this: intrinsic functions,
mixing C and assembler modules, and inline assembler. For information about the
different methods, see Mixing C and assembler, page 93.
Part 1. Using the compiler
13
Special support for embedded systems
AVR® IAR C/C++ Compiler
14
Reference Guide
Introduction
Data storage
This chapter gives a brief introduction to the memory layout of the AVR
microcontroller and the fundamental ways data can be stored in memory: on
the stack, in static (global) memory, or in heap memory. For efficient memory
usage, AVR IAR C/C++ Compiler provides a set of memory models and
memory attributes, allowing you to fine-tune the access methods, resulting in
smaller code size. The concepts of memory models and memory types are
described in relation to pointers, structures, C++ class objects, and
non-initialized memory. Finally, detailed information about data storage on the
stack and the heap is provided.
The AVR microcontroller is based on the Harvard architecture—thus code and data have
separate memory spaces and require different access mechanisms. Code and different
type of data are located in memory spaces as follows:
● The internal flash space, which is used for code, __flash declared objects, and
initializers
● The data space, which can consist of external ROM, used for constants, and RAM
areas used for the stack, for registers, and for variables
● The EEPROM space, which is used for variables.
STORING DATA
In a typical application, data can be stored in memory in three different ways:
● On the stack. This is memory space that can be used by a function as long as it is
executing. When the function returns to its caller, the memory space is no longer
valid.
● Static memory. This kind of memory is allocated once and for all; it remains valid
through the entire execution of the application. Variables that are either global or
declared static are placed in this type of memory. The word static in this context
means that the amount of memory allocated for this type of variable does not
change while the application is running.
Part 1. Using the compiler
15
Introduction
● On the heap. Once memory has been allocated on the heap, it remains valid until it
is explicitly released back to the system by the application. This type of memory is
useful when the number of objects is not known until the application executes. Note
that there are potential risks connected with using the heap in systems with a limited
amount of memory, or systems that are expected to run for a long time.
EXTENDED KEYWORDS FOR DATA
The extended keywords that can be used for data control the following:
● For data memory space, keywords that control the placement and type of objects
and pointers: __tiny, __near, __far, __huge, and _ _regvar
● For the EEPROM memory space, keyword that controls the placement and type of
objects and pointers:
● For the code (flash) memory space, keywords that control the placement and type of
objects and pointers: __tinyflash, __flash, _ _farflash, and _ _hugeflash
● For the I/O memory space, keyword that controls the placement and type of objects
and pointers: __ext_io, _ _io
● Special pointer that can access data objects in both data and code memory space:
__generic
● Other characteristics of objects: __root and __no_init.
See the chapter Data storage in Part 1. Using the compiler for more information about
how to use data memory types.
__eeprom
AVR® IAR C/C++ Compiler
16
Reference Guide
Syntax
The keywords follow the same syntax as the type qualifiers const and volatile. The
following declarations place the variable
i and j in EEPROM memory. The variables k
and l behave in the same way:
__eeprom int i, j;
int __eeprom k, l;
Note that the keyword affects both identifiers.
In addition to the rules presented here—to place the keyword directly in the code—the
directives
#pragma type_attribute and #pragma object_attribute can be used
for specifying the keywords. Refer to the chapter Pragma directives for details about
how to use the extended keywords together with pragma directives.
Pointers
A keyword that is followed by an asterisk (*), affects the type of the pointer being
declared. A pointer to EEPROM memory is thus declared by:
char __eeprom * p;
Data storage
Note that the location of the pointer variable p is not affected by the keyword. In the
following example, however, the pointer variable
p2 is placed in far memory. Like p, p2
points to a character in EEPROM memory.
char __eeprom * _ _far p2;
Type definitions
Storage can also be specified using type definitions. The following two declarations are
equivalent:
The AVR IAR C/C++ Compiler supports a number of memory models that can be used
for applications with different data requirements.
Technically, the memory model specifies the default memory type attribute and default
data pointer attribute. This means that the memory model controls the following:
● The placement of static and global variables, as well as constant literals
● Dynamically allocated data, for example data allocated with malloc, or, in C++,
the operator
● The default pointer type
● The placement of the runtime stack.
new
The memory model only specifies the default memory type. It is possible to override this
for individual variables and pointers. For information about how to specify a memory
type for individual objects, see Using data memory attributes, page 19.
SPECIFYING A MEMORY MODEL
Three memory models are implemented: Tiny, Small, and Large. These models are
controlled by the --memory_model option. Each memory model has a default memory
type and a default pointer size. The code size will also be reduced somewhat if the Tiny
or Small memory model is used.
Part 1. Using the compiler
17
Memory types and memory attributes
Your project can only use one memory model at a time, and the same model must be
used by all user modules and all library modules. If you do not specify a memory model
option, the compiler will use the Tiny memory model for all processor options, except
for -v4 and -v6, where the Small memory model will be used.
The following table summarizes the different memory models:
See the AVR® IAR Embedded Workbench™ IDE User Guide for information about
setting options in IAR Embedded Workbench.
Use the
--memory_model option to specify the memory model for your project; see -m,
--memory_model, page 186.
Note that the default memory type can be overridden by explicitly specifying a memory
attribute, using either keywords or the
information about the different memory types, see Memory types and memory attributes, page 18.
Memory types and memory attributes
This section describes the concept of memory types used for accessing data by the AVR
IAR C/C++ Compiler. It also discusses pointers in the presence of multiple memory
types. For each memory type, the capabilities and limitations are discussed.
The AVR IAR C/C++ Compiler uses different memory types to access data that is
placed in different areas of the memory. There are different methods for reaching
memory areas, and they have different costs when it comes to code space, execution
speed, and register usage. The access methods range from generic but expensive
methods that can access the full memory range, to cheap methods that can access limited
memory areas. Each memory type corresponds to one memory access method. By
mapping different memories—or part of memories—to memory types, the compiler can
generate code that can access data efficiently.
For example, the memory accessible using the near memory access method is called
memory of near type, or simply near memory.
Default data
pointer
Max stack size
#pragma type_attribute directive. For more
Supported by processor
option
AVR® IAR C/C++ Compiler
18
Reference Guide
Data storage
By selecting a memory model, you have selected a default memory type that your
application will use. However, it is possible to specify—for individual variables or
pointers—different memory types. This makes it possible to create an application that
can contain a large amount of data, and at the same time make sure that variables that
are used often are placed in memory that can be efficiently accessed.
USING DATA MEMORY ATTRIBUTES
The AVR IAR C/C++ Compiler provides a set of extended keywords, which can be used
as data memory attributes. These keywords let you override the default memory type for
individual data objects, which means that you can place data objects in other memory
areas than the default memory. This also means that you can fine-tune the access method
for each individual data object, which results in smaller code size.
Summary of characteristics of memory attributes
The following table summarizes the available memory attributes:
Memory
attribute
__tiny1 byteData0-0xFF128 bytes
__near2 bytesData0-0xFFFF32 Kbytes
__far3 bytesData0-0xFFFFFF (16-bit pointer
__huge3 bytesData0-0xFFFFFF8 Mbytes
__tinyflash 1 byteCode0-0xFF128 bytes
__flash2 bytesCode0-0xFFFF32 Kbytes
__farflash 3 bytesCode0-0xFFFFFF (16-bit pointer
__hugeflash 3 bytesData0-0xFFFFFF8 Mbytes
__eeprom1 bytesEEPROM0-0xFF128 bytes
__eeprom2 bytesEEPROM0-0xFFFFFF32 Kbytes
__ioN/AI/O space0–0x3F4 bytes
__ioN/AData0x60–0xFF4 bytes
__ext_ioN/AData0x100–0xFFFF4 bytes
Table 7: Memory attributes for data
Pointer size Memory space Address range
arithmetics)
arithmetics)
Max object
size
32 Kbytes
32 Kbytes
Part 1. Using the compiler
19
Memory types and memory attributes
Memory
attribute
__generic2 bytes
__regvarN/AData0x4–0x0F4 bytes
Table 7: Memory attributes for data (Continued)
Pointer size Memory space Address range
Data or CodeThe most significant bit (MSB)
3 bytes
determines whether this pointer
points to code space (1) or data
space (0). The small generic
pointer is generated for the
processor options -v0 and -v1.
Max object
size
32 Kbytes
8 Mbytes
The keywords are only available if language extensions are enabled in the AVR IAR
C/C++ Compiler.
In IAR Embedded Workbench, language extensions are enabled by default.
-e compiler option to enable language extensions. See -e, page 179 for
Use the
additional information.
For syntax information, see Extended keywords for data, page 16. For reference
information about each keyword, see Descriptions of extended keywords, page 204.
POINTERS AND MEMORY TYPES
Pointers are used for referring to the location of data. In general, a pointer has a type.
For example, a pointer that has the type int* points to an integer.
In the AVR IAR C/C++ Compiler, a pointer also points to some type of memory. The
memory type is specified using a keyword before the asterisk.
For example, a pointer that points to an integer stored in farflash memory is declared by:
int __farflash * p;
Note that the location of the pointer variable
following example, however, the pointer variable p2 is placed in tiny memory. Like p,
p2 points to a character in farflash memory.
char __farflash * _ _tiny p2;
Whenever possible, pointers should be declared without memory attributes. For
example, the functions in the standard library are all declared without explicit memory
types.
p is not affected by the keyword. In the
AVR® IAR C/C++ Compiler
20
Reference Guide
Data storage
Differences between pointer types
A pointer must contain information needed to specify a memory location of a certain
memory type. This means that the pointer sizes are different for different memory types.
For information about the sizes of the different pointer types, seePointer types, page 141.
In the AVR IAR C/C++ Compiler, it is illegal to convert pointers between different types
without using explicit casts. For more details, see Casting, page 142.
STRUCTURES AND MEMORY TYPES
For structures, the entire object is placed in the same memory type. It is not possible to
place individual structure members in different memory types.
In the example below, the variable
struct MyStruct
{
int alpha;
int __flash * beta; /* Pointer to variables in flash memory */
};
__eeprom struct MyStruct gamma;
The following declaration is incorrect:
struct MySecondStruct
{
int blue;
__eeprom int green; /* Error! */
};
gamma is a structure placed in eeprom memory.
MORE EXAMPLES
The following is a series of examples with descriptions. First, some integer variables are
defined and then pointer variables are introduced. Finally, a function accepting a pointer
to an integer in flash memory is declared. The function returns a pointer to an integer in
eeprom memory. It makes no difference whether the memory attribute is placed before
or after the data type. In order to read the following examples, start from the left and add
one qualifier at each step
int a;
int __flash b;
__eeprom int c;
int * d;
A variable defined in default memory.
A variable in flash memory.
A variable in eeprom memory.
A pointer stored in default memory. The pointer
points to an integer in default memory.
Part 1. Using the compiler
21
C++ and memory types
C++ and memory types
int __flash * e;
A pointer stored in default memory. The pointer
points to an integer in flash memory.
int __flash * _ _eeprom f;
A pointer stored in eeprom memory pointing to
an integer stored in flash memory.
int __eeprom * myFunction(
int __flash *);
A declaration of a function that takes a
parameter which is a pointer to an integer stored
in flash memory. The function returns a pointer
to an integer stored in eeprom memory.
In short:
int
int __flash
int __flash *
int __flash * _ _eeprom
The basic type is an integer.
The integer is stored in flash memory.
This is a pointer to the integer.
The pointer is stored in eeprom memory.
A C++ class object is placed in one memory type, in the same way as for normal C
structures. However, the class members that are considered to be part of the object are
the non-static member variables. The static member variables can be placed individually
in any kind of memory.
Remember, in C++ there is only one instance of each static member variable, regardless
of the number of class objects.
Also note that for non-static member functions—unless class memory is used, see
Classes, page 111—the
this pointer will be of the default data pointer type. This means
that it must be possible to convert a pointer to the object to the default pointer type. The
restrictions that apply to the default pointer type also apply to the
this pointer.
AVR® IAR C/C++ Compiler
22
Reference Guide
Data storage
Example
In the example below, an object, named
delta, of the type MyClass is defined in data16
memory. The class contains a static member variable that is stored in data20 memory.
// The class declaration (placed in a header file):
class MyClass
{
public:
int alpha;
int beta;
__eeprom static int gamma;
};
// Definitions needed (should be placed in a source file):
__eeprom int MyClass::gamma;
// A variable definition:
MyClass delta;
The stack and auto variables
Variables that are defined inside a function—not declared static—are named auto
variables by the C standard. A small number of these variables are placed in processor
registers; the rest are placed on the stack. From a semantic point of view, this is
equivalent. The main differences are that accessing registers is faster, and that less
memory is required compared to when variables are located on the stack.
Auto variables live as long as the function executes; when the function returns, the
memory allocated on the stack is released.
The stack can contain:
● Local variables and parameters not stored in registers
● Temporary results of expressions
● The return value of a function (unless it is passed in registers)
● Processor state during interrupts
● Processor registers that should be restored before the function returns (callee-save
registers).
Part 1. Using the compiler
23
The stack and auto variables
The stack is a fixed block of memory, divided into two parts. The first part contains
allocated memory used by the function that called the current function, and the function
that called it, etc. The second part contains free memory that can be allocated. The
borderline between the two areas is called the top of stack and is represented by the stack
pointer, which is a dedicated processor register. Memory is allocated on the stack by
moving the stack pointer.
A function should never refer to the memory in the area of the stack that contains free
memory. The reason is that if an interrupt occurs, the called interrupt function can
allocate, modify, and—of course—deallocate memory on the stack.
Advantages
The main advantage of the stack is that functions in different parts of the program can
use the same memory space to store their data. Unlike a heap, a stack will never become
fragmented or suffer from memory leaks.
It is possible for a function to call itself—a so-called a recursive function—and each
invocation can store its own data on the stack.
Potential problems
The way the stack works makes it impossible to store data that is supposed to live after
the function has returned. The following function demonstrates a common
programming mistake. It returns a pointer to the variable x, a variable that ceases to exist
when the function returns.
int * MyFunction()
{
int x;
... do something ...
return &x;
}
Another problem is the risk of running out of stack. This will happen when one function
calls another, which in turn calls a third, etc., and the sum of the stack usage of each
function is larger than the size of the stack. The risk is higher if large data objects are
stored on the stack, or when recursive functions—functions that call themselves either
directly or indirectly—are used.
AVR® IAR C/C++ Compiler
24
Reference Guide
Dynamic memory on the heap
Memory for objects allocated on the heap will live until the objects are explicitly
released. This type of memory storage is very useful for applications where the amount
of data is not known until runtime.
In C, memory is allocated using the standard library function
related functions
In C++, there is a special keyword,
constructors. Memory allocated with
The AVR IAR C/C++ Compiler supports having heaps in tiny, near, far, and huge
memory. For more information about this, see The return address stack, page 43.
Potential problems
Applications that are using heap-allocated objects must be designed very carefully,
because it is easy to end up in a situation where it is not possible to allocate objects on
the heap.
The heap can become exhausted because your application simply uses too much
memory. It can also become full if memory that no longer is in use has not been released.
For each allocated memory block, a few bytes of data for administrative purposes is
required. For applications that allocate a large number of small blocks, this
administrative overhead can be substantial.
There is also the matter of fragmentation; this means a heap where small sections of free
memory is separated by memory used by allocated objects. It is not possible to allocate
a new object if there is no piece of free memory that is large enough for the object, even
though the sum of the sizes of the free memory exceeds the size of the object.
Unfortunately, fragmentation tends to increase as memory is allocated and released.
Hence, applications that are designed to run for a long time should try to avoid using
memory allocated on the heap.
Data storage
malloc, or one of the
calloc and realloc. The memory is released again using free.
new, designed to allocate memory and run
new must be released using the keyword delete.
Part 1. Using the compiler
25
Dynamic memory on the heap
AVR® IAR C/C++ Compiler
26
Reference Guide
Controlling functions
Functions
This chapter contains information about functions. First, you get a brief
overview of mechanisms for controlling functions, as well as information about
memory type attributes for function storage. Then, the special function types
interrupt and monitor are described, including how to declare C++ member
functions by using special function types.
Writing a function in C or C++, you may want to control for example the following:
● The function storage, see Function storage, page 28
● The function execution, see Special function types, page 29
● The used calling convention, see Calling convention, page 99.
The AVR IAR C/C++ Compiler provides a wide set of extended keywords which let you
control a function.
EXTENDED KEYWORDS FOR FUNCTIONS
The extended keywords that can be used for functions can be divided into three groups:
● Keywords that control the placement and type of the functions. Keywords of this
group must be specified both when the function is declared and when it is defined:
__nearfunc and _ _farfunc.
● Keywords that control the type of the functions. Keywords of this group only have
to be specified when the function is defined:
__version_1.
● Keywords that only control the defined function: __root, __monitor, and
__noreturn.
Keywords that control the placement and type of the functions are also referred to as
type attributes. Typically these functions controls aspects of the function visible to the
surrounding context. Keywords that only control the behavior of the function and do not
affect the function interface are referred to as object attributes. To read more about type
and object attributes, see Type and object attributes, page 144. For reference information
about each keyword, see the chapter Extended keywords, page 203.
__interrupt, _ _task, and
Part 1. Using the compiler
27
Function storage
Function storage
Syntax
The extended keywords are specified before the return type, for example:
__interrupt void alpha(void);
The keywords that are type attributes must be specified both when they are defined and
in the declaration. Object attributes only have to be specified when they are defined
since they do not affect the way an object or function is used.
In addition to the rules presented here—to place the keyword directly in the code—the
directives #pragma type_attribute and #pragma object_attribute can be used
for specifying the keywords. Refer to the chapter Pragma directives for details about
how to use the extended keywords together with pragma directives.
There are two memory attributes for controlling function storage:__nearfunc and
__farfunc
The following table summarizes the characteristics for each memory attribute:
Memory attributeAddress rangePointer sizeUsed in processor option
When using the -v5 or the -v6 option, it is possible, for individual functions, to override
the __farfunc attribute and instead use the _ _nearfunc attribute. The default
memory attribute can be overridden by explicitly specifying a memory attribute in the
function declaration or by using the
It is possible to call a __nearfunc function from a __farfunc function and vice versa.
Only the size of the function pointer is affected. Note that pointers with function
memory attributes have restrictions in implicit and explicit casts when casting between
pointers and also when casting between pointers and integer types; see Casting, page
142. For more information about function pointers, see Function pointers, page 141.
It is possible to place functions into named segments using either the
#pragmalocation directive. For more information, see Controlling data and function
placement, page 47.
.
#pragma type_attribute directive:
@ operator or the
AVR® IAR C/C++ Compiler
28
Reference Guide
Special function types
Functions
This section describes the special function types interrupt and monitor. The AVR IAR
C/C++ Compiler allows an application to take full advantage of these AVR features,
without forcing you to implement anything in assembler language.
INTERRUPT FUNCTIONS
In embedded systems, the use of interrupts is a method of detecting external events
immediately; for example, detecting that a button has been pressed.
In general, when an interrupt occurs in the code, the microcontroller simply stops
executing the code it runs, and starts executing an interrupt routine instead. It is
imperative that the environment of the interrupted function is restored; this includes the
values of processor registers and the processor status register. This makes it possible to
continue the execution of the original code when the code that handled the interrupt has
been executed.
The AVR microcontroller supports many interrupt sources. For each interrupt source, an
interrupt routine can be written. Each interrupt routine is associated with a vector
number, alternatively multiple vector numbers, which is specified in the AVR
microcontroller documentation from the chip manufacturer. The header file
ioderivative.h, where derivative corresponds to the selected derivative, contains
predefined names for the existing exception vectors.
To define an interrupt function, the
directive can be used. For example:
Note: An interrupt function must have the return type void, and it cannot specify any
parameters.
If a vector is specified in the definition of an interrupt function, the processor interrupt
vector table is populated. It is also possible to define an interrupt function without a
vector. This is useful if an application is capable of populating or changing the interrupt
vector table at runtime. See the chip manufacturer’s AVR microcontroller
documentation for more information about the interrupt vector table.
__interrupt keyword and the #pragma vector
Part 1. Using the compiler
29
Special function types
MONITOR FUNCTIONS
A monitor function causes interrupts to be disabled during execution of the function. At
function entry, the status register is saved and interrupts are disabled. At function exit,
the original status register is restored, and thereby the interrupt status that existed before
the function call is also restored.
To define a monitor function, you can use the
information, see __monitor, page 210.
Example of implementing a semaphore in C
In the following example, a semaphore is implemented using one static variable and two
monitor functions. A semaphore can be locked by one process, and is used for
preventing processes from simultaneously using resources that can only be used by one
process at a time, for example a printer.
/* When the_lock is non-zero, someone owns the lock. */
static volatile unsigned int the_lock = 0;
/* get_lock -- Try to lock the lock.
* Return 1 on success and 0 on failure. */
__monitor keyword. For reference
__monitor int get_lock(void)
{
if (the_lock == 0)
{
/* Success, we managed to lock the lock. */
the_lock = 1;
return 1;
}
else
{
/* Failure, someone else has locked the lock. */
return 0;
}
}
The following is an example of a program fragment that uses the semaphore:
void my_program(void)
{
if (get_lock())
{
/* ... Do something ... */
/* When done, release the lock. */
release_lock();
}
}
The drawback using this method is that interrupts are disabled for the entire monitor
function.
Example of implementing a semaphore in C++
In C++, it is common to implement small methods with the intention that they should be
inlined. However, the AVR IAR C/C++ Compiler does not support inlining of functions
and methods that are declared using the
__monitor keyword.
In the following example in C++, an auto object is used for controlling the monitor
block, which uses intrinsic functions instead of the
#include <inavr.h>
__monitor keyword.
volatile long tick_count = 0;
/* Class for controlling critical blocks */
class Mutex
{
public:
Mutex ()
{
_state = __save_interrupt();
__disable_interrupt();
}
~Mutex ()
{
__restore_interrupt(_state);
}
private:
unsigned char _state;
};
Part 1. Using the compiler
31
Special function types
void f()
{
static long next_stop = 100;
extern void do_stuff();
long tick;
/* A critical block */
{
Mutex m;
/* Read volatile variable 'tick_count' in a safe way
and put the value in a local variable */
C++ member functions can be declared using special function types. However, the
following restriction apply:
Interrupt member functions must be static. When calling a non-static member
function, it must be applied to an object. When an interrupt occurs and the interrupt
function is called, there is no such object available.
FUNCTION DIRECTIVES
Note: This type of directives are primarily intended to support static overlay, a feature
which is useful in some smaller microcontrollers. The AVR IAR C/C++ Compiler does
not use static overlay, as it has no use for it.
The function directives
by the AVR IAR C/C++ Compiler to pass information about functions and function calls
to the IAR XLINK Linker. These directives can be seen if you use the compiler option
Assembler file (
For reference information about the function directives, see the AVR® IAR Assembler Reference Guide.
FUNCTION, ARGFRAME, LOCFRAME, and FUNCALL are generated
-lA) to create an assembler list file.
AVR® IAR C/C++ Compiler
32
Reference Guide
Segments and memory
Placing code and data
This chapter introduces the concept of segments, and describes the different
segment groups and segment types. It also describes how they correspond to
the memory and function types, and how they interact with the runtime
environment. The methods for placing segments in memory, which means
customizing a linker command file, are described.
The intended readers of this chapter are the system designers that are
responsible for mapping the segments of the application to appropriate
memory areas of the hardware system.
In an embedded system, there are many different types of physical memory. Also, it is
often critical where parts of your code and data are located in the physical memory. For
this reason it is important that the development tools meet these requirements.
WHAT IS A SEGMENT?
A segment is a logical entity containing a piece of data or code that should be mapped
to a physical location in memory. Each segment consists of many segment parts.
Normally, each function or variable with static storage duration is placed in a segment
part. A segment part is the smallest linkable unit, which allows the linker to include only
those units that are referred to. The segment could be placed either in RAM or in ROM.
Segments that are placed in RAM do not have any content, they only occupy space.
The AVR IAR C/C++ Compiler has a number of predefined segments for different
purposes. Each segment has a name that describes the contents of the segment, and a
segment memory type that denotes the type of content. In addition to the predefined
segments, you can define your own segments.
At compile time, the compiler assigns each segment its contents. The IAR XLINK
Linker™ is responsible for placing the segments in the physical memory range, in
accordance with the rules specified in the linker command file. There are supplied linker
command files, but, if necessary, they can be easily modified according to the
requirements of your target system and application. It is important to remember that,
from the linker's point of view, all segments are equal; they are simply named parts of
memory.
Part 1. Using the compiler
33
Placing segments in memory
For detailed information about individual segments, see the chapter Segment reference
in Part 2. Compiler reference.
Segment memory type
XLINK assigns a segment memory type to each of the segments. In some cases, the
individual segments may have the same name as the segment memory type they belong
to, for example
segment memory types in those cases.
By default, the
memory types:
Segment memory typeDescription
CODEFor executable code in flash memory space
DATAFor data placed in data memory space (RAM),
XDATAFor data placed in EEPROM memory space
Table 9: XLINK segment memory types
XLINK supports a number of other segment memory types than the ones described
above. However, they exist to support other types of microcontrollers.
For more details about segments, see the chapter Segment reference.
CODE. Make sure not to confuse the individual segment names with the
AVR IAR C/C++ Compiler uses only the following XLINK segment
and for data placed in flash memory space
Placing segments in memory
AVR® IAR C/C++ Compiler
34
Reference Guide
The placement of segments in memory is performed by the IAR XLINK Linker. It uses
a linker command file that contains command line options which specify the locations
where the segments can be placed, thereby assuring that your application fits on the
target chip. You can use the same source code with different derivatives just by
rebuilding the code with the appropriate linker command file.
In particular, the linker command file specifies:
● The placement of segments in memory
● The maximum stack size
● The maximum heap size (only for the IAR DLIB runtime environment).
This section describes the methods for placing the segments in memory, which means
that you have to customize the linker command file to suit the memory layout of your
target system. For showing the methods, fictitious examples are used.
Placing code and data
CUSTOMIZING THE LINKER COMMAND FILE
The only change you will normally have to make to the supplied linker command file is
to customize it so it reflects the target system memory map.
As an example, we can assume that the target system has the following memory layout:
RangeType
0x100–0xFFFRAM
0x0–0x1FFFFFLASH
0x0–0xFFFEEPROM
0x1000–0xFFFFExternal RAM
Table 10: Memory layout of a target system (example)
The flash memory can be used for storing both
CODE and DATA segment memory types.
The RAM memory can contain segments of DATA type. The main purpose of
customizing the linker command file is to verify that your application code and data do
not cross the memory range boundaries, which would lead to application failure.
The contents of the linker command file
The config directory contains ready-made linker command files. The file contains the
information required by the linker, and is ready to be used. If, for example, your
application uses additional external RAM, you need to add details about the external
RAM memory area. Remember not to change the original file. We recommend that you
make a copy in the working directory, and modify the copy instead.
Note: The supplied linker command file includes comments explaining the contents.
Among other things, the linker command file contains three different types of XLINK
command line options:
● The CPU used:
-ca90
This specifies your target microcontroller.
● Definitions of constants used later in the file. These are defined using the XLINK
option -D.
● The placement directives (the largest part of the linker command file). Segments can
be placed using the
the order they are found, while the latter will try to rearrange them to make better
use of the memory. The -P option is useful when the memory where the segment
should be placed is not continuous.
Note: In the linker command file, all numbers are specified in hexadecimal format.
However, neither the prefix
-Z and -P options. The former will place the segment parts in
0x nor the suffix h is used.
Part 1. Using the compiler
35
Placing segments in memory
See the IAR Linker and Library Tools Reference Guide for more details.
Using the -Z command for sequential placement
Use the -Z command when you need to keep a segment in one consecutive chunk, when
you need to preserve the order of segment parts in a segment, or, more unlikely, when
you need to put segments in a specific order.
The following illustrates how to use the -Z command to place the segment MYSEGMENTA
followed by the segment MYSEGMENTB in DATA memory (that is, external RAM) in the
memory range
-Z(DATA)MYSEGMENTA,MYSEGMENTB=1000-CFFF
Two segments of different types can be placed in the same memory area by not
specifying a range for the second segment. In the following example, the MYSEGMENTA
segment is first located in memory. Then, the rest of the memory range could be used by
MYCODE.
-Z(DATA)MYSEGMENTA=1000-CFFF
-Z(CODE)MYCODE
Two memory ranges may overlap. This allows segments with different placement
requirements to share parts of the memory space; for example:
-Z(DATA)MYSMALLSEGMENT=1000-20FF
-Z(DATA)MYLARGESEGMENT=1000-CFFF
Even though it is not strictly required, make sure to always specify the end of each
memory range. If you do this, the IAR XLINK Linker will alert you if your segments do
not fit in the specified ranges.
0x1000-0xCFFF.
AVR® IAR C/C++ Compiler
36
Reference Guide
Using the -P command for packed placement
The -P command differs from -Z in that it does not necessarily place the segments (or
segment parts) sequentially. With
earlier placements.
The following example illustrates how the XLINK
efficient use of the memory area. The command will place the data segment MYDATA in
DATA memory (that is, in RAM) in the memory range:
-P(DATA)MYDATA=0-FFF,1000-1FFF
If your application has an additional RAM area in the memory range 0xF000-0xF7FF,
you just add that to the original definition:
-P(DATA)MYDATA=0-FFF,1000–1FFF,F000-F7FF
-P it is possible to put segment parts into holes left by
-P option can be used for making
Data segments
Placing code and data
Note: Copy initialization segments—BASENAME_I and BASENAME_ID—must be
placed using -Z.
This section contains descriptions of the segments used for storing the different types of
data—static, stack, heap, and located. In moste cases these segments are located in the
data memory space. However, some of the segments are located in the code memory
space.
To get a clear understanding about how the data segments work, you must be familiar
with the different memory types and the different memory models available in the
IAR C/C++ Compiler
. If you need to refresh these details, see the chapter Data storage.
AVR
STATIC MEMORY SEGMENTS
Static memory is memory that contains variables that are global or declared static, as
described in the chapter Data storage. Declared static variables can be divided into the
following categories:
● Variables that are initialized to a non-zero value
● Variables that are initialized to zero
● Variables that are located by use of the @ operator or the #pragma location
directive
● Variables that are declared as const and therefore can be stored in external ROM
● Variables defined with the __no_init keyword, meaning that they should not be
initialized at all.
For the static memory segments it is important to be familiar with:
● The segment naming
● How the memory types correspond to segment groups and the segments that are part
of the segment groups
● Restrictions for segments holding initialized data
● The placement and size limitation of the segments of each group of static memory
segments.
Segment naming
All static data segment names consist of two parts—the segment base name and a
suffix—for instance, NEAR_Z. The segment base names are derived from the memory
type attributes, for example the attribute:
__near
Part 1. Using the compiler
37
Data segments
would yield the segment base name
NEAR.
The suffix indicates what type of declared data the segment holds. The following table
summarizes the different suffixes, which XLINK segment memory type they are, and
which category of declared data they denote:
SuffixCategories of declared data
_NNon-initialized data
_ZZero-initialized data
_INon-zero initialized data
_IDInitializers for the above
_CConstants
_FData placed in flash memory
_ANNon-initialized absolute addressed data
_ACConstant absolute addressed data
Table 11: Segment name suffixes
For information about the static data segments, their possible memory ranges, and in
what type of memory they can be placed, see the chapter Segment reference in this guide.
For more details about segment memory types, see Segment memory type, page 34.
Examples
Assume the following examples:
__near int j;
__near int i = 0;
__no_init _ _near int j; The near non-initialized variables will be placed in the
The near variables that are to be initialized to zero
when the system starts will be placed in the segment
NEAR_Z.
segment NEAR_N.
__near int j = 4;
When using the -y option, the near non-zero
initialized variables will be placed in the segment
NEAR_I, and initializer data in segment NEAR_ID.
AVR® IAR C/C++ Compiler
38
Reference Guide
Placing code and data
Initialized data
In ISO/ANSI C all static variables—variables that are allocated at a fixed memory
address—have to be initialized by the run-time system to a known value. This value is
either an explicit value assigned to the variable, or if no value is given, it is cleared to
zero.
AVR IAR C/C++ Compiler, there are two exceptions to this rule and they both
In the
use keywords for ISO/ANSI C language extensions. Variables declared
are not initialized at all. Variables declared
__eeprom are allocated in the EEPROM
memory and because the EEPROM memory can typically be used for storing
configuration data—data that need to live through a reset—these variables will not be
initialized by the runtime system. Instead, these initializers are stored in a separate
segment, which can be loaded to the EEPROM as part of the program download.
Initialization at system startup
When an application is started, the system startup code initializes static and global
variables in three steps:
1 It clears the memory of the variables that should be initialized to zero; these
variables are located in segments with the suffix
_Z.
2 It initializes the non-zero variables by copying a block of ROM to the location of the
variables in RAM. This means that the data in the ROM segment with the suffix
is copied to the corresponding I segment.
This works when both segments are placed in continuous memory. However, if one
of the segments is divided into smaller pieces, it is important that:
● The other segment is divided in exactly the same way
● It is legal to read and write the memory that represents the gaps in the sequence.
For example, if the segments are assigned the following ranges, the copy will fail:
__no_init
ID
NEAR_I
NEAR_ID0x4000-0x41FF
0x1000-0x10FF
and 0x1200-0x12FF
However, in the following example, the linker will place the content of the segments
in identical order, which means that the copy will work appropriately:
NEAR_I
NEAR_ID
0x1000-0x10FF
0x4000-0x40FF
Note that the gap between the ranges will also be copied. Note also that the
and 0x1200-0x12FF
and 0x4200-0x42FF
NEAR_ID
segment holding the initializers is always located in flash memory and that these
initializers are only used once, that is before reaching the
main function.
Part 1. Using the compiler
39
Data segments
3 Finally, global C++ objects are constructed, if any.
Initialization of local aggregates at function invocation
Initialized aggregate auto variables—struct, union, and array variables local to a
function—have the initial values in blocks of memory As an auto variable is allocated
either in registers or on the stack, the initialization has to take place every time the
function is called. Assume the following example:
The initializers are copied to the b variable allocated on the stack each time the function
is entered.
The initializers can either come from the code memory space (flash) or from the data
memory space (optional external ROM). By default, the initializers are located in
segments with the suffix
_C and these segments are copied from external ROM to the
stack.
If you use either the
aggregate initializers are located in segments with the suffix
-y option or the --initializers_in_flash option, the
_F, which are copied from
flash memory to the stack. The advantage of storing these initializers in flash is that
valuable data space is not wasted. The disadvantage is that copying from flash is slower.
AVR® IAR C/C++ Compiler
40
Reference Guide
Initialization of constant objects
There are different ways of initializing constant objects.
By default, constant objects are placed in segments with the suffix
in the optional external ROM that resides in the data memory space. The reason for this
is that it must be possible for a default pointer—a pointer without explicit memory
attributes—to point to the object, and a default pointer can only point to the data
memory space.
However, if you do not have any external ROM in the data memory space, and for single
ship applications you most likely do not have it, the constant objects have to be placed
in RAM and initialized as any other non-constant variables. To achieve this, use the
option, which means the objects are placed in segments with the suffix _ID.
if you want to place an object in flash, you can use any of the memory attributes
__tinyflash, __flash, __farflash, or __hugeflash. The object becomes a flash
object, which means you cannot take the address of it and store it in a default pointer.
However, it is possible to store the address in either a __flash pointer or a __generic
pointer, though neither of these are default pointers. Note that if you attempt to take the
_C, which are located
-y
Placing code and data
address of a constant __flash object and use it as a default pointer object, the compiler
will issue an error. If you make an explicit cast of the object to a default pointer object,
the error message disappears, instead there will be problems at run-time as the cast
cannot copy the object from the flash memory to the data memory.
Note: To access strings located in flash, you must use alternative library routines that
expect flash strings. A few such alternative functions are provided in the
pgmspace.h
header file. They are flash alternatives for some common C library functions with an
extension _P. For your own code, you can always use the __flash keyword when
passing the strings between functions. For reference information about the alternative
functions, see AVR–specific library functions, page 249.
SEGMENTS FOR STATIC DATA IN THE LINKER COMMAND
FILE
As described in the section Static memory segments, page 37, static data can be placed
in many different segments depending on the application requirements and your target
system. In the linker command file the segment definitions can look like this:
/* First the segments to be placed in ROM are defined */
-Z(CODE)TINY_F=0-FF
-Z(CODE)NEAR_F=0-1FF
-Z(CODE)TINY_ID,NEAR_ID=0-1FFF
/* Then, the RAM data segments are defined */
-Z(DATA)TINY_I,TINY_Z,TINY_N=60-FF
-Z(DATA)NEAR_I,NEAR_Z=60-25F
/* Then the segments to be placed in external EPROM are defined
*/
-Z(DATA)NEAR_C=_EXT_EPROM_BASE:+_EXT_EPROM_SIZE
/* The _EXT_EPROM_BASE and _EXT_EPROM_SIZE symbols are defined in
the linker command file template, where they have the value 0. If
you want to use those symbols, you must provide values that suit
the hardware. This method can also be used for placing other
types of objects in the external memory space. */
THE DATA STACK
The data stack is used by functions to store auto variables, function parameters and
temporary storage that is used locally by functions, as described in the chapter Data storage. It is a continuous block of memory pointed to by the processor stack pointer
Y.
register
The data segment used for holding the stack is called
initializes the stack pointer to the end of the stack segment.
CSTACK. The system startup code
Part 1. Using the compiler
41
Data segments
If external SRAM is available it is possible to place the stack there. However, the
external memory is slower than the internal stack so moving it to external memory will
decrease the performance.
Allocating a memory area for the stack is done differently when you use the command
line interface compared to when you use the IAR Embedded Workbench IDE.
Data stack size allocation in IAR Embedded Workbench
Select Project>Options. In the General Options category, click the System page.
Add the required stack size in the Data stack text box.
Data stack size allocation from the command line
The size of the CSTACK segment is defined in the linker command file.
The default linker file sets up a constant representing the size of the stack, at the
beginning of the linker file:
-D_CSTACK_SIZE=size
Specify an appropriate size for your application. Note that the size is written
hexadecimally without the 0x notation.
AVR® IAR C/C++ Compiler
42
Reference Guide
Placement of data stack segment
Further down in the linker file, the actual stack segment is defined in the memory area
available for the stack:
-Z(DATA)CSTACK+_CSTACK_SIZE=60-25F
Note: This range does not specify the size of the stack; it specifies the range of the
available memory.
Stack size considerations
The compiler uses the internal data stack, CSTACK, for a variety of user program
operations, and the required stack size depends heavily on the details of these
operations. If the given stack size is too large, RAM will be wasted. If the given stack
size is too small, there are two things that can happen, depending on where in memory
you have located your stack. Both alternatives are likely to result in application failure.
Either variable storage will be overwritten, leading to undefined behavior, or the stack
will fall outside of the memory area, leading to an abnormal termination of your
application. Because the second alternative is easier to detect, you should consider
placing your stack so that it grows towards the end of the memory.
Placing code and data
THE RETURN ADDRESS STACK
The return address stack is used for storing the return address when a CALL, RCALL,
ICALL, or EICALL instruction is executed. Each call will use two or three bytes of return
address stack. An interrupt will also place a return address on this stack.
To determine the size of the return address stack, see Stack size considerations, page 42.
Notice however that if the cross-call optimization has been used (
--no_cross_call), the value can be off by as much as a factor of six depending on
how many times the cross-call optimizer has been run (
--cross_call_passes). Each
cross-call pass adds one level of calls, for example, two cross-call passes may result in
a tripled stack usage.
If external SRAM is available, it is possible to place the stack there. However, the
external memory is slower than the internal memory so moving the stacks to external
memory will normally decrease the system performance; see --enable_external_bus,
page 181.
Allocating a memory area for the stack is done differently when you use the command
line interface compared to when you use the IAR Embedded Workbench IDE.
-z9 without
RSTACK size allocation in IAR Embedded Workbench
Select Project>Options. In the General Options category, click the System page.
Add the required stack size in the Return address stack text box.
RSTACK size allocation from the command line
The size of the RSTACK segment is defined in the linker command file.
The default linker file sets up a constant representing the size of the stack, at the
beginning of the linker file:
-D_RSTACK_SIZE=size
Specify an appropriate size for your application. Note that the size is written
hexadecimally without the 0x notation.
Placement of the RSTACK segment
Further down in the linker file, the actual stack segment is defined in the memory area
available for the stack:
-Z(DATA)RSTACK+_RSTACK_SIZE=60-25F
Note: This range does not specify the size of the stack; it specifies the range of the
available memory.
Part 1. Using the compiler
43
Data segments
THE HEAP
The heap contains dynamic data allocated by use of the C function malloc (or one of
its relatives) or the C++ operator
new.
If your application uses dynamic memory allocation, you should be familiar with the
following:
● Linker segment used for the heap, which differs between the DLIB and the CLIB
runtime environment
● Allocating the heap size, which differs depending on which build interface you are
using
● Placing the heap segments in memory.
Heap segments in DLIB
Heaps can be placed in the following memory types:
Memory typeSegment nameMemory attribute
TinyTINY_HEAP
NearNEAR_HEAP__near
FarFAR_HEAP__far
HugeHUGE_HEAP_ _huge
Table 12: Heaps, memory types, and segments
* The TINY_HEAP segment is only available in the Tiny memory model.
To access a heap in a specific memory, use the appropriate memory attribute as a prefix
to the standard functions malloc, free, calloc, and realloc, for example:
__near_malloc
If you use any of the standard functions without a prefix, the function will be mapped to
the default memory type near.
Each heap will reside in a segment with the name
For information about how to access a heap in a specific memory using C++, see New and Delete operators, page 114.
*
__tiny
_HEAP prefixed by a memory attribute.
AVR® IAR C/C++ Compiler
44
Reference Guide
Heap segments in CLIB
The memory allocated to the heap is placed in the segment HEAP, which is only included
in the application if dynamic memory allocation is actually used.
Placing code and data
Heap size allocation in IAR Embedded Workbench
Select Project>Options. In the General Options category, click the Heap
configuration page.
Add the required heap size in the appropriate text box.
Heap size allocation from the command line
The size of the heap segments are defined in the linker command file.
The default linker file sets up a constant, representing the size of each heap, at the
beginning of the linker command file:
-D_TINY_HEAP_SIZE=size
-D_NEAR_HEAP_SIZE=size
-D_FAR_HEAP_SIZE=size
-D_HUGE_HEAP_SIZE=size
-D_HEAP_SIZE=size /* For CLIB */
Specify the appropriate size for your application.
If your application uses near or far memory, symbols for heaps for these memories
should also be defined in the linker command file.
Placement of heap segments
The actual heap segment is allocated in the memory area available for the heap:
-Z(DATA)HEAP+_TINY_HEAP_SIZE=60-25F
Note: This range does not specify the size of the heap; it specifies the range of the
available memory.
Use the same method for all used heaps.
Heap size and standard I/O
If you have excluded FILE descriptors from the DLIB runtime environment, like in the
normal configuration, there are no input and output buffers at all. Otherwise, like in the
full configuration, be aware that the size of the input and output buffers is set to 512
bytes in the
which is considerably slower than when I/O is buffered. If you execute the application
using the simulator driver of the IAR C-SPY Debugger, you are not likely to notice the
speed penalty, but it is quite noticeable when the application runs on an AVR
microcontroller. If you use the standard I/O library, you should set the heap size to a
value which accommodates the needs of the standard I/O buffer.
stdio library header file. If the heap is too small, I/O will not be buffered,
Part 1. Using the compiler
45
Code segments
Code segments
LOCATED DATA
A variable that has been explicitly placed at an address, for example by using the
compiler
segment. The former is used for constant-initialized data, and the latter for items
declared as __no_init. The individual segment part of the segment knows its location
in the memory space, and it should not be specified in the linker command file.
@ syntax, will be placed in either the SEGMENT_AC or the SEGMENT_AN
USER-DEFINED DATA SEGMENTS
If you create your own data segments—see Controlling data and function placement,
page 47—these must also be defined in the linker command file using the -Z or -P
segment control directives.
This section contains examples and descriptions of the segments used for storing code,
in other words, functions, and the interrupt vector table. Typically, these segments are
placed in the code memory space (flash).
The -Z command is used for defining all segments in the following examples. The
addresses used in the examples are based on the assumed target system described in the
Table 10, Memory layout of a target system (example), on page 35. Note that because
the described target system is limited in size of code memory space, several segments
supported by the compiler are not applicable for this target system.
For a complete list of all segments, see Summary of segments, page 149.
AVR® IAR C/C++ Compiler
46
Reference Guide
INTERRUPT AND RESET VECTORS
The interrupt vector table contains pointers to interrupt routines, including the reset
routine. The table is placed in the segment
interrupt vectors and one reset vector. For this reason, you should specify 14 interrupt
vectors, each of two bytes.
The linker directive would then look like this:
-Z(CODE)INTVEC=0-1B /* 14 interrupt vectors; 2 bytes each */
INTVEC. The AT90S80515 derivative has 13
FUNCTIONS
Functions are placed in the CODE or FARCODE segments, depending on which -v
processor option you are using. The
memory attributes
segments for the functions. For information about which attribute is used by default for
-v option, see the Table 3, Summary of processor configuration, on page 8.
each
__nearfunc or __farfunc, which in turn determines the used
-v option implicitly determines the default function
In the linker command file it can look like this:
-Z(CODE)CODE=0-1FFF
USER-DEFINED SEGMENTS
If you create your own segments—see Controlling data and function placement, page
47—these must also be defined in the linker command file using the -Z or -P segment
control directives. In the linker command file it can look like this:
-Z(CODE)MYSEGMENT=100-2FF
Compiler-generated segments
The compiler uses a set of internally generated segments, which are used for storing
information that is vital to the operation of the program.
● The SWITCH segment which contains data statements used in the switch library
routines. These tables are encoded in such a way as to use as little space as possible.
● The INITTAB segment contains the segment initialization description blocks that
are used by the
consist of a number of SegmentInitBlock_Type objects. This type is declared in
the segment_init.h file which is located in the avr\src\lib directory.
● The DIFUNCT segment is only used when a source file has been compiled in C++
mode and the file contains global objects (class instances). The segment will then
contain a number of function pointers that point to constructor code that should be
performed for each object.
In the linker command file it can look like this:
-Z(CODE)SWITCH,INITTAB,DIFUNCT=0-1FFF
Placing code and data
__segment_init function which is called by CSTARTUP. This table
Efficient usage of segments and memory
This section lists several features and methods to help you manage memory and
segments.
CONTROLLING DATA AND FUNCTION PLACEMENT
The @ operator, alternatively the #pragma location directive, can be used for placing
global and static variables at absolute addresses. The syntax can also be used for placing
variables or functions in named segments. The variables must be declared either
__no_init or const. If declared const, it is legal for them to have initializers. The
named segment can either be a predefined segment, or a user-defined segment.
Part 1. Using the compiler
47
Efficient usage of segments and memory
Note: Take care when explicitly placing a variable or function in a predefined segment
other than the one used by default. This is possible and useful in some situations, but
incorrect placement can result in anything from error messages during compilation and
linking to a malfunctioning application. Carefully consider the circumstances; there
might be strict requirements on the declaration and use of the function or variable.
C++ static member variables can be placed at an absolute address or in named segments,
just like any other static variable.
Variables and functions can also be placed into named segments using the
--segment
option, in which case you can override the default segment base name. Note that if you
use this method, the object does not need to be declared neither __no_init nor const
as it is only the segment name that will be modified.
Data placement at an absolute location
To place a variable at an absolute address, the argument to the operator @ and the
#pragma location directive should be a literal number, representing the actual
address.
Example
__no_init char alpha @ 0x2000;/* OK */
AVR® IAR C/C++ Compiler
48
Reference Guide
#pragma location=0x2002
const int beta=5;/* OK */
const int gamma @ 0x2004 = 3;/* OK */
int delta @ 0x2006;/* Error, neither */
/* "_ _no_init" nor "const".*/
See Located data, page 46 for information about how to handle this in the linker
command file.
Note: A variable placed in an absolute location should be defined in an include file, to
be included in every module that uses the variable. An unused definition in a module
will be ignored. A normal
extern declaration—one that does not use an absolute
placement directive—can refer to a variable at an absolute address; however,
optimizations based on the knowledge of the absolute address cannot be performed.
Data placement into named segments
It is possible to place variables into named segments using either the @ operator or the
#pragma location directive. A string should be used for specifying the segment name.
Example
__no_init int alpha @ "MYSEGMENT"; /* OK */
#pragma location="MYSEGMENT"
const int beta=5;/* OK */
const int gamma @ "MYSEGMENT" = 3; /* OK */
Placing code and data
int delta @ "MYSEGMENT";/* Error, neither */
/* "__no_init" nor "const" */
Function placement into named segments
It is possible to place functions into named segments using either the @ operator or the
#pragma location directive. When placing functions into segments, the segment is
Using IAR extensions in C, read-only SFRs—for instance, in header files—can be
declared like this:
volatile const __no_init int x @ 0x100;
In C++, const variables are static (module local), which means that each module with
this declaration will contain a separate variable. When you link an application with
several such modules, the linker will report that there are more than one variable located
at address
To avoid this problem and have it work the same way in C and C++, you should declare
these SFRs
extern volatile const __no_init int x @ 0x100;
0x100.
extern, for example:
USING USER-DEFINED SEGMENTS
In addition to the predefined segments, you can use your own segments. This is useful
if you need to have precise control of placement of individual variables or functions.
Part 1. Using the compiler
49
Verifying the linked result of code and data placement
A typical situation where this can be useful is if you need to optimize accesses to code
and data that is frequently used, and place it in a different physical memory.
To use your own segments, use the
#pragma location directive, or the --segment
option.
If you use your own segments, these must also be defined in the linker command file
using the
-Z or the -P segment control directives.
Verifying the linked result of code and data placement
The linker has several features that help you to manage code and data placement, for
example, messages at link time and the linker map file.
SEGMENT TOO LONG ERRORS AND RANGE ERRORS
All code and data that is placed in relocatable segments will have its absolute addresses
resolved at link time. It is also at link time it is known whether all segments will fit in
the reserved memory ranges. If the contents of a segment do not fit in the address range
defined in the linker command file, XLINK will issue a segment too long error.
Some instructions do not work unless a certain condition holds after linking, for
example that a branch must be within a certain distance or that an address must be even.
XLINK verifies that the conditions hold when the files are linked. If a condition is not
satisfied, XLINK generates a range error or warning and prints a description of the
error.
For further information about these types of errors, see the IAR Linker and Library Tools Reference Guide.
AVR® IAR C/C++ Compiler
50
Reference Guide
LINKER MAP FILE
XLINK can produce an extensive cross-reference listing, which can optionally contain
the following information:
● A segment map which lists all segments in dump order
● A module map which lists all segments, local symbols, and entries (public symbols)
for every module in the program. All symbols not included in the output can also be
listed
● Module summary which lists the contribution (in bytes) from each module
● A symbol list which contains every entry (global symbol) in every module.
Use the option Generate linker listing in IAR Embedded Workbench, or the option
on the command line, and one of their suboptions to generate a linker listing.
-X
Placing code and data
Normally, XLINK will not generate an output file if there are any errors, such as range
errors, during the linking process. Use the option Always generate output in IAR
Embedded Workbench, or the option
-B on the command line, to generate an output file
even if a range error was encountered.
For further information about the listing options and the linker listing, see the IAR Linker
and Library Tools Reference Guide, and the AVR® IAR Embedded Workbench™ IDE
User Guide.
MANAGING MULTIPLE MEMORY SPACES
Output formats that do not support more than one memory space—like MOTOROLA and
INTEL-HEX—may require up to one output file per memory space. This causes no
problems if you are only producing output to one memory space (flash), but if you also
are placing objects in EEPROM or an external ROM in the DATA memory space, the
output format cannot represent this, and the linker issues the following error message:
Error[e133]: The output format Format cannot handle multiple
address spaces. Use format variants (-y -O) to specify which
address space is wanted.
To limit the output to flash, make a copy of the linker command file for the derivative
and memory model you are using, and put it in your project directory. Use this copy in
your project and add the following line at the end of the file:
-y(CODE)
To produce output for the other memory space(s), you must generate one output file per
memory space (because the output format you have chosen does not support more than
one memory space). Use the XLINK option
For each additional output file, you have to specify format, XLINK segment type, and
file name. For example:
-Omotorola,(DATA)=external_rom.a90
-
O
motorola,(XDATA)=eeprom.a90
Note: As a general rule, an output file is only necessary if you use non-volatile
memory. In other words, output from the data space is only necessary if the data space
contains external ROM.
-O for this purpose.
Part 1. Using the compiler
51
Verifying the linked result of code and data placement
The IAR Postlink utility
You can also use the IAR Postlink utility, delivered with the AVR IAR C/C++ Compiler
to generate multiple output files. This application takes as input an object file (of the
simple format) and extracts one or more of its XLINK segment types into one
XLINK
file (which can be in either Intelextendedhex format or MotorolaS-record
format). For example, it can put all code segments into one file, and all EEPROM
segments into another.
See the postlink.htm document for more information about IAR Postlink.
AVR® IAR C/C++ Compiler
52
Reference Guide
The DLIB runtime
environment
This chapter describes the runtime environment in which an application
executes. In particular, the chapter covers the DLIB runtime library and how
you can modify it—setting options, overriding default library modules, or
building your own library—to optimize it for your application.
The chapter also covers system initialization and termination; how an
application can control what happens before the function main is called, and
how you can customize the initialization.
The chapter then describes how to configure functionality like locale and file
I/O, how to get C-SPY runtime support, and how to prevent incompatible
modules from being linked together.
For information about the CLIB runtime environment, see the chapter The CLIB runtime environment.
Introduction to the runtime environment
The runtime environment is the environment in which your application executes. The
runtime environment depends on the target hardware, the software environment, and the
application code. The IAR DLIB runtime environment can be used as is together with
the IAR C-SPY Debugger. However, to be able to run the application on hardware, you
must adapt the runtime environment.
This section gives an overview of:
● The runtime environment and its components
● Library selection.
RUNTIME ENVIRONMENT FUNCTIONALITY
The runtime environment (RTE) supports ISO/ANSI C and C++ including the standard
template library. The runtime environment consists of the runtime library, which
contains the functions defined by these standards, and include files that define the library
interface.
Part 1. Using the compiler
53
Introduction to the runtime environment
The runtime library is delivered both as prebuilt libraries and as source files, and you
can find them in the product subdirectories avr\lib and avr\src, respectively.
The runtime environment also consists of a part with specific support for the target
system, which includes:
● Support for hardware features:
● Direct access to low-level processor operations by means of intrinsic functions,
such as functions for register handling
● Peripheral unit registers and interrupt definitions in include files
● Special compiler support for accessing strings in flash memory, see AVR–specific
library functions, page 249
● Runtime environment support, that is, startup and exit code and low-level interface
to some library functions.
Some parts, like the startup and exit code and the size of the heaps must be tailored for
the specific hardware and application requirements.
For further information about the library, see the chapter Library functions.
LIBRARY SELECTION
To configure the most code-efficient runtime environment, you must determine your
application and hardware requirements. The more functionality you need, the larger
your code will get.
IAR Embedded Workbench comes with a set of prebuilt runtime libraries. To get the
required runtime environment, you can customize it by:
● Setting library options, for example, for choosing scanf input and printf output
formatters, and for specifying the size of the stack and the heap
● Overriding certain library functions, for example cstartup.s90, with your own
customized versions
● Choosing the level of support for certain standard library functionality, for example,
locale, file descriptors, and multibytes, by choosing a library configuration: normal
or full.
In addition, you can also make your own library configuration, but that requires that you
rebuild the library. This allows you to get full control of the runtime environment.
Note: Your application project must be able to locate the library, include files, and the
library configuration file.
AVR® IAR C/C++ Compiler
54
Reference Guide
The DLIB runtime environment
SITUATIONS THAT REQUIRE LIBRARY BUILDING
Building a customized library is complex. You should therefore carefully consider
whether it is really necessary.
You must build your own library when:
● There is no prebuilt library for the required combination of compiler options or
hardware support
● You want to define your own library configuration with support for locale, file
descriptors, multibyte characters, et cetera.
For information about how to build a customized library, see Building and using a customized library, page 62.
LIBRARY CONFIGURATIONS
It is possible to configure the level of support for, for example, locale, file descriptors,
multibytes. The runtime library configuration is defined in the library configuration file.
It contains information about what functionality is part of the runtime environment. The
configuration file is used for tailoring a build of a runtime library, as well as tailoring the
system header files used when compiling your application. The less functionality you
need in the runtime environment, the smaller it is.
The following DLIB library configurations are available:
Library configuration Description
Normal DLIBNo locale interface, C locale, no file descriptor support, no multibyte
characters in printf and scanf, and no hex floats in strtod.
Full DLIBFull locale interface, C locale, file descriptor support, multibyte
characters in printf and scanf, and hex floats in strtod.
Table 13: Library configurations
In addition to these configurations, you can define your own configurations, which
means that you must modify the configuration file. Note that the library configuration
file describes how a library was built and thus cannot be changed unless you rebuild the
library. For further information, see Building and using a customized library, page 62.
The prebuilt libraries are based on the default configurations, see Table 15, Prebuilt libraries, page 57. There is also a ready-made library project template that you can use
if you want to rebuild the runtime library.
Part 1. Using the compiler
55
Using a prebuilt library
DEBUG SUPPORT IN THE RUNTIME LIBRARY
You can make the library provide different levels of debugging support—basic, runtime,
and I/O debugging.
The following table describes the different levels of debugging support:
Debugging
support
Basic debuggingDebug information for
Runtime debugging With runtime control
I/O debuggingWith I/O emulation
Table 14: Levels of debugging support in runtime libraries
Linker option in IAR
Embedded Workbench
C-SPY
modules
modules
Linker command
line option
-FubrofDebug support for C-SPY
-rThe same as -Fubrof, but
-rtThe same as -r, but also
Description
without any runtime support
also includes debugger
support for handling program
abort, exit, and assertions.
includes debugger support for
I/O handling, which means
that stdin and stdout are
redirected to the C-SPY
Terminal I/O window, and that
it is possible to access files on
the host computer during
debugging.
If you build your application project with the XLINK options With runtime control
modules or With I/O emulation modules, certain functions in the library will be
replaced by functions that communicate with the IAR C-SPY Debugger. For further
information, see C-SPY Debugger runtime interface, page 76.
To set linker options for debug support in IAR Embedded Workbench, choose
Project>Options and select the Linker category. On the Output page, select the
appropriate Format option.
Using a prebuilt library
AVR® IAR C/C++ Compiler
56
Reference Guide
The prebuilt runtime libraries are configured for different combinations of the following
features:
● Type of library
● Processor option (-v)
● Memory model option (--memory_model)
● AVR enhanced core option (--enhanced_core)
The DLIB runtime environment
● Small flash memory option (--64k_flash)
● 64-bit doubles option (--64bit_doubles)
● Library configuration—Normal or Full.
For the AVR IAR C/C++ Compiler and the Normal library configuration, there are
prebuilt runtime libraries for all combinations of these options. For the Full library
configuration there is one prebuilt runtime library delivered. The following table shows
the names of the libraries and how they reflect the used settings:
Generic
Library file
dlavr-3s-ec-
processor
option
-v3-v3SmallXX--Normal
sf-n.r90
dlavr-3s-ec-
-v3-v3SmallX--XFull
64-f.r90
Table 15: Prebuilt libraries
Generic
processor
option
Memory
model
Enhanced
core
Small flash
64-bit
doubles
Library
configuration
The names of the libraries are constructed in the following way:
● <library> is dl for the IAR DLIB Library, or cl for the IAR CLIB Library,
respectively (for a list of CLIB library files, see Runtime environment, page 85)
● <target> is avr
● <cpu> is a value from 0 to 6, matching the -v option
● <memory_model> is either t, s, or l for Tiny, Small, or Large memory model,
respectively
● <enhanced_core> is ec when enhanced core is used. When the enhanced core is
not used, this value is not specified
● <small_flash> is sf when the small flash memory is available. When small flash
memory is not available, this value is not specified
● <64-bit_doubles> is 64 when 64-bit doubles are used. When 32-bit doubles are
used, this value is not specified
● <library_configuraton> is one of n or f for normal and full, respectively.
Note: The library configuration file has the same base name as the library.
IAR Embedded Workbench will include the correct library object file and library
configuration file based on the options you select. See the AVR® IAR Embedded Workbench™ IDE User Guide for additional information.
Part 1. Using the compiler
57
Using a prebuilt library
On the command line, you must specify the following items:
● Specify which library object file to use on the XLINK command line, for instance:
dlavr-3s-ec-64-f.r90
● Specify the include paths for the compiler and assembler:
-I avr\inc
● Specify the library configuration file for the compiler:
--dlib_config C:\...\dlavr-3s-ec-64-f.h
You can find the library object files and the library configuration files in the subdirectory
avr\lib\dlib.
CUSTOMIZING A PREBUILT LIBRARY WITHOUT REBUILDING
The prebuilt libraries delivered with the AVR IAR C/C++ Compiler can be used as is.
However, it is possible to customize parts of a library without rebuilding it. There are
two different methods:
● Setting options for:
● Formatters used by printf and scanf
● The sizes of the heap and the stack
● Overriding library modules with your own customized versions.
The following items can be customized:
AVR® IAR C/C++ Compiler
58
Reference Guide
Items that can be customizedDescribed on page
Formatters for printf and scanfChoosing formatters for printf and scanf, page 59
Startup and termination codeSystem startup and termination, page 64
Low-level input and outputStandard streams for input and output, page 67
File input and outputFile input and output, page 70
Low-level signal functionsSignal and raise, page 73
Low-level time functionsTime, page 74
Size of heaps, stacks, and segmentsPlacing code and data, page 33
Table 16: Customizable items
For a description about how to override library modules, see Overriding library
modules, page 61.
Choosing formatters for printf and scanf
To override the default formatter for all the printf- and scanf-related functions,
except for wprintf and wscanf variants, you simply set the appropriate library
options. This section describes the different options available.
Note:
● If you rebuild the library, it is possible to optimize these functions even further,
see Configuration symbols for printf and scanf, page 69
● For information about how to choose formatter for the AVR-specific functions
printf_P and scanf_P, see AVR–specific library functions, page 249.
CHOOSING PRINTF FORMATTER
The printf function uses a formatter called _Printf. The default version is quite
large, and provides facilities not required in many embedded applications. To reduce the
memory consumption, three smaller, alternative versions are also provided in the
standard C/EC++ library.
The following table summarizes the capabilities of the different formatters:
Formatting capabilities_PrintfFull _PrintfLarge
Basic specifiers c, d, i, o, p, s, u, X,
x, and %
Multibyte support***No
Floating-point specifiers a, and AYe sN oN oN o
Floating-point specifiers e, E, f, F, g,
and G
Conversion specifier nYe sYe sN oN o
Format flag space, +, -, #, and 0Ye sYe sYe sN o
Length modifiers h, l, L, s, t, and Z Ye sYe sYe sN o
Field width and precision, including * Ye sYe sYe sN o
long long supportYesYesNoNo
Table 17: Formatters for printf
* Depends on which library configuration is used.
The DLIB runtime environment
_PrintfSmall
(default)
Ye sYe sYe sYe s
Ye sYe sN oN o
_PrintfTiny
Part 1. Using the compiler
59
Choosing formatters for printf and scanf
For information about how to fine-tune the formatting capabilities even further, see
Configuration symbols for printf and scanf, page 69.
Specifying print formatter in IAR Embedded Workbench
To specify the printf formatter in IAR Embedded Workbench, choose
Project>Options and select the General Options category. Select the appropriate
option on the Library options page.
Specifying printf formatter from the command line
To use any other variant than the default (_PrintfSmall), add one of the following
lines in the linker command file you are using:
-e_PrintfLarge=_Printf
-e_PrintfSmall=_Printf
-e_PrintfTiny=_Printf
CHOOSING SCANF FORMATTER
In a similar way to the printf function, scanf uses a common formatter, called
_Scanf. The default version is very large, and provides facilities that are not required
in many embedded applications. To reduce the memory consumption, two smaller,
alternative versions are also provided in the standard C/C++ library.
The following table summarizes the capabilities of the different formatters:
Formatting capabilities_ScanfFull _ScanfLarge
Basic specifiers c, d, i, o, p, s, u, X,
x, and %
Multibyte support***
Floating-point specifiers a, and AYe sN oN o
Floating-point specifiers e, E, f, F, g,
and G
Conversion specifier nYe sN oN o
Scan set [ and ]Ye sYe sN o
Assignment suppressing *Ye sYe sN o
long long supportYesNoNo
Table 18: Formatters for scanf
* Depends on which library configuration that is used.
Ye sYe sYe s
Ye sN oN o
_ScanfSmall
(default)
AVR® IAR C/C++ Compiler
60
Reference Guide
For information about how to fine-tune the formatting capabilities even further, see
Configuration symbols for printf and scanf, page 69.
Specifying scanf formatter in IAR Embedded Workbench
To specify the scanf formatter in IAR Embedded Workbench, choose
Project>Options and select the General Options category. Select the appropriate
option on the Library options page.
Specifying scanf formatter from the command line
To use any other variant than the default (_ScanfSmall), add one of the following lines
in the linker command file you are using:
-e_ScanfLarge=_Scanf
-e_ScanfSmall=_Scanf
Overriding library modules
The library contains modules which you probably need to override with your own
customized modules, for example functions for character-based I/O and cstartup.
This can be done without rebuilding the entire library. This section describes the
procedure for including your version of the module in the application project build
process. The library files that you can override with your own versions are located in the
avr\src\lib directory.
Note: If you override a default I/O library module with your own module, C-SPY
support for the module is turned off. For example, if you replace the module
with your own version, the C-SPY Terminal I/O window will not be supported.
The DLIB runtime environment
__write
Overriding library modules using IAR Embedded Workbench
This procedure is applicable to any source file in the library, which means
library_module.c in this example can be any module in the library.
1 Copy the appropriate library_module.c file to your project directory.
2 Make the required additions to the file (or create your own routine, using the default
file as a model), and make sure that it has the same module name as the original
module. The easiest way to achieve this is to save the new file under the same name as
the original file.
3 Add the customized file to your project.
4 Rebuild your project.
Part 1. Using the compiler
61
Building and using a customized library
Overriding library modules from the command line
This procedure is applicable to any source file in the library, which means
library_module.c in this example can be any module in the library.
1 Copy the appropriate library_module.c to your project directory.
2 Make the required additions to the file (or create your own routine, using the default
file as a model), and make sure that it has the same module name as the original
module. The easiest way to achieve this is to save the new file under the same name as
the original file.
3 Compile the modified file using the same options, include paths, and library
configuration file as for the rest of the project:
iccavr library_module
This creates a replacement object module file named library_module.r90.
4 Add library_module.r90 to the XLINK command line, either directly or by using
an extended linker command file, for example:
xlink library_module dlavr-3s-ec-64-n.r90
Make sure that library_module is located before the library on the command line.
This ensures that your module is used instead of the one in the library.
Run XLINK to rebuild your application.
This will use your version of
For information about the XLINK options, see the IAR Linker and Library Tools Reference Guide.
library_module.r90, instead of the one in the library.
Building and using a customized library
In some situations, see Situations that require library building, page 55, it is necessary
to rebuild the library. In those cases you need to:
● Set up a library project
● Make the required library modifications
● Build your customized library
● Finally, make sure your application project will use the customized library.
Information about the build process is described in AVR® IAR Embedded Workbench™
IDE User Guide.
Note: It is possible to build IAR Embedded Workbench projects from the command
line by using the IAR Command Line Build Utility (
batch file (build_libs.bat) provided for building the library from the command line.
AVR® IAR C/C++ Compiler
62
Reference Guide
iarbuild.exe). There is also a
The DLIB runtime environment
SETTING UP A LIBRARY PROJECT
IAR Embedded Workbench provides a library project template which can be used for
customizing the runtime environment configuration. This library template has full
library configuration, see Table 13, Library configurations, page 55.
In IAR Embedded Workbench, modify the generic options in the created library project
to suit your application, see Basic settings for project configuration, page 5.
Note: There is one important restriction on setting options. If you set an option on file
level (file level override), no options on higher levels that operate on files will affect that
file.
MODIFYING THE LIBRARY FUNCTIONALITY
You must modify the library configuration file and build your own library to modify
support for, for example, locale, file descriptors, and multibytes. This will include or
exclude certain parts of the runtime environment.
The library functionality is determined by a set of configuration symbols. The default
values of these symbols are defined in the file Dlib_defaults.h. This read-only file
describes the configuration possibilities. In addition, your library has its own library
configuration file dlavrCustom.h, which sets up that specific library with full library
configuration. For more information, see Table 16, Customizable items, page 58.
The library configuration file is used for tailoring a build of the runtime library, as well
as tailoring the system header files.
Modifying the library configuration file
In your library project, open the file dlavrCustom.h and customize it by setting the
values of the configuration symbols according to the application requirements.
When you are finished, build your library project with the appropriate project options.
USING A CUSTOMIZED LIBRARY
After you have built your library, you must make sure to use it in your application
project.
In IAR Embedded Workbench you must perform the following steps:
1 Choose Project>Options and click the Library Configuration tab in the General
Options category.
2 Choose Custom DLIB from the Library drop-down menu.
3 In the Library file text box, locate your library file.
4 In the Configuration file text box, locate your library configuration file.
Part 1. Using the compiler
63
System startup and termination
System startup and termination
This section describes the runtime environment actions performs during startup and
termination of applications. The following figure gives a graphical overview of the
startup and exit sequences:
Reset
cstartup
Program entry label
Hardware setup
Static initialization
Dynamic C++ initialization
Return from
main
and call
exit
__low_level_init
Application
main
_exit
_exit
Dynamic C++ destruction
atexit
and
System terminated
Figure 1: Startup and exit sequences
execution
__exit
exit
abort
_Exit
The code for handling startup and termination is located in the source files
cstartup.s90 and _exit.s90, and low_level_init.c located in the
avr\src\lib directory.
AVR® IAR C/C++ Compiler
64
Reference Guide
The DLIB runtime environment
SYSTEM STARTUP
When an application is initialized, a number of steps are performed:
● When the cpu is reset it will jump to the program entry label _ _program_start in
the system startup code.
● Enables the external data and address buses if needed
● Initializes the stack pointers to the end of CSTACK and RSTACK, respectively
● The function __low_level_init is called, giving the application a chance to
perform early initializations
● Static variables are initialized except for __no_init and __eeprom declared
variables; this includes clearing zero-initialized memory and copying the ROM
image of the RAM memory of the rest of the initialized variables depending on the
return value of
● Static C++ objects are constructed
● The main function is called, which starts the application.
__low_level_init
SYSTEM TERMINATION
An application can terminate normally in two different ways:
● Return from the main function
● Call the exit function.
As the ISO/ANSI C standard states that the two methods should be equivalent, the
system startup code calls the
exit function is the return value of main.
The default
exit function is written in C. It calls a small function _exit, also written
in C, that will perform the following operations:
● Call functions registered to be executed when the application ends. This includes
C++ destructors for static and global variables, and functions registered with the
standard C function atexit
● Close all open files
● Call __exit
● When __exit is reached, stop the system.
An application can also exit by calling the
function just calls __exit to halt the system, and does not perform any type of cleanup.
_Exit function is equivalent to the abort function, except for the fact that _Exit
The
takes an argument for passing exit status information.
If you want your application to perform anything extra at exit, for example resetting the
system, you can write your own implementation of the
exit function if main returns. The parameter passed to the
abort or the _Exit function. The abort
__exit(int) function.
Part 1. Using the compiler
65
Customizing system initialization
C-SPY interface to system termination
If your project is linked with the XLINK options With runtime control modules or
With I/O emulation modules, the normal
with special ones. C-SPY will then recognize when those functions are called and can
take appropriate actions to simulate program termination. For more information, see
C-SPY Debugger runtime interface, page 76.
Customizing system initialization
It is likely that you need to customize the code for system initialization. For example,
your application might need to initialize memory-mapped special function registers
(SFRs), or omit the default initialization of data segments performed by
You can do this by providing a customized version of the routine
which is called from cmain before the data segments are initialized. Modifying the file
cstartup directly should be avoided.
The code for handling system startup is located in the source files
low_level_init.c, located in the avr\src directory.
Note: Normally, there is no need for customizing either of the files
cexit.s90.
If you intend to rebuild the library, the source files are available in the template library
project, see Building and using a customized library, page 62.
Note: Regardless of whether you modify the routine
cstartup.s90, you do not have to rebuild the library.
__exit and abort functions are replaced
cstartup.
__low_level_init,
cstartup.s90 and
cmain.s90 or
__low_level_init or the file
AVR® IAR C/C++ Compiler
66
Reference Guide
__LOW_LEVEL_INIT
Some applications may need to initialize I/O registers, omit the default initialization of
data segments performed by the system startup code, or set up for use of external
memory.
You can do this by providing a customized version of the routine
which is called from the system startup code before the data segments are initialized.
The value returned by
__low_level_init determines whether or not data segments
should be initialized by the system startup code. If the function returns
segments will not be initialized.
Note: The file
intrinsics.h must be included by low_level_init.c to assure
correct behavior of the __low_level_init routine.
__low_level_init,
0, the data
MODIFYING THE FILE CSTARTUP.S90
As noted earlier, you should not modify the file cstartup.s90 if a customized version
__low_level_init is enough for your needs. However, if you do need to modify
of
the file cstartup.s90, we recommend that you follow the general procedure for
creating a modified copy of the file and adding it to your project, see Overriding library modules, page 61.
Standard streams for input and output
There are three standard communication channels (streams)—stdin, stdout, and
stderr—which are defined in stdio.h. If any of these streams are used by your
application, for example by the functions
low-level functionality to suit your hardware.
There are primitive I/O functions, which are the fundamental functions through which
C and C++ performs all character-based I/O. For any character-based I/O to be available,
you must provide definitions for these functions using whatever facilities the hardware
environment provides.
The DLIB runtime environment
printf and scanf, you need to customize the
IMPLEMENTING LOW-LEVEL CHARACTER INPUT AND
OUTPUT
To implement low-level functionality of the stdin and stdout streams, you must write
the functions __read and _ _write, respectively. You can find template source code for
these functions in the
avr\src directory.
If you intend to rebuild the library, the source files are available in the template library
project, see Building and using a customized library, page 62. Note that customizing the
low-level routines for input and output does not require you to rebuild the library.
Note: If you write your own variants of
__read or _ _write, special considerations
for the C-SPY runtime interface are needed, see C-SPY Debugger runtime interface,
page 76.
Example of using __write and __read
The code in the following examples use memory-mapped I/O to write to an LCD
display:
{
int nChars = 0;
/* Check for stdout and stderr
(only necessary if file descriptors are enabled.) */
if (Handle != 1 && Handle != 2)
{
return -1;
}
for (/*Empty */; Bufsize > 0; --Bufsize)
{
LCD_IO = * Buf++;
++nChars;
}
return nChars;
}
The code in the following example uses memory-mapped I/O to read from a keyboard:
__no_init volatile unsigned char KB_IO @ 0xD2;
size_t __read(int Handle, unsigned char *Buf, size_t BufSize)
{
int nChars = 0;
/* Check for stdin
(only necessary if FILE descriptors are enabled) */
if (Handle != 0)
{
return -1;
}
for (/*Empty*/; BufSize > 0; --BufSize)
{
int c = KB_IO;
if (c < 0)
break;
*Buf++ = c;
++nChars;
}
return nChars;
}
For information about the @ operator, see Controlling data and function placement, page
47.
AVR® IAR C/C++ Compiler
68
Reference Guide
Configuration symbols for printf and scanf
When you set up your application project, you typically need to consider what printf
and scanf formatting capabilities your application requires, see Choosing formatters for printf and scanf, page 59.
If the provided formatters do not meet your requirements, you can customize the full
formatters. However, that means you need to rebuild the runtime library.
The default behavior of the
symbols in the file
The following configuration symbols determine what capabilities the function
should have:
Table 20: Descriptions of scanf configuration symbols
Part 1. Using the compiler
69
File input and output
File input and output
CUSTOMIZING FORMATTING CAPABILITIES
To customize the formatting capabilities, you need to set up a library project, see
Building and using a customized library, page 62. Define the configuration symbols
according to your application requirements.
The library contains a large number of powerful functions for file I/O operations. If you
use any of these functions you need to customize them to suit your hardware. In order
to simplify adaptation to specific hardware, all I/O functions call a small set of primitive
functions, each designed to accomplish one particular task; for example, _ _
a file, and __
write outputs a number of characters.
Note that file I/O capability in the library is only supported by libraries with full library
configuration, see Library configurations, page 55. In other words, file I/O is supported
when the configuration symbol
__DLIB_FILE_DESCRIPTOR is enabled. If not enabled,
functions taking a FILE * argument cannot be used.
Template code for the following I/O files are included in the product:
I/O functionFileDescription
__close close.cCloses a file.
__lseek lseek.cSets the file position indicator.
__open open.cOpens a file.
__read read.cReads a character buffer.
__write write.cWrites a character buffer.
remove remove.cRemoves a file.
rename rename.cRenames a file.
Table 21: Low-level I/O files
The primitive functions identify I/O streams, such as an open file, with a file descriptor
that is a unique integer. The I/O streams normally associated with stdin, stdout, and
stderr have the file descriptors 0, 1, and 2, respectively.
Note: If you link your library with I/O debugging support, C-SPY variants of the
low-level I/O functions will be linked for interaction with C-SPY. For more
information, see Debug support in the runtime library, page 56.
open opens
AVR® IAR C/C++ Compiler
70
Reference Guide
Locale
The DLIB runtime environment
Locale is a part of the C language that allows language- and country-specific settings for
a number of areas, such as currency symbols, date and time, and multibyte encoding.
Depending on what runtime library you are using you get different level of locale
support. However, the more locale support, the larger your code will get. It is therefore
necessary to consider what level of support your application needs.
The DLIB library can be used in two major modes:
● With locale interface, which makes it possible to switch between different locales
during runtime
● Without locale interface, where one selected locale is hardwired into the
application.
LOCALE SUPPORT IN PREBUILT LIBRARIES
The level of locale support in the prebuilt libraries depends on the library configuration.
● All prebuilt libraries supports the C locale only
● Libraries with full library configuration have support for the locale interface. For
prebuilt libraries with locale interface, it is by default only supported to switch
multibyte encoding during runtime.
● Libraries with normal library configuration do not have support for the locale
interface.
If your application requires a different locale support, you need to rebuild the library.
CUSTOMIZING THE LOCALE SUPPORT
If you decide to rebuild the library, you can choose between the following locales:
● The standard C locale
● The POSIX locale
● A wide range of international locales.
Locale configuration symbols
The configuration symbol _DLIB_FULL_LOCALE_SUPPORT, which is defined in the
library configuration file, determines whether a library has support for a locale interface
or not. The locale configuration symbols _LOCALE_USE_LANG_REGION and
_ENCODING_USE_ENCODING define all the supported locales and encodings.
If you want to customize the locale support, you simply define the locale configuration
symbols required by your application. For more information, see Building and using a customized library, page 62.
Part 1. Using the compiler
71
Locale
Note: If you use multibyte characters in your C or assembler source code, make sure
that you select the correct locale symbol (the local host locale).
Building a library without support for locale interface
The locale interface is not included if the configuration symbol
_DLIB_FULL_LOCALE_SUPPORT is set to 0 (zero). This means that a hardwired locale
is used—by default the standard C locale—but you can choose one of the supported
locale configuration symbols. The
setlocale function is not available and can
therefore not be used for changing locales at runtime.
Building a library with support for locale interface
Support for the locale interface is obtained if the configuration symbol
_DLIB_FULL_LOCALE_SUPPORT is set to 1. By default, the standard C locale is used,
but you can define as many configuration symbols as required. Because the setlocale
function will be available in your application, it will be possible to switch locales at
runtime.
CHANGING LOCALES AT RUNTIME
The standard library function setlocale is used for selecting the appropriate portion
of the application’s locale when the application is running.
The
setlocale function takes two arguments. The first one is a locale category that is
constructed after the pattern LC_CATEGORY. The second argument is a string that
describes the locale. It can either be a string previously returned by
can be a string constructed after the pattern:
lang_REGION
or
lang_REGION.encoding
The lang part specifies the language code, and the REGION part specifies a region
qualifier, and
The
lang_REGION part matches the _LOCALE_USE_LANG_REGION preprocessor
encoding specifies the multibyte encoding that should be used.
symbols that can be specified in the library configuration file.
setlocale, or it
AVR® IAR C/C++ Compiler
72
Reference Guide
Example
This example sets the locale configuration symbols to Swedish to be used in Finland and
UTF8 multibyte encoding:
setlocale (LC_ALL, "sv_FI.Utf8");
Environment interaction
The DLIB runtime environment
According to the C standard, your application can interact with the environment using
the functions getenv and system.
Note: The
provide an implementation of it.
The
for the key that was passed as argument. If the key is found, the value of it is returned,
otherwise 0 (zero) is returned. By default, the string is empty.
To create or edit keys in the string, you must create a sequence of null terminated strings
where each string has the format:
key=value\0
The last string must be empty. Assign the created sequence of strings to the __environ
variable.
If you need a more sophisticated environment variable handling, you should implement
your own getenv, and possibly putenv function. This does not require that you rebuild
the library. You can find source templates in the files getenv.c and environ.c in the
avr\src\lib directory. For information about overriding default library modules, see
Overriding library modules, page 61.
If you need to use the
function available in the library simply returns -1.
If you decide to rebuild the library, you can find source templates in the library project
template. For further information, see Building and using a customized library, page 62.
Note: If you link your application with support for I/O debugging, the functions
getenv and system will be replaced by C-SPY variants. For further information, see
Debug support in the runtime library, page 56.
putenv function is not required by the standard, and the library does not
getenv function searches the string, pointed to by the global variable __environ,
system function, you need to implement it yourself. The system
Signal and raise
There are default implementations of the functions signal and raise available. If
these functions do not provide the functionality that you need, you can implement your
own versions.
Part 1. Using the compiler
73
Time
Time
This does not require that you rebuild the library. You can find source templates in the
files Signal.c and Raise.c in the avr\src\lib directory. For information about
overriding default library modules, see Overriding library modules, page 61.
If you decide to rebuild the library, you can find source templates in the library project
template. For further information, see Building and using a customized library, page 62.
To make th e time and date functions work, you must implement the three functions
clock, time, and __getzone.
This does not require that you rebuild the library. You can find source templates in the
Clock.c and Time.c, and Getzone.c in the avr\src\lib directory. For
files
information about overriding default library modules, see Overriding library modules,
page 61.
If you decide to rebuild the library, you can find source templates in the library project
template. For further information, see Building and using a customized library, page 62.
The default implementation of
Note: If you link your application with support for I/O debugging, the functions
time will be replaced by C-SPY variants that return the host clock and time
and
respectively. For further information, see C-SPY Debugger runtime interface, page 76.
__getzone specifies UTC as the time-zone.
clock
Strtod
AVR® IAR C/C++ Compiler
74
Reference Guide
The function strtod does not accept hexadecimal floating-point strings in libraries
with the normal library configuration. To make a library do so, you need to rebuild the
library, see Building and using a customized library, page 62. Enable the configuration
_DLIB_STRTOD_HEX_FLOAT in the library configuration file.
symbol
Assert
Heaps
The DLIB runtime environment
If you have linked your application with support for runtime debugging, C-SPY will be
notified about failed asserts. If this is not the behavior you require, you must add the
source file xReportAssert.c to your application project. Alternatively, you can
rebuild the library. The
can find template code in the
__ReportAssert function generates the assert notification.You
avr\src directory. For further information, see Building
and using a customized library, page 62. To turn off assertions, you must define the
NDEBUG.
symbol
In the IAR Embedded Workbench, this symbol
NDEBUG is by default defined in a
Release project and not defined in a Debug project. If you build from the command line,
you must explicitly define the symbol according to your needs.
The runtime environment supports heaps in the following memory types:
Memory typeSegment nameExtended keyword
TinyTINY_HEAP__tinyTiny
NearNEAR_HEAP_ _nearSmall
FarFAR_HEAP__farMedium
HugeHUGE_HEAP__hugeLarge
Table 22: Heaps and memory types
Used by default in
memory model
See The heap, page 44 for information about how to set the size for each heap. To use a
specific heap, the prefix in the table is the extended keyword to use in front of
free, calloc, and realloc. The default functions will use one of the specific heap
malloc,
variants, depending on project settings such as memory model. For information about
how to use a specific heap in C++, see New and Delete operators, page 114.
Part 1. Using the compiler
75
C-SPY Debugger runtime interface
C-SPY Debugger runtime interface
To include support for runtime and I/O debugging, you must link your application
with the XLINK options With runtime control modules or With I/O emulation modules, see Debug support in the runtime library, page 56. In this case, C-SPY
variants of the following library functions will be linked to the application:
FunctionDescription
abortC-SPY notifies that the application has called abort *
__exitC-SPY notifies that the end of the application has been reached *
__read
__write
__openOpens a file on the host computer
__closeCloses the associated host file on the host computer
__seekSeeks in the associated host file on the host computer
removeWrites a message to the Debug Log window and returns -1
renameWrites a message to the Debug Log window and returns -1
timeReturns the time on the host computer
clockReturns the clock on the host computer
systemWrites a message to the Debug Log window and returns -1
_ReportAssert Handles failed asserts *
Table 23: Functions with special meanings when linked with debug info
* The linker option With I/O emulation modules is not required for these functions.
stdin, stdout, and stderr will be directed to the Terminal I/O
window; all other files will read the associated host file
stdin, stdout, and stderr will be directed to the Terminal I/O
window, all other files will write to the associated host file
AVR® IAR C/C++ Compiler
76
Reference Guide
LOW-LEVEL DEBUGGER RUNTIME INTERFACE
The low-level debugger runtime interface is used for communication between the
application being debugged and the debugger itself. The debugger provides runtime
services to the application via this interface; services that allow capabilities like file and
terminal I/O to be performed on the host computer.
These capabilities can be valuable during the early development of an application, for
example in an application using file I/O before any flash file system I/O drivers have
been implemented. Or, if you need to debug constructions in your application that use
stdin and stdout without the actual hardware device for input and output being
available. Another debugging purpose can be to produce debug trace printouts.
The DLIB runtime environment
The mechanism used for implementing this feature works as follows. The debugger will
detect the presence of the function
if you have linked it with the XLINK options for C-SPY runtime interface. In this case,
the debugger will automatically set a breakpoint at the __DebugBreak function. When
the application calls, for example
will cause the application to break and perform the necessary services. The execution
will then resume.
__DebugBreak, which will be part of the application
open, the __DebugBreak function is called, which
THE DEBUGGER TERMINAL I/O WINDOW
To make the Terminal I/O window available, the application must be linked with
support for I/O debugging, see Debug support in the runtime library, page 56. This
means that when the functions
operations on the streams
from the C-SPY Terminal I/O window.
Note: The Terminal I/O window is not opened automatically just because __read or
__write is called; you must open it manually.
See the AVR® IAR Embedded Workbench™ IDE User Guide for more information
about the Terminal I/O window.
__read or __write are called to perform I/O
stdin, stdout, or stderr, data will be sent to or read
Checking module consistency
This section introduces the concept of runtime model attributes, a mechanism used by
the IAR compiler, assembler, and linker to ensure module consistency.
When developing an application, it is important to ensure that incompatible modules are
not used together. For example, in the AVR IAR C/C++ Compiler, it is possible to
specify the size of the
for 64-bit doubles, it is possible to check that the routine is not used in an application
built using 32-bit doubles.
The tools provided by IAR use a set of predefined runtime model attributes. You can use
these predefined attributes or define your own to perform any type of consistency check.
RUNTIME MODEL ATTRIBUTES
A runtime attribute is a pair constituted of a named key and its corresponding value. Two
modules can only be linked together if they have the same value for each key that they
both define.
There is one exception: if the value of an attribute is *, then that attribute matches any
value. The reason for this is that you can specify this in a module to show that you have
considered a consistency property, and this ensures that the module does not rely on that
property.
double floating-point type. If you write a routine that only works
Part 1. Using the compiler
77
Checking module consistency
Example
In the following table, the object files could (but do not have to) define the two runtime
attributes
color and taste. In this case, file1 cannot be linked with any of the other
files, since the runtime attribute color does not match. Also, file4 and file5 cannot
be linked together, because the taste runtime attribute does not match.
On the other hand,
file4 or file5, but not with both.
Object fileColorTaste
file1bluenot defined
file2rednot defined
file3red*
file4redspicy
file5redlean
Table 24: Example of runtime model attributes
file2 and file3 can be linked with each other, and with either
USING RUNTIME MODEL ATTRIBUTES
Runtime model attributes can be specified in your C/C++ source code to ensure module
consistency with other object files by using the #pragmartmodel directive. For
example:
#pragma rtmodel="__rt_version", "1"
For detailed syntax information, see #pragma rtmodel, page 223.
Runtime model attributes can also be specified in your assembler source code by using
the RTMODEL assembler directive. For example:
RTMODEL "color", "red"
For detailed syntax information, see the AVR® IAR Assembler Reference Guide.
Note: The predefined runtime attributes all start with two underscores. Any attribute
names you specify yourself should not contain two initial underscores in the name, to
eliminate any risk that they will conflict with future IAR runtime attribute names.
At link time, the IAR XLINK Linker checks module consistency by ensuring that
modules with conflicting runtime attributes will not be used together. If conflicts are
detected, an error is issued.
AVR® IAR C/C++ Compiler
78
Reference Guide
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.