It might help to point out the use of
-D switches of
If you turn on verbose output of the Arduino IDE (I am using a pretty old version):
you will see, when you compile a sketch, that the compiler is not only called with a switch
-mmcu=atmega328p) which describes the target (i.e. the ATMEL AVR instruction set or MCU type) for which the code is compiled, but also with a number of
-D switches predefine a name as a macro and also that depend on the target.
You might see for example
F_CPU is used to pass information about the target's clock speed (16 MHz in this case) to code that depends on this, e.g. the
delay function or the
3 ways to define macros
In general, the confusion might come from the fact that including files in the Arduino build chain depends a lot on compiler flags, and there are several ways to define these:
- from the target specification (compiler built-in,
The last point means that the above mentioned
-matmega328p defines the macro
__AVR_ATmega328P__ which is e.g. used in
io.h to include the appropriate file with pin mappings, RAM sizes etc. (Google for
avr-mcus.def to find a full list of these predefined macros for AVR targets.)
Finally, note that the Arduino IDE also sets include paths depending on the target. The appropriate set of pin definitions is selected by passing an include path like this to
standard is replaced by
Short answer / summary / how to debug
First, to generate a list of the current
#define directives, use the
-dM option like this (compiling an empty program that is specified to be C with
echo | avr-gcc -x c -E -dM -mmcu=atmega328p - | sort
-mmcu=atmega328p to your needs (you can also leave it out).
Second, you can use the option
-g3 to include the macro definitions in the output. Keep the intermediate files by using
-save-temps. You can append these to the compiler call by the IDE:
avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega168 -DF_CPU=8000000L -DARDUINO=100 -I/usr/share/arduino/hardware/arduino/cores/arduino -I/usr/share/arduino/hardware/arduino/variants/standard /tmp/build5017602110288.tmp/SerialManual.cpp -o/tmp/build5017602110288.tmp/SerialManual.cpp.o -save-temps -g3
which will create a long output file
SerialManual.ii) that lists among others the
typedefs and, most importantly, from which files they come.
# 1 "/tmp/build501760211028815624.tmp/SerialManual.cpp"
# 1 "/tmp/1//"
# 1 "<built-in>"
#define __STDC__ 1
#define __cplusplus 1
#define __AVR_ATmega168__ 1
#define __CHAR16_TYPE__ short unsigned int
# 1 "<command-line>"
#define F_CPU 8000000L
#define ARDUINO 100
# 1 "/usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/iom168.h" 1 3
# 34 "/usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/iom168.h" 3
#define _AVR_IOM168_H_ 1
#define SPM_PAGESIZE 128
#define RAMSTART (0x100)
#define RAMEND 0x4FF
#define XRAMEND RAMEND
#define E2END 0x1FF
#define E2PAGESIZE 4
#define FLASHEND 0x3FFF