Hi! Versuche schon seit Tagen die CRC32 Prüfsumme von einem STM32F4 auf dem PC in C++ nach zu vollziehen. Weiss jetzt leider nicht mehr weiter. Auf dem STM32F4 werden mit der CRC_Block Berechnung ein Array mit 2 32Bit Werten berechnet. Leider schaffe ich es nicht auf das gleiche Ergebniss in C++ dem PC zu kommen. Habe schon einigen Beispielcode versucht. Bei nur einem 32Bit Werte klappt es im übrigen. Polynom = 0x4C11DB7 CRC initial value = 0XFFFFFFFF Datenbits = 32 Kann mir jemand dabei helfen? Viele Grüße
Hast du das da schon gelesen? https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CRC%20calculation%20in%20software
:
Bearbeitet durch Moderator
Nein, das hatte ich noch nicht gefunden. Schaue ich mir später mal genauer an. Vielen Dank schon mal :-).
Deepdiver99 schrieb: > Habe schon einigen Beispielcode > versucht. Auch den Code, der auf dem STM läuft? Das wäre doch am naheliegendsten. Georg
Georg schrieb: > Auch den Code, der auf dem STM läuft? Das ist leider kein C++-Code, sondern ein Logikgrab, in das man so leicht keinen Einblick bekommt ;-)
1 | void initCRC32_STM(uint32_t* crc) |
2 | { |
3 | *crc = 0xFFFFFFFF; |
4 | } |
5 | |
6 | void calcCRC32_STM(uint32_t* crc, uint32_t data) |
7 | { |
8 | uint32_t cnt; |
9 | |
10 | for(cnt=0;cnt<32;cnt++) |
11 | { |
12 | if((int32_t)(*crc ^ data)<0) |
13 | *crc = (*crc << 1) ^ 0x04C11DB7; |
14 | else |
15 | *crc <<= 1; |
16 | data <<=1; |
17 | } |
18 | } |
Oder so anders geschrieben. ;)
1 | void calcCRC32_STM(uint32_t* crc, uint32_t data) |
2 | { |
3 | uint32_t cnt; |
4 | |
5 | for(cnt=0;cnt<32;cnt++) |
6 | { |
7 | *crc = ((int32_t)(*crc ^ data))<0 ? (*crc << 1) ^ 0x04C11DB7 : *crc << 1; |
8 | data <<=1; |
9 | } |
10 | } |
Viel Spaß.
:
Bearbeitet durch User
Komme leider immer noch nicht klar. Bei dem Beispiel aus dem Link von YALU kommt nix gescheites raus.
1 | #include "stdafx.h" |
2 | #include <string.h> |
3 | #include <stdio.h> |
4 | |
5 | unsigned int CRC32WideFast(unsigned int Crc, unsigned int Size, char *Buffer) |
6 | {
|
7 | Size = Size >> 2; // /4 |
8 | |
9 | while(Size--) |
10 | {
|
11 | static const unsigned int CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial |
12 | 0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005, |
13 | 0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD }; |
14 | |
15 | Crc = Crc ^ *((unsigned int *)Buffer); // Apply all 32-bits |
16 | |
17 | Buffer += 4; |
18 | |
19 | // Process 32-bits, 4 at a time, or 8 rounds
|
20 | |
21 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits |
22 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // 0x04C11DB7 Polynomial used in STM32 |
23 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; |
24 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; |
25 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; |
26 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; |
27 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; |
28 | Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; |
29 | }
|
30 | |
31 | return(Crc); |
32 | }
|
33 | |
34 | char Buffer[] = {0x33,0x55}; |
35 | |
36 | int _tmain(int argc, _TCHAR* argv[]) |
37 | {
|
38 | printf("CRC : 0x%x\n", CRC32WideFast(0xffffffff, 2, Buffer)); |
39 | return(0); |
40 | }
|
Konnte jetzt aber nach langen probieren auf der Seite http://zorc.breitbandkatze.de/crc.html die CRC32 Prüfsumme vom STM32F4 nach voll ziehen. Der Anfangswert ist 0xffffffff. Daraus wird mit dem Datenbyte die Prüfsumme gebildet. Diese Prüfsumme nehmen ich dann als neuen Anfangswert für das nächste Datenbyte. Wie aber geht sie Sache "rückwärts" mit der letzten Prüfsumme?
Deepdiver99 schrieb: > char Buffer[] = {0x33,0x55}; Das kann ja nix werden. Ein Array mit der Größe von zwei Byte, aus dem vier Byte gelesen werden sollen. Im Code steht aber zu Glück: > Size = Size >> 2; // /4 Also wird 2/4 geteilt, ergibt hier 0. (ich hoffe jetzt kommt hier niemand mit halben Adressen ;) ) Und damit wird hier: > while(Size--) nie was ausgeführt, weil Size NULL ist.
Hast Recht:-). Jetzt wo du mir das erklärt hast sehe ich es auch. Na, dann probiere ich es noch mal mit char Buffer[] = {0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x55};
Stimmt aber immer noch nicht mit dem Ergebniss vom STM32F4
1 | /* Enable CRC clock */
|
2 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE); |
3 | |
4 | /* Reset CRC generator */
|
5 | CRC_ResetDR(); |
6 | |
7 | uint32_t buffer[2]; |
8 | buffer[0] = 0x33; |
9 | buffer[1] = 0x55; |
10 | uint32_t CRCValue = CRC_CalcBlockCRC((uint32_t *)buffer, 2); |
Da kommt dann beim STM32F4 = 0x5df6dc01 raus. Auf dem PC mit:
1 | char Buffer[] = {0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x55}; |
2 | |
3 | printf("CRC : 0x%x\n", CRC32WideFast(0xffffffff, 8, Buffer)); |
kommt = 0xf1d140a9 raus. Eigentlich müsste das jetzt doch gleich sein?
Der Inhalt deines Buffers ist falsch. Du übergibst im Moment 0x33000000 und 0x55000000. Versuch es mit: char Buffer[] = {0x33,0x00,0x00,0x00,0x55,0x00,0x00,0x00};
Little/Big endian? Probier mal
1 | char Buffer[] = {0x33,0x00,0x00,0x00,0x55,0x00,0x00,0x00}; |
Sonst kannst auch mal http://www.tty1.net/pycrc/index_en.html probieren.
Läuft :-) ! Vielen Dank für eure Hilfe. Was ist der Vorteil von der Lookup Tabelle? Höhere Geschwindigkeit?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.