STM32F103 (bent jau mano naudojamas) turi hardwarinį CRC32 skaičiuotuvą. Tačiau bėda- kažko tai suskaičiuotas CRC32 neatitinka kokio nors online kalkuliatoriaus rezultatui. Internetas prirašytas visko, bet niekur dorai nepaaiškinta kodėl nesutampa.
Atsakymas labai paprastas- big ar little endian skaičiuoja mūsų MCU ir dar kokia bitų seka.
CRC32 pas STM32 skaičiuojasi 32 bitų skaičiais. Todėl kokį nors baitų (ar raidžių) masyvą reikia papildyti iki kartotinio 4 dydžio. Jei masyvas sudarytas iš 32bitų elementų, reikia pasitikrinti tą “endian”. Poto imti masyvą po 4 baitus, sukuisti bitų seką (gerai, kad yra komanda RBIT, Reverse the bit order in a 32-bit word.), suskaičiuoti su hardware CRC32 rezultatą ir vėl sukuisti bitus su ta pačia komanda. Jei reikia, rezultatą invertuoti.
/* tekstines eilutes CRC skaiciavimas. Kartotinis 4. Netilpe baitai ignoruojami */ uint32_t RealCRC32txt(char * buf) { uint32_t len=strlen(buf)/4; return RealCRC32((uint32_t *) buf, len); } /* CRC skaiciavimas naudojant 32 bitu masyva. Jei tikras masyvas, tai svarbu baitu seka, jei konversija is char/byte masyvo, tada nesvarbu */ uint32_t RealCRC32(uint32_t * buf, uint32_t len) //demesio, kas 4 baitai! { uint32_t crc,tmp,i; hcrc.State = HAL_CRC_STATE_BUSY; __HAL_CRC_DR_RESET(&hcrc); for(i=0;i<len;i++) { tmp=buf[i]; //tmp = ((tmp>>24)&0xff) | ((tmp<<8)&0xff0000) | ((tmp>>8)&0xff00) | ((tmp<<24)&0xff000000); //baitu sekos konverteris tmp = __RBIT(tmp); hcrc.Instance->DR = tmp; } crc = __RBIT(hcrc.Instance->DR); hcrc.State = HAL_CRC_STATE_READY; return crc; }
Užkomentuota ilga eilutė atkomentuojama, jei reikia skaičiuoti CRC tikram 32 bitų masyvui.
Teksto “00010002” CRC32= 1366C59F
Buvau ir aš ant šito užsirovęs, kol pavyko padaryt atitikmenį „tikram“ CRC32. Jau nepamenu kaip, bet kažkur CMSIS bibliotekėlėse radau, kaip „teisingai“ padaryt.