Wie kann ich dafür sorgen, dass ein Code-Snippet nur einmal in der Lebensdauer eines Programms ausgeführt wird? Es kann viele Male aus- und eingeschaltet werden. Die einzige Möglichkeit, das Code-Snippet erneut auszuführen, muss das Board erneut flashen.
Der Code ist ein Kalibrierungsabschnitt, den ich nicht erneut ausführen möchte. Wenn ich EEPROM oder Flash verwende, setzen wir ein Flag auf „true“ oder „false“. Wenn wir also diesen Speicherort zum ersten Mal lesen, was wäre der Zufallswert in diesem Speicherbereich?
Was ist die beste Methode, um dies in eingebettetem C zu implementieren?
Ihr Mikrocontroller verfügt möglicherweise über EEPROM, OTP-Speicher und Benutzersicherungsbits, in denen Sie ein Flag setzen können.
Es gibt keine "beste Methode in Embedded C", das Schreiben von nichtflüchtigem Speicher ist in jedem Mikrocontroller anders.
bearbeiten:
BLITZ
Der Inhalt des Flash-Speichers wird während der Programmierung des Geräts gelöscht. Nach der Programmierung enthalten alle nicht geschriebenen Bytes 0xFF. Konsultieren Sie das Datenblatt, um einen Bereich zu finden, der innerhalb der laufenden Firmware sicher programmiert werden kann.
EEPROM
Obwohl dies in den Datenblättern nicht garantiert wird, enthielten alle EEPROMs, die ich bisher gesehen habe, 0xFF:s, wenn sie ab Werk versendet wurden (außer denen, die mit einer eindeutigen MAC-Adresse vorprogrammiert sind, aber das ist ausdrücklich dokumentiert). Einige Programmiergeräte/Software sind auch in der Lage, EEPROM-Inhalte zu löschen oder zu programmieren. Einige können dauerhaft oder reversibel schreibgeschützt werden.
OTP
Einmal programmierbarer Speicher enthält immer gut definierte Anfangswerte, die im Datenblatt dokumentiert sind.
Es ist immer eine gute Idee, eine gute Prüfsumme wie CRC32 in die geschriebenen Daten aufzunehmen, um sich vor Datenverfälschung durch defekte Teile, Übertragungsfehler, kosmische Strahlung usw. zu schützen.
Du sagtest:
Die einzige Möglichkeit, diesen Code auszuführen, muss das Board erneut blinken.
Andere haben gesagt, EEPROM zu verwenden, um ein Flag zu speichern, um anzuzeigen, wann die Funktion run_once() ausgeführt wurde. Dies hat jedoch einen Nachteil: Wenn Sie den Mikrocontroller neu flashen, wurde das ran_it_once-Flag im EEPROM bereits gesetzt und die Funktion run_once() wird nicht ausgeführt. Wenn Ihr Mikrocontroller über ein eingebettetes EEPROM verfügt, ist es möglicherweise möglich, das ran_it_once-Flag zu löschen, wenn Sie den Mikrocontroller neu flashen, sofern der Programmierer dies unterstützt.
Ein besserer Weg ist, Versionsnummern sowohl im EEPROM als auch im Code zu haben. Wenn der Code nach dem Einschalten ausgeführt wird, sollte er die Versionsnummer aus dem EEPROM lesen und mit der im Code gespeicherten Versionsnummer vergleichen. Wenn sie nicht übereinstimmen, wird die Funktion run_once() aufgerufen, und der letzte Akt des Codes run_once() besteht darin, die Firmware-Versionsnummer in das EEPROM zu schreiben. Jedes Mal, wenn Sie den Quellcode der Firmware ändern, müssen Sie die darin eingebettete Versionsnummer erhöhen.
Wählen Sie einen Mikrocontroller, der seinen eigenen Programmspeicher schreiben/löschen kann. Nachdem Sie den betreffenden Code ausgeführt haben, lassen Sie den letzten Teil des Codes die erste Anweisung durch einen Sprung ersetzen, der ihn umgeht. Optional können Sie auch den Rest löschen (vielleicht durch nop ersetzen), sodass die Wahrscheinlichkeit, dass er jemals wieder ausgeführt wird, absolut null ist.
Diese Nachricht wird sich in 5..4 selbst zerstören...
Da Sie diesen Code für die Kalibrierung verwenden, wäre mein Vorschlag, einen Sprengprozess zu erstellen, der den Kalibrierungscode als erste Stufe ausführt und ihn nicht einmal auf der fertigen Produktionsversion der Platine hat. Dies ähnelt der Antwort von Apalopohapa, unterscheidet sich jedoch in dem Sinne, dass Sie zwei separate Programmladungen haben würden: Haben Sie einen Sprengprozess, der die erste Programmladung flasht, die alle Kalibrierungen ausführt und die Daten daraus ausspuckt. Nehmen Sie dann diese Daten und integrieren Sie sie in die Daten des zweiten Programmladevorgangs.
Ein Vorteil dieses Ansatzes besteht darin, dass Sie den benötigten Speicherplatz absolut minimieren – Sie müssen nicht Ihren einmaligen Code speichern, sondern nur die Daten, die er generiert. Indem Sie einen Blast-Prozess haben, der zwei separate Programme lädt, isolieren Sie sich auch ein wenig von Fehlern im Initialisierungscode, die sonst herumliegen könnten. Sie haben auch eine gewisse zusätzliche Flexibilität, wenn Sie Ihren Kalibrierungscode erneut ausführen möchten: Anstatt zusätzlichen Code schreiben zu müssen, um das Bit zu löschen, das anzeigt, dass Ihr Code ausgeführt wurde (was versehentlich bereits gelöscht werden könnte), führen Sie einfach Ihren erneut aus Sprengvorgang.
AlphaGoku
hoo2
Oldtimer
vsz
Oldtimer
Michael Johnson
Ganeshredcobra
Michael Johnson
alex.forencich
rdtsc