Hallo,
ich benutze einen Atmega644P und habe folgende Frage.
Ich möchte bestimmte Funktionen gleichermaßen im Bootloader-Bereich und
in den Applikationen benutzen. Diese Funktionen sind aber zu groß um sie
in den Bootloader-Bereich zu schreiben. Ich habe schon diverse Ansätze
gesehen um eine Funktion aus dem Bootloader Bereich aufzurufen. Dies
geschah mithilfe von Sprungtabellen im Bootloader. Nun wäre meine Frage
ob dies auch in die andere Richtung möglich ist.
Im Prinzip habe ich also folgendes vor. Ich möchte den Speicher in in 3
Teile aufteilen.
Der erste Teil ist der Bootloader, der ja durch die Spezifikation des
AVR auf bis zu 1024Byte am Ende des Flash-Speichers angelegt wird.
Der zweite Teil ist der Bereich, den sowohl der Bootloader als auch das
Hauptprogramm benutzen können. Hier sollen nur Funktionen stehen. Dies
könnte zum Beispiel der Bereich von 0x0000 bis zur Hälfte des
verfügbaren Flashspeichers sein.
Der Dritte Bereich ist der des Hauptprogramms.
Der Bootloader nutzt einige Funktionen aus dem gemeinsamen Bereich und
springt dann zur Addresse des Hauptprogramms, welches ebenso Funktionen
aus dem gemeinsamen Bereich nutzen soll.
Die Frage ist, ob dies überhaupt möglich ist. Kann der Bootloader
Funktionen aus dem Applikations-Bereich aufrufen und anschließend wieder
zurück in den Bootloader springen.
Wenn ja, wie kann ich das umsetzen?
Vielen Dank schonmal und viele Grüße
Andreas
Andreas D. schrieb:> Der erste Teil ist der Bootloader, der ja durch die Spezifikation des> AVR auf bis zu 1024Byte am Ende des Flash-Speichers angelegt wird.
Beim ATmega644 sinds bis 8kB.
Eine saubere Lösung, Teile eines anderen Programms zu linken, gibt es
nicht.
Bla schrieb:> Das ist aber gefährlich. Was ist, wenn dein Bootloader dann im vermurkst> aufgespielten Code vom Hauptprogramm hängenbleibt?
Ich würde sogar sagen, daß damit der ganze Sinn des Bootloaders
untergraben wird. Der ist ja gerade deshalb so schön getrennt, damit er
auch mit einer kaputten Firmware oder nach einem mittendrin
abgebrochenen Flashvorgang noch tut.
Dann lieber umgekehrt, also den Bootloader per Fuse eine Nummer größer
und dann die entsprechende Funktion dort hinein. Dann liegt sie an einer
definierten Stelle, weil sich der Bootloader nicht mehr ändert. Ist dann
sicher einfacher dranzulinken... bzw. dranzumurksen, denn trotzdem gilt
ja: Murks bleibt Murks.
Das der Bootloader Bereich sogar bis 8kB erweiterbar ist ist interessant
und gut zu wissen. Es geht dabei aber um Funktionen von der Größe von
sogar mehr als 8kB. Den Bootloader auszuweiten bringt also nichts. Und
das ganze muss im Bootloader sein, weil der eine Operation mit den
"geteilten Funktionen" ausführen soll und anschließend das Programm
schreiben soll, das ebenso auf diese Funktionen zugreift.
Von daher würde ich das schon gerne umsetzen. Dabei bleibt aber immer
noch die Frage nach der Möglichkeit.
Wenn man in der Lage ist Funktionen im Bootloader aus der
Applikationsbereich aufzurufen und zurück zu gelangen, sollte das ja
auch umgedreht gehen.
>Wenn man in der Lage ist Funktionen im Bootloader aus der>Applikationsbereich aufzurufen und zurück zu gelangen, sollte das ja>auch umgedreht gehen.
Dazu muss der Bootloader die Adressen der Funktionen
kennen. Die werden sich aber wohl mit jeder Programmänderung
verschieben. So einen Müll würde ich mir nicht antun.
Das Problem ist eben mit Spruntabellen lösbar. Wie gesagt Umgedreht
haben es schon genug Leute umgesetzt.
Im übrigen wird die Technik der Jump-Tabellen auch von AVR selbst
genutzt für die Interrupt Vektoren ;).
>Das Problem ist eben mit Spruntabellen lösbar. Wie gesagt Umgedreht>haben es schon genug Leute umgesetzt.
Dann schreib deinen Kram in Assembler und gut ist. Wo ist
das Problem?
Wozu soll der Quatsch überhaupt gut sein?
Ich glaube hier besteht ein Missverständnis, diese gemeinsamen
Funktionen sollen nicht updatebar sein und müssen nur aufgrund ihrer
Größe aus dem Bootloader Bereich raus?
Wenn das so ist kann man das schon genauso wie Funktionen im Bootloader
welche für die Applikation verfügbar sein sollen implementieren. Ich
würde mir am Beginn der Bereichs mit den gemeinsamen Funktionen ein
Array mit den Adressen dieser Funktionen erstellen und sie aus dem
Bootloader bzw Applikation über Functionpointer verwenden, das sollte
ganz normal so funktionieren.
Der einzige Nachteil den ich sehe ist, dass du der Bereich der
gemeinsamen Funktionen nicht über Fuses schützen kannst.
Jetzt mal unabhängig davon ob es beim TO Sinn macht:
Wie wäre es denn umsetzbar? Jeder zweite hier mault rum, sagt dass sowas
grober Murks ist. Aber einen Lösungsvorschlag bringt keiner. Das aber
war die Frage des TE. Das es unsinnig, ja sogar gefährlich ist wurde ihm
oft genug gesagt, dass weiß er wohl mittlerweile. So wie ich das
verstehe sieht er aber einen konkreten Nutzen. Ich maße mir nicht an
sein Vorhaben zu beurteilen, aber er wird schon wissen was er vorhat.
Vielleicht stellt er auch später fest dass seine Idee doch nicht sogut
war. Wayne?
Ganz ehrlich, so unsinnig finde ich das Vorhaben garned. Allerdings
würde ich gemeinsame Routinen in den Bootloader-Bereich legen und
niemals überschreiben. Damit sichergestellt ist dass man sich nicht
versehentlich aussperrt weil der Bootloader nicht mehr korrekt arbeitet
nach einem fehlerhaften Flashvorgang.
Kommunikationsroutinen, z.B. Treiber für UART oder USB, oder Utilitys
wie CRC-Berechnung sind doch wunderbare Kandidaten für Routinen, die von
Bootloader und Applikation gleichermaßen genutzt werden könnten. Von dem
her kann ich schon verstehen dass man diese zentralisieren möchte.
Keine Ahnung ob das klappt:
Gemeinsame Routinen würde ich auf jeden Fall in eine vorkompilierte Lib
(.a) auslagern, damit garantiert wird dass Bootloader und Applikation
binär-identische Versionen der Routinen verwenden.
Dann müsste per Linkerscript gesteuert werden dass diese Routinen an den
selben Adressen, die natürlich irgendwo hart hinterlegt sein müssen,
gelegt werden.
Dadurch resultieren die Funktionsaufrufe aus Bootloader und Applikation
nach dem Linken zu den selben Sprungbefehlen.
Letzter Schritt: aus der Applikation müsste alles entfernt werden was
auch im Bootloader genutzt wird. Z.B. mittels strip die Symbole aus dem
.elf rauslöschen.
Oder, vielleicht sogar besser: wenn der Bootloader Intel-Hex Dateien
akzeptiert, einfach die Daten die im Bootloader-Bereich landen würden
verwerfen.
holger schrieb:> Dann schreib deinen Kram in Assembler und gut ist.
Nö, da ist garnichts gut.
Du hast 2 komplett eigenständige Programme. Auch in Assembler weiß das
eine Programm nicht, wo im anderen Funktionen und Variablen stehen.
Man kann höchstens mit .org bestimmte Adressen für Funktionen und
Variablen erzwingen und diese .org-Anweisungen mit Label in das andere
Programm übernehmen. Eigene Variablen dürfen dann nicht an diesen
Stellen plaziert werden.
Murks bleibt es trotzdem.
lex schrieb:> Jetzt mal unabhängig davon ob es beim TO Sinn macht:> Wie wäre es denn umsetzbar? Jeder zweite hier mault rum, sagt dass sowas> grober Murks ist. Aber einen Lösungsvorschlag bringt keiner.
Weil es unter den gegebenen Randbedingungen nicht möglich ist. Jeglicher
Code, den der Bootloader für seine normale Funktion braucht, muß in
die Bootloader-Sektion, wo er per Fuse geschützt ist. Wenn - wie
geschrieben - die Bootloader-Sektion dafür zu klein ist, dann ist der µC
zu klein. Punkt.
Jetzt kann man natürlich anfangen zu frickeln, indem man bestimmte
Funktionen des Bootloaders optional macht und nur dann anbietet, wenn
der dazu notwendige Code außerhalb der Bootloader-Sektion existiert (was
mindestens eine Prüfsumme erfordert). Am Ende bleibt aber trotzdem die
Tatsache, daß man nur die Funktionalität des Bootloaders auch
garantieren kann, die auf Code aus der Bootloader-Sektion beruht.
Meine Vermutung geht dahin, daß der TO einfach zu viel in den Bootloader
stopfen will. Mehrstufige Bootvorgänge sind nicht umsonst bei größeren
Systemen der Normalfall.
XL
Andreas D. schrieb:> Wenn man in der Lage ist Funktionen im Bootloader aus der> Applikationsbereich aufzurufen und zurück zu gelangen, sollte das ja> auch umgedreht gehen.
Wie schlecht deine Idee ist, wurde schon geschrieben.
Ich verstehe allerdings nicht, worin dein Problem liegt Sprungtabellen
zu generieren? Zumal Du bereits selbst schon Beispiele hierfür erwähnst.
Im Gegensatz zu manchen Antworten hier darfst Du diese natürlich nicht
gemeinsam mit deiner Applikation generieren, sonst bekommst Du einen
Abhängigkeit rein, die Du nicht willst. Sondern es muss ein drittes
Projekt speziell für deine 3. "Speicherbank" werden. Die muss natürlich
auch immer an der gleichen Stelle stehen.
Axel Schwenke schrieb:> Weil es unter den gegebenen Randbedingungen nicht möglich ist. Jeglicher> Code, den der Bootloader für seine normale Funktion braucht, muß in> die Bootloader-Sektion, wo er per Fuse geschützt ist. Wenn - wie> geschrieben - die Bootloader-Sektion dafür zu klein ist, dann ist der µC> zu klein. Punkt.
Müssen muß gar nichts. Ob das für die Aufgabenstellung des TO eine
sinnvolle Lösung ist, und ob dann alle seine Anforderungen erfüllbar
sind, kann mangels Info keiner sagen, aber prizipiell geht das.
Oliver