Hallo, ich konsolidiere gerade Code und zerlege Programmteile, die ich in mehreren Projekten benötigt habe in einzelne abgeschlossene Teile und libs. So ist ja schon meine crontab Implementierung herausgefallen: https://github.com/petershaw/AVR-Crontab Bisher habe ich ohne Bootloader gearbeitet muss ich gestehen, aber mein neustes Projekt bekommt nur eine UART Schnittstelle und ich weiß das ich die firmware des öfteren updaten muss. Den Stein aus dem Board zu nehmen und zu flashen ist hier keine Option. Also Bootloader. Da gibt es je genug info hier im Forum. Meine Idee - und Bestrebung der Konsolidierung - ist es einen Bootloader zu schreiben, der wieder für die meisten meiner Projekte taugt. Dafür muss er zwei Funktionen besitzen: Firmware einspielen (check) zugriff auf die System-Einstellungen geben, die ich (wie die meisten hier) im eeprom ablege. Bisher ist mein eeprom ein wüster Sumpf aus gesetzten Bits an der richtigen Stelle. In der Firmware lege ich hart fest auf welcher Position welche Einstellung sitzt. Das ist zwar schön klein, aber unbrauchbar, wenn man abstrakter werden möchte. Meine Frage an euch ist: wie organisiert ihr euren eeprom? Ich habe da diese Idee, inspiriert von dem Solais BootProm (http://docs.oracle.com/cd/E19201-01/821-0901-10/OK_OBP.html) und denke darüber nach einen key/value store zu implementieren. In meinem Bootloader könnte ich dann mit set KEY Value get KEY del KEY die werte setzten. Dabei würde er am Ende einen serialisierten Sting in den eeprom schreiben, wobei booleans einfach als KEY-flag geschrieben werden und somit = true sind. ein false gibt es nicht, bzw der Flag taucht dann gar nicht auf. eeprom: name:Struppi;kind=Dog;LCD_on;Debug würde so zu der Tabelle: name = Struppi kind = Dog LCD_on = true Debug = true im Bootloader könnte ich dann sagen set Debug false um das Flag zu entfernen. Natürlich kann ich mir dann auch alles schön auflisten lassen. Nach meinen Berechnungen komme ich mit meinen Gewöhnlichen Settings in 1024 Byte bequem aus. Was haltet ihr davon? Wie macht ihr das so? Danke, ps
>Meine Frage an euch ist: wie organisiert ihr euren eeprom?
Mein letztes EEPROM habe ich von der Platine eines entsorgten Telefons
abgelötet. Ist ein Atmel 24c32. Auf diese Weise habe ich bereits mehrere
dutzend EEPROMs organisiert.
Spasskeks. ok, tittel kann man optimieren.
:
Bearbeitet durch User
Also ich organisiere meine eeproms i.d.R. von vorne hach hinten, ohne Lücken. Also von Byte 0x00 aufwärts. Manchmal auch mit Lücken. Und gelegentlich lasse ich 0x00 weg.
Zuunterst (ab 0x0001) kommt immer die Geraetekennung, als ID und als String, dann kommt die Hardwareversion, dann die Firmwareversion. Und dann ist alles geraetespezifisch.
Fliegenpilz schrieb im Beitrag #3348501: > SCNR schrieb: >> Also von Byte 0x00 aufwärts. > > Das ist schlecht. Fang bei 0x01 an, ichg sage dir, is besser so. Das ist interessant. Warum soll man das so machen?
petershaw schrieb: > Warum soll man das so machen? Weil einige ältere AVRs sich gern mal bei zu langsamem Abfallen der Versorgungsspannung den Inhalt der Zelle 0 zerschossen haben. Bei moderneren AVRs und aktiviertem BOD ist das aber kein Problem mehr. ...
Ich organisiere meine Daten nach Modulen, jedes Modul bekommt einen Block mit einer Base-Adresse, z.B. 0x0100, 0x0200, 0x0300 mit einer ungefähren Abschätzung wie gross Die Daten werden könnten. Das erste Byte in jedem Block ist die Version. Wenn sich das Moul ändert und neue oder andere Daten benötigt zähle ich die Version in der Software nach oben. In der Init-Funktion des Moduls gibts dann eine switch(), die neue Daten an die entsprechende Stelle speichert (default-Wert setzen) oder ggf. Daten ändert. Diese switch kann man dann ohne breaks schreiben um Versionsupdates über mehrere Schritte auszuführen. Der case mit der aktuellen Version ist leer und 0xFF (EEProm leer) lädt alle Defaulteinstellungen. Die Daten innerhalb des Bockes sind dann modulspezifisch und abhängig vom Entwicklungsablauf. Das Modul selber weiss nicht, wo seine Daten abgelegt sind, es muss nur ein Zeiger und Länge klarkommen. Dazu gibt es zwei Funktion "EEProm_SaveParams" und "EEProm_GetParams". Das EEProm-Modul weiss wiederum nichts vom Inhalt des Blockes. Ich halte die Variante mit Strings ein bisschen zu groß. Der Vorteil, der sich durch die Verschiebbarkeit ergibt, wird durch den Overhaed an String-Parsing und lange Schreibzyklen negiert. Was passiert, wenn ein Parameter länger wird? Musst du dann alles folgende nach hinten kopieren? Du könntest deinen Key auch binär kodieren und eine wahlfreie Adresse dazu ablegen ala: "Gib mir Parameter 0815" oder "Speicher Paramter 0815". Die Nummern würde ich dann über ein globals enum realisieren. Als Sprungtabelle geht das einigermaßen fix.
Peter Shaw schrieb: > In der Firmware lege ich hart fest auf welcher > Position welche Einstellung sitzt. Das ist zwar schön klein, aber > unbrauchbar, wenn man abstrakter werden möchte. Man kann sich auch überorganisieren. Der EEPROM ist Privatsache der Applikation und interessiert den Bootloader nicht. Falls der Bootloader selber was speichern muß (IP-Adresse), reserviert man ihm einen Bereich oder er speichert es in seinem Flash. Für die Applikation nehme ich immer eine Struct im SRAM. Nach dem Reset wird sie aus dem EEPROM geladen bzw. auf Anforderung in den EEPROM gesichert. Stimmt die CRC im EEPROM nicht, bleibt die Struct mit ihrer default Initialisierung geladen.
:
Bearbeitet durch User
Peter Dannegger schrieb: > Für die Applikation nehme ich immer eine Struct im SRAM. Nach dem Reset > wird sie aus dem EEPROM geladen bzw. auf Anforderung in den EEPROM > gesichert. > Stimmt die CRC im EEPROM nicht, bleibt die Struct mit ihrer default > Initialisierung geladen. So ähnlich mache ich es auch. Nur habe ich am Anfang noch eine Versionsnummer mit drin. Beim Laden wird die geprüft und wenn sie kleiner ist als die aktuelle wird eine Update-Routine aufgerufen. Ist sie größer als die aktuelle, werden die Standardwerte belassen.
Peter Dannegger schrieb: > Der EEPROM ist Privatsache der Applikation Hallo Peter, danke für deinen Beitrag! Die Privatsache der Applikation ergibt sich aus der Betrachtungsweise wo ich das Level ansetze. Die Applikation kann auch der gesamte Chip sein, oder gar die Platine. In mach seltenen Fällen macht es vielleicht sogar sinn das fertige Gerät samt Umsysteme als Applikation zu sehen. Sicherlich ist Dein Gedanke hier aber richtig. Laufen unterschiedliche firmwares auf dem Chip hat der bl nichts im eeprom verloren. Was aber wenn dieser dazu dient die fw upzudaten. Ich möchte in dem Falle ein neue Version aufspielen. Also das Verhalten der einen spezifischen App ändern, bzw fixen. Gehört dazu nicht auch, die Einstellungen (Preferences) updaten zu können. Mein Ansatz ergibt sich aus der Überlegung das es manchmal rein über die Einstellung möglich ist ein Fix zu fahren. Also Softwarearchitekt lege ich das aber ungerne in die Firmeware, sondern eigentlich dahin wo ich auch die Updates einspielen kann: in den Bootloader. Daraus ergibt sich der "Service.Modus" Deine Anmerkungen hierzu interessieren mich sehr.
Ich würde mich denen anschließen, die das EEPROM als guten Platz für eine Versions- und eventuell auch Unterversionskennung ansehen. Ich würde noch etwas weiter gehen, und alles, was mit diesem Bereich zutun hat in eine eigene Datei (h/c) auszulagern. Auf diese Weise sieht man gleich, wenn sich Inkonsistenzen durch neuere Anforderungen (Versionen) ergeben. Hier könnte dann auch die jeweils "Neue" Version ihre Anpassung an die Einstellungen aus einer alten Version vornehmen und sogar angepasste Meldungen, dann natürlich aus dem Flash, ausgeben.
petershaw schrieb: > Deine Anmerkungen hierzu interessieren mich sehr. Die Frage ist, soll es ein allgemeiner Bootloader werden oder einer nur speziell für dieses Projekt. Ich habe auch einige Projekte, wo im EEPROM ein kleiner Bereich für den Bootloader reserviert ist. Darin kann man z.B. einmalig den Gerätetyp eintragen und so verhindern, daß eine falsche Firmware programmiert wird. Dieser Bereich sollte für die Applikation nicht schreibbar sein. Soll die Applikation Settings empfangen können, so hat sie ihre eigenen Routinen dafür. Bootloader und Applikation benutzen also keinen Code oder EEPROM gemeinsam. Die Applikation kann über ein Watchdogreset den Bootloader starten und damit das Update einleiten.
:
Bearbeitet durch User
Schreib dir doch einen allgemeinen Bootloader. Der kann dann zb. S19-Zeilen intepretieren und flashen. Zusätlich denkst du dir in diesem Format einfach noch weitere Zeilen aus, die im Standard nicht vorkommen und belegt sie mit so Funktionen wie EEPROM beschreiben, EEPROM umkopieren, EEPROM löschen. Jetzt musst du beim Software (make-file) bauen an den S19-File noch weitere eigen Zeilen anhängen, die das machen, was du willst. Die Software des Bootloaders auf PC-Seite muss dann nichts von deinen Änderungen wissen und überträgt einfach nur die Zeilen. So kann man z.b. auch ein Software-Download in Shadow mit späterem Umkopieren realisieren.
Hallo Jungs, das sind alles sehr interessante Gesichtspunkte und haben mich ein entscheidenden Schritt in meiner Planung weitergebracht. Mein Ursprüngliches Modell muss ich definitiv Überdehnen und gehe erstmal zurück ans Whiteboard. Es bleibt jedoch bei einem gewünschten "God"-Mode. hier muss ich Settings und Firmaware aus einer "Shell" bedienen können. Werte lesen/setzen, flashen.... Ob ich das als Makefile mache und eine Software anbiete, oder über eine Terminal-Lösung implementiere die auf der Bootloader oder Softwareseite aufsetzt (ev. lib, die eingebunden sein muss) plane ich momentan neu. Thema ist, das verschiedene Customized Software stände auf den Chips laufen werden und ich sicher gehen möchte im Wartungsbetrieb nicht auf eine große Liste an unterschieden in der Software reagieren zu müssen. ..tbd.
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.