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).

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.