.init3 as the code in
.init2
ensures the internal register __zero_reg__ is already cleared.
Back to \ref faq_index.
\section faq_use_bv What is all this _BV() stuff about?
When performing low-level output work, which is a very central point
in microcontroller programming, it is quite common that a particular
bit needs to be set or cleared in some IO register. While the device
documentation provides mnemonic names for the various bits in the IO
registers, and the \ref avr_io "AVR device-specific IO definitions" reflect these names in definitions for
numerical constants, a way is needed to convert a bit number (usually
within a byte register) into a byte value that can be assigned
directly to the register. However, sometimes the direct bit numbers
are needed as well (e. g. in an SBI() instruction), so the
definitions cannot usefully be made as byte values in the first place.
So in order to access a particular bit number as a byte value, use the
_BV() macro. Of course, the implementation of this macro is
just the usual bit shift (which is done by the compiler anyway, thus
doesn't impose any run-time penalty), so the following applies:
\code
_BV(3) => 1 << 3 => 0x08
\endcode
However, using the macro often makes the program better readable.
"BV" stands for "bit value", in case someone might ask you. :-)
Example: clock timer 2 with full IO clock
(CS2x = 0b001), toggle OC2 output on compare match
(COM2x = 0b01), and clear timer on compare match
(CTC2 = 1). Make OC2 (PD7) an output.
\code
TCCR2 = _BV(COM20) | _BV(CTC2) | _BV(CS20);
DDRD = _BV(PD7);
\endcode
Back to \ref faq_index.
\section faq_cplusplus Can I use C++ on the AVR?
Basically yes, C++ is supported (assuming your compiler has been
configured and compiled to support it, of course). Source files
ending in \c \.cc, \c \.cpp or \c \.C will automatically cause the
compiler frontend to invoke the C++ compiler. Alternatively, the C++
compiler could be explicitly called by the name \c avr-c++.
However, there's currently no support for \c libstdc++, the standard
support library needed for a complete C++ implementation. This
imposes a number of restrictions on the C++ programs that can be
compiled. Among them are:
- Obviously, none of the C++ related standard functions, classes,
and template classes are available.
- The operators \c new and \c delete are not implemented, attempting
to use them will cause the linker to complain about undefined
external references. (This could perhaps be fixed.)
- Some of the supplied include files are not C++ safe, i. e. they need
to be wrapped into \code extern "C" { ... } \endcode
(This could certainly be fixed, too.)
- Exceptions are not supported. Since exceptions are enabled by
default in the C++ frontend, they explicitly need to be turned
off using \c -fno-exceptions in the compiler options. Failing
this, the linker will complain about an undefined external
reference to \c __gxx_personality_sj0.
Constructors and destructors \e are supported though, including global
ones.
When programming C++ in space- and runtime-sensitive environments like
microcontrollers, extra care should be taken to avoid unwanted side
effects of the C++ calling conventions like implied copy constructors
that could be called upon function invocation etc. These things could
easily add up into a considerable amount of time and program memory
wasted. Thus, casual inspection of the generated assembler code
(using the \ref opt_save_temps "-save-temps" compiler option)
seems to be warranted.
Back to \ref faq_index.
\section faq_varinit Shouldn't I initialize all my variables?
Variables in static storage are guaranteed to be initialized by the C standard.
This includes global and static variables without explicit initializer,
which are initialized to 0.
\c avr-gcc does this by placing the appropriate code
into section \ref sec_dot_init ".init4". With respect to the
standard, this sentence is somewhat simplified (because the standard
allows for machines where the actual bit pattern used differs
from all bits being 0), but for the AVR target, in general, all integer-type
variables are set to 0, all pointers to a NULL pointer, and all
floating-point variables to 0.0.
As long as these variables are not explicitly initialized, or their
initializer is all zeros, they go into the \ref sec_dot_bss ".bss"
output section. This section simply records the size of the
variable, but otherwise doesn't consume space, neither within the
object file nor within flash memory. (Of course, being a variable, it
will consume space in the target's SRAM.)
In contrast, global and static variables that have a non-zero initializer go
into the \ref sec_dot_data ".data" output section of the file. This will
cause them to consume space in the object file (in order to record the
initializing value), \e and in the flash ROM of the target device.
The latter is needed to initialize the variables in RAM from the
initializers kept in ROM during the startup code, so that all variables
will have their expected initial values when \c main() is entered.
Back to \ref faq_index.
\section faq_16bitio Why do some 16-bit timer registers sometimes get trashed?
Some of the timer-related 16-bit IO registers use a temporary register
(called TEMP in the AVR datasheet) to guarantee an atomic access to
the register despite the fact that two separate 8-bit IO transfers are
required to actually move the data. Typically, this includes access
to the current timer/counter value register (TCNTn),
the input capture register (ICRn), and write access
to the output compare registers (OCRnM). Refer to
the actual datasheet for each device's set of registers that involves
the TEMP register.
When accessing one of the registers that use TEMP from the main
application, and possibly any other one from within an interrupt
routine, care must be taken that no access from within an interrupt
context could clobber the TEMP register data of an in-progress
transaction that has just started elsewhere.
To protect interrupt routines against other interrupt routines, it's
usually best to use the ISR() macro when declaring the interrupt
function, and to ensure that interrupts are still disabled when
accessing those 16-bit timer registers.
Within the main program, access to those registers could be
encapsulated in calls to the cli() and sei() macros. If the status of
the global interrupt flag before accessing one of those registers is
uncertain, something like the following example code can be used.
\code
#include .S,
or explicitly using -x assembler-with-cpp), the compiler
frontend needs to be told to pass the \c \--gstabs option down to the
assembler. This is done using -Wa,\--gstabs. Please take
care to \e only pass this option when compiling an assembler input
file. Otherwise, the assembler code that results from the C
compilation stage will also get line number information, which
confuses the debugger.
\note You can also use -Wa,-gstabs since the compiler will add the
extra \c '-' for you.
Example:
\verbatim
$ EXTRA_OPTS="-Wall -mmcu=atmega128 -x assembler-with-cpp"
$ avr-gcc -Wa,--gstabs ${EXTRA_OPTS} -c -o foo.o foo.S
\endverbatim
Also note that the debugger might get confused when entering a piece
of code that has a non-local label before, since it then takes this
label as the name of a new function that appears to have been entered.
Thus, the best practice to avoid this confusion is to only use
non-local labels when declaring a new function, and restrict anything
else to local labels. Local labels consist just of a number only.
References to these labels consist of the number, followed by the
letter \b b for a backward reference, or \b f for a forward reference.
These local labels may be re-used within the source file, references
will pick the closest label with the same number and given direction.
Example:
\verbatim
myfunc:
push r16
push r17
push r18
push YL
push YH
...
clr r16 ; start loop
ldi YL, lo8(sometable)
ldi YH, hi8(sometable)
rjmp 2f ; jump to loop test at end
1: ld r17, Y+ ; loop continues here
...
breq 3f ; return from myfunc prematurely
...
inc r16
2: cmp r16, r18
brlo 1b ; jump back to top of loop
3: pop YH
pop YL
pop r18
pop r17
pop r16
ret
\endverbatim
Back to \ref faq_index.
\section faq_port_pass How do I pass an IO port as a parameter to a function?
Consider this example code:
\code
#include .rodata input section).
To work around this, you need to do something like this:
\code
#include .data and/or .bss segment)
in that
memory area, it is essential to set up the external memory interface
early during the \ref sec_dot_init "device initialization" so the
initialization of these variable will take place. Refer to
\ref faq_startup for a description how to do this using few lines of
assembler code, or to the chapter about memory sections for an
\ref c_sections "example written in C".
The explanation of malloc() contains a \ref malloc_where "discussion"
about the use of internal RAM vs. external RAM in particular with
respect to the various possible locations of the \e heap (area
reserved for malloc()). It also explains the linker command-line
options that are required to move the memory regions away from their
respective standard locations in internal RAM.
Finally, if the application simply wants to use the additional RAM for
private data storage kept outside the domain of the C compiler
(e. g. through a char * variable initialized directly to a
particular address), it would be sufficient to defer the
initialization of the external RAM interface to the beginning of
main(),
so no tweaking of the .init3 section is necessary. The
same applies if only the heap is going to be located there, since the
application start-up code does not affect the heap.
It is not recommended to locate the stack in external RAM. In
general, accessing external RAM is slower than internal RAM, and
errata of some AVR devices even prevent this configuration from
working properly at all.
Back to \ref faq_index.
\section faq_optflags Which -O flag to use?
There's a common misconception that larger numbers behind the \c -O
option might automatically cause "better" optimization. First,
there's no universal definition for "better", with optimization often
being a speed vs. code size trade off. See the
\ref gcc_optO "detailed discussion" for which option affects which
part of the code generation.
A test case was run on an ATmega128 to judge the effect of compiling
the library itself using different optimization levels. The following
table lists the results. The test case consisted of around 2 KB of
strings to sort. Test \#1 used qsort() using the standard library
strcmp(), test \#2 used a function that sorted the strings by their
size (thus had two calls to strlen() per invocation).
When comparing the resulting code size, it should be noted that a
floating point version of fvprintf() was linked into the binary (in
order to print out the time elapsed) which is entirely not affected by
the different optimization levels, and added about 2.5 KB to the code.
| Optimization Flags | Size of .text | Time for Test \#1 | Time for Test \#2 |
|---|---|---|---|
| -O3 | 6898 | 903 μs | 19.7 ms |
| -O2 | 6666 | 972 μs | 20.1 ms |
| -Os | 6618 | 955 μs | 20.1 ms |
| -Os -mcall-prologues | 6474 | 972 μs | 20.1 ms |
.text.bootloader, this will not work because
\c \--section-start refers to an output section, but the
output section for input section .text.bootloader is the
.text section.
To verify that everything went as expected,
generate the disassembly with avr-objdump ... -j .bootloader.
The top of the list file will show
\verbatim
1 .bootloader 00000004 00002000 00002000 00000204 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
\endverbatim
Or display section properties with avr-readelf \--section-details
\verbatim
$ avr-readelf -t main.elf
Section Headers:
[Nr] Name
Type Addr Off Size ES Lk Inf Al
Flags
[ 2] .bootloader
PROGBITS 00002000 000204 000004 00 0 0 1
[00000006]: ALLOC, EXEC
\endverbatim
A different way to locate the section is by means of a custom linker
script. The
avr-gcc Wiki
has an example that locates the .progmem2.data section which
is used by the compiler for variables in address-space \c __flash2.
Back to \ref faq_index.
\section faq_fuses My UART is generating nonsense! My ATmega128 keeps crashing! Port F is completely broken!
Well, certain odd problems arise out of the situation that the AVR
devices as shipped by Atmel often come with a default fuse bit
configuration that doesn't match the user's expectations. Here is a
list of things to care for:
- All devices that have an internal RC oscillator ship with the fuse
enabled that causes the device to run off this oscillator, instead of
an external crystal. This often remains unnoticed until the first
attempt is made to use something critical in timing, like UART
communication.
- The ATmega128 ships with the fuse enabled that turns this device
into ATmega103 compatibility mode. This means that some ports are not
fully usable, and in particular that the internal SRAM is located at
lower addresses. Since by default, the stack is located at the top of
internal SRAM, a program compiled for an ATmega128 running on such a
device will immediately crash upon the first function call (or rather,
upon the first function return).
- Devices with a JTAG interface have the \c JTAGEN fuse programmed by
default. This will make the respective port pins that are used for
the JTAG interface unavailable for regular IO.
Back to \ref faq_index.
\section faq_flashstrings Why do all my "foo...bar" strings eat up the SRAM?
By default, all strings are handled as all other initialized
variables: they occupy RAM (even though the compiler might warn you
when it detects write attempts to these RAM locations), and occupy the
same amount of flash ROM so they can be initialized to the actual
string by startup code.
That way, any string literal will be a valid argument to any C
function that expects a const char* argument.
Of course, this is going to waste a lot of SRAM.
In \ref avr_pgmspace "Program Space String Utilities",
a method is described how such
constant data can be moved out to flash ROM. However, a constant
string located in flash ROM is no longer a valid argument to pass to a
function that expects a const char*-type string, since the
AVR processor needs the special instruction \c LPM to access these
strings. Thus, separate functions are needed that take this into
account. Many of the standard C library functions have equivalents
available where one of the string arguments can be located in flash
ROM. Private functions in the applications need to handle this, too.
For example, the following can be used to implement simple debugging
messages that will be sent through a UART:
\code
#include -mcvt
which is supported since avr-gcc v15. This will link the
crtmcu-cvt.o variant of the startup code
that provides a CVT and activates it by setting the
CPUINT_CTRLA.CPUINT_CVT bit. A C code will look something like:
\code
#include .init3 section
(i.e. during
the startup code, before main()) to disable the watchdog early enough so
it does not continually reset the AVR.
| Library Call | Reentrant Issue | Workaround / Alternative |
|---|---|---|
| #rand, #random | Uses global variables to keep state information. | Use special reentrant versions: #rand_r, #random_r. |
| #strtof, #strtod, #strtol, #strtoul | Uses the global variable \c errno to return success/failure. | Ignore \c errno, or protect calls with #cli/#sei or #ATOMIC_BLOCK if the application can tolerate it. Or use #scanf or #scanf_P if possible. |
| #malloc, #realloc, #calloc, #free | Uses the stack pointer and global variables to allocate and free memory. | Protect calls with #cli/#sei or #ATOMIC_BLOCK if the application can tolerate it. If using an OS, use the OS provided memory allocator since the OS is likely modifying the stack pointer anyway. |
| #fdevopen, #fclose | Uses #calloc and #free. | Protect calls with #cli/#sei or
#ATOMIC_BLOCK if the application
can tolerate it. Or use #fdev_setup_stream or #FDEV_SETUP_STREAM.
Note: #fclose will only call #free if the stream has been opened with #fdevopen. |
| \ref avr_eeprom "eeprom_*", \ref avr_boot "boot_*" | Accesses I/O registers. | Protect calls with #cli/#sei, #ATOMIC_BLOCK, or use OS locking. |
| \ref avr_pgmspace "pgm_*_far" | Accesses I/O register RAMPZ. | Starting with GCC 4.3, RAMPZ is automatically saved for \ref ISR "ISRs",
so nothing further is needed if only using interrupts.
Some OSes may automatically preserve RAMPZ during context switching. Check the OS documentation before assuming it does. Otherwise, protect calls with #cli/#sei, #ATOMIC_BLOCK, or use explicit OS locking. |
| #printf, #printf_P, #vprintf, #puts, #puts_P | Alters flags and character count in global FILE \c stdout. | Use only in one thread. Or if returned character count is unimportant,
do not use the *_P versions.
Note: Formatting to a string output, e.g. #sprintf, #sprintf_P, #snprintf, #snprintf_P, #vsprintf, #vsprintf_P, #vsnprintf, #vsnprintf_P, is thread safe. The formatted string could then be followed by an #fwrite which simply calls the lower layer to send the string. |
| #fprintf, #fprintf_P, #vfprintf, #vfprintf_P, #fputs, #fputs_P | Alters flags and character count in the FILE argument. Problems can occur if a global FILE is used from multiple threads. | Assign each thread its own FILE for output. Or if returned character count is unimportant, do not use the *_P versions. |
| #assert | Contains an embedded #fprintf. See above for #fprintf. | See above for #fprintf. |
| #clearerr | Alters flags in the FILE argument. | Assign each thread its own FILE for output. |
| #getchar, #gets | Alters flags, character count, and unget buffer in global FILE \c stdin. | Use only in one thread. *** |
| #fgetc, #ungetc, #fgets, #scanf, #scanf_P, #fscanf, #fscanf_P, #vscanf, #vfscanf, #vfscanf_P, #fread | Alters flags, character count, and unget buffer in the FILE argument. | Assign each thread its own FILE for input. ***
Note: Scanning from a string, e.g. #sscanf and #sscanf_P, are thread safe. |