Hi Leute, ich bräuchte nochmal euren Rat :) Ich habe vor einiger Zeit einen Bootloader geschrieben(Bootloader und passendes PC Programm), welcher sich an dem Beispiel aus dem Artikel "AVR Bootloader in C - eine einfache Anleitung" (http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung) orientiert hat. Außerdem hab ich mit dem Artikel von RN-Wissen über das Intel-Hex-File (http://www.rn-wissen.de/index.php/HEX-Datei) gearbeitet. Der Bootloader läuft auch ohne Probleme, alles wie gewünscht. Nun will ich aber auch größere uC-Progromme, die größer als 64Kbyte sind, mit dem Bootloader flashen. Da aber ja die Standart-Adressierung im Hex-File nur 16 Bit groß ist, wird auf eine andere Form der Adressierung zurück gegriffen. Im Artikel von RN-Wissen wird dies zwar ein wenig erleutert, jedoch tappe ich noch im Dunklen. Könnte mir jemand eine Taschenlampe reichen? :)
Hauke schrieb: > Im Artikel von RN-Wissen wird dies zwar > ein wenig erleutert, jedoch tappe ich noch im Dunklen. Es bleibt ja auch die Frage, ob linear oder segmentiert adressiert wird. Da musst du dich nach der Quelle deiner HEX-Files richten, an besten erzeugst du eines mit mit als 64 kByte und schaust es mit dem Editor an, dann siehst du schon, was du noch einbauen musst. Gruss Reinhard
Reinhard Kern schrieb: > Da musst du dich nach der Quelle deiner HEX-Files richten, an besten > erzeugst du eines mit mit als 64 kByte und schaust es mit dem Editor an, > dann siehst du schon, was du noch einbauen musst. Erstmal danke für die schnellen Antworten! Ich werd Mittwoch auf der Arbeit (wo wir nicht das Studio benutzen) mal gucken, was für ein Hex-File erzeugt wird. Und dann melde ich mich spätestens nochmal wenn ich die Software für den uC anpasse, denn von Speicheradressierung hab ich noch zu wenig Anhung. LG
Hauke schrieb: > Da aber ja die Standart-Adressierung > im Hex-File nur 16 Bit groß ist Ist sie nicht. Hex bietet sogar zwei Möglichkeiten, die 64k-Grenze zu überhüpfen. Nicht ganz zufällig analog zu diverser Hardware bekannter CPU-Hersteller übrigens... Egal, ob die "segment offset"-Variante oder die "linear offset"-Variante verwendet wird, bei beiden ist die Sache im Prinzip gleich: es ist ein spezieller Record in das Hexfile zu schreiben, der die Basisadresse angibt, die zu der 16-bit-Addressierung der folgenden Datenzeilen zu addieren ist. Nur die Codierung dieser Basisadresse ist leicht unterschiedlich und natürlich der Record-Typ. Der Hex-Interpreter muß ja wissen, wie er den Scheiß zu interpretieren hat. Das Blöde an der Sache ist: längst nicht jeder Hex-Interpreter kann überhaupt mit solche Offsets umgehen. Und noch viel weniger beherrschen beide Varianten zu seiner Angabe tatsächlich vollständig korrekt. Das liegt ganz offensichtlich an der krassen Inkompetenz vieler C-Programmierer, die scheinbar niemals an die Grenzen von "int" denken und denen auch keine hilfreiche runtime-Umgebung diese fehlenden Gedankengänge wenigstens in Form einer satten "integer overflow"-Exception gelegentlich in's Gehirn zurücknagelt... Deine erste Aufgabe wird also sein, die diesbezüglichen Fähigkeiten des Systems abzuklopfen, an das du letztlich die Hexfiles verfüttern willst.
>Das liegt ganz offensichtlich an der krassen Inkompetenz vieler >C-Programmierer, die scheinbar niemals an die Grenzen von "int" denken >und denen auch keine hilfreiche runtime-Umgebung diese fehlenden Ich würde bei Intel-Hex tatsächlich nicht über "int" nachdenken. Die Offsets sind unsigned. Aber das scheint dir bei deinem Hassgelaber vollständig entgangen zu sein. Wenn man keine Ahnung hat, einfach mal die Fresse halten.
>Ein unsigned int hat dann keine Grenze, oder wie?
Was willst du denn jetzt hier?
Hi Leute, ich bastel wieder ein bisschen an meinem Bootloader und versuche ihn zu optimieren. Mit der Speicher Adressierung bei über 64KB uC's muss ich nochmal gucken, wie genau ich das mache. Nun habe ich aber eine andere Frage: Mir ist grad eingefallen, dass es doch eigentlich egal ist wie viel RAM mein Bootloader benötigt oder? Das eigentliche Bootloaderprogramm wird ja in den Flash des µC gespeichert. Den benötigten Platz im Flash muss ich ja wissen, um die Fusebits richtig setzen zu können. Aber wenn dann mein Bootloader gestartet wird, werden ja die Variablen erzeugt und im RAM gespeichert. Wenn ich später den Bootloader wieder lasse und in mein Hauptprogramm springe, müsste das Hauptprogramm doch den RAM mit seinen eigenen Variablen überschreiben. Oder? Somit müsste es doch vollkommen egal sein, wie viel RAM ich in meinem Bootloader belege, was die Programmierung erheblich einfacher machen würde. Irre ich mich? LG Hauke
Hauke F. schrieb: > Somit müsste es doch vollkommen egal sein, wie viel RAM ich in meinem > Bootloader belege Du solltest nicht mehr belegen, als der Chip physikalisch hat :-) Ansonsten hast du Recht.
Georg G. schrieb: > Du solltest nicht mehr belegen, als der Chip physikalisch hat :-) Ja das könnte von Vorteil sein :D Danke für die schnelle Antwort!
Der Bootloader sollte immer ein eigenständiges Programm sein. Startet er die Applikation, initialisiert diese den RAM komplett neu. Bootloader und Applikation zu vermischen, gibt nur Ärger.
Peter Dannegger schrieb: > Der Bootloader sollte immer ein eigenständiges Programm sein. > Startet er die Applikation, initialisiert diese den RAM komplett neu. > > Bootloader und Applikation zu vermischen, gibt nur Ärger. Es wird aber nur der RAM initilisiert. Die benutzten Register wie UART und vor allen Dingen Interrupts müssen vom Bootloader zurück gesetzt werden. mfg.
Und man sollte den Watchdog zu beginn des Bootloaders abschalten oder imemr resetten. Sonst kommt man iwann auf die Idee die WDEN Fuse zu setzen oder in der Hauptsoftware den Bootloader per Watchdog aufzurufen zbd dann steckste inenr Endlosschleife fest. WDT Abschalten im Bootloader (einfach unter die includes pasten): #include <avr/wdt.h> void wdt_init(void) __attribute__((naked)) __attribute__((section(".init1"))); void wdt_init(void) { MCUCR = 0; wdt_disable(); return; } Die Interrupts musste ersmal in den Bootloader biegen und dann zurückbiegen. Hinbiegen: GICR = (1 << IVCE); /* enable change of interrupt vectors */ GICR = (1 << IVSEL); /* move interrupts to boot flash section */ Zurückbiegen: GICR = (1 << IVCE); /* enable change of interrupt vectors */ GICR &= ~(1 << IVSEL); /* move interrupts to application flash section *
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.