Immunitätsbewusste Programmierung - Immunity-aware programming

Beim Schreiben von Firmware für ein eingebettetes System , Immunität bewusste Programmierung bezieht sich Techniken der Programmierung , die die Toleranz von transienten Fehlern in den Verbesserung der Programmzählern oder anderen Modulen eines Programms , das sonst zum Scheitern führen würde. Vorübergehende Fehler werden typischerweise durch einzelne Ereignisstörungen , unzureichende Leistung oder durch starke elektromagnetische Signale verursacht, die von einem anderen "Quellen"-Gerät übertragen werden.

Immunitätsbewusste Programmierung ist ein Beispiel für defensive Programmierung und EMV-bewusste Programmierung . Obwohl die meisten dieser Techniken für die Software im "Opfer"-Gerät gelten, um es zuverlässiger zu machen, gelten einige dieser Techniken für die Software im "Quell"-Gerät, damit es weniger unerwünschtes Rauschen emittiert.

Aufgabe und Ziele

Die Firmware von Mikrocontrollern kann die elektromagnetische Verträglichkeit eines eingebetteten Systems kostengünstig verbessern .

Eingebettete Systemfirmware wird normalerweise nicht als Quelle von Hochfrequenzstörungen angesehen . Funkemissionen werden oft durch harmonische Frequenzen des Systemtakts und Schaltströme verursacht. Die Impulse auf diesen Drähten können schnelle Anstiegs- und Abfallzeiten haben, wodurch ihre Drähte als Funksender fungieren. Dieser Effekt wird durch schlecht gestaltete Leiterplatten verstärkt . Diese Effekte werden durch die Verwendung von Mikrocontroller-Ausgangstreibern mit langsameren Anstiegszeiten oder durch das Abschalten von Systemkomponenten reduziert.

Der Mikrocontroller ist einfach zu steuern. Es ist auch anfällig für Störungen durch Funkfrequenzstörungen. Daher kann die Toleranz des Systems gegenüber elektromagnetischen Störungen kostengünstig verbessert werden, indem die Software des Mikrocontrollers dazu gebracht wird, solchen Fehlern zu widerstehen, indem die Notwendigkeit von Hardwareänderungen verringert wird.

Mögliche Störungen von Mikrocontroller-basierten Systemen

CMOS- Mikrocontroller haben spezifische Schwachstellen, die durch Software verstärkt werden können, die gegen elektromagnetische Störungen arbeitet. Häufig ist eine Fehlermöglichkeits- und Auswirkungsanalyse eines Systems und seiner Anforderungen erforderlich. Fragen der elektromagnetischen Verträglichkeit können einer solchen Analyse leicht hinzugefügt werden.

Energieversorgung

Langsame Änderungen der Versorgungsspannung verursachen keine signifikanten Störungen, aber schnelle Änderungen können unvorhersehbare Probleme verursachen. Wenn eine Spannung die Parameter im Datenblatt des Controllers um 150 Prozent überschreitet, kann dies dazu führen, dass der Eingangsport oder der Ausgangsport in einem Zustand hängen bleibt, der als CMOS- Latch-up bekannt ist . Ohne interne Stromsteuerung führt ein Latch-up dazu, dass der Mikrocontroller durchbrennt. Die Standardlösung ist eine Mischung aus Software- und Hardwareänderungen. Die meisten eingebetteten Systeme verfügen über einen Watchdog-Timer . Dieser Watchdog sollte sich außerhalb des Mikrocontrollers befinden, damit er wahrscheinlich gegen jede plausible elektromagnetische Störung immun ist. Es sollte die Stromversorgung zurücksetzen und kurz ausschalten. Die Watchdog-Periode sollte die Hälfte oder weniger der Zeit und Leistung betragen, die zum Ausbrennen des Mikrocontrollers erforderlich sind. Das Netzteildesign sollte gut geerdet und entkoppelt sein, indem Kondensatoren und Induktivitäten in der Nähe des Mikrocontrollers verwendet werden. einige typische Werte sind 100uF und 0,1uF parallel.

Eine geringe Leistung kann bei den meisten Mikrocontrollern zu schwerwiegenden Fehlfunktionen führen. Damit die CPU Anweisungen erfolgreich dekodieren und ausführen kann, darf die zugeführte Spannung nicht unter den Mindestspannungspegel fallen. Wenn die gelieferte Spannung unter diesen Wert fällt, kann die CPU damit beginnen, einige Befehle falsch auszuführen. Die Folge sind unerwartete Aktivitäten auf den internen Daten- und Kontrollleitungen. Diese Aktivität kann Folgendes verursachen:

  • Beschädigung des CPU-Registers
  • Korruption der E/A-Register
  • I/O-Pin zufälliges Umschalten
  • SRAM- Korruption
  • EEPROM- Korruption

Die Brownout- Erkennung löst die meisten dieser Probleme in den meisten Systemen, indem sie das System abschaltet, wenn die Hauptstromversorgung unzuverlässig ist. Ein typisches System löst jedes Mal einen Timer erneut aus, wenn die AC-Hauptspannung 90 % ihrer Nennspannung überschreitet. Wenn der Timer abläuft, unterbricht er den Mikrocontroller, der dann sein System herunterfährt. Viele Systeme messen auch die Stromversorgungsspannungen, um eine langsame Verschlechterung der Stromversorgung zu verhindern.

Der Oszillator

Die Eingangsports von CMOS- Oszillatoren haben hohe Impedanzen und sind daher sehr anfällig für transiente Störungen. Nach dem Ohmschen Gesetz verursacht eine hohe Impedanz hohe Spannungsunterschiede. Sie sind auch sehr empfindlich gegenüber Kurzschlüssen durch Feuchtigkeit oder Staub.

Ein typischer Fehler ist, wenn die Stabilität der Oszillatoren beeinträchtigt ist. Dies kann dazu führen, dass es stoppt oder seine Periode ändert. Die normalen Systemhedges bestehen darin, einen Hilfsoszillator zu haben, der ein billiges, robustes Schema verwendet, wie beispielsweise einen Ring von Invertern oder einen Widerstands-Kondensator-One-Shot-Timer. Nach einem Reset (möglicherweise verursacht durch einen Watchdog-Timer) kann das System auf diese standardmäßig zurückgreifen und den empfindlichen Quarzoszillator erst einschalten, wenn Timing-Messungen sich als stabil erwiesen haben. Bei hochzuverlässigen Systemen ist es auch üblich, die Taktfrequenz durch Vergleichen mit einem externen Standard zu messen, normalerweise einem Kommunikationstakt, der Stromleitung oder einem Widerstands-Kondensator-Timer.

Bursts von elektromagnetischen Störungen kann Taktperioden oder verursachen Runt - Impulse verkürzen , die zu fehlerhaftem Datenzugriff oder Befehlsausführung führen. Die Folge sind falsche Speicherinhalte oder Programmzeiger. Die Standardmethode, dies in der Hardware zu überwinden, besteht darin, einen Phasenregelkreis auf dem Chip zu verwenden, um das eigentliche Taktsignal des Mikrocontrollers zu erzeugen. Software kann Datenstrukturen regelmäßig überprüfen und kritische Ports mithilfe von Voting lesen, wobei die Lesevorgänge zeitlich oder räumlich verteilt werden.

Ein-/Ausgangsports

Ein-/Ausgangsports – auch Adressleitungen und Datenleitungen – verbunden durch lange Leitungen oder externe Peripherie sind die Antennen, die Störungen wirken lassen. Elektromagnetische Störungen können zu falschen Daten und Adressen auf diesen Leitungen führen. Starke Schwankungen können dazu führen, dass der Computer I/O-Register falsch liest oder sogar die Kommunikation mit diesen Ports unterbricht. Elektrostatische Entladung kann sogar Anschlüsse zerstören oder Fehlfunktionen verursachen.

Die Pins der meisten Mikrocontroller sind hochohmige Eingänge oder gemischte Ein- und Ausgänge. Eingangspins mit hoher Impedanz sind empfindlich gegenüber Rauschen und können falsche Pegel registrieren, wenn sie nicht richtig abgeschlossen sind. Pins, die nicht in einem IC abgeschlossen sind, müssen mit Widerständen verbunden werden. Diese müssen mit Masse oder Versorgung verbunden werden, um einen bekannten logischen Zustand zu gewährleisten.

Image
Ursache-Wirkungs-Abbildung. Die Ursache muss ermittelt werden, damit das Problem behoben werden kann.

Korrekturmaßnahmen

Eine Analyse möglicher Fehler vor der Korrektur ist sehr wichtig. Die Ursache muss ermittelt werden, damit das Problem behoben werden kann.

Die Motor Industry Software Reliability Association identifiziert die erforderlichen Schritte im Fehlerfall wie folgt:

  • Information/Warnung des Benutzers
  • Speichern Sie die fehlerhaften Daten, bis ein definierter Reset durchgeführt werden kann
  • Halten Sie das System in einem definierten Zustand, bis der Fehler behoben werden kann

Grundsätzlich setzt man Redundanz ein, um Fehlern entgegenzuwirken. Dies umfasst das Ausführen von zusätzlichem Code (zeitliche Redundanz) sowie das Halten zusätzlicher Bits (Redundanz im Raum).

Befehlszeiger (IP) Fehlermanagement

Ein gestörter Befehlszeiger kann zu schwerwiegenden Fehlern führen, wie beispielsweise einem undefinierten Sprung an eine beliebige Stelle im Speicher, an der unzulässige Befehle gelesen werden. Der Zustand des Systems ist undefiniert. IP-Fehler können durch die Verwendung von softwarebasierten Lösungen wie Funktionstoken und einer NOP-Folie (s) behandelt werden.

Viele Prozessoren, wie beispielsweise der Motorola 680x0, weisen eine Hardwarefalle auf, wenn sie auf einen unzulässigen Befehl stoßen. Anstelle des zufälligen Befehls wird ein korrekter Befehl ausgeführt, der im Trap-Vektor definiert ist. Traps können einen größeren Bereichsfehler verarbeiten als Funktionstoken und NOP-Slides. Ergänzend zu illegalen Befehlen handhaben Hardware-Traps sicher Speicherzugriffsverletzungen, Überläufe oder eine Division durch Null.

Token-Passing (Funktionstoken)

Image
Tokenübergabe als Ausführungsflusskontrolle
Image
C-Quelle: Tokenübergabe mit globaler Funktions-ID.

Eine verbesserte Rauschimmunität kann durch eine als Token-Passing bekannte Ausführungsflusssteuerung erreicht werden. Die rechte Abbildung zeigt schematisch das Funktionsprinzip. Dieses Verfahren behandelt Programmablauffehler, die durch die Befehlszeiger verursacht werden.

Die Implementierung ist einfach und effizient. Jede Funktion ist mit einer eindeutigen Funktions-ID versehen. Beim Aufruf der Funktion wird die Funktions-ID in einer globalen Variablen gespeichert. Die Funktion wird nur ausgeführt, wenn die Funktions-ID in der globalen Variablen und die ID der Funktion übereinstimmen. Wenn die IDs nicht übereinstimmen, ist ein Befehlszeigerfehler aufgetreten und es können spezifische Korrekturmaßnahmen ergriffen werden. Eine Beispielimplementierung von Token-Passing unter Verwendung einer in C programmierten globalen Variablen ist in der folgenden Quellenauflistung angegeben.

Dies ist im Wesentlichen eine "Arm / Fire"-Sequenz für jeden Funktionsaufruf. Das Erfordern einer solchen Sequenz ist Teil sicherer Programmiertechniken, da sie Toleranz für Einzelbitfehler (oder in diesem Fall Streubefehlszeiger) erzeugt.

Die Implementierung von Funktionstoken erhöht die Programmcodegröße um 10 bis 20 % und verlangsamt die Leistung. Um die Implementierung zu verbessern, kann die Funktions-ID anstelle von globalen Variablen wie oben als Argument im Funktionsheader übergeben werden, wie im folgenden Codebeispiel gezeigt.

Image
C-Quelle: Token-Übergabe mit Funktionsparametern

NOP-Folie

Mit NOP-Fills kann in einigen Fällen die Zuverlässigkeit eines Systems bei einem gestörten Befehlszeiger verbessert werden. Der gesamte Programmspeicher, der nicht vom Programmcode verwendet wird, wird mit No-Operation ( NOP ) -Anweisungen gefüllt . Im Maschinencode wird ein NOP-Befehl oft durch 0x00 dargestellt (zB Intel 8051, ATmega16 usw.). Das System wird in einem definierten Zustand gehalten. Am Ende des physikalischen Programmspeichers muss eine Befehlszeiger-Fehlerbehandlung (IPEH IP-Error-Handler) implementiert werden. In einigen Fällen kann dies ein einfaches Zurücksetzen sein.

Wenn während der Ausführung ein Befehlszeigerfehler auftritt und ein Programm auf ein mit NOP-Befehlen gefülltes Speichersegment zeigt, ist zwangsläufig ein Fehler aufgetreten und wird erkannt.

Drei Methoden zur Implementierung von NOP-Fills sind anwendbar:

  • Bei der ersten Methode wird der ungenutzte physikalische Speicher manuell durch Suchen und Ersetzen in der (HEX-) Programmdatei auf 0x00 gesetzt . Der Nachteil dieser Methode ist, dass dies nach jeder Kompilierung erfolgen muss.
Image
Programmspeicher gefüllt mit Code, NOPs und Errorhandler
  • Die zweite Methode verwendet die Fill- Option des Linkers, der die ungenutzten Speicherbereiche mit einer vordefinierten Konstante (in diesem Fall 0x00) auffüllt.
  • Die dritte Möglichkeit besteht darin, eine entsprechende Anzahl von NOP- Assembler- Direktiven direkt in den Programmcode aufzunehmen.

Bei Verwendung des CodevisionAVR C- Compilers können NOP-Füllungen einfach implementiert werden. Der Chip-Programmierer bietet die Möglichkeit, das Programm- Flash und das EEPROM zu bearbeiten , um es mit einem bestimmten Wert zu füllen. Bei einem Atmel ATmega16 muss kein Sprung auf die Reset-Adresse 0x00 implementiert werden, da der Überlauf des Befehlszeigers seinen Wert automatisch auf 0x00 setzt. Leider sind Resets aufgrund eines Überlaufs nicht gleichbedeutend mit einem absichtlichen Reset. Beim beabsichtigten Reset werden alle notwendigen MC-Register per Hardware zurückgesetzt, was nicht durch einen Sprung auf 0x00 geschieht. Daher wird diese Methode in den folgenden Tests nicht angewendet.

Image
Speicher vor und nach der Implementierung von Funktionstoken und NOP-Fills

E/A-Registerfehler

Die Mikrocontroller-Architektur erfordert, dass die I/O-Leitungen am äußeren Rand des Siliziumchips platziert werden. Somit sind I/O-Kontakte auf ihrem Weg zum Siliziumkern stark von transienten Störungen betroffen, und I/O-Register sind einer der anfälligsten Teile des Mikrocontrollers. Falsch gelesene I/O-Register können zu einem falschen Systemzustand führen. Die schwerwiegendsten Fehler können am Reset-Port und am Interrupt-Eingangsport auftreten. Gestörte Datenrichtungsregister (DDR) können das Schreiben auf den Bus verhindern.

Diese Störungen können wie folgt verhindert werden:

1. Zyklisches Update der wichtigsten Register

Durch zyklisches Aktualisieren des wichtigsten Registers und der Daten in den Datenrichtungsregistern in möglichst kurzen Abständen können Fehler reduziert werden. Somit kann ein falsch gesetztes Bit korrigiert werden, bevor es negative Auswirkungen haben kann.

2. Mehrfaches Lesen von Eingangsregistern

Ein weiteres Verfahren zum Filtern von Störungen ist das mehrfache Lesen von Eingangsregistern. Die eingelesenen Werte werden dann auf Konsistenz geprüft. Wenn die Werte konsistent sind, können sie als gültig angesehen werden. Eine Definition eines Wertebereichs und/oder die Berechnung eines Mittelwertes kann bei einigen Anwendungen die Ergebnisse verbessern.
Nebenwirkung : erhöhte Aktivität
Nachteilig ist die erhöhte Aktivität durch permanente Updates und Auslesungen von Peripheriegeräten. Diese Aktivität kann zusätzliche Emissionen und Fehler verursachen.
Externe Interrupt-Ports; Paketüberfluss
Externe Interrupts werden durch fallende/steigende Flanken oder High/Low-Potential am Interrupt-Port ausgelöst, was zu einer Interrupt-Anforderung (IRQ) im Controller führt. Hardware-Interrupts werden in maskierbare Interrupts und nicht-maskierbare Interrupts (NMI) unterteilt. Bei einigen zeitkritischen Funktionen kann das Auslösen maskierbarer Interrupts gestoppt werden. Bei einem Interrupt-Aufruf wird der aktuelle Instruktionszeiger (IP) auf dem Stack gespeichert und der Stack-Zeiger (SP) dekrementiert. Die Adresse der Interrupt-Service-Routine (ISR) wird aus der Interrupt-Vektortabelle gelesen und in das IP-Register geladen, und als Folge wird die ISR ausgeführt.
Werden Interrupts – aufgrund von Störungen – schneller erzeugt als verarbeitet, wächst der Stack, bis der gesamte Speicher belegt ist. Daten auf dem Stack oder andere Daten können überschrieben werden. Eine defensive Softwarestrategie kann angewendet werden. Der Stapelzeiger (SP) kann beobachtet werden. Das Anwachsen des Stapels über eine definierte Adresse hinaus kann dann gestoppt werden. Der Wert des Stack-Pointers kann zu Beginn der Interrupt-Service-Routine überprüft werden. Zeigt der SP auf eine Adresse außerhalb der definierten Stackgrenzen, kann ein Reset ausgeführt werden.

Daten Redundanz

Bei Systemen ohne Fehlererkennungs- und Korrektureinheiten kann die Zuverlässigkeit des Systems durch Schutz durch Software verbessert werden. Der Schutz des gesamten Speichers (Code und Daten) mag in Software nicht praktikabel sein, da dies einen inakzeptablen Overhead verursacht, aber es ist eine softwareimplementierte kostengünstige Lösung für Codesegmente.

Eine weitere elementare Anforderung digitaler Systeme ist die fehlerfreie Übertragung von Daten. Die Kommunikation mit anderen Komponenten kann die Schwachstelle und Fehlerquelle eines Systems sein. Ein gut durchdachtes Übertragungsprotokoll ist sehr wichtig. Die unten beschriebenen Techniken können auch auf übertragene Daten angewendet werden, wodurch die Übertragungszuverlässigkeit erhöht wird.

Zyklische Redundanz und Paritätsprüfung

Eine zyklische Redundanzprüfung ist eine Art Hash-Funktion, die verwendet wird, um eine Prüfsumme zu erzeugen , bei der es sich um eine kleine ganze Zahl aus einem großen Datenblock wie Netzwerkverkehr oder Computerdateien handelt. CRCs werden vor und nach der Übertragung oder Vervielfältigung berechnet und verglichen, um ihre Gleichheit zu bestätigen. Ein CRC erkennt alle Ein- oder Zwei-Bit-Fehler, alle ungeraden Fehler, alle Burst-Fehler, wenn der Burst kleiner als der CRC ist, und die meisten der Wide-Burst-Fehler. Paritätsprüfungen können auf einzelne Zeichen (VRC – Vertical Redundancy Check ) angewendet werden , was zu einem zusätzlichen Paritätsbit führt, oder auf einen Datenblock (LRC – Longitudinal Redundancy Check ), der ein Blockprüfzeichen ausgibt . Beide Methoden lassen sich relativ einfach durch die Verwendung einer XOR-Operation implementieren. Ein Kompromiss besteht darin, dass weniger Fehler erkannt werden können als beim CRC. Paritätsprüfungen erkennen nur ungerade Zahlen von gekippten Bits. Die geraden Bitfehlerzahlen bleiben unentdeckt. Eine mögliche Verbesserung ist die Verwendung von sowohl VRC als auch LRC, genannt Double Parity oder Optimal Rectangular Code (ORC).

Einige Mikrocontroller verfügen über eine Hardware-CRC-Einheit.

Verschiedene Arten der Vervielfältigung

Eine spezifische Methode der Datenredundanz ist die Duplizierung, die auf verschiedene Weise angewendet werden kann, wie im Folgenden beschrieben:

  • Datenvervielfältigung
Um mit Datenkorruption fertig zu werden, können mehrere Kopien wichtiger Register und Variablen gespeichert werden. Konsistenzprüfungen zwischen Speicherorten, die dieselben Werte speichern, oder Abstimmungstechniken können dann beim Zugriff auf die Daten durchgeführt werden.
Es müssen zwei verschiedene Modifikationen des Quellcodes implementiert werden.
  • Die erste entspricht dem Duplizieren einiger oder aller Programmvariablen, um Datenredundanz einzuführen, und dem Modifizieren aller Operatoren, um die eingeführte Kopie der Variablen zu verwalten.
  • Die zweite Modifikation führt Konsistenzprüfungen in den Kontrollfluss ein, so dass die Konsistenz zwischen den beiden Kopien jeder Variablen überprüft wird.

Beim Auslesen der Daten werden die beiden Datensätze verglichen. Eine Störung wird erkannt, wenn die beiden Datensätze nicht gleich sind. Ein Fehler kann gemeldet werden. Wenn beide Datensätze beschädigt sind, kann ein schwerwiegender Fehler gemeldet werden und das System kann entsprechend reagieren.

In den meisten Fällen unterliegen sicherheitskritische Anwendungen strengen Beschränkungen in Bezug auf Speicherbelegung und Systemleistung. Die Duplizierung des gesamten Variablensatzes und die Einführung einer Konsistenzprüfung vor jedem Lesevorgang sind aus Sicht der Fehlerabdeckung die optimale Wahl. Durch die Duplizierung des gesamten Variablensatzes kann ein extrem hoher Prozentsatz von Fehlern durch diese Software-Redundanztechnik abgedeckt werden. Auf der anderen Seite kann man durch Duplizieren eines geringeren Prozentsatzes von Variablen die erhaltene Fehlerabdeckung mit dem CPU-Zeit-Overhead abwägen.

Image
Eine experimentelle Analyse des CPU-Zeit-Overheads und der Anzahl duplizierter Variablen

Das experimentelle Ergebnis zeigt, dass das Duplizieren von nur 50 % der Variablen ausreicht, um 85 % der Fehler mit einem CPU-Zeitaufwand von nur 28 % abzudecken.

Zu beachten ist auch die Implementierung der Konsistenzprüfung, da diese in der Regel nach jedem Lesevorgang bzw. am Ende der Lebensdauer jeder Variablen durchgeführt wird. Eine sorgfältige Implementierung dieser Prüfung kann die CPU-Zeit und die Codegröße für diese Anwendung minimieren.

Image
C-Beispielcode: Duplizierung von Funktionsparametern
Image
C-Beispielcode: Duplizierung von Testbedingungen
  • Duplizierung von Funktionsparametern

Da die Erkennung von Fehlern in Daten durch Duplizieren aller Variablen und Hinzufügen von Konsistenzprüfungen nach jedem Lesevorgang erreicht wird, sind besondere Überlegungen bezüglich der Prozedurschnittstellen anzustellen. Parameter, die an Prozeduren übergeben werden, sowie Rückgabewerte werden als Variablen betrachtet. Daher wird jeder Prozedurparameter sowie die Rückgabewerte dupliziert. Eine Prozedur wird nach wie vor nur einmal aufgerufen, liefert aber zwei Ergebnisse zurück, die denselben Wert haben müssen. Die Quellenliste rechts zeigt eine Beispielimplementierung der Funktionsparameterduplizierung.

  • Testvervielfältigung

Einen Test zu duplizieren ist eine der robustesten Methoden, die es für die generische Soft-Error-Erkennung gibt. Nachteilig ist, dass weder über die Fehlerursache (EMI, ESD etc.) noch über die Art der zu erwartenden Fehler (Fehler, die den Kontrollfluss beeinträchtigen, Fehler, die Daten beeinträchtigen, etc.) gemacht werden können. Fehlerhafte Bitänderungen in Datenbytes, während sie im Speicher, Cache, Register gespeichert oder auf einem Bus übertragen werden, sind bekannt. Diese Datenbytes können Operationscodes (Anweisungen), Speicheradressen oder Daten sein. Somit ist dieses Verfahren in der Lage, eine Vielzahl von Fehlern zu erkennen und ist nicht auf ein bestimmtes Fehlermodell beschränkt. Bei dieser Methode erhöht sich der Arbeitsspeicher etwa um das Vierfache und die Ausführungszeit beträgt etwa das 2,5-fache des gleichen Programms ohne Testduplizierung. Das Quellenverzeichnis auf der rechten Seite zeigt eine Beispielimplementierung der Duplizierung von Testbedingungen.

  • Verzweigungsduplizierung
Image
Zweigniederlassungen

Im Vergleich zur Testduplikation, bei der eine Bedingung gegengeprüft wird, wird bei der Verzweigungsduplikation die Bedingung dupliziert.

Für jeden Bedingungstest im Programm sollte die Bedingung und der resultierende Sprung neu bewertet werden, wie in der Abbildung gezeigt. Erst wenn die Bedingung wieder erfüllt ist, wird der Sprung ausgeführt, ansonsten ist ein Fehler aufgetreten.

  • Doppelte Anweisung und Vielfalt in der Umsetzung

Was bringt es, wenn Daten, Tests und Verzweigungen dupliziert werden, wenn das berechnete Ergebnis falsch ist? Eine Lösung besteht darin, eine Anweisung vollständig zu duplizieren, sie jedoch anders zu implementieren. Es werden also zwei unterschiedliche Programme mit gleicher Funktionalität, aber mit unterschiedlichen Datensätzen und unterschiedlichen Implementierungen ausgeführt. Ihre Ausgaben werden verglichen und müssen gleich sein. Diese Methode deckt nicht nur Bit-Flips oder Prozessorfehler ab, sondern auch Programmierfehler (Bugs). Sollen insbesondere Hardware-(CPU-)Fehler behandelt werden, kann die Software über verschiedene Teile der Hardware realisiert werden; beispielsweise verwendet eine Implementierung eine Hardware-Multiplikation und die andere Implementierung multipliziert durch Verschieben oder Addieren. Dies verursacht einen erheblichen Overhead (mehr als ein Faktor von zwei für die Größe des Codes). Andererseits sind die Ergebnisse außergewöhnlich genau.

Häfen

Ports zurücksetzen und Ports unterbrechen

Reset-Ports und Interrupts sind sehr wichtig, da sie durch steigende/fallende Flanken oder High/Low-Potential am Interrupt-Port ausgelöst werden können. Transiente Störungen können zu ungewollten Resets führen oder Interrupts auslösen und damit zum Absturz des gesamten Systems führen. Für jeden ausgelösten Interrupt wird der Befehlszeiger auf dem Stack gespeichert und der Stack-Zeiger wird dekrementiert.

Versuchen Sie, die Anzahl flankengetriggerter Interrupts zu reduzieren . Wenn Interrupts nur mit einem Pegel ausgelöst werden können, hilft dies sicherzustellen, dass Rauschen an einem Interrupt-Pin keine unerwünschte Operation verursacht. Es ist zu beachten, dass pegelgetriggerte Interrupts zu wiederholten Interrupts führen können, solange der Pegel hoch bleibt. Bei der Implementierung muss dieses Merkmal berücksichtigt werden; wiederholte ungewollte Interrupts müssen im ISR deaktiviert werden. Ist dies nicht möglich, so sollte bei sofortiger Eingabe eines flankengetriggerten Interrupts eine Softwareprüfung des Pins auf Richtigkeit des Pegels ausreichen.

Für alle ungenutzten Interrupts muss eine Fehlerbehandlungsroutine implementiert werden, um das System nach einem unbeabsichtigten Interrupt in einem definierten Zustand zu halten.

Unbeabsichtigte Resets stören den korrekten Programmablauf und sind für umfangreiche Anwendungen oder sicherheitskritische Systeme nicht akzeptabel.

Differenzierung zurücksetzen (Kalt-/Warmstart)

Eine häufige Systemanforderung ist die automatische Wiederaufnahme der Arbeit nach einer Störung/Störung. Es kann sinnvoll sein, den Zustand eines Systems beim Herunterfahren aufzuzeichnen und die Daten in einem nichtflüchtigen Speicher zu speichern. Beim Hochfahren kann das System bewerten, ob das System aufgrund einer Störung oder eines Fehlers wieder anläuft (Warmstart), und der Systemstatus kann wiederhergestellt oder ein Fehler angezeigt werden. Bei einem Kaltstart können die gespeicherten Daten im Speicher als gültig betrachtet werden.

Externe Stromaufnahmemessung

Image
Hard- und Software-Kombination: Erkennung von Netzschwankungen mittels AD-Wandler

Diese Methode ist eine Kombination aus Hard- und Softwareimplementierungen. Es schlägt eine einfache Schaltung vor, um eine elektromagnetische Störung mit den eigenen Ressourcen des Geräts zu erkennen. Die meisten Mikrocontroller, wie der ATmega16, integrieren Analog-Digital-Wandler (ADCs), mit denen ungewöhnliche Schwankungen der Stromversorgung durch Störungen erkannt werden könnten.

Wenn die Software eine Störung erkennt, könnte der Mikrocontroller in einen sicheren Zustand übergehen, während er darauf wartet, dass die Aggression vorbei ist. Während dieses sicheren Zustands sind keine kritischen Ausführungen erlaubt. Die Grafik zeigt, wie eine Interferenzerkennung durchgeführt werden kann. Diese Technik kann problemlos mit jedem Mikrocontroller verwendet werden, der über einen AD-Wandler verfügt.

Wachhund

Ein Watchdog-Timer ist ein elektronischer Timer, der einen anormalen Betrieb anderer Komponenten erkennt und Korrekturmaßnahmen einleitet, um den normalen Betrieb wiederherzustellen. Es stellt insbesondere sicher, dass mikrocontrollergesteuerte Geräte nicht vollständig ausfallen, wenn ein Softwarefehler oder ein kurzzeitiger Hardwarefehler auftritt. Watchdog-Timer basieren typischerweise entweder auf einem monostabilen Timer oder einem digitalen Zähler. Die Timer-Schaltung kann auf dem Mikrocontroller-Chip integriert oder als externe Schaltung implementiert sein. Watchdog-Timer können die Zuverlässigkeit eines Mikrocontrollers in einer elektromagnetisch beeinflussten Umgebung deutlich verbessern.

Die Software teilt dem Watchdog in regelmäßigen Abständen mit, dass er noch einwandfrei funktioniert. Wenn der Watchdog nicht informiert wird, bedeutet dies, dass die Software nicht mehr wie angegeben funktioniert. Anschließend setzt der Watchdog das System in einen definierten Zustand zurück. Während des Resets kann das Gerät keine Daten verarbeiten und reagiert nicht auf Anrufe.

Da die Strategie zum Zurücksetzen des Watchdog-Timers sehr wichtig ist, müssen zwei Voraussetzungen erfüllt werden:

  • Der Watchdog darf nur zurückgesetzt werden, wenn alle Routinen ordnungsgemäß funktionieren.
  • Der Reset muss so schnell wie möglich durchgeführt werden.

Eine einfache Aktivierung des Watchdogs und regelmäßige Resets des Timers nützen einen Watchdog nicht optimal. Für beste Ergebnisse muss der Refresh-Zyklus des Timers so kurz wie möglich eingestellt und von der Hauptfunktion aufgerufen werden, damit ein Reset durchgeführt werden kann, bevor ein Schaden entsteht oder ein Fehler aufgetreten ist. Wenn ein Mikrocontroller keinen internen Watchdog hat, kann eine ähnliche Funktionalität durch die Verwendung eines Timer-Interrupts oder eines externen Geräts implementiert werden.

Brown-out

Eine Brown-Out- Schaltung überwacht den VCC-Pegel während des Betriebs, indem er ihn mit einem festen Triggerpegel vergleicht. Wenn VCC unter den Triggerpegel fällt, wird der Brown-Out-Reset sofort aktiviert. Wenn VCC wieder ansteigt, wird die MCU nach einer gewissen Verzögerung neu gestartet.

Siehe auch

Anmerkungen

Externe Links