Hi, ich habe absichtlich nicht Bootloader in den Titel geschrieben, denn ich moechte nur "fast" einen Bootloader bauen. Der Hintergrund ist der folgende: Ich habe ein gut funktionierendes Funkprotokoll (CRC, ACK, encr) laufen. Das Funknetzwerk hat einzelne Nodes. Jede Node hat einen grossen Teil Code, der identisch ist (naemlich das Protokoll, usw.). Es gibt auch einen Server, der mit dem PC verbunden ist. Der Teil, der ab und zu ein Update braucht ist nur, wie auf Kommandos reagiert werden soll. Das heisst im Wesentlichen eine einzelne Funktion (und ausschliesslich von ihr benutzte daten) zB: react(uint8_t *, uint8_t len); Dabei benutzt der Funkcode externe ISRs und Timer. Die Reaktion auf ein Datenpacket braucht normalerweise keine ISRs oder aehnliches. Der "Bootloader" soll auch nicht beim Neustart sondern immer laufen, ein Kommando triggert dann nur das beschreiben des Flash. Das recyclen der Funktionen aus dem Bootloader und dann springen in den App Code ueber jump tables. o.Ae. scheint ein bisschen zu viel. Naiv wuerde ich erwarten, dass ich einfach nur eine Funktion zum Flash ab einer bestimmten Stelle schreiben einbauen muss und dann dem "Bootloader" (der eigentlich das Hauptprogramm ist) mitteilen muss, dass er in der Hauptschleife einmal die Funktion aufrufen an der Stelle aufrufen und der zwei Variablen uebergeben muss: react. Und der Flashteil, wo die sitzt ist halt ueberschreibbar. Vielleicht ist die Idee naiv - ich habe mich mit Bootloadern noch nicht tuefgehend beschaeftigt. Ich wuerde mich ueber Kommentare freuen. Gruss
Ich hab den Eindruck, Du hältst ein software-update für gleichwertig zur Aufnahme irgendwelcher Daten zur Verarbeitung in einem Programm. Das updaten ist m.E. aber wesentlich heikler und auch zeitraubender als eine normale Datenübergabe in ein RAM. Die übliche Programmausführung wird beim bootloaden behindert oder gar gesperrt. Als Reaktion auf ankommende Daten häufig ein update zu machen dürfte ein ziemlich riskanter Weg sein, was die Zeitabläufe angeht. Auch wenn die EEPROMs schon eine hohe Zubverlässigkeit haben, stellt meiner Meinung nach häufige Umprogrammierung auch noch immer einen Verkürzungsfaktor für die Datenhaltigkeit dar.
Ist es nicht einfacher, jedem Node den absolut identischen Code zu verpassen und mit einem Switch-Case anhand eines Flags im EEPROM oä. zu entscheiden, was gemacht werden soll? Oder ist es notwendig, dieses Stückchen Code ständig und überall ändern zu können?
Peter R. schrieb: > Ich hab den Eindruck, Du hältst ein software-update für gleichwertig zur > Aufnahme irgendwelcher Daten zur Verarbeitung in einem Programm. > Nein. --- @ Georg: Das hatte ich auch schon ueberlegt. Es ist aber ein bisschen komplexer als es nur mit ein paar Flags zu machen waere. Man muesste dann schon fast einen Parser basteln, und das sprengt wohl auch wieder den Umfang. Jedenfalls sprengt es den EEprom der Controller, die ich momentan einsetze. Daher meine Idee, diese eine Funktion im Flash auf eine bestimmte Stelle zu schreiben und ein Update (ein ueberschreiben) der Funktionalitaet (wie auf uebergebene Daten aus dem RAM reagiert wird) zuzulassen. Natuerlich nur, wenn ein Firmware update durchgefuehrt wird und nicht bei jedem Eintreffen neuer Daten.
Jan K. schrieb: > ich habe absichtlich nicht Bootloader in den Titel geschrieben, denn ich > moechte nur "fast" einen Bootloader bauen. Der Hintergrund ist der > folgende: Usw. Vorab, der Begriff Bootloader wird im Zusammenhang mit Microcontrollern m.E. oft ungenau oder falsch gebraucht. Im allgemeinen bezeichnet bootstrap loader ein beim Start eines Computers bereits vorhandenes und initial ausgeführtes Programm, das einfach als Loader fungiert, also weitere Programmstücke in den volatilen Speicher (aka RAM) laden und dann ausführen kann, ggfs. auch mehrstufig. Die Möglichkeit, diese nachgeladene Programm in einen weiteren nichtvolatilen Speicher zu übertragen und ggfs. bei nachfolgenden Einschaltvorgängen ohne bootstrap direkt auszuführen, oder sogar in einem weiteren Schritt den initialen Bootloader auszutauschen, ist damit nicht zwingend verbunden oder gleichzusetzen. Es scheint aber so, daß genau dieses (quasi ein Bootloader, der sich wie ein Brennprogramm verhält, das ihm übergebene Programm also nicht abschließend ausführt, sondern in nichtvolatilem Programmspeicher aka Flash ablegt) in diesem Umfeld der typische Sprachgebrauch geworden ist. So einen Bootloader brauchst Du in der Tat nicht. Allerdings unterscheidet sich das, was Du tun möchtest, m.E. nur bezüglich des Codeumfangs davon, insofern liegst Du mit "fast" schon ganz richtig. Der hauptsächliche Unterschied ist, daß Dein "Bootloader" groß und der nachzuladende Teil klein ist. Etwas mehr als der "Bootloader" mußt Du allerdings insofern tun, als der mit dem Ablegen des Programms im Flash seine Arbeit erledigt hat, während Du Dir ggfs. auch noch einen Mechanismus für das Binden (das, was man früher einen Linker nannte - http://de.wikipedia.org/wiki/Linker_%28Computerprogramm%29) - ausdenken musst. > Naiv wuerde ich erwarten, dass ich einfach nur eine Funktion zum Flash > ab einer bestimmten Stelle schreiben einbauen muss und dann dem > "Bootloader" (der eigentlich das Hauptprogramm ist) mitteilen muss, dass > er in der Hauptschleife einmal die Funktion aufrufen an der Stelle > aufrufen und der zwei Variablen uebergeben muss: react. Genau. Bzw. umgekehrt, Du reservierst ein Stück Programmspeicher für die nachzuladende Funktion (wenn es nur eine ist, entfällt das Linken, dann fängt die einzige Funktion einfach am Anfang an) und die dort abgelegte Funktion wird schlicht dort aufgerufen. Natürlich mußt Du Dir Gedanken über Anfangsbedingungen machen (was steht da anfänglich drin, eine Dummyfunktion, oder eine Defaultfunktion?) und darüber, daß sich die allgemeine Programmausführung und das zeitraubende Überschreiben der nachzuladenden Funktion nicht in die Quere kommen. Es kann auch nicht schaden, das Verfahren so robust wie möglich auszulegen, also den übertragenen Codeblock mit einer Prüfsumme abzusichern etc. HTH
Und danach kommen die speziellen Eigenschaften deines Controllers ins Spiel. * Unter welchen Umständen kann das Flash programmiert werden? - Im allgemeinen können im betroffenen Flashbereich keine Lesezugriffe vorgenommen werden, während das Flash gelöscht oder geschrieben wird. Also keine Programmausführung, keine ISRs, keine konstanten Daten lesen in diesem Bereich zu dieser Zeit. * Wie ist die Architektur des uC? - Havard: keine Programmausführung im RAM Bereich. Denkbar ist das Einblenden von RAM in den Codebereich. Beim ATmega kann der Bootblock das restliche Flash löschen/schreiben. - von Neumann: Programm kann im RAM ausgeführt werden. Dazu wird der Flash Code ins RAM kopiert und dort ausgeführt. Er muss natürlich entsprechend lokatiert sein. * Wie ist die Segmentierung des Flashs? - Was ist die kleinste Segementgröße die gelöscht werden kann? - Wie groß ist der Code der geschrieben werden soll? - Ist genug RAM vorhanden um den neuen Code zu puffern und in einem Rutsch zu schreiben? Oder muss das in Häppchen unterteilt werden? Wenn wir jetzt wüssten, um welche(n) Controller es sich handelt, hagelt es bestimmt lauter gut gemeinte Ratschläge. Aber so ist das alles noch zu akademisch. Gruß, Bernd
Danke fuer eure Antworten, Bernd, Wolfgang. Ja, ich habe voellig vergessen, welche Controller ich verwende - das steht aber sogar schon fest, weil die Hardware schon existiert: Ich verwende AVRs, genaugenommen Attiny841. Da bin ich auch (selbst wenn die Hardware nicht existierte) festgelegt, weil ich die beiden 16bit Timer, HardwareSPI usw. brauche. Der hat keine separate Boot-Section im Flash, nicht genug RAM um den gesamten zu schreibenden Code zu puffern. Allerdings existieren kleine Bootloader dafuer bereits, und self-programming kann der laut Datenblatt auch. Man muss immer 4 pages auf einmal loeschen, das macht 4*8 words. Das kann ich gut im RAM puffern. Waehrend der erase/write Zeiten muss ich halt aufpassen, dass das Timing stimmt. Wenn dort ISRs oder das restliche Programm aussetzen bedeutet das nur, dass der Sender des Codes eben warten muss und keine Antwort bekommt. Das macht das Funkprotokoll sowieso. Nur der timeout muss ggf. angepasst werden. Auch Pruefsumme etc. ist schon im Protokoll implementiert, sollten es mehrere Packete werden gibts eben eine eben noch eine obendrauf. Gruesse
Jan K. schrieb: > Ich verwende AVRs, genaugenommen Attiny841. [...] > Man muss immer 4 pages auf einmal loeschen, das macht 4*8 words. Da nehmen sich die Controller von Atmel und Microchips offenbar nichts. Der 12F1840 z.B. erlaubt ebenfalls erase/write in Blöcken/rows/pages von 32 words. Bedenke, daß der Program-Flash nur eine Endurance von 10.000 solcher Zyklen hat, statt der 100.000 des EEPROM. Je nach Updatefrequenz sind die ziemlich schnell aufgebraucht.
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.