2013-10-12 01:03 PM
Hello,
I am trying to apply CRC to an 8-bit array for creating checksum in order to use in transfer. Since CRC of STM32F4 uses registers as 32-bit, I need to do something tricky.For instance, a 8-bit buffer with 42 elements will be handled with 40 or 44 elements by CRC. How can we use CRC_CalcBlockCRC( ); command for such an array?Thanks for your ideas and experiences!2013-10-12 01:18 PM
The standard 32-bit computation on STM32 parts is ill suited to byte operation, the F3 I think has more flexibility.
[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=4051]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FCRC%20computation&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=40512013-10-12 01:25 PM
Thanks for reply!
So, do you think it is a healthy manner to add extra bytes to the end, and calculating like CRC_CalcBlockCRC((uint32_t*)Array, (sizeof(Array)/4) + 1); like padding?2013-10-12 02:04 PM
I think that's ill advised, you'd need to control the padding bytes, and the value you generate wouldn't be compatible with anything else. You could also finish up the final 1-3 bytes in software. ST picked an odd polynominal/shift for a little endian machine.
I guess I'd need to know more about the use in the specific application.2013-10-13 04:29 AM
I have a struct which includes 42 bytes of data, padding done by #pragma pack(1)
My code memcpy(); this Struct into a Buffer, and CRC_CalcBlockCRC, as follows:// 'Packet' is my struct
uint8_t Buffer[42]; CRC_ResetDR(); memcpy(&Buffer[0], &Packet, sizeof(Buffer)); CRC_Cs = CRC_CalcBlockCRC((uint32_t*)Buffer, ????); Checksum = (uint8_t)CRC_Cs; If I use 10 for CRC size, last 2 bytes not used, If used 11, gives different values everytime.2013-10-13 08:33 AM
// 'Packet' is my struct
uint32_t Buffer[11]; // aligned buffer bigger than Packet
CRC_ResetDR();
Buffer[10] = 0; // Assure padding in zero/consistent
memcpy(&Buffer[0], &Packet, sizeof(Packet));
CRC_Cs = CRC_CalcBlockCRC(Buffer, 11);
Checksum = (uint8_t)CRC_Cs; // It's not a byte, but Ok
2013-10-13 11:51 AM
Thanks for your comments. I wrote a code for checkum with XOR operator, and checked with scope and both CRC and my function take similar cpu times. Advantage of CRC for me was its dedicated hardware, but soft operation seems better for me :)
My code:uint8_t checksum(uint8_t *array, uint16_t size)
{ uint8_t cs = 0; for(int n=0; n < size; ++n) { cs ^= array[n]; } return cs; }2013-10-13 03:08 PM
uint8_t checksum(uint8_t *array, uint32_t size)
{
uint8_t cs = 0;
while(size--)
cs ^= *array++;
return cs;
}
2013-10-14 08:32 AM
Clive, what is the advantage of your modified algorithm?
I've checked and it takes more time (~2.20 us) compared to my code (~1.70 us)2013-10-14 08:48 AM
Depends what the compiler/optimizer does with it. Mixing 16-bit and 32-bit types is usually slower, the machine should be more efficient with 32-bit types.