hallo,
eine kurze Frage zur Fehlerwahrscheinlichkeit beim Einsatz von Zeigern
auf ein Array.
Gibt es für einen Controller nachweisbar einen Unterschied in der
Fehlerwahrscheinlichkeit, wenn man einen Zeiger "wild" in einem Feld
herumsprignen lässt im Vergleich zu einem stetigen Inkrementieren?
Man könnte ja beispielsweise alle Elemente eines Arrays aufaddieren
wollen und den Zähler im ersten Fall der Reihe nach von [0] bis [n-1]
laufen lassen, im zweiten Fall in zufälliger Reihenfolge, wobei
natürlich jedes Feld nur einmal ausgelesen werden soll.
Wäre diese zweite Variante physikalisch fehlerträchtiger oder nicht?
Wenn du sicherstellst, dass jedes Elemant nur einmal gelesen wird, dann
sollte es keinen Unterschied machen, ob durchgehend aufsteigend oder
wild durch einander gelesen wird.
Mir stellen sich nur die Fragen:
1) Echte Zufallszugriffe beim Mikrocontroller? Wie willst du das
umsetzen?
2) Warum sollte sich jemand die Arbeit machen mit Zufallszugriffen +
check, auf Einzelzugriff pro Element, wenn er doch einfach alle Elemente
der Reihe durchgehen kann.
@Error (Gast)
>eine kurze Frage zur Fehlerwahrscheinlichkeit beim Einsatz von Zeigern>auf ein Array.
Der Zugriff auf ein Array über einen Index ist sicherer, weil man den
Index vor jedem Zugriff auf den gültigen Bereich prüfen kann.
Beim Zugiff über einen einfachen Pointer mit Post/pre Dekrement etc.
geht das nicht!
>Gibt es für einen Controller nachweisbar einen Unterschied in der>Fehlerwahrscheinlichkeit, wenn man einen Zeiger "wild" in einem Feld>herumsprignen lässt im Vergleich zu einem stetigen Inkrementieren?
Hmm, der formale Nachweis könnte einfacher und sicherer sein, weil
deterministisch und einfacher strukturiert.
>laufen lassen, im zweiten Fall in zufälliger Reihenfolge, wobei>natürlich jedes Feld nur einmal ausgelesen werden soll.
Dann brauchst du aber einen Algorithmus, der alle Indizes zufällig, aber
dennoch jeweils einmalig erzeugt. Machbar, aber nicht einfacher.
>Wäre diese zweite Variante physikalisch fehlerträchtiger oder nicht?
Theoretisch vielleicht nicht, praktisch schon.
Error schrieb:> Wäre diese zweite Variante physikalisch fehlerträchtiger oder nicht?
?
Wenn du da unterschiedliche Ergebnisse kriegst, dann ist entweder
tatsächlich in der CPU irgendwas grauslich kaputt (das würde sich aber
auch an anderen Stellen bemerkbar machen) oder aber (die viel
wahrscheinlichere Variante): du hast ganz banal einen Fehler im
Programm.
Für die CPU ist ein Adressierung über Pointer nichts irgendwie
spezielles. 2 Zahlen werden addiert. Erst danach trennen sich die Wege
und in dem Fall wird das Ergebnis auf den Adressbus gelegt und vom
Speicher der Wert von dieser Stelle abgerufen. Letzteres passiert aber
auch, wenn du sequentiell durch das Array durchgehst. Der einzige
Unterschied: die Addition, die in dem einen Fall aus irgendeinem
berechnetem Wert besteht und im anderen Fall aus einer schnöden Addition
mit einer Konstanten.
Hallo,
Falk Brunner schrieb:> Der Zugriff auf ein Array über einen Index ist sicherer, weil man den> Index vor jedem Zugriff auf den gültigen Bereich prüfen kann.>> Beim Zugiff über einen einfachen Pointer mit Post/pre Dekrement etc.> geht das nicht!
Da möchte ich doch wiedersprechen. Auch bei einem Post/Pre-Dekrement
kann geprüft werden, ob der Pointer noch in den gültigen Bereich zeigt -
zumindest insoweit, dass keine anderen Speicherbereiche betroffen sind,
häufig auch exakt:
Dabei sind allerdings zur vollständigen Sicherheit noch weitere
Kleinigkeiten zu beachten, wie z.B. dass die Überprüfung des Pointers
sowie das Auslesen des Wertes zusammen als eine Atomic Operation
durchgeführt werden muss.
Ich würde sogar so weit gehen, dass das sequenzielle Auslesen des
Speichers mit Pre- oder Postinkrement sogar weniger fehleranfällig ist,
da im Fall der Indizierung zwei Variablen fehlerhaft sein könnten (der
Pointer und der Index) und eine (oder mehrere) zusätzliche Operation(en)
(Addition des Index auf den Pointer) notwendig sind.
Insgesamt unterscheiden sich die beiden Varianten allerdings nur
marginal, wenn sie richtig implementiert werden. Handelt es sich um
sicherheitsrelevante Anwendungen, kann man über einen Speicherschutz
nachdenken (entweder in Hardware - ECC - oder in Software - Redundante,
möglichst komplementäre Ablage, oder sogar durch redundante, sich im
Wertebereich unterscheidende Berechnung). Dann ist aber auch ein
Befehlssatzcheck sowie mindestens ein externer Watchdog angeraten.
Schöne Grüße,
Martin
...aber ist nicht ein Pointer nichts anderes als ein Datum auf dem
Adressbus?
Wenn ich nun ein Array derart auslese, dass ich den Adressbus in Form
eines Gray-Codes belege, also so, dass sich nach Möglichkeit von Adresse
zu Adresse immer nur ein Bit ändert, dann stelle ich mir schon vor, dass
insgesamt weniger Bitfehler auftreten würden...
...Oder verliert der Adressbus nach jedem Zugriff seine Daten absolut
vollständig?
Error schrieb:> ...aber ist nicht ein Pointer nichts anderes als ein Datum auf dem> Adressbus?
Ein Arrayzugriff über Index ist aber auch nichts anderes als ein Datum
auf dem Adressbus. Lediglich die Schreibweise ist eine andere.
> Wenn ich nun ein Array derart auslese, dass ich den Adressbus in Form> eines Gray-Codes belege, also so, dass sich nach Möglichkeit von Adresse> zu Adresse immer nur ein Bit ändert, dann stelle ich mir schon vor, dass> insgesamt weniger Bitfehler auftreten würden...
Da dürfen sowieso keine Bitfehler auftreten!
Auf dieser Ebene muss alles 100% perfekt funktionieren, ansonsten ist
das alles unbrauchbar. Wenn von der CPU der Befehl kommt, das Byte von
der Adresse 100 zu lesen, dann muss da auch das Byte von der Adresse 100
gelesen werden. Und wenn der nächste Befehl von 105 lesen will, dann
muss auch von 105 gelesen werden.
Was tust du denn wenn 2 Variablen einmal zufällig hintereinander im
Speicher liegen und bei einer Programmänderung kommen sie getrennt
voneinander zu liegen? Das eine mal funktioniert der Zugriff und das
andere mal nicht? Oder wie?
Wenn die CPU das Byte von einer bestimmten Adresse anfordert, dann muss
das klappen (sofern es den Speicher überhaupt an dieser Adresse gibt).
Und zwar 100% und zu jeder Zeit. Alles andere ist ein
Zufallszahlengenerator aber kein Computer.
Hallo,
Error schrieb:> ...Oder verliert der Adressbus nach jedem Zugriff seine Daten absolut> vollständig?
So ist es. Gray-Code würde sich nur dann anbieten, wenn er extern
überwacht wird. Dann kann man aber auch einen einfachen Zähler
einsetzen. Insgesamt eignet sich der Gray-Code nicht wirklich zur
Fehlererkennung, da die Hamming-Distanz weiterhin nur 1 beträgt.
Allerdings ist er gut geeignet (und dafür auch entwickelt worden), um
bei einer parallelen Datenübertragung (oder Sensorauswertung)
ungewünschte Zwischenzustände zu vermeiden. Ein Einsastzgebiet sind z.B.
digitale Weg- oder Winkelencoder.
Schöne Grüße,
Martin
Hallo,
Karl Heinz Buchegger schrieb:> Und zwar 100% und zu jeder Zeit. Alles andere ist ein> Zufallszahlengenerator aber kein Computer.
Naja, bei komplexeren Microcontrollern kommt man schon auf Fehlerraten
im Bereich von 1000-3000 FIT, also 1 bis 3 Fehler alle 10^6
Betriebsstunden. Wenn man entsprechend viele davon einsetzt (z.B. im
Automobilbereich), dann muss man sich hier schon Gedanken machen, wie
mit Fehlern umzugehen ist - und dabei gibt es dann kein "darf nicht"
oder "kann nicht".
Oder um es 'mal so auszudrücken: Wenn in jedem Fahrzeug im Schnitt 3
sicherheitsrelevante Steuergeräte verbaut sind (Motor, ABS, Airbag),
kommt es bei 43 Mio PKW in Deutschland bei einer durchschnittlichen
Betriebszeit von rund 500 Stunden im Jahr zu rund 60.000 Fehlern im
Jahr.
Die ISO 26262 schreibt vor, dass man für wirklich sicherheitskritische
Fehler, die in mindestens 10% der Fahrsituationen zu einem tödlichen
Unfall führen können und in denen der Fahrer nicht reagieren kann (ASIL
D) einen Diagnostischen Deckungsgrad von 99% erreichen muss. Damit wären
aber 600 Fehler pr Jahr potentiell tödlich, wovon dann statistisch
mindestens 60 tatsächlich mit einem tödlichen Unfall enden müssten.
Gut, dass das die Steuergeräte nicht wissen, und die tatsächliche Rate
erheblich darunter liegt...
Besonders deswegen, da in modernen Fahrzeugen in der Regel von den bis
zu 70 eingesetzten Steuergeräten 5 bis 10 als sicherheitsrelevant
einzustufen sind.
Insofern macht es schon Sinn sich zu überlegen, wie man die Berechnungen
in einem µC auch auf niedrigster Ebene überprüfen kann - die angedachte
pseudozufälligen Zugriffe sind jedoch dafür leider nicht geeignet.
Schöne Grüße,
Martin
Hi Martin,
wenn du davon ausgehen "musst", das in der CPU beim
Zugriff auf die Register oder den Speicher Fehler auftreten,
dann spielt es keine Rolle in welcher Weise du darauf zugreifst
der Fehler wird in jedem Fall auftreten
die einzigste Möglichkeit solche Fehler zu erkennen
und evenentuell zu korrigieren besteht darin,
das ganze mehrfach redundant auszulegen
das kannst du dann beliebig "Kompliziert" gestallten
(mehrere Zugriffe, mehrere CPUs, mehrere Compiler usw)
Gruss Uwe
Uwe B. schrieb:> das ganze mehrfach redundant auszulegen
Dann wäre noch näher zu untersuchen wie sich das Gerät nach kurzem
Spannungsausfall verhält. Entweder fängt es definiert bei Punkt NULL an
oder irgenwo mittendrin?? Da nützen auch 100 CPUs nichts wenn die
Strategie falsch war.
Na da wird es schon Techniken geben die das wieder sincron bekommen.
In der Luftfahrt sind ja auch redundante Systeme üblich.
Und da glaube ich nicht das sich alle Triebwerke im Flug abschalten und
eine Windows Loginfenster im Amaturenfeld erscheint :)
>Dann wäre noch näher zu untersuchen wie sich das Gerät nach kurzem>Spannungsausfall verhält. Entweder fängt es definiert bei Punkt NULL an>oder irgenwo mittendrin?? Da nützen auch 100 CPUs nichts wenn die>Strategie falsch war.
mir ging es nur um das Eingangsthema vom TE :
"Fehlerwahrscheinlichkeit beim Einsatz von Zeigern"
und wollte damit sagen das es meiner Meinung nach egal ist
wie die Software den Zugriff handelt, wenn von einem Hardwarefehler
in der CPU ausgegangen wird.
und ich glaube auch nicht das sich bei 100 CPUs zu einem Zeitpunkt x
bei allen genau der gleiche Fehler zeigt...
man hat dann halt 99 CPUs die richtig funktionieren und die müssen die
"defekte" dann halt erkennen und ausklammern
aber wie gesagt, ist ein beliebig kompliziertes Thema
Hallo,
in der Praxis wird man wie so oft ein abgestuftes Verfahren einsetzen;
je nach maximaler Kritikalität mit unterschiedlicher Tiefe und
Komplexität. Ein Beispiel könnte so aussehen:
Programm läuft auf einem µC; dieser überprüft die ihm zugängliche
Peripherie und sich selber so weit wie möglich (AD-Wandler durch
Referenzspannungen, Speucher durch ECC oder redundante Ablage,
Befehlssatz durch Durchführen einer Kontrollrechnung, Programmablauf).
Er wiederum wird von einem externen Element überwacht (kleiner
Zweitprozessor, Dual-Core-Lockstep, intelligenter Watchdog), welches bei
einer Abweichung des Verhaltens (auch das Zeitverhalten) des
Hauptprozessors vom Erwarteten unabhängig von diesem einen sicheren
Zustand herstellen kann (je nach der Komplexität des sicheren Zustands
richtet sich dann auch die Komplexität der Überwachungseinheit).
Ergänzend wird die Versorgungsspannung der beiden überwacht und bei
Unter- oder Überspannung der sichere Zustand ausgelöst.
Dies entspricht dann im Groben dem VDA-E-Gas-Konzept; die Details
auszuarbeiten ist allerdings knifflig, und dabei kann es dann durchaus
auch auf die Art des Zugriffs ankommen, da dieser zumindest bei dem
Befehlssatzcheck berücksichtigt sein muss (register indirect; register
indirect with index und/oder Art des Pipelinings). Ganz interessant wird
die Zugriffsmethode natürlich dann, wenn Caches mit im Spiel sind. Dabei
dürfte die zufällige Methode dann tatsächlich eine leicht höhere
Fehlerwahrscheinlichkeit haben, da es dann häufiger zu Cache-Miss und
Cache-Fill-Szenarien kommt.
Zum Thema 100 Prozessoren: Die in der Luft-/Raumfahrt üblichen Methodik,
mehrere Systeme parallel arbeiten zu lassen, sind natürlich (unter der
Voraussetzung, dass sie nicht redundant, sondern divergent ausgeführt
sind) ebenfalls zielführend. Hier ergeben sich dann - neben den
gewaltigen Kosten - ganz andere Problematiken bezüglich Synchronisation
und der Entscheidung, wer nun recht hat...
Insofern kann ich mich meinem Vorredner anschließen: "ist ein beliebig
komplexes Thema" ;-)
Schöne Grüße,
Martin
Error schrieb:> Man könnte ja beispielsweise alle Elemente eines Arrays aufaddieren> wollen und den Zähler im ersten Fall der Reihe nach von [0] bis [n-1]> laufen lassen, im zweiten Fall in zufälliger Reihenfolge, wobei> natürlich jedes Feld nur einmal ausgelesen werden soll.>> Wäre diese zweite Variante physikalisch fehlerträchtiger oder nicht?
Ja.
Ich habe häufig mit parallelen Interfaces am FPGA zu tun (DDR-RAM, ADC).
Die Testpattern die die meisten Fehlern provozieren sind, die aus einem
Pseudo-Noise- Generator. Wenn man genauer hinschaut da sind die
Arbeitsphasen am kritischsten bei dem die meisten bits wackeln.
also sechsel von adresse 0x0000 auf 0xFFFF und zurück wäre auch so was
kritisches. Da sackt auch die betriebsspannung ab, das kann schon in
kritische bereiche (-5%) gehen. Beliebt sind auch Muster wie 01010, da
kann das Übersprechen zwischen den leitungen Bits kippen lassen.
MfG