Firmware flashen

Aus c't-Lab
Wechseln zu: Navigation, Suche

Flashen mit AVR-Studio

Eine gute Lösung ist der AVR ISP-MkII oder auch der AVR Dragon, beide mit USB-Anschluß. Sie arbeiten mit dem AVR-Studio ab V4.12 (Freeware von Atmel) zusammen. Mit dem AVR-Studio kann man den µC des jeweiligen c't-Lab-Moduls flashen, die Fuse-Bits setzen und alle Daten auch verifizieren.

Es sind die Fuses entsprechend der Anleitung zu setzen, sonst arbeiten die Schaltungen nicht!

AVR-Studio Fuses-Einstellungen

Nur folgende Einträge sind anzuhaken, alle anderen bleiben leer:

  • ? SPIEN - Serial programm downloading (SPI) enabled
  • x CKOPT
  • - BOOTSZ - Boot Flash size = 256 words start address=$3F00
  • - BODLEVEL - Brown-out detection at VCC=4.0 V
  • x BODEN - Brown-out detector enable
  • - SUT_CKSEL - Ext. Crystal/Resonator High Freq.:, Start-up time: 1k CK + 64ms

Zum Vergleich:

  • HIGH: 0xCF
  • LOW: 0x0F
Programmierkabel 
AVR DRAGON ISP(X1, 6polig)
ISP c't Lab Module (X2, 10polig)

X1           X2
Pin          Pin
1 -- MISO -- 9
2 -- VCC --- 2
3 -- SCK --- 7
4 -- MOSI -- 1
5 -- nRES -- 5
6 -- GND --- 4/6/8/10

Flashen mit PonyProg und Skript-Datei

Wenn man PonyProg verwendet, kann man dies auch mit einem Script erledigen.

Folgendes wird einfach in eine Textdatei mit der Endung *.e2s geschrieben.

(Die Datei bezieht sich auf das DCG in der 16-Bit variante. Bei anderen Modulen sind die beiden Dateien anzupassen)

#Programming sequence BEGIN
SELECTDEVICE ATMEGA32
CLEARBUFFER
LOAD-PROG DCG.hex  
LOAD-DATA DCG_16_2.eep
PAUSE "Connect and powerup the circuit, are you ready?"
ERASE-ALL
WRITE&VERIFY-ALL

#HIGH BYTE:{OCDEN,JTAGEN,SPI,CKOPT,EESAVE,BOOTSZ1,BOOTSZ0,BOOTRST}
#           0     0      1   1     0      0       0       0
#LOW  BYTE:{BODLEVEL,BODEN,SUT1,SUT0,CKSEL3,CKSEL2,CKSEL1,CKSEL0}
#           1        1     0    0    0      0      0      0"
WRITE-FUSE 0x30C0
#Programming sequence END

Achtung: Die Fusebits werden hier negiert gegenüber der Variante, die bei avrdude anzugeben ist, dargestellt! Die Zeile "WRITE-FUSE 0x30C0" weist darauf hin, dass HFUSE=0x30 und LFUSE=0xC0 sein soll. Bei Verwendung von avrdude muss aber 0xCF bzw. 0x3F als HFUSE und LFUSE angegeben werden. Der Grund dafür ist, dass die Fuse-Bits im gelöschten Zustand alle gleich "1" sind. Im geschriebenen Zustand (laut Datenblatt von Atmel ist dies der "aktive" Zustand) sind die Bits logisch "0". Es herrscht leider immer Verwirrung, ob ein Feature nun mit einer "0" oder mit einer "1" eingeschaltet wird. Dies ist vom verwendeten Flash-Programm abhängig. Das obige Beispiel arbeitet mit PonyProg korrekt, das untenstehende Beispiel mit avrdude ist ebenfalls in Ordnung und die AVR-Studio-Einstellungen sind sowieso selbsterklärend, weil dort vorgegebene Texte ausgewählt werden müssen. Wenn jemand die Einstellungen mit PonyProg in der grafischen Oberfläche macht, dann soll er bitte die Flash-Anleitung auf der c't-Lab-Seite genau beachten, dort gibt es auch einen Screenshot.

Flashen mit avrdude

Das Programm avrdude ist ein Kommandozeilenprogramm, welches für alle gängigen Betriebssysteme (Windows, Linux, MacOS) zur Verfügung steht. Avrdude arbeitet mit vielen Programmern zusammen, die Kommandozeilenoptionen sind aber auf den ersten Blick unübersichtlich (siehe Dokumentation). Daher will ich hier kurz beschreiben, wie man mit avrdude ein c't-Lab-Modul programmiert.

Wer sich mit den Fuse-Bits unsicher ist, der sollte sich einmal den Fuse Bits Calculator ansehen. Dort kann man alle Einstellungen ausprobieren und bekommt dann die Hexadezimalwerte geliefert, welche als Fuse-Byte-Einstellungen an avrdude übergeben werden müssen.

Der folgende Befehl schreibt das erste Fuse-Byte in einen ATmega32 unter Benutzung eines AVR-Dragon am USB-Port. Die Parameter geben den Controller-Typ ("-p m32" = ATmega32), die Bitrate ("-B10" - dies ist ein sicherer Wert, um auch Controller programmieren zu können, welche mit langsamem internen Takt laufen), den Programmieradapter ("-c dragon_ISP" = AVR-Dragon im ISP-Modus (wenn man den BlueMP3-ISP Adapter nimmt: stk200)) sowie den Port ("-P usb"(wenn man den BlueMP3-ISP Adapter nimmt: lpt1 unter Windows oder parport0 unter Linux, die Zahlen muessen unter Umstaenden noch angepasst werden)) an. Der eigentliche Schreibbefehl ("-U lfuse:w:0x3F:m") setzt sich aus dem Speichertyp ("lfuse"), der Aktion ("w" = Schreiben), dem Wert ("0x3F") und dem Typ der Daten ("m" bedeutet, dass der Wert direkt angegeben wurde; er könnte auch aus einer Datei gelesen werden) zusammen:

> avrdude -p m32 -B10 -c dragon_isp -P usb -U lfuse:w:0x3F:m 
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.16s avrdude: Device signature = 0x1e9502 avrdude: reading input file "0x3F" avrdude: writing lfuse (1 bytes): Writing | ################################################## | 100% 0.05s avrdude: 1 bytes of lfuse written avrdude: verifying lfuse memory against 0x3F: avrdude: load data lfuse data from input file 0x3F: avrdude: input file 0x3F contains 1 bytes avrdude: reading on-chip lfuse data: Reading | ################################################## | 100% 0.05s avrdude: verifying ... avrdude: 1 bytes of lfuse verified avrdude: safemode: Fuses OK avrdude done. Thank you.

Der nächste Befehl schreibt das zweite Fuse-Byte eines ATmega32. Der einzige Unterschied zum letzten Befehl ist, dass jetzt "hfuse" mit "0xCF" beschrieben werden soll:

> avrdude -p m32 -B10 -c dragon_isp -P usb -U hfuse:w:0xCF:m
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.16s avrdude: Device signature = 0x1e9502 avrdude: reading input file "0xCF" avrdude: writing hfuse (1 bytes): Writing | ################################################## | 100% 0.05s avrdude: 1 bytes of hfuse written avrdude: verifying hfuse memory against 0xCF: avrdude: load data hfuse data from input file 0xCF: avrdude: input file 0xCF contains 1 bytes avrdude: reading on-chip hfuse data: Reading | ################################################## | 100% 0.05s avrdude: verifying ... avrdude: 1 bytes of hfuse verified avrdude: safemode: Fuses OK avrdude done. Thank you.

Dieser Befehl schreibt die Datei "DDS.hex" in den Flash-ROM. In den Speicherbereich "flash" wird die Datei "DDS.hex" geschrieben. Der Parameter "i" gibt an, dass die Datei im Intel-Hex-Format vorliegt:

> avrdude -p m32 -B10 -c dragon_isp -P usb -U flash:w:DDS.hex:i
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.15s avrdude: Device signature = 0x1e9502 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "DDS.hex" avrdude: writing flash (24508 bytes): Writing | ################################################## | 100% 20.73s avrdude: 24508 bytes of flash written avrdude: verifying flash memory against DDS.hex: avrdude: load data flash data from input file DDS.hex: avrdude: input file DDS.hex contains 24508 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 15.13s avrdude: verifying ... avrdude: 24508 bytes of flash verified avrdude: safemode: Fuses OK avrdude done. Thank you.

Der letzte Befehl schreibt schließlich die Datei "DDS.eep" in den EEPROM eines ATmega32:

> avrdude -p m32 -B10 -c dragon_isp -P usb -U eeprom:w:DDS.eep:i
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.15s avrdude: Device signature = 0x1e9502 avrdude: reading input file "DDS.eep" avrdude: writing eeprom (186 bytes): Writing | ################################################## | 100% 4.17s avrdude: 186 bytes of eeprom written avrdude: verifying eeprom memory against DDS.eep: avrdude: load data eeprom data from input file DDS.eep: avrdude: input file DDS.eep contains 186 bytes avrdude: reading on-chip eeprom data: Reading | ################################################## | 100% 0.19s avrdude: verifying ... avrdude: 186 bytes of eeprom verified avrdude: safemode: Fuses OK avrdude done. Thank you.

Man kann die Befehle natürlich auch zusammenfassen und alles (Fuses, Flash EEPROM) auf einmal flashen (hier am Beispiel für das DIV, Achtung: Zeilenumbruch beim Ausführen entfernen!):

> avrdude -p m32 -B10 -c dragon_isp -P usb -U lfuse:w:0x3F:m -U hfuse:w:0xCF:m 
    -U flash:w:DIV.hex:i -U eeprom:w:DIV.eep:i
avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.15s avrdude: Device signature = 0x1e9502 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "0x3F" avrdude: writing lfuse (1 bytes): Writing | ################################################## | 100% 0.05s avrdude: 1 bytes of lfuse written avrdude: verifying lfuse memory against 0x3F: avrdude: load data lfuse data from input file 0x3F: avrdude: input file 0x3F contains 1 bytes avrdude: reading on-chip lfuse data: Reading | ################################################## | 100% 0.05s avrdude: verifying ... avrdude: 1 bytes of lfuse verified avrdude: reading input file "0xCF" avrdude: writing hfuse (1 bytes): Writing | ################################################## | 100% 0.05s avrdude: 1 bytes of hfuse written avrdude: verifying hfuse memory against 0xCF: avrdude: load data hfuse data from input file 0xCF: avrdude: input file 0xCF contains 1 bytes avrdude: reading on-chip hfuse data: Reading | ################################################## | 100% 0.05s avrdude: verifying ... avrdude: 1 bytes of hfuse verified avrdude: reading input file "DIV.hex" avrdude: writing flash (20606 bytes): Writing | ################################################## | 100% 18.41s avrdude: 20606 bytes of flash written avrdude: verifying flash memory against DIV.hex: avrdude: load data flash data from input file DIV.hex: avrdude: input file DIV.hex contains 20606 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 13.82s avrdude: verifying ... avrdude: 20606 bytes of flash verified avrdude: reading input file "DIV.eep" avrdude: writing eeprom (398 bytes): Writing | ################################################## | 100% 8.70s avrdude: 398 bytes of eeprom written avrdude: verifying eeprom memory against DIV.eep: avrdude: load data eeprom data from input file DIV.eep: avrdude: input file DIV.eep contains 398 bytes avrdude: reading on-chip eeprom data: Reading | ################################################## | 100% 0.34s avrdude: verifying ... avrdude: 398 bytes of eeprom verified avrdude: safemode: Fuses OK avrdude done. Thank you.

Alternativer Programmieradapter

BlueMP3-ISP

http://www.heise.de/ct/projekte/machmit/ctlab/wiki/FirmwareFlashen


AvrUsb500

Nach dieser Vorlage läßt sich recht einfach ein Programmieradapter in 'Fädeltechnik' aufbauen. Die originale Schaltung wurde modifiziert. Anstatt des FT232BL kam ein FT232RL zum Einsatz. Der IO-Pegel bzw. die Versorgungsspannung läßt sich per Jumper auf 3,3V oder 5V einstellen. Der Adapter ist Stk500 kompatibel und kann daher direkt aus dem AVR-Studio angesprochen werden.

Avrusb.jpg