Non ho tempo per una spiegazione completa, ma posso darti in stile libro di cucina i comandi che uso sulla mia macchina Linux per programmare gli AVR:
Preparativi
- Su Ubuntu, assicurati che siano installati diversi pacchetti richiesti:
sudo apt-get install avr-libc avrdude binutils-avr gcc-avr srecord
facoltativamente inseriregdb-avr simulavr
per il debug e la simulazione. - Ho iniziato a creare una directory in cui tutti i miei progetti ATtiny trovano casa:
mkdir ~/attiny: cd ~/attiny
- Per ogni progetto creo una sottocartella dedicata (e non mi dispiace i nomi lunghi):
mkdir waveShare4digit8segmentDisplay; cd waveShare4digit8segmentDisplay
Crea fonte
- Modifica il file sorgente con il tuo editor di testo preferito:
vi project.cpp
Impostazioni
I comandi seguenti si basano fortemente sulle variabili di ambiente, per semplificare la manutenzione.
- Il nome di base dei file utilizzati/creati:
src=project
- Flag comuni del compilatore:
cflags="-g -DF_CPU=${avrFreq} -Wall -Os - Werror -Wextra"
Potrebbe essere necessario modificare le variabili seguenti a seconda dell'esatto programmatore utilizzato. Fare riferimento al man
pagine per i dettagli.
baud=19200
Il baudrate a cui il tuo programmatore comunica con il PC:programmerDev=/dev/ttyUSB003
Il nome del dispositivo in cui si trova il programmatore. Selezionadmesg
output per i dettagli.programmerType=avrisp
Questo potrebbe essere diverso per il tuo esatto programmatore.
Le variabili seguenti dipendono dall'esatto controller che vuoi programmare:
avrType=attiny2313
Selezionaavrdude -c $programmerType
per i dispositivi supportati.avrFreq=1000000
Controlla la scheda tecnica del controller per l'orologio predefinito.
Compila
- Il primo passo è creare un file oggetto:
avr-gcc ${cflags) -mmcu=${avrType) -Wa,-ahlmns=${src).lst -c -o ${src).o ${src).cpp
- Il secondo passo è creare un file ELF:
avr-gcc ${cflags) -mmcu=${avrType) -o ${src).elf ${src).o
- Il terzo passo è creare un file Intel Hex, questo è il file che viene effettivamente inviato al programmatore:
avr-objcopy -j .text -j .data -O ihex ${src).elf ${src).flash.hex
Programmazione
- Il passaggio finale è programmare il dispositivo:
avrdude -p${avrType} -c${programmerType} -P${programmerDev} -b${baud} -v -U flash:w:${src}.flash.hex
Makefile
In alternativa a ricordare i comandi, ho creato un makefile di mio gradimento personale, puoi salvarlo con il nome Makefile
(attenzione al M
maiuscolo ). Funziona come segue:
make makefile
Modifica il makefile;make edit
Modifica il file sorgente;make flash
Programma la memoria flash del dispositivo;make help
Elenca altri comandi.
Ecco il makefile:
baud=19200
src=project
avrType=attiny2313
avrFreq=4000000 # 4MHz for accurate baudrate timing
programmerDev=/dev/ttyUSB003
programmerType=arduino
cflags=-g -DF_CPU=$(avrFreq) -Wall -Os -Werror -Wextra
memoryTypes=calibration eeprom efuse flash fuse hfuse lfuse lock signature application apptable boot prodsig usersig
.PHONY: backup clean disassemble dumpelf edit eeprom elf flash fuses help hex makefile object program
help:
@echo 'backup Read all known memory types from controller and write it into a file. Available memory types: $(memoryTypes)'
@echo 'clean Delete automatically created files.'
@echo 'disassemble Compile source code, then disassemble object file to mnemonics.'
@echo 'dumpelf Dump the contents of the .elf file. Useful for information purposes only.'
@echo 'edit Edit the .cpp source file.'
@echo 'eeprom Extract EEPROM data from .elf file and program the device with it.'
@echo 'elf Create $(src).elf'
@echo 'flash Program $(src).hex to controller flash memory.'
@echo 'fuses Extract FUSES data from .elf file and program the device with it.'
@echo 'help Show this text.'
@echo 'hex Create all hex files for flash, eeprom and fuses.'
@echo 'object Create $(src).o'
@echo 'program Do all programming to controller.'
edit:
vi $(src).cpp
makefile:
vi Makefile
#all: object elf hex
clean:
rm $(src).elf $(src).eeprom.hex $(src).fuses.hex $(src).lfuse.hex $(src).hfuse.hex $(src).efuse.hex $(src).flash.hex $(src).o
date
object:
avr-gcc $(cflags) -mmcu=$(avrType) -Wa,-ahlmns=$(src).lst -c -o $(src).o $(src).cpp
elf: object
avr-gcc $(cflags) -mmcu=$(avrType) -o $(src).elf $(src).o
chmod a-x $(src).elf 2>&1
hex: elf
avr-objcopy -j .text -j .data -O ihex $(src).elf $(src).flash.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex $(src).elf $(src).eeprom.hex
avr-objcopy -j .fuse -O ihex $(src).elf $(src).fuses.hex --change-section-lma .fuse=0
srec_cat $(src).fuses.hex -Intel -crop 0x00 0x01 -offset 0x00 -O $(src).lfuse.hex -Intel
srec_cat $(src).fuses.hex -Intel -crop 0x01 0x02 -offset -0x01 -O $(src).hfuse.hex -Intel
srec_cat $(src).fuses.hex -Intel -crop 0x02 0x03 -offset -0x02 -O $(src).efuse.hex -Intel
disassemble: elf
avr-objdump -s -j .fuse $(src).elf
avr-objdump -C -d $(src).elf 2>&1
eeprom: hex
#avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
date
fuses: hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U lfuse:w:$(src).lfuse.hex
#avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U hfuse:w:$(src).hfuse.hex
#avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U efuse:w:$(src).efuse.hex
date
dumpelf: elf
avr-objdump -s -h $(src).elf
program: flash eeprom fuses
flash: hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U flash:w:$(src).flash.hex
date
backup:
@for memory in $(memoryTypes); do \
avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
done
Potrebbe sembrare necessario eseguire avrdude
come root
, se ciò accade, giustifica una domanda a sé stante . Può essere risolto con udev
ma richiede informazioni un po' specifiche su come il programmatore viene riconosciuto dal sistema operativo.
Ciao mondo
Consentitemi di inserire un "Hello World" che fa commutare un controller pin 2 (PB3) (ad es. ATtiny13, ATtiny45, ATtiny85) a 1Hz. Collega un LED e un resistore in serie al pin e il LED dovrebbe iniziare a lampeggiare.
- apporta modifiche
i
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = 0x08;
while (1) {
PORTB = 0x00; _delay_ms(500);
PORTB = 0x08; _delay_ms(500);
}
}
<ESC>:wq
- crea flash
Fatto.
È possibile utilizzare gli strumenti AVR GNU come pacchetti autonomi in Linux. Questi includono avr-gcc, avr-binutils e avr-libc. Questo è ciò che viene chiamato toolchain.
Dopo aver creato un file esadecimale e desideri installarlo sul tuo chip, puoi utilizzare avrdude.
Tutti questi sono liberamente e prontamente disponibili su Linux e non troppo difficili da configurare per lavorare insieme.
LadyAda ha un solido tutorial passo dopo passo sull'intero processo.