using_tools(3)
πΈ NAME πΈ
using_tools β Using the GNU tools
okay so bestie, real talk π this page is the short-and-sweet summary of the AVR-specific aspects of using the GNU tools. Normally the generic documentation for these tools is, like, enormous and it's maintained in texinfo files. Command-line options? Those get explained in detail in the manual page. So this is the AVR-flavored recap, from the avr-libc manual. π
π§ Options for the C compiler avr-gcc π§
π Machine-specific options for the AVR π
The C compiler frontend recognizes all of the machine-specific options below. And on top of the preprocessor macros listed in the tables, the preprocessor will also define the macros __AVR and __AVR__ (both set to the value 1) whenever you're compiling for an AVR target. β¨
The macro AVR gets defined too when you use the standard levels gnu89 (that one's the default) and gnu99 β but not with c89 and c99. no cap. π
π« -mmcu=architecture π«
Compile code for architecture. Currently known architectures are:
avr1β macros:__AVR_ARCH__=1,__AVR_ASM_ONLY__,__AVR_2_BYTE_PC__[2]. Simple CPU core, only assembler support. πavr2β macros:__AVR_ARCH__=2,__AVR_2_BYTE_PC__[2]. 'Classic' CPU core, up to 8 KB of ROM.avr25[1] β macros:__AVR_ARCH__=25,__AVR_HAVE_MOVW__[1],__AVR_HAVE_LPMX__[1],__AVR_2_BYTE_PC__[2]. 'Classic' CPU core with 'MOVW' and 'LPM Rx, Z[+]' instruction, up to 8 KB of ROM.avr3β macros:__AVR_ARCH__=3,__AVR_MEGA__[5],__AVR_HAVE_JMP_CALL__[4],__AVR_2_BYTE_PC__[2]. 'Classic' CPU core, 16 KB to 64 KB of ROM.avr31β macros:__AVR_ARCH__=31,__AVR_MEGA__[5],__AVR_HAVE_JMP_CALL__[4],__AVR_HAVE_RAMPZ__[4],__AVR_HAVE_ELPM__[4],__AVR_2_BYTE_PC__[2]. 'Classic' CPU core, 128 KB of ROM.avr35[3] β macros:__AVR_ARCH__=35,__AVR_MEGA__[5],__AVR_HAVE_JMP_CALL__[4],__AVR_HAVE_MOVW__[1],__AVR_HAVE_LPMX__[1],__AVR_2_BYTE_PC__[2]. 'Classic' CPU core with 'MOVW' and 'LPM Rx, Z[+]' instruction, 16 KB to 64 KB of ROM.avr4β macros:__AVR_ARCH__=4,__AVR_ENHANCED__[5],__AVR_HAVE_MOVW__[1],__AVR_HAVE_LPMX__[1],__AVR_HAVE_MUL__[1],__AVR_2_BYTE_PC__[2]. 'Enhanced' CPU core, up to 8 KB of ROM.avr5β macros:__AVR_ARCH__=5,__AVR_MEGA__[5],__AVR_ENHANCED__[5],__AVR_HAVE_JMP_CALL__[4],__AVR_HAVE_MOVW__[1],__AVR_HAVE_LPMX__[1],__AVR_HAVE_MUL__[1],__AVR_2_BYTE_PC__[2]. 'Enhanced' CPU core, 16 KB to 64 KB of ROM.avr51β macros:__AVR_ARCH__=51,__AVR_MEGA__[5],__AVR_ENHANCED__[5],__AVR_HAVE_JMP_CALL__[4],__AVR_HAVE_MOVW__[1],__AVR_HAVE_LPMX__[1],__AVR_HAVE_MUL__[1],__AVR_HAVE_RAMPZ__[4],__AVR_HAVE_ELPM__[4],__AVR_HAVE_ELPMX__[4],__AVR_2_BYTE_PC__[2]. 'Enhanced' CPU core, 128 KB of ROM.avr6[2] β macros:__AVR_ARCH__=6,__AVR_MEGA__[5],__AVR_ENHANCED__[5],__AVR_HAVE_JMP_CALL__[4],__AVR_HAVE_MOVW__[1],__AVR_HAVE_LPMX__[1],__AVR_HAVE_MUL__[1],__AVR_HAVE_RAMPZ__[4],__AVR_HAVE_ELPM__[4],__AVR_HAVE_ELPMX__[4],__AVR_3_BYTE_PC__[2]. 'Enhanced' CPU core, 256 KB of ROM.
Now the little footnote era, keep up π«Ά:
- [1] New in GCC 4.2
- [2] Unofficial patch for GCC 4.1
- [3] New in GCC 4.2.3
- [4] New in GCC 4.3
- [5] Obsolete.
By default, code is generated for the avr2 architecture. that's the default bestie, it's giving classic β¨
Note that when only using-mmcu=architecturebut no-mmcu=MCU type, including the file<avr/io.h>cannot work since it cannot decide which device's definitions to select. π it literally cannot pick a fave.
π« -mmcu=MCU type π«
The following MCU types are currently understood by avr-gcc. The table matches them against the corresponding avr-gcc architecture name, and shows the preprocessor symbol declared by the -mmcu option. π
- arch
avr1βat90s1200β__AVR_AT90S1200__,attiny11β__AVR_ATtiny11__,attiny12β__AVR_ATtiny12__,attiny15β__AVR_ATtiny15__,attiny28β__AVR_ATtiny28__ - arch
avr2βat90s2313β__AVR_AT90S2313__,at90s2323β__AVR_AT90S2323__,at90s2333β__AVR_AT90S2333__,at90s2343β__AVR_AT90S2343__,attiny22β__AVR_ATtiny22__,attiny26β__AVR_ATtiny26__,at90s4414β__AVR_AT90S4414__,at90s4433β__AVR_AT90S4433__,at90s4434β__AVR_AT90S4434__,at90s8515β__AVR_AT90S8515__,at90c8534β__AVR_AT90C8534__,at90s8535β__AVR_AT90S8535__ - arch
avr2/avr25[1] βat86rf401β__AVR_AT86RF401__,ata5272β__AVR_ATA5272__,ata6616cβ__AVR_ATA6616C__,attiny13β__AVR_ATtiny13__,attiny13aβ__AVR_ATtiny13A__,attiny2313β__AVR_ATtiny2313__,attiny2313aβ__AVR_ATtiny2313A__,attiny24β__AVR_ATtiny24__,attiny24aβ__AVR_ATtiny24A__,attiny25β__AVR_ATtiny25__,attiny261β__AVR_ATtiny261__,attiny261aβ__AVR_ATtiny261A__,attiny4313β__AVR_ATtiny4313__,attiny43uβ__AVR_ATtiny43U__,attiny44β__AVR_ATtiny44__,attiny44aβ__AVR_ATtiny44A__,attiny441β__AVR_ATtiny441__,attiny45β__AVR_ATtiny45__,attiny461β__AVR_ATtiny461__,attiny461aβ__AVR_ATtiny461A__,attiny48β__AVR_ATtiny48__,attiny828β__AVR_ATtiny828__,attiny84β__AVR_ATtiny84__,attiny84aβ__AVR_ATtiny84A__,attiny841β__AVR_ATtiny841__,attiny85β__AVR_ATtiny85__,attiny861β__AVR_ATtiny861__,attiny861aβ__AVR_ATtiny861A__,attiny87β__AVR_ATtiny87__,attiny88β__AVR_ATtiny88__ - arch
avr3βatmega603β__AVR_ATmega603__,at43usb355β__AVR_AT43USB355__ - arch
avr3/avr31[3] βatmega103β__AVR_ATmega103__,at43usb320β__AVR_AT43USB320__ - arch
avr3/avr35[2] βat90usb82β__AVR_AT90USB82__,at90usb162β__AVR_AT90USB162__,ata5505β__AVR_ATA5505__,ata6617cβ__AVR_ATA6617C__,ata664251β__AVR_ATA664251__,atmega8u2β__AVR_ATmega8U2__,atmega16u2β__AVR_ATmega16U2__,atmega32u2β__AVR_ATmega32U2__,attiny167β__AVR_ATtiny167__,attiny1634β__AVR_ATtiny1634__ - arch
avr3βat76c711β__AVR_AT76C711__ - arch
avr4βata6285β__AVR_ATA6285__,ata6286β__AVR_ATA6286__,ata6289β__AVR_ATA6289__,ata6612cβ__AVR_ATA6612C__,atmega48β__AVR_ATmega48__,atmega48aβ__AVR_ATmega48A__,atmega48paβ__AVR_ATmega48PA__,atmega48pbβ__AVR_ATmega48PB__,atmega48pβ__AVR_ATmega48P__,atmega8β__AVR_ATmega8__,atmega8aβ__AVR_ATmega8A__,atmega8515β__AVR_ATmega8515__,atmega8535β__AVR_ATmega8535__,atmega88β__AVR_ATmega88__,atmega88aβ__AVR_ATmega88A__,atmega88pβ__AVR_ATmega88P__,atmega88paβ__AVR_ATmega88PA__,atmega88pbβ__AVR_ATmega88PB__,atmega8hvaβ__AVR_ATmega8HVA__,at90pwm1β__AVR_AT90PWM1__,at90pwm2β__AVR_AT90PWM2__,at90pwm2bβ__AVR_AT90PWM2B__,at90pwm3β__AVR_AT90PWM3__,at90pwm3bβ__AVR_AT90PWM3B__,at90pwm81β__AVR_AT90PWM81__ - arch
avr5βat90can32β__AVR_AT90CAN32__,at90can64β__AVR_AT90CAN64__,at90pwm161β__AVR_AT90PWM161__,at90pwm216β__AVR_AT90PWM216__,at90pwm316β__AVR_AT90PWM316__,at90scr100β__AVR_AT90SCR100__,at90usb646β__AVR_AT90USB646__,at90usb647β__AVR_AT90USB647__,at94kβ__AVR_AT94K__,atmega16β__AVR_ATmega16__,ata5702m322β__AVR_ATA5702M322__,ata5782β__AVR_ATA5782__,ata5790β__AVR_ATA5790__,ata5790nβ__AVR_ATA5790N__,ata5795β__AVR_ATA5795__,ata5831β__AVR_ATA5831__,ata6613cβ__AVR_ATA6613C__,ata6614qβ__AVR_ATA6614Q__,atmega161β__AVR_ATmega161__,atmega162β__AVR_ATmega162__,atmega163β__AVR_ATmega163__,atmega164aβ__AVR_ATmega164A__,atmega164pβ__AVR_ATmega164P__,atmega164paβ__AVR_ATmega164PA__,atmega165β__AVR_ATmega165__,atmega165aβ__AVR_ATmega165A__,atmega165pβ__AVR_ATmega165P__,atmega165paβ__AVR_ATmega165PA__,atmega168β__AVR_ATmega168__,atmega168aβ__AVR_ATmega168A__,atmega168pβ__AVR_ATmega168P__,atmega168paβ__AVR_ATmega168PA__,atmega169β__AVR_ATmega169__,atmega169aβ__AVR_ATmega169A__,atmega169pβ__AVR_ATmega169P__,atmega169paβ__AVR_ATmega169PA__,atmega16aβ__AVR_ATmega16A__,atmega16hvaβ__AVR_ATmega16HVA__,atmega16hva2β__AVR_ATmega16HVA2__,atmega16hvbβ__AVR_ATmega16HVB__,atmega16hvbrevbβ__AVR_ATmega16HVBREVB__,atmega16m1β__AVR_ATmega16M1__,atmega16u4β__AVR_ATmega16U4__,atmega32β__AVR_ATmega32__,atmega32aβ__AVR_ATmega32A__,atmega323β__AVR_ATmega323__,atmega324aβ__AVR_ATmega324A__,atmega324pβ__AVR_ATmega324P__,atmega324paβ__AVR_ATmega324PA__,atmega325β__AVR_ATmega325__,atmega325aβ__AVR_ATmega325A__,atmega325pβ__AVR_ATmega325P__,atmega325paβ__AVR_ATmega325PA__,atmega3250β__AVR_ATmega3250__,atmega3250aβ__AVR_ATmega3250A__,atmega3250pβ__AVR_ATmega3250P__,atmega3250paβ__AVR_ATmega3250PA__,atmega328β__AVR_ATmega328__,atmega328pβ__AVR_ATmega328P__,atmega329β__AVR_ATmega329__,atmega329aβ__AVR_ATmega329A__,atmega329pβ__AVR_ATmega329P__,atmega329paβ__AVR_ATmega329PA__,atmega3290β__AVR_ATmega3290__,atmega3290aβ__AVR_ATmega3290A__,atmega3290pβ__AVR_ATmega3290P__,atmega3290paβ__AVR_ATmega3290PA__,atmega32c1β__AVR_ATmega32C1__,atmega32hvbβ__AVR_ATmega32HVB__,atmega32hvbrevbβ__AVR_ATmega32HVBREVB__,atmega32m1β__AVR_ATmega32M1__,atmega32u4β__AVR_ATmega32U4__,atmega32u6β__AVR_ATmega32U6__,atmega406β__AVR_ATmega406__,atmega644rfr2β__AVR_ATmega644RFR2__,atmega64rfr2β__AVR_ATmega64RFR2__,atmega64β__AVR_ATmega64__,atmega64aβ__AVR_ATmega64A__,atmega640β__AVR_ATmega640__,atmega644β__AVR_ATmega644__,atmega644aβ__AVR_ATmega644A__,atmega644pβ__AVR_ATmega644P__,atmega644paβ__AVR_ATmega644PA__,atmega645β__AVR_ATmega645__,atmega645aβ__AVR_ATmega645A__,atmega645pβ__AVR_ATmega645P__,atmega6450β__AVR_ATmega6450__,atmega6450aβ__AVR_ATmega6450A__,atmega6450pβ__AVR_ATmega6450P__,atmega649β__AVR_ATmega649__,atmega649aβ__AVR_ATmega649A__,atmega6490β__AVR_ATmega6490__,atmega6490aβ__AVR_ATmega6490A__,atmega6490pβ__AVR_ATmega6490P__,atmega649pβ__AVR_ATmega649P__,atmega64c1β__AVR_ATmega64C1__,atmega64hveβ__AVR_ATmega64HVE__,atmega64hve2β__AVR_ATmega64HVE2__,atmega64m1β__AVR_ATmega64M1__,m3000β__AVR_M3000__ - arch
avr5/avr51[3] βat90can128β__AVR_AT90CAN128__,at90usb1286β__AVR_AT90USB1286__,at90usb1287β__AVR_AT90USB1287__,atmega128β__AVR_ATmega128__,atmega128aβ__AVR_ATmega128A__,atmega1280β__AVR_ATmega1280__,atmega1281β__AVR_ATmega1281__,atmega1284β__AVR_ATmega1284__,atmega1284pβ__AVR_ATmega1284P__,atmega1284rfr2β__AVR_ATmega1284RFR2__,atmega128rfr2β__AVR_ATmega128RFR2__ - arch
avr6βatmega2560β__AVR_ATmega2560__,atmega2561β__AVR_ATmega2561__,atmega2564rfr2β__AVR_ATmega2564RFR2__,atmega256rfr2β__AVR_ATmega256RFR2__
okay so the device list is literally never-ending and I'm obsessed with it π here's every single one, and yes you need all of them:
avrxmega2atxmega8e5__AVR_ATxmega8E5__
avrxmega2atxmega16a4__AVR_ATxmega16A4__
avrxmega2atxmega16a4u__AVR_ATxmega16A4U__
avrxmega2atxmega16c4__AVR_ATxmega16C4__
avrxmega2atxmega16d4__AVR_ATxmega16D4__
avrxmega2atxmega32a4__AVR_ATxmega32A4__
avrxmega2atxmega32a4u__AVR_ATxmega32A4U__
avrxmega2atxmega32c3__AVR_ATxmega32C3__
avrxmega2atxmega32c4__AVR_ATxmega32C4__
avrxmega2atxmega32d3__AVR_ATxmega32D3__
avrxmega2atxmega32d4__AVR_ATxmega32D4__
avrxmega2atxmega32e5__AVR_ATxmega32E5__
avrxmega4atxmega64a3__AVR_ATxmega64A3__
avrxmega4atxmega64a3u__AVR_ATxmega64A3U__
avrxmega4atxmega64a4u__AVR_ATxmega64A4U__
avrxmega4atxmega64b1__AVR_ATxmega64B1__
avrxmega4atxmega64b3__AVR_ATxmega64B3__
avrxmega4atxmega64c3__AVR_ATxmega64C3__
avrxmega4atxmega64d3__AVR_ATxmega64D3__
avrxmega4atxmega64d4__AVR_ATxmega64D4__
avrxmega5atxmega64a1__AVR_ATxmega64A1__
avrxmega5atxmega64a1u__AVR_ATxmega64A1U__
avrxmega6atxmega128a3__AVR_ATxmega128A3__
avrxmega6atxmega128a3u__AVR_ATxmega128A3U__
avrxmega6atxmega128b1__AVR_ATxmega128B1__
avrxmega6atxmega128b3__AVR_ATxmega128B3__
avrxmega6atxmega128c3__AVR_ATxmega128C3__
avrxmega6atxmega128d3__AVR_ATxmega128D3__
avrxmega6atxmega128d4__AVR_ATxmega128D4__
avrxmega6atxmega192a3__AVR_ATxmega192A3__
avrxmega6atxmega192a3u__AVR_ATxmega192A3U__
avrxmega6atxmega192c3__AVR_ATxmega192C3__
avrxmega6atxmega192d3__AVR_ATxmega192D3__
avrxmega6atxmega256a3__AVR_ATxmega256A3__
avrxmega6atxmega256a3u__AVR_ATxmega256A3U__
avrxmega6atxmega256a3b__AVR_ATxmega256A3B__
avrxmega6atxmega256a3bu__AVR_ATxmega256A3BU__
avrxmega6atxmega256c3__AVR_ATxmega256C3__
avrxmega6atxmega256d3__AVR_ATxmega256D3__
avrxmega6atxmega384c3__AVR_ATxmega384C3__
avrxmega6atxmega384d3__AVR_ATxmega384D3__
avrxmega7atxmega128a1__AVR_ATxmega128A1__
avrxmega7atxmega128a1u__AVR_ATxmega128A1U__
avrxmega7atxmega128a4u__AVR_ATxmega128A4U__
avrtiny10attiny4__AVR_ATtiny4__ avrtiny10attiny5__AVR_ATtiny5__
avrtiny10attiny9__AVR_ATtiny9__ avrtiny10attiny10__AVR_ATtiny10__
avrtiny10attiny20__AVR_ATtiny20__ avrtiny10attiny40__AVR_ATtiny40__
and the little footnotes that come with them, pls don't skip these bestie π«Ά
[1]'avr25' architecture is new in GCC 4.2[2]'avr35' architecture is new in GCC 4.2.3[3]'avr31' and 'avr51' architectures is new in GCC 4.3
-morder1-morder2
okay so these two are the register-assignment-shuffle options β¨ they change the order of register assignment. The default is:
r24, r25, r18, r19, r20, r21, r22, r23, r30, r31, r26, r27, r28, r29,
r17, r16, r15, r14, r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2,
r0, r1
Order 1 uses:
r18, r19, r20, r21, r22, r23, r24, r25, r30, r31, r26, r27, r28, r29,
r17, r16, r15, r14, r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2,
r0, r1
Order 2 uses:
r25, r24, r23, r22, r21, r20, r19, r18, r30, r31, r26, r27, r28, r29,
r17, r16, r15, r14, r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2,
r1, r0
-mint8β assumeintis an 8-bit integer. lowkey important warning: this is not really supported by avr-libc, so it should normally not be used, fr fr. The default is to use 16-bit integers.-mno-interruptsβ generates code that changes the stack pointer without disabling interrupts. Normally, the state of the status registerSREGis saved in a temporary register, interrupts are disabled while changing the stack pointer, andSREGis restored. Specifying this option will define the preprocessor macro__NO_INTERRUPTS__to the value1.-mcall-prologuesβ use subroutines for function prologue/epilogue. For complex functions that use a lot of registers (the ones that need to be saved/restored on function entry/exit), this saves some space at the cost of a slightly increased execution time. tradeoff queen π-mtiny-stackβ change only the low 8 bits of the stack pointer.-mno-tablejumpβ deprecated, use-fno-jump-tablesinstead.-mshort-callsβ userjmp/rcall(limited range) on >8K devices. Onavr2andavr4architectures (less than 8 KB of flash memory), this is always the case. Onavr3andavr5architectures, calls and jumps to targets outside the current function will by default usejmp/callinstructions that can cover the entire address range, but that require more flash ROM and execution time.-mrtlβ dump the internal compilation result calledRTLinto comments in the generated assembler code. Used for debugging avr-gcc π-msizeβ dump the address, size, and relative cost of each statement into comments in the generated assembler code. Also used for debugging avr-gcc.-mdebβ generate lots of debugging information tostderr. it's giving chatty ngl
β¨ Selected general compiler options β¨
The following general gcc options might be of some interest to AVR users, bestie π
-Onβ optimization level n. Increasing n is meant to optimize more, and an optimization level of0means no optimization at all, which is the default if no-Ooption is present. The special option-Osis meant to turn on all-O2optimizations that are not expected to increase code size.
Note that at -O3, gcc attempts to inline all 'simple' functions. For the AVR target, this will normally constitute a large pessimization due to the code increasement π The only other optimization turned on with -O3 is -frename-registers, which could rather be enabled manually instead.
A simple -O option is equivalent to -O1.
Note also that turning off all optimizations will prevent some warnings from being issued, since the generation of those warnings depends on code analysis steps that are only performed when optimizing (unreachable code, unused variables).
See also the appropriate FAQ entry for issues regarding debugging optimized code.
-Wa,assembler-options-Wl,linker-options
Pass the listed options to the assembler, or linker, respectively.
-gβ generate debugging information that can be used by avr-gdb.-ffreestandingβ assume a 'freestanding' environment as per the C standard. This turns off automatic builtin functions (though they can still be reached by prepending__builtin_to the actual function name). It also makes the compiler not complain whenmain()is declared with avoidreturn type, which makes some sense in a microcontroller environment where the application cannot meaningfully provide a return value to its environment (in most cases,main()won't even return anyway). However, this also turns off all optimizations normally done by the compiler which assume that functions known by a certain name behave as described by the standard. E. g., applying the functionstrlen()to a literal string will normally cause the compiler to immediately replace that call by the actual length of the string, while with-ffreestanding, it will always callstrlen()at run-time.-funsigned-charβ make any unqualifiedchartype anunsigned char. Without this option, they default to asigned char.-funsigned-bitfieldsβ make any unqualified bitfield type unsigned. By default, they are signed.-fshort-enumsβ allocate to anenumtype only as many bytes as it needs for the declared range of possible values. Specifically, theenumtype will be equivalent to the smallest integer type which has enough room.-fpack-structβ pack all structure members together without holes.-fno-jump-tablesβ do not generate tablejump instructions. By default, jump tables can be used to optimizeswitchstatements. When turned off, sequences of compare statements are used instead. Jump tables are usually faster to execute on average, but in particular forswitchstatements, where most of the jumps would go to thedefaultlabel, they might waste a bit of flash memory.
NOTE: the tablejump instructions use theLPMassembler instruction for access to jump tables. Always use the-fno-jump-tablesswitch if compiling a bootloader for devices with more than 64 KB of code memory. like, always always π
π¦ Options for the assembler avr-as π¦
π Machine-specific assembler options π
-mmcu=architecture-mmcu=MCU name
avr-as understands the same -mmcu= options as avr-gcc. By default, avr2 is assumed, but this can be altered by using the appropriate .arch pseudo-instruction inside the assembler source file.
-mall-opcodesβ turns off opcode checking for the actual MCU type, and allows any possible AVR opcode to be assembled. chaos mode, slay π-mno-skip-bugβ don't emit a warning when trying to skip a 2-word instruction with aCPSE/SBIC/SBIS/SBRC/SBRSinstruction. Early AVR devices suffered from a hardware bug where these instructions could not be properly skipped π-mno-wrapβ forRJMP/RCALLinstructions, don't allow the target address to wrap around for devices that have more than 8 KB of memory.--gstabsβ generate.stabsdebugging symbols for assembler source lines. This enables avr-gdb to trace through assembler source files. This option must not be used when assembling sources that have been generated by the C compiler β those files already contain the appropriate line number information from the C source files.-a[cdhlmns=file]β turn on the assembler listing. The sub-options are:comit false conditionalsdomit debugging directiveshinclude high-level sourcelinclude assemblyminclude macro expansionsnomit forms processingsinclude symbols=fileset the name of the listing file
The various sub-options can be combined into a single -a option list; =file must be the last one in that case. no skipping the order bestie π€
π Examples for assembler options passed through the C compiler π
Remember that assembler options can be passed from the C compiler frontend using -Wa (see above), so in order to include the C source code into the assembler listing in file foo.lst, when compiling foo.c, the following compiler command-line can be used:
$ avr-gcc -c -O foo.c -o foo.o -Wa,-ahls=foo.lst
In order to pass an assembler file through the C preprocessor first, and have the assembler generate line number debugging information for it, the following command can be used:
$ avr-gcc -c -x assembler-with-cpp -o foo.o foo.S -Wa,--gstabs
Note that on Unix systems that have case-distinguishing file systems, specifying a file name with the suffix .S (upper-case letter S) will make the compiler automatically assume -x assembler-with-cpp, while using .s would pass the file directly to the assembler (no preprocessing done). the case sensitivity jump scare is so real π
Controlling the linker avr-ld πβ¨
Selected linker options π
Okay so avr-ld doesn't have any machine-specific options, bestie β but a bunch of the standard linker options are still gonna be super relevant for AVR girlies. periodt.
-lnameβ This one goes looking for the archive library calledlibname.a, then uses it to clear up any currently unresolved symbols. It searches along a path made of builtin pathname entries that got baked in at compile time (e. g./usr/local/avr/libon Unix systems), and that path can also be extended by pathname entries you pass with-Loptions (which, important, have to come before the-loptions on the command-line). π-Lpathβ Another place to look for archive libraries that-loptions ask for. π--defsym symbol=exprβ Defines a global symbolsymboland gives itexpras its value. β¨-Mβ Prints a linker map to stdout. πΊοΈ-Map mapfileβ Prints a linker map tomapfile. π--crefβ Outputs a cross reference table to the map file (if-Mapis also there), or to stdout. π--section-start sectionname=orgβ Starts sectionsectionnameat absolute addressorg. π-Tbss orgβ Starts thebsssection atorg. π«§-Tdata orgβ Starts thedatasection atorg. πΎ-Ttext orgβ Starts thetextsection atorg. π-T scriptfileβ Usesscriptfileas the linker script and replaces the default linker script. Default linker scripts live in a system-specific location (e. g. under/usr/local/avr/lib/ldscriptson Unix systems), and their names are the AVR architecture name (avr2throughavr5) plus the suffix.x. They describe how all the different memory sections get linked together. π§©
Passing linker options from the C compiler π
By default, every unknown non-option argument on the avr-gcc command-line gets passed straight to the linker β that means all filename arguments that don't have a suffix handled by avr-gcc. So all files ending in .o (object files) and .a (object libraries) get handed over to the linker. No cap.
System libraries usually aren't passed by their explicit filename; instead they use the -l option, which takes an abbreviated form of the archive filename (see above). avr-libc ships two system libraries, libc.a, and libm.a. The standard library libc.a will always get searched for unresolved references whenever the linker is started through the C compiler frontend (i. e., there's always at least one implied -lc option). The mathematics library libm.a, though, needs to be explicitly requested with -lm. See also the entry in the FAQ explaining this. π§
Makefiles conventionally use the make macro LDLIBS to keep track of -l (and possibly -L) options that should only be appended to the C compiler command-line when linking the final binary. Meanwhile, the macro LDFLAGS stores other command-line options for the C compiler that should be passed as options during the linking stage. The difference is placement: options go early on the command-line, while libraries go at the end, because they're there to resolve global symbols that are still unresolved at that point. π§
You can pass specific linker flags from the C compiler command-line with the -Wl compiler option, see above. This option needs there to be no spaces in the appended linker option, but some of the linker options above (like -Map or --defsym) would require a space. In those situations, you can replace the space with an equal sign instead. For example, this command-line compiles foo.c into an executable and also makes a link map with a cross-reference list in the file foo.map:
$ avr-gcc -O -o foo.out -Wl,-Map=foo.map -Wl,--cref foo.c
Alternatively, a comma works as a placeholder and will be replaced by a space before the option is passed to the linker. So for a device with external SRAM, this command-line would make the linker put the data segment at address 0x2000 in the SRAM:
$ avr-gcc -mmcu=atmega128 -o foo.out -Wl,-Tdata,0x802000
See the explanation of the data section for why 0x800000 needs to be added to the actual value. Note that the stack will still stay in internal RAM, through the symbol __stack that the run-time startup code provides. That's probably a good idea anyway (internal RAM access is faster), and it's even required for some early devices that had hardware bugs preventing them from using a stack in external RAM. Also note that the heap for malloc() will still be placed after all the variables in the data section, so in this situation, no stack/heap collision can occur. πΈ
To relocate the stack from its default spot at the top of internal RAM, you can change the value of the symbol __stack on the linker command-line. Since the linker is typically called from the compiler frontend, you can do this with a compiler option like -Wl,--defsym=__stack=0x8003ff
The above makes the code use stack space from RAM address 0x3ff downwards. How much stack space is available then depends on the bottom address of internal RAM for a particular device. It is the responsibility of the application to ensure the stack does not grow out of bounds, and to arrange for the stack to not collide with variable allocations made by the compiler (sections .data and .bss). π
That's the whole vibe, bestie! Version 2.1.0, dated Sat Jan 29 2022, from using_tools(3) β slay. πβ¨
π¦ where this page comes from
- fedora 43: avr-libc 2.2.1-3.fc43 Β· BSD-3-Clause
- fedora 44: avr-libc 2.2.1-5.fc44 Β· BSD-3-Clause
- opensuse-leap 16.0: avr-libc 2.1.0-bp160.1.33 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms