Ich versuche jetzt schon seit mehreren Tagen diesen Bootloader auf meinem ATMega128 zum laufen zu bringen: http://www.chip45.com/index.pl?page=chip45boot&lang=de Aber es will einfach nicht laufen. Nachdem ich f eingebe und das erste Zeichen gesendet wird, bricht er ab, und der ">" Prompt kommt wieder. Ich bin jetzt zumindest schon so weit das ich glaube einen Fehler gefunden zu haben: Die Interruptvektor Adressen stehen an der falschen Stelle. Die Adresse ist jeweils verdoppelt. Also Vektor 1 steht nicht an 0xF002 sondern an 0xF004 (Siehe angehängte Datei). Ich kompiliere das ganze mit gcc, und weder unter Linux noch unter WinAVR stimmen die Adressen. Wenn ich den Prozessortyp auf atmega8 ändere scheinen die Interrupts an der richtigen Stelle zu sein. Weiß jemand eine Lösung? Hier der Quellcode (ich hab die Baudrate geändert) http://pastebin.com/858283 und hier das Makefile (Prozessortyp, Bootadresse und Takt geändert): http://pastebin.com/858287
Die GNU Toolchain stellen alle Adressen als Byteadressen dar, die Atmel Tools und Manuals verwenden beim Code Wortadressen. Dhaer die Abweichung. Bei Einstellung "Mega" sind die Vektoren nur 2 Bytes lang, deshalb erscheint es so, als würde es nun passen. Aber 2 Bytes sind halt nicht 2 Worte.
Funktioniert die precomplied Version aus dem Originalarchiv oder hast du Hardware-/Hostprobleme? chip45boot.lss habe ich mir nicht weiter angesehen, es fehlen mir darin die C-Sourcezeilen. http://pastebin.com/858283 kann ich nicht erkennen, wo du was geändert hast. http://pastebin.com/858287 habe ich nicht angesehen, weil die Übertragung vom Server nicht in endlicher Zeit zustande kommt.
Also ist alles korrekt so? So ein Mist, und ich dacht ich hätte den Fehler gefunden. Naja, aber der Fehler tritt auf jedem Fall beim Sprung in die interrupt Routine auf. Bis dahin klappt alles.
Die precompiled Version kann ich leider nicht ausprobieren da ich nicht das passende Quarz habe. Im .c file habe ich nur die Baudrate geändert: #define BAUDRATE 19200 Im Makefile habe ich folgendes geändert: MCU = atmega128 BOOTBLOCKSTARTADDRESS = 0x1F000 F_CPU = 8000000 Sonst ist alles das selbe wie im Original. Zwischendurch habe ich noch andere Boot adressen ausprobiert (0F000 und 0F800) So, ich hab jetzt endlich die richtige lss Datei angehängt denke ich. Alle guten Dinge sind ja bekanntlich drei :-)
Habe zwar eher nicht so den Durchblick bzw. noch nicht soo viel Erfahrung mit dem GCC, aber: // check if current buffer is a data record (starts with S1, S2 or S3) if(*thisBuffer++ == 'S' ) { lädts Du evtl. ein "ihex"-file, statt eines S-Records?
Nein, ich sende eine SRecord File. Hab auch schon verschiedene Dateien ausprobiert. auch wenn ich einfach nur das mache: >g (Er resettet) >f (er geht in den Programmier modus) (Er fügt eine Leerzeile ein, und jetzt kann ich mein Programm senden) Wenn ich jetzt eine Datei Sende, oder sogar einfac nur ein S bricht er ab, und er gibt mir wieder den Prompt: > Er kommt auch anscheinend nicht einmal bis in die Interruptroutine. Ich habe mal alles aus der Interruptroutine rausgenommen, und einfach nur ein uartPutChar('X'); da rein geschrieben. Aber das X kommt nicht an. Aber in die while(1) Schleife (Zeile 275) kommt er.
Dann muss sich doch mal jemand anners äußern... Wird am ende bestimmt damit zusammenhängen, dass der Bootloader gaanz am Ende vom Flash steht und Du mit
1 | |
2 | // test if flash is empty (i.e. flash content is 0xff)
|
3 | if(pgm_read_byte_near(0x0000) == 0xFF) { |
4 | bootloaderEnableFlag = TRUE; // set enable flag |
near nicht bis zum Anfang, also bis nach 0x0000 kommst, um nachzusehen, ob der Flash mit 0xFF an dieser Stelle leer ist. Vlt. steht ja gerade bei 0x00 was drinn(alte Firmware - Vectortabelle) lass Dir mal ausgeben, was an 0x0000 steht - sicher 0x0C. Da gibt es bestimmt beim 128er auch ein "pgm_read_byte_far". Oder der Bootinterruptvector stimmt nicht :-((
Nein, da ligt das Problem leider nicht., da die Bootloaderenableflag ja schon in der if Abfrage davor auf TRUE gesetzt wird: // poll USART receive complete flag 64k times to catch the 'i' reliably do { if(bit_is_set(myUCSRA, myRXC)) if(myUDR == 'i') bootloaderEnableFlag = TRUE; } while(--loop);
Aber ich hab gerade eine neue Vermutung: die Adresse wo der Bootloader laut Datenblatt hin soll ist $F000. Ich bin jetzt zwar schon komplett von diesem beklopptem Word- und Byteadressen scheiß, aber wenn das auch eine Wordadresse ist, dann müsste er ja an der Byteadresse 1E000 stehen oder? Tut er aber nicht, sondern er steht an der Byteadresse F000. Dann dürftedas auch klar sein warum er seinen Interrupt nicht findet. Ganz hinten im Flash ist ja gar nichts. Und der Bootloader startet eher aus Zufall weil vorher im Flash nichts drinsteht. Ich glaub ich werde gleich morgen mal ausprobieren die Startadresse auf 1E000 zu setzen. Hab leider gerade nicht die nötige hardware da.
Also Fehler (vermutlich) gefunden: Erstmal ein bisschen blödheit von mir, wegen den Word und Byteadressen, aber vor allem Blödheit von Mikroelektronika (www.mikroe.com): Ich benutze nämlich das BIGAVR Board, da ist ein ISP Programmer für USB gleich drauf. Eigentlich ganz geil das Board, aber die Programmiersoftware scheint ein Problem mit den oberen 64K zu haben. Die Intel Hex Datei ist noch korrekt, da steht drin das der Bootloader an 0x1E000 muss, aber in der Flashsoftware liegt er dann trotzdem nur an 0xE000. Und da die natürlich wieder ihr eigenes Süppchen kochen mussten ist das Board bzw. der Programmer auch zu keiner anderen (mir bekannten) Software kompatibel. Ich hab jetzt mal ne Nachricht bei denen ins Forum gesetzt, ich hoffe die bringen das in Ordnung. Und zwar möglichst schnell weil ich muss den ganzen bootloader Müll ja nur machen damit ich das Ding unter Linux benutzen kann. Gruß, Stefan
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.