Bei der Umstellung und Erweiterung des optiboot Bootloaders bin ich auf ein seltsames Verhalten des Programms avrdude aufmerksam geworden. Die Adresse der zu beschreibenden EEproms wird bei einem ATmega8 anders übermitteelt als beim ATmega328. Hier ist der Mitschnitt der Kommunikation von avrdude für einen mega8: > /dev/ttyUSB3 55 00 00 20 U.. # ^^ < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 48 65 6C 6C 20 d..EHell < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 04 00 20 U.. # ^^ < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 6F 20 57 6F 20 d..Eo Wo < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 08 00 20 U.. # ^^ < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 72 6C 64 20 20 d..Erld < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 0C 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 66 72 6F 6D 20 d..Efrom < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 10 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 20 45 45 70 20 d..E EEp < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 14 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 72 6F 6D 21 20 d..Erom! < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 18 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 00 FF FF FF 20 d..E.... < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 00 00 20 U.. ...... < /dev/ttyUSB4 0A 0D .. < /dev/ttyUSB4 57 61 74 63 68 2D 64 6F 67 20 49 6E 74 65 72 72 Watch-dog Interr 75 70 74 0A 0D upt.. < /dev/ttyUSB4 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 66 72 6F 6D Hello World from 20 46 6C 61 73 68 21 0A 0D Flash!.. < /dev/ttyUSB4 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 66 72 6F 6D Hello World from 20 45 45 70 72 6F 6D 21 0A 0D EEprom!.. < /dev/ttyUSB4 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 77 69 74 68 Hello World with 20 73 74 72 69 6E 67 21 0A 0D string!.. Die entsprechende Stelle der Adresse habe ich mit der # ^^ Zeile gekennzeichnet. Hier werden immer 4 Bytes blockweise übermittelt und die Adresse ist eine Byte Adresse! Jetzt die Übermittelung der gleichen Daten für einen mega328: > /dev/ttyUSB3 55 00 00 20 U.. # ^^ < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 48 65 6C 6C 20 d..EHell < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 02 00 20 U.. # ^^ < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 6F 20 57 6F 20 d..Eo Wo < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 04 00 20 U.. # ^^ < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 72 6C 64 20 20 d..Erld < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 06 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 66 72 6F 6D 20 d..Efrom < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 08 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 20 45 45 70 20 d..E EEp < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 0A 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 72 6F 6D 21 20 d..Erom! < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 0C 00 20 U.. < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 64 00 04 45 00 FF FF FF 20 d..E.... < /dev/ttyUSB4 14 10 .. > /dev/ttyUSB3 55 00 00 20 U.. ...... < /dev/ttyUSB4 0A 0D .. < /dev/ttyUSB4 57 61 74 63 68 2D 64 6F 67 20 49 6E 74 65 72 72 Watch-dog Interr 75 70 74 0A 0D upt.. < /dev/ttyUSB4 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 66 72 6F 6D Hello World from 20 46 6C 61 73 68 21 0A 0D Flash!.. < /dev/ttyUSB4 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 66 72 6F 6D Hello World from 20 45 45 70 72 6F 6D 21 0A 0D EEprom!.. < /dev/ttyUSB4 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 77 69 74 68 Hello World with 20 73 74 72 69 6E 67 21 0A 0D string!.. Hier werden genau wie beim Mega8 die EEprom Daten als 4-Byte Block übertragen, die Adresse steigt aber nur um den Wert 2!!! Es wird hier also wie bei den Flash-Daten eine Wortadresse übermittelt. Nun meine Frage dazu: Für welche Prozessoren gilt die Byte-Adresse und für welche die Wort-Adresse? Leider habe ich keinen ATmega16 und ATmega32 zur Verfügung, um meine Vermutung zu bestätigen, dass für diese beiden Prozessoren auch die Byte-Adresse gilt wie für den Mega8. Die aktuelle Version meiner optiboot Assembler-Version ist derzeit auf dem SVN Archiv des Transistortester-Projekts im Unterverzeichnis bootloaders/optiboot geparkt. Eine PDF Dokumentation ist im Unterverzeichnis bootloaders/Doku/german (bootloader.pdf) in Deutsch und im Unterverzeichnis bootloaders/Doku/english in Englisch zu finden. Da die Anpassung an die verschiedenen Architekturen, Flashgrößen automatisch erfolgt, ist ein Linux-System oder das Vorhandensein entsprechender Programmwerkzeuge (bc, cat, cut, echo, grep und tr) Voraussetzung.
Mit deinen „Bytewürsten“ (;-) kann ich gerade nicht so viel anfangen. Was für einen programmer type (-c) benutzt du denn? Kannst du AVRDUDE mal mit -vvvv starten und dann die relevanten Teile hier zitieren (also die beiden Stellen, an denen der EEPROM jeweils adressiert wird)? p.s.: Habe noch schnell nachgesehen, die EEPROM pagesize ist sowohl beim ATmega8 als auch ATmega328 gleich 4.
:
Bearbeitet durch Moderator
Jörg W. schrieb: > Was für einen programmer type (-c) benutzt du denn? Es handelt sich hier um den seriellen Download. Auf dem ATmega ist die Assembler-Version des Optiboot Bootloaders installiert. Als Programmer-Typ wird arduino und als Port /dev/ttyACM0 oder /dev/ttyUSB0 verwendet. Die serielle Schnittstelle wird von einem USB-seriell Wandler angesteuert. In diesem Fall hier mit der Baudrate 19200. Ein Ausschnitt Protokoll von avrdude für den ATmega8: avrdude: writing eeprom (25 bytes):
1 | Writing | | 0% 0.00savrdude: Send: U [55] . [00] . [00] [20] |
2 | avrdude: Recv: . [14] |
3 | avrdude: Recv: . [10] |
4 | avrdude: Send: d [64] . [00] . [04] E [45] H [48] e [65] l [6c] l [6c] [20] |
5 | avrdude: Recv: . [14] |
6 | avrdude: Recv: . [10] |
7 | Writing | ####### | 14% 0.04savrdude: Send: U [55] . [04] . [00] [20] |
8 | avrdude: Recv: . [14] |
9 | avrdude: Recv: . [10] |
10 | avrdude: Send: d [64] . [00] . [04] E [45] o [6f] [20] W [57] o [6f] [20] |
11 | avrdude: Recv: . [14] |
12 | avrdude: Recv: . [10] |
13 | Writing | ############## |
Für den ATmega328:
1 | avrdude: writing eeprom (25 bytes): |
2 | |
3 | Writing | | 0% 0.00savrdude: Send: U [55] . [00] . [00] [20] |
4 | avrdude: Recv: . [14] |
5 | avrdude: Recv: . [10] |
6 | avrdude: Send: d [64] . [00] . [04] E [45] H [48] e [65] l [6c] l [6c] [20] |
7 | avrdude: Recv: . [14] |
8 | avrdude: Recv: . [10] |
9 | Writing | ####### | 14% 0.02savrdude: Send: U [55] . [02] . [00] [20] |
10 | avrdude: Recv: . [14] |
11 | avrdude: Recv: . [10] |
12 | avrdude: Send: d [64] . [00] . [04] E [45] o [6f] [20] W [57] o [6f] [20] |
13 | avrdude: Recv: . [14] |
14 | avrdude: Recv: . [10] |
15 | Writing | ############## | 28% 0.04savrdude: Send: U [55] . [04] . [00] [20] |
Die Memory Details für den ATmega8:
1 | Block Poll Page Polled |
2 | Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack |
3 | ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- |
4 | eeprom 4 20 128 0 no 512 4 0 9000 9000 0xff 0xff |
und für den ATmega328p
1 | Block Poll Page Polled |
2 | Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack |
3 | ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- |
4 | eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff |
Auch hier sieht man wieder das unterschiedliche Verhalten des avrdude. Beim Mega8 steigen die Byteaddressen um 4, beim Mega328p um 2 ! Ich habe das optiboot Programm entsprechend angepasst, deswegen laufen beide Testprogramme, wie man aus dem 1. Protokoll entnehmen kann (Ausgabe Hallo World from EEprom!). Das erste Protokoll habe ich mit zwei separaten USB-seriell Wandlern mitgeschrieben, die jeweils an TX und RX angeschlossen waren.
:
Bearbeitet durch Moderator
Hmpf, das ist hornalter STK500v1-Code. Den habe ich nie selbst angefasst, davon habe ich schlicht keine Ahnung. Arduino und Optiboot dürften die letzten sein, die dieses Relikt aus dem vorigen Jahrtausend noch benutzen. Alle anderen sind mal irgendwann auf STK500v2 gegangen. Der Dreh- und Angelpunkt dürfte das hier sein:
1 | if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO])) |
2 | a_div = 2; |
3 | else
|
4 | a_div = 1; |
5 | |
6 | // ...
|
7 | for (; addr < n; addr += block_size) { |
8 | // MIB510 uses fixed blocks size of 256 bytes
|
9 | if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) { |
10 | block_size = 256; |
11 | } else { |
12 | if (n - addr < page_size) |
13 | block_size = n - addr; |
14 | else
|
15 | block_size = page_size; |
16 | }
|
17 | // ...
|
18 | stk500_loadaddr(pgm, m, addr/a_div); |
page_size ist 4, das ist zugleich der Erhöhungsschritt für jede Iteration. Wenn eine der beiden obigen Operationen (Loadpage Lo oder Read Lo) definiert ist für den Speicherbereich, dann wird nur die halbe Adresse ausgegeben. Ich vermute, dass die Halbierung der Adresse für das Beschreiben des Flashs erforderlich ist. Brian Deans Logeintrag für die entsprechenden Revisions ist recht allgemein:
1 | r162 | bsd | 2002-12-01 16:05:56 +0100 (Sun, 01 Dec 2002) | 4 lines |
2 | |
3 | The STK500 can perform paged read/write operations even on standard |
4 | "non-paged" parts. Take advantage of that and use the faster internal |
5 | routines of the STK500 for those parts as well. |
6 | |
7 | r161 | bsd | 2002-12-01 07:35:18 +0100 (Sun, 01 Dec 2002) | 8 lines |
8 | |
9 | Optimize reading and writing for the STK500 programmer if the part |
10 | supports paged reads and writes. This greatly decreases the |
11 | program/verify time from about 4.5 minutes down to about 10 seconds in |
12 | a 12K program size test case. |
13 | |
14 | Print out the hardware and firmware version for the STK500 if verbose |
15 | is enabled. |
Man müsste die Unterscheidung zwischen Flash und EEPROM wohl besser anhand des Namens des Speicherbereichs vornehmen. Das passiert etwas weiter oben ohnehin schon:
1 | if (strcmp(m->desc, "flash") == 0) { |
2 | memtype = 'F'; |
3 | }
|
4 | else if (strcmp(m->desc, "eeprom") == 0) { |
5 | memtype = 'E'; |
6 | }
|
7 | else { |
8 | return -2; |
9 | }
|
Das könnte man dann auch gleich so zusammenfassen:
1 | if (strcmp(m->desc, "flash") == 0) { |
2 | memtype = 'F'; |
3 | a_div = 2; |
4 | }
|
5 | else if (strcmp(m->desc, "eeprom") == 0) { |
6 | memtype = 'E'; |
7 | a_div = 1; |
8 | }
|
9 | else { |
10 | return -2; |
11 | }
|
Bitte eröffne mal einen Bugreport: https://savannah.nongnu.org/bugs/?func=additem&group=avrdude Ich würde den dann als Anlass nehmen, mit Brian mal das, was ich hier geschrieben habe, zu diskutieren.
Jörg W. schrieb: > Bitte eröffne mal einen Bugreport: Das habe ich hier gemacht: https://savannah.nongnu.org/bugs/?48131
Danke, ich habe den Report mal an Brian Dean weitergereicht (und ihm noch privat eine Mail dazu als Erläuterung geschrieben).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.