Programmieren - alles kontrollieren 4.940 Themen, 20.676 Beiträge

Hilfe mit C-Programm

Nobody666 / 12 Antworten / Baumansicht Nickles

Hallo,


hab hier anbei ein C-Programm. Es sollte am Ende so etwas wie S3 0A 00 00 00 4B 31 00 04 10 01 9B herauskommen(ohne Blanks). S3 ist hier fest, 09 sollte die anzahl der nachfolgenden Bytes sein, dann kommmen eine 4 Byte lange hexZahl, anschließend eine 5 Byte lange hexZahl und das letzte Byte sollte die Summe der Zahlen ab S3 sein.


Kann mir bitte jemand erklären, wie das ganze funktioniert, da ich es ein wenig umschreiben muß???


Danke


 


void OutputMotorolaFormat(FILE *fp, unsigned long addr, char *buffer, unsigned nbytes)
{
   unsigned i, j, bytecount, sumcheck;
   char c, *ptr = buffer;
   unsigned long localaddress = addr;


   for (i = 0; i < nbytes; i += 16) {
      bytecount = nbytes - i;
      if (bytecount > 16) bytecount = 16;
      fprintf(fp, "S3%02X%08lX", bytecount + 5, localaddress);
      sumcheck = bytecount + 5;
      for (j = 0; j < 3; j++)
         sumcheck += (localaddress >> (8 * j)) & 0xFF;
      for (j = 0; j < bytecount; j++) {
         fprintf(fp, "%02X", (int)(c = *ptr++));
         sumcheck += c;
      }
      fprintf(fp, "%02X\n", ~sumcheck & 0xFF);
      localaddress += bytecount;
   }
}

bei Antwort benachrichtigen
Andreas42 Nobody666 „Hilfe mit C-Programm“
Optionen

Hi!

Öh, schwierig... (und dabei bin ich kein C-Spezialist).

OK, langsam und von Vorne:

Übergeben wird eine Adresse und eine Byteanzahl.

Sinn ist eine Art Speicherdump Zeilenweise auszugeben.

Die Zeile beginnt mit "S3".
Dann folgt ein Byte, das die Länge der Zeile angiebt (im Beispiel $0A).
Nun folgt die übergebene Adresse, dargestellt durch 4 Bytes.
Diese 4 Bytes werden byteweise summert (die Adresse wird als Long interpretiert und Bitweise summiert).
In deinem Beisoiel ist die Adrsse $0000004B. Adiert wird $4B + $00 + $00 *$00
Das &0xFF ist die Maskierung als Byte. Mit >>(8*j) wird bitweise verschoben (im Beispiel zuerst (8*0, dann 8*1, dann 8*2, dann 8*3)

Ist die Angebene Bytesanzahl >0 gewesen, wird nun diese Anzahl an Bytes ab der angegebenen Speicheradresse ausgegeben. Der Wert des Bytes wird wieder auf die Prufsumme addiert. dabei wird der bereichnete Wert auf Byte maskiert (er wird daher nie >255).

Nun wird die Prüfsumme bitweise negiert, auf bytemaskiert und ausgebenen.

OK: letzte Besonderheit:

Die erste Vorschleife bewirkt, dass bei übergebenen nbytes > 16 das Ganze auf "Zeilen" mit max. 16 (Speicherdump)Bytes umgebrochen wird.

Ich hoffe, dass ich das nicht total falsch interpretiert habe. Die Bedeutung des Tile musste ich auch erst nachschlagen...

Ich hoffe, das war keine Hausaufgabe bzw. Hausarbeit...

Bis denn
Andreas

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
Nobody666 Andreas42 „Hi! Öh, schwierig... und dabei bin ich kein C-Spezialist . OK, langsam und von...“
Optionen

Hallo,
erstmal danke für die schnelle Antwort. Ist keine Hausaufgabe, will ein kleines Tool schreiben.
Also, hab eine 12 stellige Dezimalzahl (210453663745). Diese ist in einer Variablen gespeichert.
Ebenso hab ich einen hexawert in einer anderen Variablen gespeichert.
Aussehen soll das ganze nun so, und das Programm soll das irgendwie so ähnlich machen, funktioniert aber nicht:
S3 steht fest am Anfang, danach kommt eine Hexzahl, die die Anzahl der nachfolgenden Bits ausgibt. Hier 0A. Auch kein Problem.
Jetzt muß ich den Hexawert in der einer 4 Bit großen Hexdarstellung ausgeben. Geht auch einfach mit 08lx.
So, jetzt muß ich die Dezimalzahl verarbeiten, und zwar soll das ganze
so aussehen. 210453663745 wird zu 31 00 04 10 01 (ohne Blanks). 31000 muß auch noch vorangefügt werden.
Ist also Dezimalzahl in Hexaformat von hinten gelesen. Das ist mein erstes Problem. Am Schluß soll noch eine Summe dieser Zeile ab dem S3 stehen,in der Form: FF - (0A+00+00+00+4B+31+00+04+10+01).
Am Ende sollte also dastehen:
S30A0000004B310004100164
Wäre über Hilfe sehr dankbar, bin mit Latein und Nerven mehr als am
Ende!!!!

bei Antwort benachrichtigen
Andreas42 Nobody666 „Hallo, erstmal danke für die schnelle Antwort. Ist keine Hausaufgabe, will ein...“
Optionen

Hi!

Ich hab' verstanden worum es geht.

Mein Vorschlag: vergiss die vorhandene Routine.

Dieses kompakte C-Gequäle macht es IMHO nur unötig schwer.

Ich würde da so rangehen:

Bau einen Strinf auf, der deine Zeile enthält (bis auf die Prüfsumme am Schluss).
Deine "Dezimalzahl" würde ich dabei ebenfalls als Hex-Wert ausgeben und dann die Bytewerte "drehen" (bzw. die Zifferpaare entsprechend tauschen - als Stringmanipulation ist das ja kein Problem).

Falls nötig, hier der Hinweis auf sprintf() für die Ausgabe "in einen String".

Die Prüfsumme berechnest du dann aus dem String, indem jeweils zwei Ziffern wieder in einen Bytewert umgrechnet werden und dann addiert werden (-> sscanf()).

Bis denn
Andreas

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
Nobody666 Andreas42 „Hi! Ich hab verstanden worum es geht. Mein Vorschlag: vergiss die vorhandene...“
Optionen

@Andreas42.
Hi, hab Deinen Vorschlag mit Freuden aufgenommen.
Hab jetzt folgendes:
#include

bei Antwort benachrichtigen
Andreas42 Nobody666 „@Andreas42. Hi, hab Deinen Vorschlag mit Freuden aufgenommen. Hab jetzt...“
Optionen

Hi!

Das Problem geschieht warscheinlich beim Aufspalten des Hex-Strings in 2Ziffer-Werte:

for (int i=0; i sscanf(test,"%2x",&aufspaltung[i]);
}

In Test steht immer der selbe Hex-String und jedesmal werden die ersten 2 Ziffern ausgewertet. Du musst nach jedem Durchlauf die ersten zwei Ziffern von test abschneiden, damit auf den nächsten 2 Ziffern positioniert wird.

Bis denn
Andreas

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
Nobody666 Andreas42 „Hi! Das Problem geschieht warscheinlich beim Aufspalten des Hex-Strings in...“
Optionen

Hi,
da hast du Recht, das Problem liegt beim Aufspalten. Eigentlich sollte sscanf seine Suche beim erneuten aufruf unmittelbar nach dem zuletzt umgewandelten Zeichen, jedenfalls steht das überall so. Kannst du mir bitte sagen, wie ich das einbauen kann, damit das abgeschnitten wird?
Danke!!!!

bei Antwort benachrichtigen
mr.escape Nobody666 „Hi, da hast du Recht, das Problem liegt beim Aufspalten. Eigentlich sollte...“
Optionen
Eigentlich sollte sscanf seine Suche beim erneuten aufruf unmittelbar nach dem zuletzt umgewandelten Zeichen, jedenfalls steht das überall so.
Und zwar zu recht, aber nur innerhalb eines aufrufes. Z.B.:
sscanf(test,"%2x%2x",&aufspaltung[i],&aufspaltung[i+1]);
Hier werden zwei zwei nibble grosse hex zahlen , beginnend bei test in die variablen aufspaltung[i] und aufspaltung[i+1] gespeichert. Beim nächsten aufruf wird erneut bei test begonnen und die gleichen zwei doppel-nibble zahlen ermittelt.
Die lösung für dieses problem ist (allgemein):
sscanf(test+i*2,"%2x",&aufspaltung[i]);
In diesem spez. fall aber muss noch der uninteressante anfang("S3") übersprungen werden d.h.:
sscanf(test+i*2+2,"%2x",&aufspaltung[i]);
Die zeile:
sscanf(test,"%*2i",&aufspaltung[0]);
kann komplett entfallen (sie macht ja eh nix).

mr.escape
"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Nobody666 mr.escape „ Und zwar zu recht, aber nur innerhalb eines aufrufes. Z.B.: sscanf test, 2x 2x...“
Optionen

Großen Dank an
anreas42 und mr.escape. Es funktioniert!!!!!!!!

bei Antwort benachrichtigen
Andreas42 Nobody666 „Großen Dank an anreas42 und mr.escape. Es funktioniert!!!!!!!!“
Optionen

Hi!

Freut mich zu hören! :-)

Bis denn
Andreas

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
Nobody666 Nachtrag zu: „Hilfe mit C-Programm“
Optionen

Hi, nochmal eine kurze Frage:
gibt es, wenn ja wie lautet sie eine einfache Möglichkeit sicherzustellen, dass von der Prüfsumme immer nur die letzten beiden Zahlen z.B. 6E (bei 436E oder so) angezeigt werden?

bei Antwort benachrichtigen
Andreas42 Nobody666 „Hilfe mit C-Programm“
Optionen

Hi!

Schau nochmal in das "Original" in deinem Startbeitrag. Da wurde das gemacht:

fprintf(fp, "%02X\n", ~sumcheck & 0xFF);

Der Trick besteht darin, per Bitoperation, bei einem Intergerwert alle Bits auszublenden, die nicht zum Wertebereich passen. Das erfolgt hier mit & 0xFF.
Man kann das natürlich auch "zu Fuss" erledigen:

Prüffsumme nehmen, durch 256 teilen (Integerdivision = ohne Nachkommawert!). Das Ergebnis mal 256 nehmen und von der ursprünglichen Prüfsumme abziehen.
Der Rest liegt dann im Bereich 0 - 255.

Bis denn
Andreas

Hier steht was ueber mein altes Hard- und Softwaregedoens.
bei Antwort benachrichtigen
Nobody666 Nachtrag zu: „Hilfe mit C-Programm“
Optionen

Hi,
hab doch noch ein kleines Problem:
Meine Prüfsumme darf in Hexaform max 2stellig, d.h. bei einem Ergebnis von z.B. 45a25b darf nur 5b dann stehen(also immer die letzten 2 Ziffern). Hab schon irgendwie versucht, das wieder in einen String umzuwandeln und dann nur die letzten 2 anzuzeigen, geht aber leider nicht. Kann mir da noch bitte jemand weiterhelfen???
DANKE!!!!

bei Antwort benachrichtigen