CRC16 Prüfsumme vs. Hyper Terminal

Gast #355814
Lesenswert?

Tag zusammen!

Ich möchte via RS232 mit meinem DSP-Evaluation-Board mit dem PC
kommunizieren. Um eine einfache Dateiübertragung zu realisieren möchte
ich Daten mittels X-Modem Protokoll an Hyperterminal senden. Nun
enthalten X-Modem-Datenpakete am Ende eine 2Byte-CRC Checksumme.
Nachdem ich die verschiedensten Algorithmen (erfolglos) durchprobiert
habe, hab ich folgende Fragen:

1. Welches CRC Generatorpolynom verwendet Hypertermial intern?!
2. Hat jemand vielleicht eine C-Routine, die die CRC16
Hyperterminal-konform berechnet?

Vielen Dank schonmal,

Thomas
Gast #355815
Lesenswert?

hallo,

ick habe eben mal nachgeschaut, das x-modem-protokoll enthält nur eine
1-byte prüfsume die durch eine einfach addition aller bytes gebildet
wird ... schau mal in wikipedia unter x-modem ... vielleicht reicht der
artikel schon aus.

mfg
Gast #355819
Lesenswert?

Danke schonmal!

Konnte allerdings noch immer keine Verbindung herstellen. Selbst wenn
ich den Frame exakt so sende, wie er in o.g. Link als Beispiel dient,
stimmt die Checksumme nicht.
Weiteres Problem: Ich komme nicht auf die im Beispiel angegebene
Checksumme. Generelle Frage: Berücksichtige ich bei der CRC Berechnung
nur die reinen Nutzdaten oder auch den Header?!

Am Verzweifeln,

Thomas
Gast #355820
Lesenswert?

Problem gelöst. Falls mal jemand ähnliches vorhat:

Frame-Struktur für 1024 Byte 1k-XModem-Frame:

| STX | # | 0xFF-# | Byte 1 | ... | Byte 1024 | CRC HI | CRC LO |

Feststellungen:

1. Hyper-Terminal CRC-Berechnung erfolgt nach dem Polynom
x^16+x^12+x^5+x^0

2. Das im o.g. MSDN-Link angegebene Frame-Beispiel ist falsch:
a) Für eine 1024 Byte-übertragung muss im Header statt SOH ein STX
gesendet werden
b) Die Beispiel CRC-Werte sind falsch

3. Berechnung der Hyper-Terminal konformen CRC z.B. hiermit:

unsigned int calc_crc (unsigned char *ptr, unsigned int count)
{
  int crc=0,i;
  while (count>0)
  {
    crc=crc^(int)*ptr++<<8;
    for(i=0;i<8;i++)
    {
      if(crc&0x8000) crc=crc<<1^0x1021;
      else crc=crc<<1;
    }
    count--;
  };
  return(crc&0xffff);
}

mit
count: Anzahl Datenblöcke-1, hier: 1023
*ptr: Pointer auf ersten Datenwert

Rückgabe:
unsigned int crc

Gruß & schönen Feierabend!
#1591672
Lesenswert?

Hallo zusammen,

Thomas schrieb:
> unsigned int calc_crc (unsigned char *ptr, unsigned int count)
>
> {
>
>   int crc=0,i;
>
>   while (count>0)
>
>   {
>
>     crc=crc^(int)*ptr++<<8;   //(1)
>
>     for(i=0;i<8;i++)
>
>     {
>
>       if(crc&0x8000) crc=crc<<1^0x1021;
>
>       else crc=crc<<1;
>
>     }
>
>     count--;
>
>   };
>
>   return(crc&0xffff);
>
> }

Wie CRC-16 an sich funktioniert ist mir klar, aber mal abgesehen davon, 
dass Konstruktionen wie (1) sehr schwer zu lesen sind, ist mir nicht 
klar, wie diese funktion arbeitet. Insbesondere verstehe ich den Sinn 
von (1) nicht und wozu diese For-Schleife gut ist... Desweiteren ist mir 
nicht klar, was diese Funktion letztlich zurückgibt und warum das 
Ergebnis mit 0xffff verUNDet wird. Der Rückgabewert wird bei 
erfolgreicher Prüfung 0, oder?

vG Stephan

Ich bitte dringend um Hilfe
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.