STM32 - Crc Berechnung in C# nachbilden

Gast #3301039
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 ?
Gast #3301051
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#?
Gast #3304187
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?
Gast #3305310
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.
Angehängte Dateien:
Gast #3305311
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
}
Gast #3319523
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
}
Persönliche Seite #3321320
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)
Angehängte Dateien:
#3560584
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren