Hi Leuts, ich schreib nen Bootcode mit der aktuelle IAR Kickstart version. Dabei habe ich also 2 Softwareteile im FLASH. Ich spiele den Bootcode rein und bestimme er steht in den 1. 8 kB. Im 2. Teil also der Application die ich extra compiliere wird dann der weitere Speicherbereich angegeben. Nun zum CRC 32 Problem. Benutzt wird in beidem Compiler und softare die Ethernet CRC32. (0x4C11DB7) Bootcode: Ich benutze die Hardware im stm32 um die CRC32 zu validieren. Zum Testen nehme ich dabei genau eine Adresse mit 32 Bit(in der Application auch so eingestellt). Also berechne ich die CRC32 z.B. nur über den Wert 0x20000440 -> laut (http://www.lammertbies.nl/comm/info/crc-calculation.html) 0x93C6F4B6 Application: In der Application benutzte ich den Compiler um die CRC32 zu erstellen. Hier liegt vermutlich auch der Fehler. Ich weis nicht welche Einstellungen für Complement, Bitorder und Reverse byte order within Word ich brauche. (der eingestellte CRC Bereich wurde ebenfalls auf eine Adresse Beschränkt) Auf jeden Fall komme ich bisher nie auf einen Erfolgreichen Vergleich. Wäre für Vorschläge dankbar. Gruß Flo
Auf https://my.st.com/public/STe2ecommunities/default.aspx crc in das Suchfeld eintippen. Man findet dann zumindest einen Thread C-Quellcode, in dem der CRC analog zur STM32 Hardware implementiert ist.
Hi nochmal, also die Antwort hat mir nicht viel geholfen. Auch mit einigen der Beispiele kam ich auf keinen grünen Zweig. 1. Auf dem stm32: CRC_ResetDR(); u32Crc = CRC_GetCRC(); u32Crc32 = CRC_CalcCRC(0x20000440); Wie muss ich das in C umwandeln, damit ich wie bei dem oben genannten Onlinerechner 0x93C6F4B6 raus bekomme? Ich finde nirgends im Datenblatt wie die Formateinstellungen der CRC32 sind. 2. Auf dem PC: Habe von IAR keinerlei support über die Einstellung im Compiler gefunden, da die CRC32 vermutlich noch nicht soo lange drin ist. (Project->Options->Linker->Checksum) Da ich nun die Einstellungen bei der Hardware nicht weis kann ich auch hier nicht genau sagen was ich einstellen muss. Zum Testen: CRC über eine 32 Bit Adresse, CRC32, StartValue: 0xFFFFFFFF; AsIs/1er Komplement, LSB/MSB, Reverse Byteorder in Word? Hat wer Vroschläge? Gruß Flo
Hi, Name : "CRC-32" Width : 32 Poly : 04C11DB7 Init : FFFFFFFF RefIn : True RefOut : True XorOut : FFFFFFFF Check : CBF43926 Schau dir mal folgende Diskussion an: https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/CRC32%20calculation%20mismatch&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000626BE2B829C32145B9EB5739142DC17E¤tviews=635 CU Dirk
Hallo, Danke erstmal für die Antworten! Also inzwischen geht immer noch nicht mehr. Aber ich versuche im folgendes. Die revbit Funktion stammt von einem Beispiel hier: https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fARM%20CortexM3%20STM32%2fCRC%20calculation%20in%20software&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000626BE2B829C32145B9EB5739142DC17E¤tviews=2028 sorry für den langen Link. Aber das Beispiel steht weiter unten im dem Thread. Beim Link von Dirk war ich schon und das hier ist quasi aus beiden Foren zusammengebaut denke ich. Ich verwende die Funktion folgender maßen um zu testen: uint32_t revbit(uint32_t data) { asm("rbit r0,r0"); return data; }; void main () { /*here is the Init of variables */ /* here is the Peripheral setup */ CRC_ResetDR(); u32Crc = CRC_GetCRC(); u32DoubleWord= 0x20000770; u32DoubleWord = revbit(u32DoubleWord); u32Crc32 = CRC_CalcCRC(u32DoubleWord); u32Crc32=revbit(u32Crc32 ^ 0xFFFFFFFFL); } Das Ergebnis bei Lammert Bies ist:0x9E3297D9 Das Ergebnis der obigen Berechnung ist bei: u32Crc32=0x745A49CD Wenn wer nen blöden Fehler sieht bitte schreien ;) Grüße Flo
Hi, Probier mal: u32Crc32=revbit(u32Crc32 ^ 0xFFFFFFFFL); zu u32Crc32=revbit(u32Crc32) ^ 0xFFFFFFFFL; Schau dir auch mal das an: Beitrag "CRC - Byte-weise oder Wort-weise?" CU Dirk
Hi Dirk, also die Änderung hab ich auch probiert. Aber mir dann überlegt das es grad wurst ist. denn ob ich nun ne XOR machen bevor oder nachdem ich revbit mache ist grad wurst. Ich hab noch gesehn, das die beiden Assembler Anwendungen andere Variablendeklarationen haben. Also ich nutze u32 revbit(u32 data) { asm("rbit r0,r0"); return data; }; aber statt u32 uint32_t. Ich weis nicht ob der Compiler hier u32 kennen müsste?! Auch im getesteten Beispiel von Dirks letztem Link werden u32 und uint32_t verwendet. Macht das was aus?? Weis jemand wie ich den Teil verwenden kann? <BR> crc_model.cm_width = 32; // 32-bit CRC <BR> crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial <BR> crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's <BR> crc_model.cm_refin = FALSE; // CRC calculated MSB first <BR> crc_model.cm_refot = FALSE; // Final result is not Ich müsste vermutlich das einbinden um cm_t zu nutzen?! <BR>// IMPORTED FUNCTIONS AND MACROS : <BR>// cm_ini(), cm_nxt(), cm_crc() <BR>cm_t crc_model; Danke Gruß Flo
Hi, Hab mir gerade nochmal die Werte aus dem Beispiel angesehen. CRC32: 0x70070020 => 745a49cd CRC32: 0x20000770 => 9e3297d9 Einfach die Byte-Order umdrehen... ^_^ CU Dirk
Hi Dirk, danke dir. Das war der ausschlaggebende Tipp. Für alle die es brauch und zu Faul sind es selber zu basteln nochmal hier. Damit kann man die Berechnungen von Lammber nachvollziehen. Funktioniert bei mir in IAR Kickstart. Wenn wer eine Idee hat das zu vereinfachen nur her. Ich vermute man könnte auch irgendwas schneller machen oder weglassen. uint32_t u32RevByte(uint32_t u32RevValue) { uint8_t HighWordLoNibble, HighWordHighNibble, LowWordLoNibble; unint8_t LowWordHighNibble; /* Copy orignial bytes to temp variables */ HighWordHighNibble = (uint8_t)((u32RevValue>>24)&0xFF); HighWordLoNibble = (uint8_t)((u32RevValue>>16)&0xFF); LowWordHighNibble = (uint8_t)((u32RevValue>>8)&0xFF); LowWordLoNibble = (uint8_t)((u32RevValue)&0xFF); /* rev byte order in variable */ u32RevValue=(uint32_t)HighWordHighNibble; u32RevValue=u32RevValue|((uint32_t)(HighWordLoNibble<<8)&0x0000FF00)); u32RevValue=u32RevValue|((uint32_t)((LowWordHighNibble<<16)&0x00FF0000)) ; u32RevValue=u32RevValue|((uint32_t)((LowWordLoNibble<<24)&0xFF000000)); return u32RevValue; } uint32_t revbit(uint32_t data) { asm("rbit r0,r0"); return data; }; void main () { /*here is the Init of variables */ /* here is the Peripheral setup */ CRC_ResetDR(); u32Crc = CRC_GetCRC(); u32DoubleWord= 0x20000770; u32DoubleWord = revbit(u32DoubleWord); u32Crc32 = CRC_CalcCRC(u32DoubleWord); u32Crc32=revbit(u32Crc32 ^ 0xFFFFFFFFL); } Nun zur anderen Seite: Ich weis Dirk hat oben die Einstellungen in einer Software für CRC gepostet. Aber weis jemand sicher ob das die original Einstellungen sind, die auch der stm32 mikrocontroller hat. Weil dort sind sie ja neu gesetzt. Das heißt noch nicht es sind die original Einstellungen oder? Gruß Flo
Also hier nochmal die Frage, da vermutlich nach der Anwort oben keiner weiter gelesen hat. Nun zur anderen Seite: Ich weis Dirk hat oben die Einstellungen in einer Software für CRC gepostet. Aber weis jemand sicher ob das die original Einstellungen sind, die auch der stm32 mikrocontroller hat. Weil dort sind sie ja neu gesetzt. Das heißt noch nicht es sind die original Einstellungen oder? Alternative: Weis jemand ne Software die mir vor dem Download in den FLASH ne CRC32 berechnet und die ich dann ans Ende vom FLASH schreiben kann? Gruß Flo
to Flo: komisch, habe ich dein Kode einfach kopiert aber bekomme ich andere CRC als du schreibst. Kannst du es bitte nochmal checken und schreiben ein Beispiel? Danke.
Danke für die Codefragmente! Hätte echt nicht gedacht, dass man mit einer HW-CRC Implementierung auf dem Cortex M3 solche Verrenkungen machen muss um ein bisschen CRC32 zu berechnen... Anbei Democode für dem STM32F107 bzw. STM32F10x (für KEIL) liefert korrekte Ergebnisse im Vergleich zu folgendem online calculator: http://www.lammertbies.nl/comm/info/crc-calculation.html /* Functions */ __asm u32 revbit(u32 data) { rbit r0, r0 bx lr } uint32_t u32RevByte(uint32_t u32RevValue) { uint8_t HighWordLoNibble, HighWordHighNibble, LowWordLoNibble; uint8_t LowWordHighNibble; /* Copy orignial bytes to temp variables */ HighWordHighNibble = (uint8_t)((u32RevValue>>24)&0xFF); HighWordLoNibble = (uint8_t)((u32RevValue>>16)&0xFF); LowWordHighNibble = (uint8_t)((u32RevValue>>8)&0xFF); LowWordLoNibble = (uint8_t)((u32RevValue)&0xFF); /* rev byte order in variable */ u32RevValue=(uint32_t)HighWordHighNibble; u32RevValue=u32RevValue|((uint32_t)(HighWordLoNibble<<8)&0x0000FF00); u32RevValue=u32RevValue|((uint32_t)((LowWordHighNibble<<16)&0x00FF0000)) ; u32RevValue=u32RevValue|((uint32_t)((LowWordLoNibble<<24)&0xFF000000)); return u32RevValue; } /* Demo */ /* Variablen */ UInt32 CRC_Test_U32; UInt32 CRC_Test_Result; /* Code */ CRC_ResetDR(); CRC_Test_Result=revbit(CRC_CalcCRC(revbit(u32RevByte(CRC_Test_U32))) ^ 0xffffffff);
Mal ne Frage: statt
1 | uint32_t u32RevByte(uint32_t u32RevValue) |
ginge doch auch die asm Anweisung
1 | rev r0, r0 |
oder nicht?
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.