Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Hallo,
ich versuche gerade, diesen Bootloader
http://www.mikrocontroller.net/articles/AVR_Bootlo...
auf meinem ATmega168 zum Laufen zu bringen.
Ich hänge allerdings schon am "Hallo Welt" - Bootloader fest. Dieser
funktioniert zwar einigermaßen, wenn ich ihn an Adresse 0x0000 schreibe,
aber wenn ich ihn an die Bootloader-Adresse 0x3800(mithilfe der
Linker-Option -Ttext=0x3800) schreibe, passiert nichts.
Hier nochmal der Code:
#include<avr/io.h>#include<avr/interrupt.h>#include<avr/boot.h>#include<util/delay.h>#include"uart.h"#ifndef F_CPU
#define F_CPU 20000000UL
#endif#define BOOT_UART_BAUD_RATE 9600/* Baudrate */#define XON 17/* XON Zeichen */#define XOFF 19/* XOFF Zeichen */int main()
{
unsignedint c=0; /* Empfangenes Zeichen + Statuscode */unsignedchar temp, /* Variable */
flag=1, /* Flag zum steuern der Endlosschleife */
p_mode=0; /* Flag zum steuern des Programmiermodus */void (*start)( void ) = 0x0000; /* Funktionspointer auf 0x0000 *//* Interrupt Vektoren verbiegen */char sregtemp = SREG;
cli();
temp = MCUCR;
MCUCR = temp | (1<<IVCE);
MCUCR = temp | (1<<IVSEL);
SREG = sregtemp;
/* Einstellen der Baudrate und aktivieren der Interrupts */
uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );
sei();
uart_puts("Hallo hier ist der Bootloader\n\r");
_delay_ms(1000);
do
{
c = uart_getc();
if( !(c & UART_NO_DATA) )
{
switch((unsignedchar)c)
{
case'q':
flag=0;
uart_puts("Verlasse den Bootloader!\n\r");
break;
default:
uart_puts("Du hast folgendes Zeichen gesendet: ");
uart_putc((unsignedchar)c);
uart_puts("\n\r");
break;
}
}
}
while(flag);
uart_puts("Springe zur Adresse 0x0000!\n\r");
_delay_ms(1000);
/* vor Rücksprung eventuell benutzte Hardware deaktivieren
und Interrupts global deaktivieren, da kein "echter" Reset erfolgt *//* Interrupt Vektoren wieder gerade biegen */
cli();
temp = MCUCR;
MCUCR = temp | (1<<IVCE);
MCUCR = temp & ~(1<<IVSEL);
/* Rücksprung zur Adresse 0x0000 */
start();
return0;
}
Hat jemand ne Idee was ich falsch machen könnte?
Gruß Jürgen
Jürgen schrieb:> wenn ich ihn an die Bootloader-Adresse 0x3800(mithilfe der>> Linker-Option -Ttext=0x3800)
Wo trägst du die denn ein?
Im Makefile wäre das so richtig.
In die AVR-Studio-Options kommt die Wordadresse:
0x3800 / 2 = 0x1c00
mfg.
Ich benutze die Optimierungseinstellung -Os und ich setze in den
AVR-Studio options die Linker option -Ttext=0x3800, sodass dann im
Makefile folgendes erscheint:
Schau mal ins Hexfile, sind dort die Adressen 0x38xx sichtbar? Die
zweite Zeile sollte etwa mit :1003800 beginnen.
Setzt du F_CPU richtig? Sonst ist die Baudrate total verwurstelt...
Im Hex file beginnt die 2. Zeile mit :103810000C945...
Die F_CPU sollte richtig sein, da ich von der seriellen Schnittstelle
einwandfreie Zeichenketten bekomme wenn ich das Programm nicht im
Boot-Bereich starte.
Ich habe jetzt mithilfe der StatusLED herausgefunden, dass der
Mikrocontroller in uart.c hängen bleibt. Ich verwende die
Implementierung der seriellen Schnittstelle von Peter Fluery(siehe
Anhang). An der durch den Pfeil markierten Stelle läuft das Programm nun
nicht weiter:
Hmm sieht für mich alles ok aus. Vielleicht fällt ja jmd anders was auf?
Der Passus aus der uart.c passt (ich wundere mich, dass der Compiler
hier das Z-Register verwendet, wo ein lds/ori/sts genügt):
+00001D6E: ECE1 LDI R30,0xC1 Load immediate
+00001D6F: E0F0 LDI R31,0x00 Load immediate
+00001D70: 8180 LDD R24,Z+0 Load indirect with displacement
+00001D71: 6280 ORI R24,0x20 Logical OR with immediate
+00001D72: 8380 STD Z+0,R24 Store indirect with displacement
+00001D73: 9508 RET Subroutine return
In deiner "boot.txt" sieht die Vektoren-Tabelle okay aus; zumindest sind
Rx complete und DRE umgesetzt:
Das Verschieben der Tabelle erfüllt auch die Bedingung, dass das Setzen
von IVCE und IVSEL innerhalb von 4 Zyklen (gem. Wiki-Aritkel) geschehen
muss. Stack wird auch für den 168er passend gesetzt (0x4FF), deswegen
knallt's auch nicht. Auch hier fällt mir wieder die Verwendung des Z
Registers auf, mein Compiler macht das anders (avr-gcc 4.3.3).
Hab mal den C Code reingemischt:
char sregtemp = SREG;
+00001C6B: B72F IN R18,0x3F In from I/O location
cli();
+00001C6C: 94F8 CLI Global Interrupt Disable
temp = MCUCR;
+00001C6D: E5E5 LDI R30,0x55 Load immediate
+00001C6E: E0F0 LDI R31,0x00 Load immediate
+00001C6F: 8180 LDD R24,Z+0 Load indirect with displacement
+00001C70: 2F98 MOV R25,R24 Copy register
MCUCR = temp | (1<<IVCE);
+00001C71: 6091 ORI R25,0x01 Logical OR with immediate
+00001C72: 8390 STD Z+0,R25 Store indirect with displacement
MCUCR = temp | (1<<IVSEL);
+00001C73: 6082 ORI R24,0x02 Logical OR with immediate
+00001C74: 8380 STD Z+0,R24 Store indirect with displacement
SREG = sregtemp;
+00001C75: BF2F OUT 0x3F,R18 Out to I/O location
Tom M. schrieb:> Hmm sieht für mich alles ok aus. Vielleicht fällt ja jmd anders was auf?
Ich bezweifle, dass das Disassembly tatsächlich von obigen Source-Code
stammt, denn dieser Teil
uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );
sei();
uart_puts("Hallo hier ist der Bootloader\n\r");
_delay_ms(1000);
ist dort doppelt drin, und zwar vor und nach dem Verschieben der
Vektoren. Und das vor dem Verschieben ist natürlich tötlich.
Tom M. schrieb:> Der Passus aus der uart.c passt (ich wundere mich, dass der Compiler> hier das Z-Register verwendet, wo ein lds/ori/sts genügt):
Was mich ebenfalls an dem -Os zweifeln lässt.
So ich habe festgestellt, dass das Disassembly tatsächlich nicht das
richtige war, denn der Teil
uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );
sei();
uart_puts("Hallo hier ist der Bootloader\n\r");
_delay_ms(1000);
erscheint wie bereits erwähnt 2 mal. Diesen hatte ich zu Debugzwecken an
der Anfang geschoben. Ich habe hier nun nochmal das richtige file,
kompiliert mit -Os, das genausowenig funktioniert.
Also ich habe mittlerweile eine andere Implementierung für sie serielle
Kommunikation genommen und jetzt klappt auch fast alles, nur das ich
scheinbar nicht in den Flash speicher schreiben kann. Ich benutze die
Funktion
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang