Hallo, ich bin recht neu in der Mikrocontrollerprogrammierung, daher möchte ich mich vorab für mein rudimentäres Wissen entschuldigen (und so sieht für die Profis hier sicher auch mein Programm aus). Ich bringe mir dabei alles selbst, hauptsächlich mit Hilfe dieses Forums, bei aber für mein Problem habe ich nichts passendes gefunden. Ich habe grade angefangen mit einem UART bootloader zu experimentieren und dazu das GCC-Tutorial genutzt (danke an den Ersteller). Ich nutze AtmelStudio 7 und das ganze läuft auf einem ATmega328p. Nach einigen Stunden habe ich den bootloader zum laufen gekriegt und war auch sehr glücklich darüber. Wenn ich dann mein Programm damit flashe scheint auch alles zu gehen. Ich habe mir eine kleine UART Diagnose für die Eingänge gebastelt aber leider zeigt er beim "Reload" und "Semi" Eingang auf meinem Terminal einige "FF" Zeichen an. Ich habe keine Erklärung dafür, wenn ich das Hauptprogramm mittels ISP direkt drauf flashe funktioniert es einwandfrei. Im bootloader Programm habe ich in den "Flash segment" Bereich des Linkers folgendes eingetragen ".text=0x3800". Das ist die Word-adresse entsprechend der Fuses die ich gesetzt habe. Im bootloader, wie auch im Hauptprogramm habe ich die uart.h und uart.cpp eingefügt. Wie gesagt, bin ich Anfänger und hoffe, dass ich alle nötigen Dateien angehängt habe. Vielen Dank schon einmal.
Hallo, also ich bin mir grade etwas unsicher warum noch niemand geantwortet hat. Vielleicht habe ich das Problem nicht genug beschrieben oder es fehlen noch Daten oder ich habe nicht genug Geduld. Ich würde mich nach wie vor sehr über Hilfe freuen.
Ich tippe auf falsch eingestellte Baudrate/Parität/Bitzahl usw.... Atmrga & Co sind nicht mein Gebiet... Kann dir also da kaum Helfen.
:
Bearbeitet durch User
Hallo, entweder das oder man probiert zur Gegenkontrolle einen getesteten Bootloader aus. Wobei auch hier die Einstellungen für diesen beachtet werden müssen. Für verschiedene Baudraten ... https://github.com/MCUdude/MiniCore/tree/master/avr/bootloaders/optiboot_flash/bootloaders/atmega328p Je nach Ergebnis dann die Schlussfolgerung ziehen.
Erst ein mal vielen, vielen Dank für eure Antworten. Mit Arduino kenne ich mich gar nicht aus und ich weiß grade nicht wie ich das .hex file an den definierten Speicherort flashen kann. Ich übertrage mehrere Sachen per USART zur Diagnose. Alle anderen funktionieren einwandfrei und wie gesagt, auch die im bild fehlerhaften Stellen funktionieren einwandfrei, wenn ich es ohne Bootloader, sondern mit ISP flashe mit den gleichen baud und anderen Einstellungen. Kann es vielleicht sein, dass wenn ich das Programm mit dem Bootloader flashe es beim USART Puffer beschreiben auf Speicherbereiche zugreift in den bereits was steht und das byte dann ff ist? Dafür kenne ich mich zu wenig aus. Oder ist es vielleicht so, dass weil ich die uart.h/.cpp im bootloader, sowie im Hauptprogramm identisch habe es damit durcheinander kommt?
Julien schrieb: > ich weiß grade nicht wie > ich das .hex file an den definierten Speicherort flashen kann. Die Adressen solltem im Hex File selbst drin stehen. Das Dateiformat ist bei Wikipedia erklärt, du kannst es mit dieser Info manuell überprüfen. Bevor man neue Daten in den Flash Speicher schreibt, muss er selbstverständlich gelöscht werden. Das sollte der Bootloader erledigen. 0xFF ist der gelöschte Zustand. Du kannst den Speicher mit dem ISP Programmieradapter Auslesen und so prüfen, ob das erwartete Programm vollständig drin ist. Wenn nicht, waren entweder deine Hex Dateien fehlerhaft oder der Bootloader. Warum fummelst du überhaupt mit einem Bootloader herum. Ich würde mir das nur antun, wenn ich einen wichtigen Grund dazu hätte. Und dann würde ich immer nur den Bootloader von Arduino nehmen, denn der hat sich millionenfach bewährt.
Hallo, der Bootloader hat mit dem eigentlichen Programm nichts zu tun. Überschrieben werden kann nur etwas, wenn die Fuse Eintellungen nicht stimmen. Sprich der Bootloaderbereich zu klein oder gar nicht gesetzt ist. Kontrolliere bitte die Fuse Einstellungen. Im schlimmsten Fall ist dein Bootloader zu groß. Deswegen teste erstmal mit bewährten Bootloader, danach kann man eigene Varianten ausprobieren. Auch wenn die verlinkten Bootloader Dateien im weiten Sinne für Arduino sind, haben diese nichts mit Arduino zu tun. Das muss man gedanklich trennen. Das sind nur weitere Varianten für verschiedene Taktraten und Bautraten. Flashen tust du die ganz normal mit deinem ISP Programmer. Dabei sollte immer der gesamte Flash gelöscht werden, wenn es keine anderen Gründe gibt. avrdude Option -e. Den kompletten Überblick gibts hier. https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung
ich habe bei mir nach Tagen suchen den optiboot loader installiert, der bei github zu finden ist in verschiedenen Varianten, bei mir dann am Schluss der 8MHz mit 115200. Der funkitioniert mit der arduino ide zusammen, wenn man das generierte hexfile selbst mit avrdude hochlädt. ./upload.sh hexfile.hex optiboot findest Du hier: https://github.com/MCUdude/MiniCore/tree/master/avr/bootloaders/optiboot_flash/bootloaders/atmega328p
Hey, erst mal erneut vielen, vielen Dank für eure Antworten. Ich habe mir mal den Flash vom Programm das ich mit dem Bootloader drauf gespielt habe ausgelesen und die fehlerhafte Zeile gefunden (Bild). Der Fehler taucht auch bei mehrmaligem flashen immer an der gleichen Stelle auf. Ich bin jetzt dabei heraus zu finden warum das so ist. Ich bin mir nicht ganz sicher, schließlich hatte ich noch keine Probleme damit, aber ich habe keinen Quarz am Controller. Vielleicht versuche ich ihm mal einen Takt von außen mit einem Quarz vor zu geben. Ich schaue mir auch noch mal genau meinen Bootloader an. Falls noch jemand einen Vorschlag hat, oder ihm das bekannt vor kommt bin ich natürlich für jeden Tipp dankbar.
Das ist offenbar der Start der String-Konstanten; aber was daraus folgt - keine Ahnung.
Die Frage klingt vielleicht blöd aber wir hatten das schon einmal: Hast du Abblock-Kondensatoren direkt am Mikrocontroller? Gerade beim Flashen ist eine stabile Stromversorgung wichtig und die Stromaufnahme höher als sonst. Steckbretter zwischen IC und Abblock-Kondensator sind ungünstig, wegen der hohen Kontaktwiderstände und Leitungslängen.
> stabile Stromversorgung Schon, aber > Der Fehler ... immer an der gleichen Stelle Kann ich mir eigentlich nicht vorstellen. Hätte eher vermutet, dass da irgendetwas nicht mit dem LineFeed zu Beginn des Blockes zurechtkommt.
>Hallo, > >Fuse kontrollieren. Könntest du das bitte etwas genauer umschreiben? Ich habe die aktuellen Einstellungen mal als Screenshot hinzugefügt.
Julien schrieb: > Könntest du das bitte etwas genauer umschreiben? > Ich habe die aktuellen Einstellungen mal als Screenshot hinzugefügt. Ich denke er meinte die markierte BOOTSZ (soll größer oder gleich der tatsächlichen Größe des Bootloader) und darunter BOOTRSR (soll an sein).
Hallo, genau das meinte ich und wollte ich sehen. Aber das passt soweit. Ansonsten steht dazu laut meiner Meinung alles hier. https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung Nur wenn du sagst das ohne Bootloader alles funktioniert und mit Bootloader nicht, dann kann es ja nur an deinem Bootloader liegen. Hast du schon einen passenden der fertigen Bootloader probiert? Wenn der interne RC zu schief takten würde das eine fehlerhafte Übertragung zu Stande kommt, dann dürfte die Serielle nie funktionieren. Würde ich erstmal ausschließen. Mit deinem Inhaltsvergleich kann ich mir aktuell nichts zusammenreinem. Möglicherweise sind das Reste vom vorherigen flashen, weil nicht komplett gelöscht. Der Bootloaderbereich liegt ja ganz hinten im Flash, den kann man nicht so einfach überschreiben. Mehr kann ich aus der Ferne nicht dazu sagen.
115200 Baud @ 8 MHz ist schon mit Quarz grenzwertig. Mit R/C Oszillator würde ich lieber eine Baudrate wählen, bei der die Abweichung durch den Frequenzteiler geringer ist. 38400 ist gut. Siehe im Datenblatt "Examples of Baud Rate Setting".
> 115200 Baud
Woher kommt dieser Wert?
Im Bootloader vom Anfang lese ich "#define BOOT_UART_BAUD_RATE
9600".
S. Landolt schrieb: > 115200 Baud Aus meiner Phantasie, weil das die Standard Baudrate des neuen Arduino Bootloaders ist. Wollte nur drauf hinweisen, dass nicht alle Baudraten gleich gut sind. Niedriger ist auch nicht zwangsläufig besser. Lieber ausrechnen auf die Tabellen im Datenblatt gucken.
Also Quarz erschiene mir auch sinnvoller, bei einem ATmega328P mit seinen '10 % factory calibration', das nur am Rande. Aber, auch wenn ich mich wiederhole: auffällig ist doch, dass der Fehler exakt dort auftritt, wo ein LineFeed zu Beginn einer Speicherseite geschrieben werden soll - da sollte Julien seinen Bootloader mal genauer anschauen.
Hehe - er könnte ja mal probehalber aus seinem "\r\nTrigger: " ein "\r\nTrig ger: " machen und schauen, was passiert. (... und überhaupt sich dann von der virtuellen Ballerei verabschieden)
Landolt formulierte schlecht:
> wo ein LineFeed zu Beginn einer Speicherseite geschrieben werden soll
Besser wäre:
wo zu Beginn einer neuen Speicherseite ein innerhalb des Programmes
stehendes LineFeed eintrifft.
Hallo, noch mal vielen Dank für eure Denkanstöße. >Besser wäre: >wo zu Beginn einer neuen Speicherseite ein innerhalb des Programmes >stehendes LineFeed eintrifft. Ich habe nun mal alle LineFeeds und "\033[2J" raus genommen. Der Fehler wandert zwar weiter, er ist aber immer noch vorhanden. Wie man auf dem Bild sehen kann, wandert er immer mit der "unvollständigen" Zeile und tritt genau eine Page später auf. Das Problem liegt auf jeden Fall in meinem Bootloader. Wie gesagt bin ich eher Anfänger und habe mich an diese Anleitung und Bootloader gehalten: https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung
Warum nimmst du nicht endlich den Bootloader von Arduino?
Es geht also um die letzte Speicherseite - mal in der Gegend "/* Dateiende -> schreibe Restdaten */" suchen. (ich mit meinem Assembler tue mich da schwer)
Vielleicht ist das jetzt dümmlich, aber: in write_page verstehe ich die Reihenfolge von _delay_ms und program_page nicht - ich hätte es genau umgekehrt gemacht.
Stefan Frings protestierte:
> Warum nimmst du nicht endlich den Bootloader von Arduino?
"Jeder soll nach seiner Façon selig werden."
Stefan ⛄ F. schrieb: > Warum nimmst du nicht endlich den Bootloader von Arduino? Weil ich den booloader gerne starten möchte, wenn PB7 auf GND gezogen ist. Ist das nicht der Fall soll das Hauptprogramm starten. Kann ich den Arduino bootloader so modifizieren? Ich habe den bootloader nun schon mit dem AtmelStudio drauf geflashed aber wenn ich den controller starte kommt nichts im UART Terminal. Habe dann die Arduino IDE runter geladen und versucht damit den bootloader drauf zu packen. Da hat er über falsch gesetzte lock fuses gemeckert. Die sind aber nicht gesetzt (default) und ich denke, dass er das macht weil ich den internen 8Mhz clock nutze. Außerdem habe ich jetzt keinen Zugriff mehr auf den controller und musste nen neuen nehmen. Ich scheine wohl wahrlich zu blöde für die Arduino IDE zu sein. Ich finde da nen ganzen Haufen von Einstellungsmöglichkeiten nicht, die ich im AtmelSudio habe. S. Landolt schrieb: > Es geht also um die letzte Speicherseite - mal in der Gegend "/* > Dateiende -> schreibe Restdaten */" suchen. > (ich mit meinem Assembler tue mich da schwer) Das habe ich mir nach deinem Hinweis auch genau angesehen, aber das ist es nicht. Nach der "kurzen" Zeile im .hex file schreibt der die page korrekt in den flash. Der Anfang der nächsten Page erzeugt den Fehler. Es ist meiner Vermutung nach irgend etwas im Bereich "/* Füllen des Flash-Puffers mit dem "alten" Inhalt der Page */ memcpy_PF(flash_data, flash_page, SPM_PAGESIZE);" falsch aber ich kriege es nicht zu fassen. Habe nun viel mit UART versucht zu diagnostizieren, die ganzen counter mit geplottet und deren Funktion versucht zu verstanden, aber ich krieg nicht raus was der Fehler ist. Ich kann mir gut vorstellen, dass es am ATMega328p liegt, das Tutorial ist ja auf den Mega88 bezogen und selbst den tutorial Beispielcode flasht er mit exakt dem gleichen Fehlerbild. Schreibe Restdaten ist nur für die aller letzte Zeile zuständig.
Julien schrieb: > Weil ich den booloader gerne starten möchte, wenn PB7 auf GND gezogen > ist. Ist das nicht der Fall soll das Hauptprogramm starten. Kann ich den > Arduino bootloader so modifizieren? Du meinst aus dem laufenden Betrieb heraus? Das kann man mit dem Watchdog machen. Watchdog starten und dann in eine Endlosschleife gehen, er resetted dann den Chip, so dass der Arduino Bootloader startet. Oder meintest du, dass der Bootloader beim Start nur aktiv sein soll, wenn PB7=LOW ist? Ich glaube dazu müsstest du dessen Quelltext editieren, was auch kein Problem sein sollte. Der ist ja öffentlich zugänglich, andere haben auch schon Varianten davon implementiert z.B. für AVR Modelle die nicht zu Standardumfang von Arduino gehören. Ich benutze in meinen eigenen Projekten nur selten Botoloader. Aber da ist dann immer der Bootloader von Arduino, selbst wenn mein Anwendungsprogramm gar nicht mit Arduino gemacht wurde. Und zwar mache ich das, weil ich Avrdude mag und weis dass Avrdude den Arduino Bootloader unterstützt. Ich habe gar keine Lust mich mit anderen speziellen PC Programmen (für den Bootloader) auseinander zu setzen. Die meisten sind eh nur für Windows verfügbar, das nutze ich auch nicht freiwillig. Julien schrieb: > Ich scheine wohl wahrlich zu blöde für die Arduino IDE zu sein. > Ich finde da nen ganzen Haufen von Einstellungsmöglichkeiten nicht, die > ich im AtmelSudio habe. In der GUI kann man nur wenig konfigurieren. Das meiste findet man in diversen Textdateien wieder. Arduino ist halt nicht so flexibel, wie deine Art zu programmieren. Dafür ist es einfacher.
Vermutlich komme ich hinterher wie die alte Fastnacht, egal: Julien schrieb: > Es ist meiner Vermutung nach irgend etwas im Bereich "/* Füllen des > Flash-Puffers mit dem "alten" Inhalt der Page */ > memcpy_PF(flash_data, flash_page, SPM_PAGESIZE);" falsch So ist es, die Stelle ist falsch: 'case PARSER_STATE_TYPE'. Durch die 'verkürzte' Zeile im Intel-Hex-File wurde an dieser Stelle flash_data wieder teilweise gefüllt, was dann durch das memcpy_PF überschrieben wird. Konkret im ersten Beispiel (mit den LF&CR): die 'verkürzte' Zeile ist 2 Bytes kürzer, diese werden aus der nächsten Zeile geholt, anschließend wird flash_data mit 16-2= 14 Bytes gefüllt, die aber werden zu Beginn der darauffolgenden Zeile 'übergebügelt', dort stehen dann fälschlicherweise 14 'FF's. Der Programmteil mit dem memcpy_PF muss wohl irgendwo direkt nach write_page stehen.
Hallo, erst ein mal vielen, vielen Dank für all eure Hilfe. Ich hasse es immer, wenn man im Forum nach ähnlichen Problemen sucht und am ende einfach nur ein "habs hin gekriegt" steht und nicht wie. Daher hier mal was ich gemacht habe: Grundsätzlich sei gesagt, dass ich das Programm aus dem Tutorial benutzt habe. Zunächst habe ich versucht so gut es geht zu verstehen was es so macht und konnte das Problem auf "memcpy_PF" eingrenzen. Zunächst habe ich versucht zu verstehen wie es funktioniert und warum es dann doch nicht funktioniert. Irgend wann habe ich mir gesagt, dass es doch alles keinen Sinn macht und wollte meinen eigenen Bootloader schreiben. Dazu habe ich den Großteil wieder verwendet, allerdings ganz ohne memcpy_PF. Ich warte auf das Startzeichen ":" Ich werte Länge, Speicherort und Hex-Typ aus und speichere sie mir in Variablen nachdem ich sie in num umgewandelt habe (so wie im Programm vom Tutorial) Dann speichere ich die in num umgewandelten Datenbytes in einen Buffer und schließlich noch die Checksumme mit der ich die Zeile prüfe. Das wiederhole ich bis ich eine Page voll habe und schreibe die dann in den Flash. So weit der Regelfall. Einige mehr Versuche brauchte ich für den Fall, dass die Hexzeile kürzer ist. Im Grunde fülle ich die kürzere Zeile mit den Zeichen der nächsten Zeile auf und schreibe dann bei einer vollständigen Page eben diese. Die darauf folgende Pagewird wieder wie gewohnt gefüllt, dann aber eben an die im hex-file stehende Adresse geschrieben. Ach ja, wichtig ist noch, dass ich nach dem Page schreiben meinen Datenpuffer mit 0xFF überschreibe. So schreibe ich keinen Datenmüll in die letzte (meist unvollständige) Page des Programms. Zuletzt erkenne ich noch den Hex-Type 01 und beende den Bootloader. Mit einigen Beispielcodes hat es geklappt. Ich werde nun eine ganze weile die Programme mit dem ISP-Programmer auslesen und prüfen ob nicht doch irgend etwas schief läuft. Zuletzt habe ich noch die Hex-Types 02 und 04 heraus genommen, da dieser Bootloader nur für den Mega328p sein soll und ich so den Bootloader auf gute 1900byte Größe drücken konnte. So reicht es, wenn der Bootbereich 1024words groß ist und ich eben so noch mal 2048byte Programmspeicher frei mache. Ich weiß jetzt ganz genau wie mein Bootloader funktioniert und kann nach belieben alles ändern und anpassen wie ich es mag, außerdem konnte ich dabei viel lernen.
Ah, ich finde grade nicht wie ich meinen Beitrag editieren kann. Ich habe geschrieben, dass ich die unvollständige Zeile mit den bytes der darauf folgenden Fülle. Das ist nicht so, weil es (natürlich) nicht funktioniert hat. Ich fülle die unvollständige Zeile mit 0xFF und schreibe die Page. Anschließend fülle ich den Buffer normal weiter mit den darauf folgenden Hex-Zeilen und schreibe die Page aber an die neue Adresse (dort wo ich angefangen habe mit 0xFF zu füllen). So funktioniert es (vermutlich sagen die Profis "ja, wie auch sonst", aber für mich ist es nen ziemlicher Erfolg).
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.