Hallo,
ich arbeite gerade an einem Bootloader auf Basis des Artikels
AVR Bootloader in C - eine einfache Anleitung für einen ATMega168A.
Die Fuses habe ich dabei so gesetzt, dass der Bootloader 1024 Words groß
sein darf (1024W_1C00), und der Boot Reset Vektor aktiv ist (BOOTRST).
Außerdem habe ich über das Linker Flag "-Ttext=0x3800" dafür gesorgt,
dass der Bootloader korrekt platziert wird.
Es funktioniert auch, und der Bootloader startet. Leider kann ich ihn
nicht über DebugWire und AVR Dragon debuggen, das Debugging läuft zwar
an, aber ich kann keine Breakpoints setzen und lande stets im
"Dissassembly" - es finde keine Verknüpfung mit dem Quellcode statt,
obwohl jegliche Optimierungen deaktiviert sind. Flashe ich ein reguläres
Programm (ab 0x00) funktioniert das Debugging. Habt ihr eine Idee woran
das liegen kann?
Der Bootloader wird per USART "gefüttert". Er nimmt das 7742 byte große
Anwendungsprogramm entgegen, aber schreibt nichts Vernünftiges. Im
angehängten Bild sieht man links den Flashspeicher der nur den
Bootloader enthält, rechts den Speicher nach dem Flashen der Anwendung.
Die ausgeschnittene Stelle ist der einzige Unterschied - enthält
natürlich viel zu wenig Daten und fängt zu spät an, oder?
Um dem Problem auf die Schliche zu kommen habe ich die Funktion
boot_program_page angepasst, damit meine Clientsoftware sie auswerten
kann. Sie überträgt die Seitennummer, Seitengröße (SPM_PAGESIZE = 128)
und nacheinander alle Bytes des zu schreibenden Puffers.
Die Daten nehme ich in meinem Anwendungsprogramm entgegen und werte sie
aus. Den Daten entnehme ich, dass die Seiten 0 bis 60 sauber beschrieben
werden. Hier das Ergebnis der ersten beiden Seiten:
1 | [LOG] Writing page 000 (0000 - 007F)
|
2 | [LOG] 0000: 0C 94 4F 00 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00
|
3 | [LOG] 0010: 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00
|
4 | [LOG] 0020: 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00
|
5 | [LOG] 0030: 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00
|
6 | [LOG] 0040: 0C 94 6C 00 0C 94 6C 00 0C 94 6F 08 0C 94 6C 00
|
7 | [LOG] 0050: 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00 0C 94 6C 00
|
8 | [LOG] 0060: 0C 94 6C 00 0C 94 6C 00 54 45 53 54 00 53 68 75
|
9 | [LOG] 0070: 74 74 69 6E 67 20 64 6F 77 6E 2E 2E 2E 00 53 68
|
10 | [LOG] Writing page 001 (0080 - 00FF)
|
11 | [LOG] 0080: 75 74 64 6F 77 6E 20 63 6F 6D 70 6C 65 74 65 00
|
12 | [LOG] 0090: 43 6F 6E 6E 65 63 74 69 6E 67 2E 2E 2E 00 11 24
|
13 | [LOG] 00A0: 1F BE CF EF D4 E0 DE BF CD BF 11 E0 A0 E0 B1 E0
|
14 | [LOG] 00B0: E6 E3 FE E1 02 C0 05 90 0A 92 A8 30 B1 07 D9 F7
|
15 | [LOG] 00C0: 23 E0 A8 E0 B1 E0 01 C0 1D 92 A1 3F B2 07 E1 F7
|
16 | [LOG] 00D0: 0E 94 01 0B 0C 94 19 0F 0C 94 00 00 40 9A 08 95
|
17 | [LOG] 00E0: 8F 92 9F 92 AF 92 BF 92 CF 92 DF 92 EF 92 FF 92
|
18 | [LOG] 00F0: 0F 93 1F 93 CF 93 DF 93 EC 01 8B 01 5A 01 CB 01
|
Die Funktion wird also offenbar korrekt benutzt. Doch wenn ich sie
wieder durch den Originalcode aus dem Artikel ersetze, bekomme ich den
Datenmüll wie oben beschrieben.
Habt ihr eine Idee woran das liegen kann? Was mich stutzig macht, ist
wie im Artikel die Seite berechnet wird:
1 | flash_page = hex_addr - hex_addr % SPM_PAGESIZE;
|
Damit würde ich bei Adresse 0x100 und 128 Byte Seitengröße auf Seite 256
kommen, obwohl dies eigentlich Seite 2 sein müsste (bzw. die 3. Seite,
wenn ab 0 gezählt wird). Habe ich die vielleicht einen Denkfehler?
Die ersten Zeilen des .hex Files des Anwendungsprogramms:
1 | :100000000C944F000C946C000C946C000C946C00DD
|
2 | :100010000C946C000C946C000C946C000C946C00B0
|
3 | :100020000C946C000C946C000C946C000C946C00A0
|
4 | :100030000C946C000C946C000C946C000C946C0090
|
5 | :100040000C946C000C946C000C946F080C946C0075
|
6 | :100050000C946C000C946C000C946C000C946C0070
|
7 | :100060000C946C000C946C00544553540053687508
|
8 | :100070007474696E6720646F776E2E2E2E0053683D
|
9 | :100080007574646F776E20636F6D706C6574650056
|
10 | :10009000436F6E6E656374696E672E2E2E00112499
|
11 | :1000A0001FBECFEFD4E0DEBFCDBF11E0A0E0B1E0D6
|
12 | :1000B000E6E3FEE102C005900D92A830B107D9F742
|
Vielen Dank im Voraus!