Forum: PC-Programmierung Prozessorwechsel: Wie Code verifizieren?


von Steffen H. (steffenh)


Lesenswert?

Hallo zusammen,

ich habe eine alte embedded Software (Mitte der 90er), die ich auf eine 
moderne Prozessorarchitektur portieren möchte (68HC05 auf Cortex M4). 
Leider habe ich den Quellcode nicht zur Verfügung. Deshalb habe ich die 
Binärdaten disassembliert und dann händisch nach C decompiliert. 
Anschließend habe ich alles auf der neuen Prozessorarchitektur 
compiliert. Soweit schaut alles auch ganz gut aus. Allerdings würde ich 
gerne nachweisen, dass bei meiner Arbeit nichts daneben gegangen ist.

Welche Möglichkeit habe ich, den Code zu verifizieren? Macht man das per 
Unit Test o.ä.? Ich habe ein Verständnis vom Code, allerdings schätze 
ich, dass es dennoch recht aufwändig sein dürfte, Testvektoren zu 
schreiben. Besteht die Möglichkeit, das zu automatisieren? Etwa, indem 
ich eine Code-Coverage vorgebe und mein Tool mir daraus automatisch die 
Vektoren erzeugt?

Das Ganze ist Hobby und dementsprechend eng ist mein Budget. 100€ oder 
so wäre es mir wert. Habt ihr eine Idee?

Grüße
Steffen

von Martin M. (capiman)


Lesenswert?

Das alte Gerät hat funktioniert und eine bestimmte Aufgabe erfüllt?

Dann schaue, ob das neue Gerät ebenso diesselbe Aufgabe erfüllt!

=> 100 Euro bereits aufgebraucht, sorry.

Tests, die die Funktionen der Geräte (von außen) verifizieren.
Das Gerät stellt dann eine Black Box dar.
Tests kann man dann auf beiden Geräten laufen lassen und Ergebnis 
vergleichen.

Unit Tests auf Source Code Ebene gehen nur auf dem neuen Gerät,
weil vom alten Gerät ja kein Source Code existiert.

Manches hängt vielleicht auch etwas davon ab,
was das Gerät überhaupt macht, z.B. muss eine PWM erzeugt werden?
Oder lauscht es auf der seriellen Schnittstelle,
und reagiert dann demensprechend.
Oder blinken LEDs in einem bestimmten Takt und Takt soll beibehalten 
werden?
Oder oder oder ...?

: Bearbeitet durch User
von Steffen H. (steffenh)


Lesenswert?

Martin M. schrieb:
> Unit Tests auf Source Code Ebene gehen nur auf dem neuen Gerät,
> weil vom alten Gerät ja kein Source Code existiert.

Es gibt keinen Highlevel Sourcecode, das stimmt. Aber es gibt 
disassemblierten Assemblercode und damit dürfte es doch gehen.

Ich dachte daran, auf Unit Ebene zu testen. Das heißt, ich nehme mir ein 
Unterprogramm und lasse mir Testvektoren generieren, die die notwendige 
Code Coverage erreichen. Die lasse ich dann auf der alten 
Prozessorarchitektur laufen und zeichne die Ergebnisvektoren auf.

Anschließend wechsele ich auf meine neue Architektur und wiederhole 
alles. Die dortigen Ergebnisvektoren vergleiche ich dann mit denen der 
alten Architektur. Stimmen sie überein, ist alles in Ordnung.

Soweit die Theorie. Wie kann ich das in die Praxis umsetzen? Gibt es 
Tools, die das automatisieren?

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Da Embedded-Anwendugen nicht nur aus einem Programm bestehen, das im 
leeren Raum vor sich hinwerkelt, sondern mit der jeweiligen Peripherie 
des Microcontrollers arbeitet, ist eine "Verifikation" auf reiner 
Funktionsebene nicht zielführend.

Denn eine Funktion, die fehlerfrei einen Timer des 68hc05 initialisiert, 
macht auf einem Cortex M4 einfach ... gar nix.

Für die Portierung eines derartigen Projektes muss man die Gesamtheit 
analysieren, welche Peripheriefunktionen werden genutzt und welche 
Spezialitäten der Peripheriefunktionen müssen dabei berücksichtigt 
werden.

Erst wenn man das genau verstanden hat, kann man sich daran versuchen, 
in der Peripherie des neuen Microcontrollers Äquivalenzen zu suchen, um 
mit der das angestrebte Verhalten der alten Peripherie nachbilden zu 
können.

Das ist also um einiges komplexer als nur "Unterprogramme" daraufhin zu 
untersuchen, ob sie z.B. drei Werte korrekt miteinander verrechnen.

von Steffen H. (steffenh)


Lesenswert?

Harald K. schrieb:
> Da Embedded-Anwendugen nicht nur aus einem Programm bestehen, das im
> leeren Raum vor sich hinwerkelt, sondern mit der jeweiligen Peripherie
> des Microcontrollers arbeitet, ist eine "Verifikation" auf reiner
> Funktionsebene nicht zielführend.

Du hast recht, natürlich gibt es Programmteile, die auf die Peripherie 
zugreifen und ein 1:1 Unit Test ist für sie nicht sinnvoll. Allerdings 
liegen diese Programmteile im Abstraction Layer (mcal) und machen 
vielleicht 10% aus.

Die übrigen 90% sind Funktionscode und vollständig abstrahiert. Kennt 
jemand eine Möglichkeit, diesen Code quer zu testen?

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Ich habe mal die KI befragt, und die schlägt doch allen ernstes vor, 
dafür KI einzusetzen ;)

Ob dein Code allerdings dafür geeignet ist, wirst du selber rausfinden 
müssen.

Oliver

von Dieter S. (ds1)


Lesenswert?

Steffen H. schrieb:
>
> Die übrigen 90% sind Funktionscode und vollständig abstrahiert. Kennt
> jemand eine Möglichkeit, diesen Code quer zu testen?

Wenn es hauptsächlich darum geht dass aus Eingabedaten Ausgabedaten 
erzeugt werden kann man das z.B. auf Binärcode-Ebene mit einem Simulator 
testen. Man läßt die enstprechenden Funktionen im Simulator laufen und 
vergleicht die Ergebnisse, auch die Ausführungszeiten der Funktionen 
kann man damit vergleichen. Ein teures/professionelles Tool das so etwas 
kann wäre z.B. TRACE32, sehr viele der unterstützten CPUs lassen sich in 
einer fast identischen Umgebung wie im Debugger mit der echten Hardware 
auch simulieren (ohne dass die Hardware dazu benötigt wird). Es gibt 
natürlich auch noch viel andere Simulatoren, eventuell reicht ja schon 
QEMU.

Die Frage ist halt ob man es für die gewünschten CPUs mit möglichst nur 
einem Simulator zu tun hat und nicht unterschiedliche Tools benötigt.

: Bearbeitet durch User
von Alexander (alecxs)


Lesenswert?

Steffen H. schrieb:
> Leider habe ich den Quellcode nicht zur Verfügung. Deshalb habe ich die
> Binärdaten disassembliert und dann händisch nach C decompiliert.
> Anschließend habe ich alles auf der neuen Prozessorarchitektur
> compiliert.

Respekt!

von 900ss (900ss)


Lesenswert?

Steffen H. schrieb:
> Deshalb habe ich die Binärdaten disassembliert und dann händisch nach C
> decompiliert

Respekt auch von mir. Welche Werkzeuge hat du genutzt? Du hast das doch 
kaum "zu Fuß" gemacht? Klar, nacharbeiten schon.

Darf man wissen um was für ein Projekt es sich handelt? Wer bezahlt 
soetwas für eine Kaffeemaschine ;) Das muss sich ja lohnen.

von Harald K. (kirnbichler)


Lesenswert?

Steffen H. schrieb:
> Allerdings
> liegen diese Programmteile im Abstraction Layer (mcal) und machen
> vielleicht 10% aus.

Du glaubst, daß derjenige, der vor Ewigkeiten mal den Code für Deinen 
68hc05 entwickelt hat, sich an diese Designrichtlinie gehalten und einen 
sauberen "abstraction layer" verwendet hat?

Optimismus im Wandel der Zeiten.

von Bruno V. (bruno_v)


Lesenswert?

Möchtest Du prüfen, ob der C-Code auf dem HC05 das gleich macht wie der 
Assembler-Code?

Hast Du "Ausgaben"? Eine serielle Schnittstelle, ein Display, etc?

Solange das "schnell" ist, kannst Du Testvektoren auch als vollständige 
Kombination sinnvoller Einzelwerte aller Eingangsgrößen per x-fach 
verschachtelter Schleife durchlaufen lassen. Einmal die 
Assembler-Routinen und dann den compilierten C-Code auf HC05, PC und 
neuer CPU.

Läuft der C-Code auf dem HC05 denn schon "rund"?

von Steffen H. (steffenh)


Lesenswert?

900ss schrieb:
> Welche Werkzeuge hat du genutzt? Du hast das doch
> kaum "zu Fuß" gemacht? Klar, nacharbeiten schon.

Ja, alles zu Fuß. Der Instruction Set des 68HC05 ist super simpel, da 
geht das recht gut. Je nach Umfang kostet das dann die Abendstunden von 
ein paar Wochen. Aber das geht schon.


Harald K. schrieb:
> Du glaubst, daß derjenige, der vor Ewigkeiten mal den Code für Deinen
> 68hc05 entwickelt hat, sich an diese Designrichtlinie gehalten und einen
> sauberen "abstraction layer" verwendet hat?

Ich habe den Code hier vor mir liegen. Deshalb glaube ich es nicht, ich 
weiß es :)

von Steffen H. (steffenh)


Lesenswert?

@all:

Die Box mit dem neuen Prozessor anschließen und mal schauen, ob sie so 
tut wie die alte, habe ich bereits gemacht. Sie tut erst einmal, was sie 
soll. Aber ich kann unmöglich alle Permutationen der Eingangssignale 
abfahren. Es ist ja auch ein speicherndes, zeitinvariantes System. 
Deshalb möchte ich auf Unit Ebene wirklich nachweisen, dass die neue Box 
sich funktional identisch zur alten verhält (validieren vs. 
verifizieren).

Wenn ich das alles händisch machen muss, beispielsweise in einer 
Simulationsumgebung, werde ich ewig daran sitzen. Das muss doch 
automatisiert gehen. Ein "einfacher" Back-to-Back Test. Oder eben halt 
nicht so "einfach"...


Natürlich wäre es auch ein Weg, meinen C-Code wieder in Assembler zu 
übersetzen und mit dem Disassembly des 68HC05 zu vergleichen. Danke für 
den Anstoß. Eventuell ist das am Ende tatsächlich die leichtere Methode.

: Bearbeitet durch User
von Dieter S. (ds1)


Lesenswert?

Und warum nicht den 68HC05 simulieren und damit dann Testvektoren 
vergleichen? Es gibt mehr als einen Simulator für diese einfache CPU, 
u.a. den hier:

https://github.com/philpem/m68emu

Vermutlich könnte damit sagar ein aktueller Mikrocontroller das 
ursprüngliche Binary in vergleichbarer Geschwindigkeit laufen lassen 
(abgesehen von der Peripherie, die bei der 68HC05 Familie aber ebenfalls 
sehr überschaubar ist).

von Bruno V. (bruno_v)


Lesenswert?

Steffen H. schrieb:
> alle Permutationen der Eingangssignale

Dann gib mal einen Blick auf die Art und Umfang der Eingangswerte und 
die zeitliche Komponente.

(Ich hab das mal für ein refaktoriertes Modul gemacht. Es gab etwa 10 
Eingangsgrößen, die meisten nur einstellige Werte, manche bis mehrere 
Hundert. Und hunderte Variablen, die demnach zu setzen waren, allerdings 
ohne zeitkomponente. Die innerste Schleife lief ein paar Mrd Mal durch 
und der output wurde per memcmp geprüft.)

von Martin M. (capiman)


Lesenswert?

Emulierst du dann eigentlich die Befehle des 68HC05 auf dem Cortex-M4?

von 900ss (900ss)


Lesenswert?

Martin M. schrieb:
> Emulierst du dann eigentlich die Befehle des 68HC05 auf dem Cortex-M4?

Im Eingangspost steht doch genau, was er gemacht hat. Also keine 
Emulation.

Möglich wäre das sicher auch.

von Martin M. (capiman)


Lesenswert?

900ss schrieb:
> Martin M. schrieb:
>> Emulierst du dann eigentlich die Befehle des 68HC05 auf dem Cortex-M4?
>
> Im Eingangspost steht doch genau, was er gemacht hat. Also keine
> Emulation.
>
> Möglich wäre das sicher auch.

> "und dann händisch nach C decompiliert"

Wenn ich Folgendes habe:

        LDX     #0
Loop4711:
        INX
        CPX     #10
        BNE     Loop4711

dann gibt es mindestens 2 Varianten, wie es dann in C aussehen könnte:
(vom Prinzip her)

A) Die schönere Variante (mit Hirnschmalz, weil man Code verstehen muss)

for (i = 0; i < 10; ++i) { … }

B) Die "Raw"-Variante (mehr oder weniger mechanische Übersetzung)

    Execute_LDX(ExecutionEnvironment, 0)
Loop4711:
    Execute_INX(ExecutionEnvironment)
    Execute_CPX(ExecutionEnvironment, 10)
    if(Execute_BNE(ExecutionEnvironment)) goto Loop4711;

An eine Emulation zur Laufzeit hatte ich zuerst gar nicht gedacht...

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

Dieter S. schrieb:
> Und warum nicht den 68HC05 simulieren und damit dann Testvektoren
> vergleichen?

> Vermutlich könnte damit sagar ein aktueller Mikrocontroller das
> ursprüngliche Binary in vergleichbarer Geschwindigkeit laufen lassen

Naja eine Emulation braucht deutlich mehr Speicher und ist gerne Faktor 
0.01 "schneller" als das Orginal. resp. braucht im ∅ 100 - 1000 
Taktzyklen für die Emulation eines einzigen Orginaltaktes. Abgesehen 
davon, das sich eine Emulation bei priorisierten Programmablauf (bspw. 
Exception/IRQ und JUMP gleichzeitig) prinzipbedingt unterscheiden muß.

Die Verifikation des Simulator ist damit auch komplexer als eine 
funktionalle Re-Implemantation gegen die Requirements zu prüfen.

Bei "Schweinereien" wie selbstmodifizierenden Code kommt allerdings kaum 
um (vollständige) Emulation herum.

von Steffen H. (steffenh)


Lesenswert?

Die Idee, das per Emulation zu lösen, habe ich schnell wieder verworfen. 
Mein neuer Prozessor unterstützt "nur" den THUMB Befehlssatz und der ist 
wirklich sehr unterschiedlich zu dem des 68HC05. (Ganz im Gegensatz zum 
ARM Befehlssatz - der hätte wirklich gut gepasst.)

Ich werde mir schauen, dass ich meinen C-Code verifiziere. Also ihn, wie 
oben vorgeschlagen, wieder in Assembler übersetzen und dann mit dem 
Disassembly aus den originalen Binärdaten vergleichen. Wer weiß, 
vielleicht erwische ich mit viel Glück den Compiler, der damals Mitte 
der 90er im Projekt verwendet wurde. Dann ähnelt sich der Code und ich 
habe es leichter.

Vielen Dank für Eure Tipps!

Grüße
Steffen

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Steffen H. schrieb:
> Wer weiß,
> vielleicht erwische ich mit viel Glück den Compiler, der damals Mitte
> der 90er im Projekt verwendet wurde.

Du weißt mehr über das Projekt als daß Du nur den Binärdump hast? Oder 
was verleitet Dich dazu, anzunehmen, daß das in C geschrieben wurde? So 
etwas wie 68xx wurde auch oft direkt in Assembler programmiert ...

von Steffen H. (steffenh)


Lesenswert?

Da hast Du recht. Gut möglich, dass das Projekt direkt in Assembler 
geschrieben wurde.

von Dieter S. (ds1)


Lesenswert?

Steffen H. schrieb:
> Die Idee, das per Emulation zu lösen, habe ich schnell wieder verworfen.
> Mein neuer Prozessor unterstützt "nur" den THUMB Befehlssatz und der ist
> wirklich sehr unterschiedlich zu dem des 68HC05. (Ganz im Gegensatz zum
> ARM Befehlssatz - der hätte wirklich gut gepasst.)

Was hat der Befehlssatz des Zielsystems mit einem Emulator zu tun, der 
üblicherweise in einer Hochsprache wie z.B. C geschrieben ist?

von Dieter S. (ds1)


Lesenswert?

Ein einfacher, schneller Test mit dem weiter oben verlinktem 68HC05 
Emulator auf einem Mikrocontroller:

- Testsystem: STM32 Nucleo Board mit einem STM32F446RE (Cortex M4)

- CPU Takt 180 MHz

- keine Optimierung beim Compiler (GCC)

- Speicherbedarf (RAM und Flash) ca. 34 KByte, davon 8 KByte RAM für den 
Speicherbereich des 68HC05 (Code/RAM/IO)

- der unten stehende Testcode braucht für 100000 68HC05 Taktzyklen ca. 
81 ms, also ca. 0.8 µs je 68HC05 Taktzyklus


Der Testcode:

1
         lda #20
2
         jsr delay
3
forever:
4
         bra forever
5
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
8
delay:
9
        stx save_x
10
11
delay_loop1:
12
13
        ldx #$FA
14
delay_loop2:
15
        nop
16
        decx
17
        bne delay_loop2
18
19
        deca
20
        bne delay_loop1
21
22
        ldx save_x
23
        rts

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Dieter S. schrieb:
> - keine Optimierung beim Compiler (GCC)

Und wie sieht das Ergebnis bei Optimierung auf 
Ausführungsgeschwindigkeit aus?

von Dieter S. (ds1)


Lesenswert?

Der obige Testcode braucht ca. 33 ms mit "-Ofast", also ca. 0.3 µs je 
68HC05 Taktzyklus.

Aber es geht nicht darum wie gut die Optimierung des Compiler ist 
sondern darum dass ein aktueller Mikrocontroller relativ problemlos den 
68HC05 schnell genug emulieren kann (ohne alle Details wie IO oder 
Interrupts zu berücksichtigen, es hängt immer von Einzelfall ab ob so 
eine Emulation auch Sinn macht).

Bei viele dieser 68HC05 liegt der Taktzyklus bei 0.5 µs bis 1 µs, 
entsprechend 2 MHz bzw. 1 MHz (entspricht einem Quarz mit 4 MHz bzw. 2 
MHz am 68HC05).

Der obige 68HC05 Testcode für den Emulator ist eine ca. 20 ms 
Verzögerung eines 68HC05 mit 4 MHz Quarz (ca. 40000 Taktzyklen), der 
Emulator mit "-Ofast" braucht dafür ca. 14 ms.

Und wenn es noch schneller sein soll nimmt man halt einen 
Mikrocontroller mit 400 MHz und mehr (z.B. einen der STM32Hxx).

Anderer Emulatoren für den 68HC05 gibt es natürlich auch, etwa der aus 
MAME.

von Daniel A. (daniel-a)


Lesenswert?

Decompiler sind nicht besonders zuverlässig. Als Beispiel, ich hab mal 
dieses Programm von mir dekompilieren lassen:
https://github.com/Daniel-Abrecht/dpa-utils/blob/ba2e0cc211221e0565a09bda88234648fa0182c5/src/main/example/utf8.c
https://dogbolt.org/?id=d365debe-8058-40a0-aeb6-09dfa4ef52d4

Das meiste wurde natürlich schon weg optimiert. Die verwendeten struct 
typen, die inline Funktionen, usw. von denen ist da natürlich nichts 
mehr zu sehen.
Nun, wie schlagen sich die Decompiler.

Hex-Rays macht das da noch am besten. Die Typen usw. stimmen so 
ungefähr, das würde funktionieren.
1
  __int64 v7; // [rsp+18h] [rbp-10h] BYREF
2
  v7 = 0xBA989FF024LL;
3
  dpa_u_puts_p_isra_0(4u, (char *)&v7 + 1);
Ghidra castet nach Long. Exotisch, sollte aber trotzdem noch gehen.
1
  undefined8 local_10;
2
  local_10 = 0xba989ff024;
3
  dpa_u_puts_p_isra_0(4,(long)&local_10 + 1);

Aber die anderen Decompiler versagen alle komplett.

BinaryNinja versagt beim Casten komplett:
1
  int64_t var_10 = 0xba989ff024;
2
  dpa_u_puts_p.isra.0(4, &*var_10[1]);

angr castet noch falscher, und vergisst dazu noch den Offset von einem 
byte:
1
  unsigned long long v3;  // [bp-0x10]
2
  v3 = 801424535588;
3
  dpa_u_puts_p.isra.0(4, &(char)v3);

dewolf initilisiert die Variable nicht, castet nicht, und der offset 
passt dann auch nicht:
1
  long var_3;
2
  dpa_u_puts_p_isra_0(4UL, &var_3 + 1L);

Reko initialisiert erst ein feld einer nicht-existenten Variable, dann 
übergibt es statdessen eine uninitialisierte Variable:
1
  qwLoc17.qw0007 = 801424535588;
2
  word64 qwLoc0F;
3
  dpa_u_puts_p.isra.0(0x04, &qwLoc0F);

Relyze übergibt ein 7 byte grosses char array. Das gefällt mir 
eigentlich. Aber leider initialisiert er es nicht:
1
  uint8_t local_0xF[7]; // [rsp-15]
2
  dpa_u_puts_p.isra.0( 4, &local_0xF );

RetDec übergibt eine uninitialisierte Variable:
1
  int64_t v4; // bp-15, 0x1060
2
  dpa_u_puts_p_isra_0(4, &v4);

Und was Snowman da veranstaltet, das wissen die götter:
1
int64_t main() {
2
    void* rsp1;
3
    void* rsp2;
4
    void* rsp3;
5
6
    rsp1 = reinterpret_cast<void*>(reinterpret_cast<int64_t>(__zero_stack_offset()) - 40);
7
    dpa_u_puts_p_isra_0(1, reinterpret_cast<int64_t>(rsp1) + 1);
8
    rsp2 = reinterpret_cast<void*>(reinterpret_cast<int64_t>(rsp1) - 8 + 8);
9
    dpa_u_puts_p_isra_0(2, reinterpret_cast<int64_t>(rsp2) + 9);
10
    rsp3 = reinterpret_cast<void*>(reinterpret_cast<int64_t>(rsp2) - 8 + 8);
11
    dpa_u_puts_p_isra_0(3, reinterpret_cast<int64_t>(rsp3) + 17);
12
    dpa_u_puts_p_isra_0(4, reinterpret_cast<int64_t>(rsp3) - 8 + 8 + 25);
13
    return 0;
14
}

Hex-Rays und Ghidra haben das hier zwar hin bekommen, aber auch da kann 
schnell mal mist raus kommen.

von Peter D. (peda)


Lesenswert?

Steffen H. schrieb:
> Aber ich kann unmöglich alle Permutationen der Eingangssignale
> abfahren.

So macht man das auch nicht.
Ich gehe mal davon aus, daß Du die Funktion des Gerätes kennst und Dir 
zuerst mal einen Programmablaufplan erstellt hast. Und diesen PAP kannst 
Du dann einfach durchsteppen.

Du mußt also nicht sämtliche Eingänge permutieren, sondern nur 
diejenigen auswerten, mit denen von einem erlaubten Zustand in alle 
erlaubten weiteren Zustände gewechselt wird.
Es wird dabei durchaus passieren, daß man Bugs in der alten Firmware 
aufspürt, die in verbotene Zustände laufen.

In der Regel schmeißt man den alten Assemblercode komplett weg und 
entwickelt nur die reine Funktionalität nach. Man kann ja jederzeit das 
alte Mustergerät bedienen, um noch unklare Details zu ermitteln.

Steffen H. schrieb:
> Natürlich wäre es auch ein Weg, meinen C-Code wieder in Assembler zu
> übersetzen und mit dem Disassembly des 68HC05 zu vergleichen.

Das dürfte so ziemlich das Unsinnigste sein. Damit verliert man 
sämtliche Kontrollmöglichkeiten und Plausibilitätsprüfungen.

Darf man mal fragen, welchen Umfang das Projekt überhaupt hat 
(Binärgröße, RAM-Verbrauch, Codezeilen in C)?

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Steffen H. schrieb:

> Welche Möglichkeit habe ich, den Code zu verifizieren?

Verifizieren bzw. Testen bedeutet im Endeffekt einen Vergleich zwischen 
"Soll" und "Ist". Damit man diesen Vergleich anstellen kann, muss man 
wissen was das "System Under Test" denn tun soll.

In dem konkreten Fall könnte man sich eventuell eine Referenz erstellen, 
indem man am alten System entsprechende Messungen durchführt. Sprich:
-Eingang E1 auf Wert X setzen, den Wert von Ausgang A1 protokollieren
-Eingang E1 auf Wert Y setzen, den Wert von Ausgang A1 protokollieren

und so weiter. Dafür gibt es ja auch Logic Analyzer, um solche Messungen 
durchzuführen.

Ich hoffe mal sehr, dass Dein unbekanntes, streng geheimes System nicht 
allzu viele Ein- und Ausgänge hat. :-)

von Peter D. (peda)


Lesenswert?

Ein Test nur mit Testvektoren wird in der Praxis auf keinen Fall 
ausreichend sein. Reale Geräte haben oft Zeitbedingungen, die 
eingehalten werden müssen.

Z.B. wird ein Gerät mit einem AT89C2051 nicht mehr laufen, wenn man es 
mit einem AT89LP2052 ausrüstet. Grund ist einfach, daß der LP die 
Instruktionen viel schneller ausführt und damit alle Abläufe zeitlich 
nicht mehr stimmen.
Das Programm wird natürlich rein logisch gesehen, exakt gleich 
ausgeführt. Nur werden Eingänge viel zu früh abgefragt und Ausgänge viel 
zu kurz gesetzt. Eine Blink-LED wird nur kurz aufblitzen, Baudraten sind 
zu hoch usw.

Im Idealfall hatte das alte Programm alle Zeitbedingungen bereits über 
einen Scheduler implementiert. Dann muß man nur die Zeitbasis für den 
Scheduler anpassen und alles sollte wieder laufen.
Nur wird das typisch nicht der Fall gewesen sein. Oftmals wurden 
Zählschleifen oder NOPs verwendet und das überall im Code verstreut.

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
Noch kein Account? Hier anmelden.