Forum: PC-Programmierung STM32 - Crc Berechnung in C# nachbilden


von stm32user (Gast)


Lesenswert?

Hallo,

ich möchte mit C# folgende Crc Funktion nachbilden:
1
uint32_t CRC_CalcCRC(uint32_t Data)
2
{
3
  CRC->DR = Data;
4
  
5
  return (CRC->DR);
6
}

In main wird diese Funktion so eingesetzt:
1
CRC_ResetDR();
2
CRCValue = CRC_CalcCRC(0x20423063);

In C# hab ich diesen Ansatz getestet:
1
UInt32 Crc = 0;
2
Crc = Crc ^ 0x20423063;
3
            
4
for (int i = 0; i < 32; i++)
5
  Crc = (Crc << 1) ^ 0x04C11DB7;

Was müsste ich in C# ändern ?

von Werner (Gast)


Lesenswert?

stm32user schrieb:
> uint32_t CRC_CalcCRC(uint32_t Data)
> {
>   CRC->DR = Data;
>
>   return (CRC->DR);
> }

Wo ist denn da eine Berechnung?
Da wird doch nur der übergebene Parameter in ein Strukt eingetragen.
Die CRC muss also anscheinend vorher schon bekannt sein...

Warum machst du nicht einfach das gleiche in C#?

von stm32user (Gast)


Lesenswert?

Hallo Werber,

diese Berechnung wird intern vom stm32 durchgeführt.

von Werner (Gast)


Lesenswert?

stm32user schrieb:
> CRCValue = CRC_CalcCRC(0x20423063);

Ich behaupte mal, dass nach dieser Zeile sowohl CRCValue als auch 
CRC->DR den Wert 0x20423063 haben...

von stm32user (Gast)


Lesenswert?

Nein eben nicht!

CRCValue hat den Wert: 0xC963AE3F

von Artur (Gast)


Lesenswert?

Schaue Mal ein paar Threads weiter unten ( 
Beitrag "Suche C# CRC32 Check kompatibel zum STM32 CRC32" ), das Thema war bei mir 
gerade aktuell.

von Dennis H. (c-logic) Benutzerseite


Angehängte Dateien:

Lesenswert?

CRC->DR  ist das Hardwareregister im STM32 für den CRC32-Teil.
Die Struct ist nur der Einfachheit halber zur Ansteuerung.

  crc = 0xffffffff;
  for(t=0;t<datalen;t++) {
      crc=Crc32Char(crc,data[t]);
  }
  crc ^= 0xffffffff;

Eventuell muß noch die Bitorder umgedreht werden vom STM32-Wert.

von stm32user (Gast)


Lesenswert?

C# Applikation:
1
UInt32 Crc = 0xffffffff;
2
Crc = Crc ^ 0x20423063;
3
for (int i = 0; i < 32; i++)
4
    if (System.Convert.ToBoolean(Crc & 0x80000000))
5
        Crc = (Crc << 1) ^ 0x04C11DB7;
6
    else
7
        Crc = (Crc << 1);

STM32 Applikation:
1
uint32_t CRC_CalcCRC(uint32_t Data)
2
{
3
  CRC->DR = Data;
4
  
5
  return (CRC->DR);
6
}
7
8
CRC_ResetDR();
9
CRCValue = CRC_CalcCRC(0x20423063);

Nun möchte ich von einem Datenblock die CRC Summer erzeugen. Hierfür 
gibt es bereits eine fertige Funktion in der stm32 Bibliothek. Es handel 
sich um folgende Funktion:
1
uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
2
{
3
  uint32_t index = 0;
4
5
  for(index = 0; index < BufferLength; index++)
6
  {
7
    CRC->DR = pBuffer[index];
8
  }
9
  return (CRC->DR);
10
}

Wenn ich diese Funktion in C# nachbilde erhalte ich nie die identische 
CRC Summe. Was müsste in der CRC Funktion ergänzt bzw. geändert werden?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

stm32user schrieb:
> Wenn ich diese Funktion in C# nachbilde erhalte ich nie die identische
> CRC Summe

Was sagt den das Datenblatt dazu welcher CRC und Welche Startwerte etc. 
zum Einsatz kommen?

von stm32user (Gast)


Angehängte Dateien:

Lesenswert?

Für die CRC Berechnung benutzt STM das Polynom 0x04C11DB7. Der Init Wert 
für die CRC Berechnung ist 0XFFFF FFFF. Bit-Reverse wird nicht 
verwendet.
Mit der BlockCrc Funktion CRC_CalcBlockCRC soll von einem ganzen 
Datenblock die Crc berechnet werden. Siehe C# Implementierung im Anhang.

von stm32user (Gast)


Lesenswert?

Das ist die STM32 Implementierung:
1
uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
2
{
3
  uint32_t index = 0;
4
5
  for(index = 0; index < BufferLength; index++)
6
  {
7
    CRC->DR = pBuffer[index];
8
  }
9
  return (CRC->DR);
10
}

von Jean Player (Gast)


Lesenswert?

Hi,
das habe ich mal selber geschrieben, sollte also funzen.
1
/**********************************************************************//**
2
<B>Function Name</B>    : CrcStm32Calc
3
<BR><B>Description</B>  : calculate the crc from the given string
4
@param Input            : start value from crc , her it is the usb one
5
              size of string
6
              string which will be calculate
7
@param Output           : None
8
@param Return           : crc checksum
9
*//***********************************************************************/
10
unsigned long CrcClass::CrcStm32Calc(unsigned long crc, unsigned long size, const char* buf)
11
{
12
  for(int i = 0; i < size; i++)
13
  {
14
    unsigned long data = 0;
15
    data |= *buf++;
16
    crc = CrcSTM32(crc, data);
17
  }
18
19
  return crc;
20
}
21
22
/**********************************************************************//**
23
<B>Function Name</B>    : CRC32WideFast
24
<BR><B>Description</B>  : calculate the crc from the given string
25
@param Input            : start value from crc , her it is the usb one
26
              size of string
27
              string which will be calculate
28
@param Output           : None
29
@param Return           : crc checksum
30
*//***********************************************************************/
31
unsigned long CrcClass::CRC32WideFast(unsigned long Crc, unsigned long Size, const char *Buffer)
32
{
33
  Size = Size >> 2; // /4  Size passed in as a byte count, assumed to be a multiple of 4
34
35
  while(Size--)
36
  {
37
    static const unsigned long CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial
38
      0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
39
      0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };
40
41
      Crc = Crc ^ *((unsigned long *)Buffer); // Apply all 32-bits
42
43
      Buffer += 4;
44
45
      // Process 32-bits, 4 at a time, or 8 rounds
46
47
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits
48
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; //  0x04C11DB7 Polynomial used in STM32
49
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
50
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
51
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
52
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
53
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
54
      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
55
  }
56
57
  return(Crc);
58
}
59
60
/**********************************************************************//**
61
<B>Function Name</B>    : CrcSTM32
62
<BR><B>Description</B>  : calculate the crc from the given string
63
@param Input            : help function for CrcStm32Calc function above
64
@param Output           : None
65
@param Return           : crc checksum
66
*//***********************************************************************/
67
unsigned long CrcClass::CrcSTM32(unsigned long Crc, unsigned long Data)
68
{
69
  int i;
70
71
  Crc = Crc ^ Data;
72
73
  for(i=0; i<32; i++)
74
    if (Crc & 0x80000000)
75
      Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32
76
    else
77
      Crc = (Crc << 1);
78
79
  return(Crc);
80
}

von Dennis H. (c-logic) Benutzerseite


Angehängte Dateien:

Lesenswert?

Bei meinem Projekt war die Kompatibilität zu gängigen Standards wichtig.

Teil für STM32

Auch geeignet für einzelne Bytes.

#include "stm32f4xx.h"

u32 CalcCRC32(u8 *buffer,u32 size)
{
  u32 i, j;
  u32 ui32;
  CRC->CR=1;
  asm("NOP");asm("NOP");asm("NOP");//delay for hardware ready
  i = size >> 2;

  while(i--) {
    ui32=*((u32 *)buffer);
    buffer += 4;
    ui32= __RBIT(ui32);//reverse the bit order of input data
    CRC->DR=ui32;
  }
  ui32=CRC->DR;
  ui32= __RBIT(ui32);//reverse the bit order of output data
  i = size & 3;
  while(i--) {
      ui32 ^= (u32)*buffer++;
    for(j=0; j<8; j++)
      if (ui32 & 1)
        ui32 = (ui32 >> 1) ^ 0xEDB88320;
      else
        ui32 >>= 1;
  }
  ui32^=0xffffffff;    //xor with 0xffffffff
  return ui32;      //now the output is compatible with 
windows/winzip/winrar
};

Teil für PC im Anhang (Der C-Source sollte doch nicht die Hürde in C# 
sein)

von Bernhard S. (menecken)


Lesenswert?

Funktionierende snippets gibts auf 
http://blog.csdn.net/cy757/article/details/8246605

C# Code:
1
static readonly uint[] Crc32Table =  
2
        {  
3
          0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,  
4
            0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD,  
5
            0x4C11DB70,0x48D0C6C7,0x4593E01E,0x4152FDA9,0x5F15ADAC,0x5BD4B01B,0x569796C2,0x52568B75,  
6
            0x6A1936C8,0x6ED82B7F,0x639B0DA6,0x675A1011,0x791D4014,0x7DDC5DA3,0x709F7B7A,0x745E66CD,  
7
            0x9823B6E0,0x9CE2AB57,0x91A18D8E,0x95609039,0x8B27C03C,0x8FE6DD8B,0x82A5FB52,0x8664E6E5,  
8
            0xBE2B5B58,0xBAEA46EF,0xB7A96036,0xB3687D81,0xAD2F2D84,0xA9EE3033,0xA4AD16EA,0xA06C0B5D,  
9
            0xD4326D90,0xD0F37027,0xDDB056FE,0xD9714B49,0xC7361B4C,0xC3F706FB,0xCEB42022,0xCA753D95,  
10
            0xF23A8028,0xF6FB9D9F,0xFBB8BB46,0xFF79A6F1,0xE13EF6F4,0xE5FFEB43,0xE8BCCD9A,0xEC7DD02D,  
11
            0x34867077,0x30476DC0,0x3D044B19,0x39C556AE,0x278206AB,0x23431B1C,0x2E003DC5,0x2AC12072,  
12
            0x128E9DCF,0x164F8078,0x1B0CA6A1,0x1FCDBB16,0x018AEB13,0x054BF6A4,0x0808D07D,0x0CC9CDCA,  
13
            0x7897AB07,0x7C56B6B0,0x71159069,0x75D48DDE,0x6B93DDDB,0x6F52C06C,0x6211E6B5,0x66D0FB02,  
14
            0x5E9F46BF,0x5A5E5B08,0x571D7DD1,0x53DC6066,0x4D9B3063,0x495A2DD4,0x44190B0D,0x40D816BA,  
15
            0xACA5C697,0xA864DB20,0xA527FDF9,0xA1E6E04E,0xBFA1B04B,0xBB60ADFC,0xB6238B25,0xB2E29692,  
16
            0x8AAD2B2F,0x8E6C3698,0x832F1041,0x87EE0DF6,0x99A95DF3,0x9D684044,0x902B669D,0x94EA7B2A,  
17
            0xE0B41DE7,0xE4750050,0xE9362689,0xEDF73B3E,0xF3B06B3B,0xF771768C,0xFA325055,0xFEF34DE2,  
18
            0xC6BCF05F,0xC27DEDE8,0xCF3ECB31,0xCBFFD686,0xD5B88683,0xD1799B34,0xDC3ABDED,0xD8FBA05A,  
19
            0x690CE0EE,0x6DCDFD59,0x608EDB80,0x644FC637,0x7A089632,0x7EC98B85,0x738AAD5C,0x774BB0EB,  
20
            0x4F040D56,0x4BC510E1,0x46863638,0x42472B8F,0x5C007B8A,0x58C1663D,0x558240E4,0x51435D53,  
21
            0x251D3B9E,0x21DC2629,0x2C9F00F0,0x285E1D47,0x36194D42,0x32D850F5,0x3F9B762C,0x3B5A6B9B,  
22
            0x0315D626,0x07D4CB91,0x0A97ED48,0x0E56F0FF,0x1011A0FA,0x14D0BD4D,0x19939B94,0x1D528623,  
23
            0xF12F560E,0xF5EE4BB9,0xF8AD6D60,0xFC6C70D7,0xE22B20D2,0xE6EA3D65,0xEBA91BBC,0xEF68060B,  
24
            0xD727BBB6,0xD3E6A601,0xDEA580D8,0xDA649D6F,0xC423CD6A,0xC0E2D0DD,0xCDA1F604,0xC960EBB3,  
25
            0xBD3E8D7E,0xB9FF90C9,0xB4BCB610,0xB07DABA7,0xAE3AFBA2,0xAAFBE615,0xA7B8C0CC,0xA379DD7B,  
26
            0x9B3660C6,0x9FF77D71,0x92B45BA8,0x9675461F,0x8832161A,0x8CF30BAD,0x81B02D74,0x857130C3,  
27
            0x5D8A9099,0x594B8D2E,0x5408ABF7,0x50C9B640,0x4E8EE645,0x4A4FFBF2,0x470CDD2B,0x43CDC09C,  
28
            0x7B827D21,0x7F436096,0x7200464F,0x76C15BF8,0x68860BFD,0x6C47164A,0x61043093,0x65C52D24,  
29
            0x119B4BE9,0x155A565E,0x18197087,0x1CD86D30,0x029F3D35,0x065E2082,0x0B1D065B,0x0FDC1BEC,  
30
            0x3793A651,0x3352BBE6,0x3E119D3F,0x3AD08088,0x2497D08D,0x2056CD3A,0x2D15EBE3,0x29D4F654,  
31
            0xC5A92679,0xC1683BCE,0xCC2B1D17,0xC8EA00A0,0xD6AD50A5,0xD26C4D12,0xDF2F6BCB,0xDBEE767C,  
32
            0xE3A1CBC1,0xE760D676,0xEA23F0AF,0xEEE2ED18,0xF0A5BD1D,0xF464A0AA,0xF9278673,0xFDE69BC4,  
33
            0x89B8FD09,0x8D79E0BE,0x803AC667,0x84FBDBD0,0x9ABC8BD5,0x9E7D9662,0x933EB0BB,0x97FFAD0C,  
34
            0xAFB010B1,0xAB710D06,0xA6322BDF,0xA2F33668,0xBCB4666D,0xB8757BDA,0xB5365D03,0xB1F740B4  
35
        };
36
        public static uint CRC32Software(byte[] pData, int Length)  
37
        {  
38
  
39
            uint nReg;
40
            uint nTemp = 0;  
41
            int i, n;  
42
            nReg = 0xFFFFFFFF;
43
            for (n = 0; n < Length; n++)  
44
            {  
45
                nReg ^= (uint)pData[n];  
46
                for (i = 0; i < 4; i++)  
47
                {  
48
                    nTemp = Crc32Table[(nReg >> 24) & 0xff]; 
49
                    nReg <<= 8;
50
                    nReg ^= nTemp; 
51
                }  
52
            }  
53
            return nReg;  
54
        }

C Code:
1
* Enable CRC clock */  
2
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);  
3
  
4
//STM32-CRC  
5
u32 CRC32(u8 *pBuf, u16 nSize)  
6
{  
7
        u32 index = 0;  
8
        CRC_ResetDR();
9
        for(index = 0; index < nSize; index++)  
10
        {  
11
            CRC->DR = (u32)pBuf[index];  
12
        }  
13
        return (CRC->DR);  
14
}

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.