Neue Firmware für HM_LC_Sw1PBU_FM mit getrenntem Aktor, Taster + Wechselschalter

Begonnen von jab, 29 Dezember 2013, 22:04:10

Vorheriges Thema - Nächstes Thema

Mr. P

Kann man den Bootloader eigentlich auch OTA flashen (solange man ihn nicht zerflasht) oder sind dafür zwingend wieder die angelöteten Kabel notwendig?
Bzw. wofür ist das CRC im Bootloader gut? Ist das womöglich schon ein Zerflash-Schutz, der den Bootloader zuerst in einen höheren Adressbereich und nach erfolgter CRC-Prüfung innerhalb des Atmega in die ersten 4k schreibt?
Greetz,
   Mr. P

Dirk

Zitat von: Mr. P am 07 August 2014, 21:30:22
Kann man den Bootloader eigentlich auch OTA flashen
Der Bootloader kann auch den Speicherbereich vom Bootloader selber beschreiben. Theoretisch sollte das eigentlich gehen.

ZitatBzw. wofür ist das CRC im Bootloader gut?
Durch den CRC-Check wird NACH dem flashen überprüft, ob die Prüfsumme des geflashten Programmcodes mit der zuvor berechneten Prüfsumme übereinstimmt.
Stimmt die Prüfsumme, wird das Programm gestartet, stimmt die Prüfsumme nicht, wird wieder der Bootloader gestartet um so erneut flashen zu können.
Das soll verhindern dass, z.B. bei einem unerwartetem Spannungsausfall, oder einer anderen Störung während des Flashens invalider oder unvollständiger Code nach dem Flashen ausgeführt wird und der AVR dadurch hängen bleibt.

Das ist also kein "Zerflash-Schutz" sondern nur ein Schutz das das Programm hängen bleibt und der Bootloader nicht mehr erreichbar ist bzw. nicht mehr z.B. per Funk gestartet werden kann. Man müsste dann an das Gerät ran um dort einen Reset auszulösen.

Die Verschlüsselung würde ich Blockweise umsetzen, so dass wenn der erste Block schon nicht entschlüsselt werden kann, das Flashen gar nicht erst gestartet wird, und eine vorherige Firmware somit intakt bleibt.

Gruß
Dirk

Mr. P

Wenn man den Bootloader OTA flasht, wäre es denn dann grundsätzlich möglich, diesen zuerst in einem Speicherbereich oberhalb der 4k hinein zu schreiben, dann eben mit der CRC-Prüfung auf Korrektheit prüfen und das sich der Bootloader dann bei erfolgten Programmstart selbst in die ersten 4k hinein schreibt?
Natürlich würde bei dem Ganzen das eigentliche Schalterprogramm verloren gehen, aber lieber das noch einmal flashen, als den Schalter aus der Wand nehmen, die Pins anlöten, mit Programmer flashen und dann wieder in der Wand zu versenken zu müssen. :-)
Greetz,
   Mr. P

Dirk

Zitat von: Mr. P am 07 August 2014, 22:05:11
Wenn man den Bootloader OTA flasht, wäre es denn dann grundsätzlich möglich, diesen zuerst in einem Speicherbereich oberhalb der 4k hinein zu schreiben, ...
So in der Art wird man das wohl machen müssen.
Beim Schreiben in den unteren Speicherbereich besteht dann aber trotzdem die Gefahr dass, wenn der zweite Schreibvorgang fehlerhaft verläuft, der Bootloader dadurch zerstört wird. Den oberen Teil des Bootloaders kann man nach einem Reset nicht wieder so einfach anspringen. Dann muss wieder der ISP her.
Da ich mich aber noch nicht so lange mit der Bootloader-Thematik beschäftige, gibt es vielleicht noch einen eleganteren Weg das zu bewerkstelligen.



Ich glaube übrigens dass ich die Idee mit dem verschlüsseln vorerst nicht umsetzen werde.
Denn ein Flashen einer korrupten Firmware kann man so doch nicht verhindern. Selbst wenn die ersten Blöcke korrekt sind, kann die Firmwaredatei manipuliert sein, so dass das Programm nicht gestartet werden kann. Der einfachste weg zu einem korrupten Programm ist es nämlich den Flashvorgang einfach mittendrin abzubrechen. Es kann so zwar keinen ungewollter lauffähiger Code auf die Geräte kommen. Ein "zerflashen" ist so aber nicht zu verhindern.

Das kann man nur verhindern, indem der Befehl den Bootloader zu starten signiert gesendet wird, oder ein aktivieren des Bootloaders per Funk generell nicht ermöglicht wird.

Gruß
Dirk

Mr. P

Zitat von: Dirk am 07 August 2014, 23:02:43
Das kann man nur verhindern, indem der Befehl den Bootloader zu starten signiert gesendet wird, oder ein aktivieren des Bootloaders per Funk generell nicht ermöglicht wird.
Also bei den beiden Bootloader-Versionen ohne Debug-Ausgabe scheint auf alle Fälle noch genug Platz zu sein, um ein Flag abzufragen, dass wenn es gesetzt ist, direkt nach dem Reset den Flash-Modus aktiviert und andernfalls wenn nach dem Neustart der Config-Button gedrückt wird.
Greetz,
   Mr. P

Dirk

Ja, klar. Das ist alles kein Problem. Mit meiner Erklärung wollte ich nur sagen dass das Verschlüsseln so nicht gegen "zerflashen" schützt.

Mr. P

Zitat von: Dirk am 08 August 2014, 00:21:12
Ja, klar. Das ist alles kein Problem. Mit meiner Erklärung wollte ich nur sagen dass das Verschlüsseln so nicht gegen "zerflashen" schützt.
Ja, leider. Ein gewisses Risiko bleibt immer. :-)
Greetz,
   Mr. P

Dirk

Ich habe mich die Tage am Bootloader noch einmal "ausgelassen".

Der Bootloader sollte nun für alle definierten Devices funktionierenden Code erzeugen. Dafür habe ich das Makefile angepasst und für jedes Device eine eigene Config-Datei gebaut.

Ich habe auch noch etwas optimiert, so dass der Bootloader incl. CRC-Check und Debugausgaben in 4k reinpassen.
Dadurch bekommt ihr im Atmega644 noch weitere 4k Flash-Speicher zum spielen :)
Ich habe dem Teil auch mal eine Versionsnummer verpasst. Ich bin mal von V0.5 ausgegangen. Oder sollen wir hier eine andere Versionsnummer nehmen?

Diese Versionsnummer wird über Debug beim Start ausgegeben, sofern Debugausgaben aktiv sind.

Aktuell werden diese Devices unterstützt:

  • HM_LC_Sw1PBU_FM (sowohl mit 8kb Bootloader Space als auch mit 4k.
  • HB_UW_Sen_THPL (Das ist der Universalsensor)

Die Section wo die Adressdaten wie HM-Type, Seriennummer und HM-ID gesteichert werden, liegt jetzt immer in den letzten 16 Bytes des Flash-Speichers.
Auf diese Daten kann man damit z.B. aus dem Hauptprogramm aus zugreifen. Damit kann man dann überall das selbe Hauptprogramm verteilen / flashen und erhält immer die Adressdaten aus dem individuellen Bootloader.
Dieses Feature muss man aber nicht nutzen.

Wie man an diese Daten vom Hauptprogramm aus zugreifen kann, kann man sich in der  Firmware des Universalsensors ansehen. Da habe ich das schon eingebaut.

Die Adressdaten werden im entsprechenden Config-File für das Device definiert.
Ich will dafür aber auch wieder ein generisches "Flash-Tool" bauen, was diese Daten direkt vor dem Flashen änder kann. Dann kann auch jeder seine individuellen Daten während des Flashens mitgeben und es muss nicht jedesmal neu kompiliert werden. Und man muss nur pro Device ein Hex-File verteilen.

Das PHP-Convert-Tool habe ich noch etwas erweitert.
Das heißt jetzt bin2eq3.php (falls der Name doof ist, können wir das auch wieder umbenennen) und akzeptiert als zusätzlichen Parameter die Page-Size vom verwendeten AVR.

So wird der Bootloader für die verschiedenen Devices kompiliert:


# für HM_LC_Sw1PBU_FM
make clean
make HM_LC_Sw1PBU_FM

#HM_LC_Sw1PBU_FM (8k Bootloader-Space)
make clean
make HM_LC_Sw1PBU_FM_8k

#HB_UW_Sen_THPL (8k Bootloader-Space)
make clean
make HB_UW_Sen_THPL


Getestet habe ich den Code bisher nur mit dem Universalsensor (HB_UW_Sen_THPL).
Für den für HM_LC_Sw1PBU_FM kompiliert auch alles ohne Fehler aber bitte testet das noch einmal.

@Jan.
Wenn alles funktioniert können wir den Code eigentlich zusammen mergen.
Entweder schicke ich dir dann einen Pullrequest oder du gibst mir Schreibrechte im Repo, dann kann ich das auch mergen.
Ganz wie du möchtest.

Gruß
Dirk

Mr. P

Sehr cool... Das begeistert, vielen Dank! :-)

Kann ich es wagen, den Bootloader am HM_LC_Sw1PBU_FM OTA zu flashen oder sollte das zur Sicherheit doch jemand testen, der ihn noch nicht in der Wand versenkt hat? :-)
Greetz,
   Mr. P

Dirk

Zitatoder sollte das zur Sicherheit doch jemand testen
Vielleicht gibt es ja noch jemanden der einen noch nicht eingebauten liegen hat.

Ich habe für den Atmege644 die Fusesettings für 4k Bootloader Size grade auch noch aktualisiert.

Wie oft bzw. wie Sicher funktioniert das Flashen denn bei euch?
Ab und zu flasht er nicht zu ende weil zu oft kein ACK kommt.
beim 2. oder 3. Versuch klappt es dann aber.

Wie ist die Erfahrung vor allem beim Flashen über größere Entfernungen?
Ggf. baue ich ja noch die RSSI-Werte in die Debugausgaben mit ein?

Im Tread vom Universalsensor hatten wir auch ab und zu Empfangsprobleme beim laufenden Betrieb. Hier hat es geholfen die Frequenz vom CC1101 geringfügig von 868.300 Mhz auf 868.290 Mhz zu ändern.

Dirk

Ich hatte noch ein paar Bugs im Bootloader die aber nur sporradisch auftreten sind.
Es hat sich dann gezeigt, dass die Interrupt-Initialisierung das Problem war.

Das habe ich noch gefixt / geändert.


  • Man kann im Device-File z.B. einen Config-Taster definieren.
    Der Bootloader startet ohne gedrückten Taster immer direkt, d.h. ohne Warten auf das Timeout, das Hauptprogramm, vorrausgesetzt der CRC-Check war ok.
    Mit gedrückten Taster oder bei einem CRC-Fehler wird der Bootloader-Code gestartet und man kann neu flashen.
    Das soll auch ein klein wenig Sicherheit bringen. Denn so ist es nicht mehr möglich ohne manuellen Eingriff einen neue Firmware zu flashen falls man den Bootloader auch über Funk aktivieren kann.
  • Ich habe die Frequenz für den CC1101 von 868,300 Mhz auf 868,290 Mhz abgesenkt. Zumindest bei mir gab es ohne diese Änderung gelegentlich Übertragungsfehler.
    Das hat sich dadurch deutlich verbessert. Könnte das einmal einer gegenprüfen?
  • Version ist jetzt 0.6
  • Damit die Taster-Sache oben noch in die 4k Passen, habe ich den Code noch etwas überarbeitet.

Ich würde mich freuen, wenn das noch mal einer mit dem HM_LC_Sw1PBU_FM.
Vielleicht liegt ja noch einer rum, der nicht ausgebaut werden muss.

Gruß
Dirk

Mr. P

Zitat von: Dirk am 13 August 2014, 18:29:09
Man kann im Device-File z.B. einen Config-Taster definieren.
Der Bootloader startet ohne gedrückten Taster immer direkt, d.h. ohne Warten auf das Timeout, das Hauptprogramm, vorrausgesetzt der CRC-Check war ok.
Mit gedrückten Taster oder bei einem CRC-Fehler wird der Bootloader-Code gestartet und man kann neu flashen.
Das soll auch ein klein wenig Sicherheit bringen. Denn so ist es nicht mehr möglich ohne manuellen Eingriff einen neue Firmware zu flashen falls man den Bootloader auch über Funk aktivieren kann.
Das heißt, ich muss den entsprechend konfigurierten Taster drücken, halten und in dem Moment entweder den Strom kurz ab- und wieder andrehen oder über einen Laptop/ein Smartphone, das ich in der Hand halte, das Device neu starten, um in die Flash-Routine zu kommen?
Falls ja und du noch ein paar Bytes übrig hast (oder gibt es diese Möglichkeit schon?)... Könntest du noch eine Warteschleife von ${x} Sekunden einbauen, die man nach dem Neustart Zeit hat, um den entsprechenden Taster zu drücken? :-)
Greetz,
   Mr. P

Dirk

Zitat von: Mr. P am 13 August 2014, 22:23:04
Das heißt, ich muss den entsprechend konfigurierten Taster drücken, halten und in dem Moment entweder den Strom kurz ab- und wieder andrehen oder über einen Laptop/ein Smartphone, das ich in der Hand halte, das Device neu starten, um in die Flash-Routine zu kommen?
Genau. aber nur wenn dieses Feature aktiv ist. Ansonste verhält sich das so wie vorher.

ZitatKönntest du noch eine Warteschleife von ${x} Sekunden einbauen, die man nach dem Neustart Zeit hat, um den entsprechenden Taster zu drücken? :-)
Daran habe ich auch schon gedacht, und bin da auch schon drann. Ich will das so bauen, dass bei einem PowerOn reset keine Warteschleife läuft, also hier muss man den Taster beim Einschalten gedrückt halten, bei einem Watchdog reset, welcher wohl per funk ausgelöst wird, würde ich dann kurz warten bevor der Bootloader startet. Denke mal 10 Sekunden sollten reichen?

Mr. P

Zitat von: Dirk am 13 August 2014, 22:37:19
Daran habe ich auch schon gedacht, und bin da auch schon drann. Ich will das so bauen, dass bei einem PowerOn reset keine Warteschleife läuft, also hier muss man den Taster beim Einschalten gedrückt halten, bei einem Watchdog reset, welcher wohl per funk ausgelöst wird, würde ich dann kurz warten bevor der Bootloader startet. Denke mal 10 Sekunden sollten reichen?
10 oder 15 Sekunden, genau. Wird wohl genügen.
Bzw. über eine Variable beim Kompilieren für jeden frei definierbar. :-)
Greetz,
   Mr. P

Dirk

Zitat von: Mr. P am 13 August 2014, 22:49:57
Bzw. über eine Variable beim Kompilieren für jeden frei definierbar. :-)
Ist eingecheckt.
Standartmäßig wird 10 Sekunden gewartet. Das kann man aber im Devicefile konfigurieren.

Hier auch noch mal kurz die Erklärungen des Ablaufes und der Blink-Sequenzen




  • Wenn noch kein Code im AVR ist, oder wenn falscher Code im AVR, z.B. aus einem vorherigem fehlerhaften Flashversuch:

    • Nach dem Einschalten blinkt die LED kurz (Bootloader gestartet)
    • dann blinkt die LED noch einmal mal kurz und der Loader meldet sich beim Flash-Programm
    • Jetzt wird ca. 10 sek. auf die Antwort vom Flash-Programm gewartet.
    • Während des flashens blinkt die LED schnell.
    • Sollte während des Flashens ein Fehler auftreten also der CRC-Check nach dem Flashen nicht ok sein, dann leuchtet die LED für ca. 2 sek. (CRC-Fehler). Der Bootloader resettet den AVR, und es geht von vorne los. Die LED leuchtet auch nach Ablauf von ca. 10 Sekunden für 2 Sekunden rot, wenn kein Flashen gestartet wurde.



  • Wenn gültiger Code im AVR ist und das Gerät eingeschaltet wurde:

    • Nach dem Einschalten blinkt die LED kurz (Bootloader gestartet)
    • Das Hauptprogramm wird ohne weitere Wartezeit gestartet

    Oder während des Einschaltens wird die Config-Taste gedrückt gehalten:

    • Nach dem Einschalten blinkt die LED kurz (Bootloader gestartet)
    • alle weiteren Schritte siehe Punkt 1


  • Wenn das Hauptprogramm den AVR durch einen Watchdog-Reset neu gestartet hat, z.B. durch einen Funkbefehl:

    • Nach dem Reset blinkt die LED kurz (Bootloader gestartet)
    • Für einen vorher festgelegte Zeit (z.B. 10 sek) blinkt die LED kurz und wiederholend. Das Blinken zeigt an, dass der Bootloader auf das Drücken der Config-Taste wartet.
    • Wird innerhalb dieser Zeit die Taste nicht gedrückt, startet das Hauptprogramm.
    • Wird die Taste innerhalb dieser Zeit gedrückt, startet der Flashvorgang wie unter Punkt 1.1 beschrieben.

Dieser ganze Vorgang funktioniert wie oben beschrieben nur wenn der CRC-Check aktiviert ist.
Ansonsten wird immer auf das Drücken der Taste gewartet, da der AVR nicht feststellen kann ob sich gültiger Code in der Programsection befindet.