Forum: Mikrocontroller und Digitale Elektronik CRC32 über 32bit Werte


von Hoellenprogger (Gast)


Lesenswert?

Hallo zusammen

Im STM32 ist eine 32bit CRC-Engine in Hardware vorhanden. Dort kann ich 
32bit werte hineingeben und es kommen 32bit werte heraus. Nun muss ich 
soetwas in Software nachbilden. Ich weiss wie das mit chars als 
eingangswerte funktioniert. Aber wie mache ich das mit 32bit 
eingangswerten? 4 Chars hintereinader funktioniert ja nicht.
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <inttypes.h>
4
#define CRC32POLYREV 0xEDB88320 /* CRC-32 Polynom, umgekehrte Bitfolge */
5
 
6
int datastream[]={1,0,0,0,1,1,0,0}; /* ASCII-"1", LSB zuerst */
7
int databits=8;
8
uint32_t crc32_rev=0xffffffff; /* Schieberegister, Startwert (111...) */
9
 
10
int main(void)
11
{   int i;
12
    for (i=0; i<databits; ++i)
13
        if ((crc32_rev & 1) != datastream[i])
14
             crc32_rev=(crc32_rev>>1) ^ CRC32POLYREV; 
15
        else 
16
             crc32_rev=crc32_rev>>1;
17
    printf("0x%08X\n",crc32_rev ^ 0xffffffff); /* inverses Ergebnis, MSB zuerst */
18
    return EXIT_SUCCESS;
19
}

Das ist von Wikipedia. Wenn ich das mit Databits = 32 mache 
funktionierts nicht. Muss noch etwas anderes geändert werden?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Aufpassen int ist ggf auf einem Microcontroller nur 16bit breit!

Und "funktioniert nicht" ist ein eindeutiger Fall von "Nutzer zu doof 
für Fehlerbeschreibung" Problem... ;)

WAS gibst du rein, WAS kommt raus, WAS erwartest du wären so die 
interesanten Fragen.

von Hoellenprogger (Gast)


Lesenswert?

Hallo

auf dem STM32 mit Keil ist int 32bit breit. Hab ich auch überprüft.

Funktioniert nicht heisst wenn ich einen Wert von 0 als bitfolge 
festlege, dann erwarte ich als Rest (also crc32_rev) 0x04c11db7. Ich 
erhalte aber 0x21ffdf1c.
1
int datastream[]={0,0,0,0, 0,0,0,0, 0,0,0,0 ,0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
2
int size = sizeof(datastream);
3
int databits=32;
4
5
unsigned int crc32_rev=0xffffffff; /* Schieberegister, Startwert (111...) */
6
7
    for (i=0; i<databits; ++i)
8
        if ((crc32_rev & 1) != datastream[i])
9
             crc32_rev=(crc32_rev>>1) ^ CRC32POLYREV;
10
        else
11
             crc32_rev=crc32_rev>>1;
12
    printf("0x%08X\n",crc32_rev ^ 0xffffffff); /* inverses Ergebnis, MSB zuerst */

Hier nochmal der auf 32bit erweiterte Code

von Hoellenprogger (Gast)


Lesenswert?

Hallo

Leider etwas verwirrt. Ich programmiere natürlich auf PC. Mit Borland 
und da ist int 32bit breit.

von eProfi (Gast)


Lesenswert?

"Mit Borland und da ist int 32bit breit."

Hast Du das überprüft?  bei TurboC ist es nämlich nur 16-Bit.
Long ist 32-Bit.


Stimmt der Startwert 0xffffffff mit dem der Hardwareunit überein?

Macht die HW-Unit am Schluß auch das
^ 0xffffffff ?

CRC ist halt nicht CRC...
Dazu haben wir schon etliche Beiträge geschrieben.
Hast Du schonmal eine andere SW-Routine versucht?

Normalerweise ist ja der Datenwert nicht als Bit-Array abgespeichert.

Das bekommen wir schon hin!

von Hoellenprogger (Gast)


Lesenswert?

Hallo

Manchmal hilft es echt ein paar Stunden etwas Anderes zu machen und dann 
nochmal in Ruhe das Ganze anzuschauen.

Ich habs jetzt geschafft. Man kann diese Routine benutzen nur müssen die 
Bitwerte gedreht werden (MSB<->LSB).

Das mit int hatte ich schon getestet. Sonst würde bei einer Zuweisung
1
unsigned int x = 0xffffffff;

eine Warnung kommen.

Das Problem an sich war, dass im Datenblatt des STM32 nicht genau stand, 
was die Hardware-Unit genau macht. Durch Probieren mit 0xaaaaaaaa und 
0x55555555 bin ich dann drauf gekommen.

von Reinhard (Gast)


Lesenswert?

Hallo,

habe auch das Problem die Hardware-CRC per Software nachzubilden.

Welche Bitwerte müssen gedreht werden?

kannst Du bitte die getestete Routine noch mitteilen?

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.