von
stm32user (Gast)
30.08.2013 09:45
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)
30.08.2013 09:55
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)
30.08.2013 09:58
Hallo Werber,
diese Berechnung wird intern vom stm32 durchgeführt.
von
Werner (Gast)
30.08.2013 10:05
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)
30.08.2013 10:07
Nein eben nicht!
CRCValue hat den Wert: 0xC963AE3F
von
Artur (Gast)
30.08.2013 10:12
Schaue Mal ein paar Threads weiter unten (
Beitrag "Suche C# CRC32 Check kompatibel zum STM32 CRC32" ), das Thema war bei mir
gerade aktuell.
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)
02.09.2013 09:44
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?
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)
03.09.2013 08:19
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)
03.09.2013 08:20
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)
13.09.2013 13:15
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 }
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)
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.