Comandi di compilazione, link ecc. per la toolchain avr-gcc

Da questo topic http://forum.arduino.cc/index.php?topic=309343.30 è nata questo mio.

Per estrarre la section .eeprom dal file .elf uso questi due comandi:

avr-objcopy -O binary -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 genfreq genfreq.eep.bin
avr-objcopy -R .eeprom -O ihex genfreq genfreq.hex

--set-section-flags=.eeprom=alloc,load non mi ricordo cosa fanno e come ci sono arrivato.

Per compilare uso questo comando:

avr-gcc -c -Wall -Os -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -fdata-sections -ffunction-sections -mmcu=atmega328p -save-temps -std=gnu99 -DSOFTWARE_MODE -D__AVR_ATmega328P__ -DF_CPU=16000000UL -I/home/maurilio/.avrspecs/mkspecs/linux-avr8-gcc -I. -I../../../MTavr/src/Core/MTio -I../../../MTavr/src/Core/MThw_serial -I/usr/avr/include -o main.o main.c

Togliete -DSOFTWARE_MODE, -D__AVR_ATmega328P__, che servono solo a me.
Anche -I../../../MTavr/src/Core/MTio ecc sono validi solo per me che ho queste lib.

Per linkare uso questo comando:
avr-gcc -Wl,--gc-sections -mmcu=atmega328p -o apptest main.o autodetect.o datacollection.o multipid.o timer2.o error.o timer0.o protocol.o spislave.o controller1.o    -L/home/maurilio/Sviluppo/embedded-AVR/avrcreator-project/acmotorspeed/apptest/../../../MTavr/lib/MTavr/atmega328p/16000000 -lCore
Come vedete c'è solo di default la garbage collector section abilitata, poi nessun flag particolare.

ops. di recente ho modificato alcuni file di configurazione per integrare l'architettura ARM e forse nell'ultimo comando manca l'ottimizzazione -Os, ora non ricordo se è necessaria anche nel linker.

Per le librerie i comandi sono simili solo che al posto della fase di link c'è la creazione della lib .a

Ciao.

X iscrizione

GRAZIE!
io sto usando (lo so, dovrei trascriverlo in un makefile) (ti consiglio di rubarti l’ultimo comandi per avere lo spazio flash/ram occupato):

#!/bin/bash

avr-gcc -Os -w -ffunction-sections -fdata-sections -MMD -Wall -Wextra -std=c11 -mmcu=atmega32u4 -DF_CPU=16000000L -c test_bottone.c && \
avr-gcc -g -std=c11 -mmcu=atmega32u4 -DF_CPU=16000000L -o test_bottone.elf test_bottone.o && \
avr-objcopy -j .text -j .data -O ihex test_bottone.elf test_bottone.hex && \
avr-size -C --mcu=atmega32u4 test_bottone.elf

in oltre vedo che usi delle librerie pure-c sono disponibili i sorgenti? io sto cercando qualcosa di più specifico per i tiny.

in oltre vedo che usi delle librerie pure-c sono disponibili i sorgenti? io sto cercando qualcosa di più specifico per i tiny.

No niente sorgenti di quelle lib. Ci sono le lib di Atmel, il codice è ottimo, però mai provato a linkare un mia applicazione. In giro di librerie C per avr qualcosa si trova, io alla fine ho scritto le mie routine proprio perché di librerie che mi andassero bene non ne ho trovato. Non è che le mie sono perfette anzi tutt'altro ma almeno le conosco nel dettaglio. Poi raramente queste lib finiscono nell'applicazione per la quale scrivo un lib interna al progetto, cioè servono solo per sviluppare l'applicazione.

-MMD

Mi pare generi l'albero delle dipendenze?
A me non serve perché ci pensa il generatore di makefile qmake.

Tu usi -std=c11, quindi C++ "incarnazione" 11. :wink:

(ti consiglio di rubarti l'ultimo comandi per avere lo spazio flash/ram occupato):

C'è l'ho, e lo genera anche per il .elf.

  • Io invece ti regalo, -save-temps, che non cancella i file temporanei e quindi ti ritrovi il file generato dal preprocessore e il .s asm del modulo .c o .cpp.

[?]Riguardo l'ottimizzazione sai se si deve specificare anche nella fase di linker?

Guarda che in giro trovi dei makefile già pronti proprio per avr. Tuttavia studiare make e saperlo usare bene ti mette nelle condizioni migliori, purtroppo non è banale e il tempo è limitato e quindi mi sono fermato di studiare make.

Ciao.

[Edit]
La documentazione a questo link funge da riferimento. A mio parere la doc andrebbe estesa.

perchè std=C11 è c++? a me non risulta: http://en.wikipedia.org/wiki/C11_(C_standard_revision)

l'mmd l'ho lasciato perchè lo usa arduino (in realtà devo ancora testare se il compilato funziona... lunedì), ma mi pare una cosa inutile.

per le ottimizazioni linker time... non saprei! so che esiste la flag (recente, e quindi da prendere con le pinze) LTO che uso su arm.

Io attualemnte sto compilando tutto in un unico oggetto, quindi l'ottimizzazione è inclusa nella normale procedura di compilazione. giusto?

avr-gcc -g -std=c11 -mmcu=atmega32u4 -DF_CPU=16000000L -o test_bottone.elf test_bottone.o

Quella di sopra è l'invocazione implicita del linker attraverso il frontend avr-gcc.

  • -std non serve e in questa fase avr-gcc non ha come usarlo.
  • -g viene ignorato dal linker e in questa fase avr-gcc non ha come usarlo

Se vuoi passare argomenti al linker tramite il frontend devi specificare -Wl, prima dell'argomento, nota la virgola, occhio non lasciare spazio tra la virgola e l'argomento.

Nota che nella fase di collegamento implicitamente il linker inserisce la libreria libc.a.

Nella doc di Atmel e nongnu c'è scritto che la libreria libm.a deve essere sempre specificata nella fase di linkaggio. Io me ne dimentico sempre di inserirla nel file di progetto, potrei inserirla di default ma non funziona perché deve essere sempre l'ultima della lista.

perchè std=C11 è c++? a me non risulta: http://en.wikipedia.org/wiki/C11_(C_standard_revision)

Vero, ho letto c++11, svista fù.

LTO è ignorato su avr, credo perché non supportata dall'architettura.
Per l'ottimizzazione -Os (Optimize to size) ho controllato con avr-ld --help e il linker ha questo argomento. Quindi si dovrebbe aggiungere alla riga di comando:

-Wl,-Os

Fatto? :smiley:

Si fatto ma non cambia nulla la dimensione è sempre quella.

Ciao.

ah, ok, quindi di nascosto viene cmq linkato qualcosa, io pensavo che semplicemente "traducesse" l'oggeto in elf, quindi nessuna ottimizzazione fosse possibile.

grazie per questo "crash course" nelle opzioni avr, darò una sistematina e cercherò di riscrivere come makefile settimana che viene.

ah, ok, quindi di nascosto viene cmq linkato qualcosa, io pensavo che semplicemente "traducesse" l'oggeto in elf, quindi nessuna ottimizzazione fosse possibile.

Non ti sei preso il tempo per ragionarci su, bastavano 10 secondi. :wink:
printf & company fanno parte della avrlibc che come vedi non viene mai esplicitata nella lista delle lib. Per questo dicevo in altro post che la toolchain ARM è più complicata da usare rispetto a quella AVR che pensa a tutto le perfino gli script del linker.

Nota che ci sono più libc.a, una per architettura, avr2, avr3, avr4 ecc.
Il 644, 328 ecc appartengono alla arch avr5 e il linker sa in automatico a quale lib linkare in base al micro selezionato. Con precisione come faccia a saperlo il linker non lo so, cioè è vero che c'è l'argomento -mmcu=... che però non è un argomento del linker.

Dal mio punto di vista il linker trova scritto nel file .o l'architettura da usare. Tanto che se provi a linkare due .o di architettura differente va in errore.

Ciao.