Hallo zusammen,
nachdem ich vergeblich versucht habe den DFU-Bootloader so abzuspecken,
dass man ihn auch mit AVR-GCC kompilieren kann damit er in den 4KB
Bootbereich des Xmega32A4U passt (weniger als 6K schafft man
offensichtlich mit avr-gcc nicht), habe ich einen anderen Weg gefunden
den Boot-Port für meine Ansprüche anzupassen und zwar ohne den
IAR-Compiler zu verwenden.
Dafür habe ich einfach mit objdump mit den Assembler-Code des Hex-Files
ausspucken lassen und dank des mitgelieferten Quellcodes auch schnell
die paar Werte gefunden um den Port und Portpin der den Bootloader
aktiviert (standardmäßig PC3 beim Atxmega32a4u) anzupassen. Prinzipiell
geht das bei jedem DFU-Bootloader binary.
Nachdem man sich Paket mit dem DFU 1.04 von der Atmel Seite
runtergeladen hat läd man einfach das passende Hex-File im Editor.
Parallel dazu sollte man das µC-Spezifische Datenblatt öffnen und im
Kapitel "Peripheral Module Address Map" nachschauen wie die Adresse des
gewünschten Ports ist. Die Adresse des vom Bootloader vorgesehen Ports
variiert je nach Xmega:
XMEGA_A1U: PORTF PIN 0
XMEGA_A3U, XMEGA_A3BU, XMEGA_C3: PORTE PIN 5
XMEGA_A4U, XMEGA_C4: PORTC PIN 3
XMEGA_B PORTC: PIN 6
Oder man schaut einfach direkt iox*.h File nach.
Die Hex-Files zwischen den verschiedenen Xmegas unterscheiden sich
natürlich etwas, aber über objdump bekommt kommt man schnell die
gewünschte Position, da die Abfragen immer gleich sind:
1 | 8000: 00 c0 rjmp .+0
|
2 | 8002: 00 91 78 00 lds r16, 0x0078
|
3 | 8006: 05 fd sbrc r16, 5
|
4 | 8008: 6a c0 rjmp .+212
|
5 | 800a: f0 92 00 06 sts 0x0640, r15 ; PORTC_DIR
|
6 | 800e: 08 e1 ldi r16, 0x18
|
7 | 8010: 00 93 12 06 sts 0x0653, r16 ; PORTC.PIN3CTRL
|
8 | 8014: 0f ef ldi r16, 0xFF
|
9 | 8016: 0a 95 dec r16
|
10 | 8018: 00 23 and r16, r16
|
11 | 801a: e9 f7 brne .-6
|
12 | 801c: 00 91 08 06 lds r16, 0x0648 ; PORTC.IN
|
13 | 8020: 02 ff sbrs r16, 3 ; PIN3
|
Nun ändert man die Adresse des Ports (bzw. PortRegister) im Hexfile ab.
Es sind genau 3 Adressen (PORT-Adresse, PORT-CTRL, PORT.IN) und eine
Pin-Nummer die angepasst werden müssen. Glücklicherweise befinden sie
sich alle in den ersten 4-Zeilen des Hex-Files.
Da jeder Port immer einen Offset von 0x20 zum nächsten hat ist es recht
einfach.
Für den Atxmega32a4u bei dem der Default-Port PORTC.3 und man ihn auf
PORTA.2 ändern will sieht das so aus:
1 | Vorher Adresse | Nachher Adresse
|
2 | PORTC_DIR 0x640 | PORTA_DIR 0x600
|
3 | PORTC_IN 0x648 | PORTA_IN 0x608
|
4 | PORTC_PIN3CTRL 0x653 | PORTC_PIN2CTRL 0x612
|
Die entsprechenden Adressen können direkt ins iHex eingetragen werden
(achtung Big-Endian, also Bytes verdrehen)
Hier das Original Hex-File:
1 | :020000020000FC
|
2 | :1080000000C00091780005FD6AC0F092400608E1CA
|
3 | ^^^^-> PORTC_DIR = 0x0640
|
4 | :10801000009353060FEF0A950023E9F700914806F5
|
5 | ^^^^-> PORTC_PIN3CTRL ^^^^-> PORTC_IN = 0x0648
|
6 | :1080200003FFECC0E0E0F0E0079116910F3F19F478
|
7 | ^^-> PIN3
|
und hier die geänderte Version für PORTA.2
1 | :020000020000FC
|
2 | :1080000000C00091780005FD6AC0F092000608E10A
|
3 | ^^^^-> PORTA_DIR = 0x0600
|
4 | :10801000009312060FEF0A950023E9F70091080676
|
5 | ^^^^-> PORTA_PIN2CTRL ^^^^-> PORTA_IN = 0x0608
|
6 | :1080200002FFECC0E0E0F0E0079116910F3F19F479
|
7 | ^^-> PIN2
|
Natürlich muss noch jeweils am Ende jeder Zeite die Checksumme neu
berechnet werden. Das kann man am einfachsten machen indem man das
geänderte Hex-File einfach mit obj-dump läd, das sagt einem dann welche
Checksumme erwartet wird (leider in Dez, muss also noch in Hex
umgerechnet werden). Also z.B. "obj-dump -D -m avr c:\boot_neu.hex"
Vielleicht hilft's ja noch jemanden.