Calculating der CRC32 by external program

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User11996
Level 3
Level 3
Hi.

I try to calculate a crc32 with a pc program in the same matter than the build in crc unit.

I need this for a bootloader, to calculate the crc from a complet hex-file and want to check this from the infineon.

But i can't find a algorithm, that gives the same result as the CRC-Kernel.


Has anyone a source-code?

I use Kernal 0 (IEEE802.3 CRC32), configure CRCCfg.kernel_ptr->CFG to 0x0,
Seedval: 0

The Infineon use this lookuptable:



uint32_t crctab[256] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
and so on....




I try this algorithm:


uint32_t GetCRC32(unsigned long iLengt, unsigned char *pBuffer)
{
uint32_t CRC = 0;

while(iLengt--)
{
CRC = (CRC >> 😎 ^ crctab[(CRC & 0xFF) ^ *pBuffer++];
}
return CRC
}



I test it with one long:
Input: 0x20000800

Infineon returns in RES or CRC: 0x60A105A3
The algroritm returns: 0x2BD0DB09

It seems, the Infineon is flipping the Bytes, becouse, if i use 0x00000001 as input, the Chip returns: 0x04c11db7.
If i try to flipp the bytes in the same matter in the pc program, i get: 0x0797C360.
0 Likes
5 Replies
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

I use srec_cat to calculate the CRC32 using a small command file for srec_cat which will append the CRC32 at the end of the image.

# srec_cat command file to add the CRC32 
# use srec_cat @add_crc.srec

# First create CRC checksum
(
18_xmc4800_tftp_bootloader_app.bin # input file
-binary # input format
-byte-swap 4
-crc32-b-e -maximum-address 18_xmc4800_tftp_bootloader_app.bin -binary # calculate CRC32
)
-byte-swap 4

# produce the output file, specify it in the Startup tab of debug settings in use file
-o 18_xmc4800_tftp_bootloader_app_crc.bin
-binary



For this to work you need to generate a bin file. This can be achieved in DAVE by selecting the output format in the project settings or via command line using objcopy.
I also modify the startup file to use one of the nonused vectors in the vector table to indicate the application where the CRC is located

/* ================== START OF VECTOR TABLE DEFINITION ====================== */
/* Vector Table - This gets programed into VTOR register by onchip BootROM */
.syntax unified

.section .reset, "a", %progbits

.align 2
.globl __Vectors
.type __Vectors, %object
__Vectors:
.long __initial_sp /* Top of Stack */
.long Reset_Handler /* Reset Handler */

Entry NMI_Handler /* NMI Handler */
Entry HardFault_Handler /* Hard Fault Handler */
Entry MemManage_Handler /* MPU Fault Handler */
Entry BusFault_Handler /* Bus Fault Handler */
Entry UsageFault_Handler /* Usage Fault Handler */
.long __text_size /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
Entry SVC_Handler /* SVCall Handler */
Entry DebugMon_Handler /* Debug Monitor Handler */
.long 0 /* Reserved */
Entry PendSV_Handler /* PendSV Handler */
Entry SysTick_Handler /* SysTick Handler */


In your applicattion using the FCE you can check the CRC32 using the code below ( which also does other sanity checks)

bool is_firmware_loaded_valid(uint32_t *address)
{
uint32_t crc32_result;
uint32_t firmware_crc = 0;
uint32_t stack_pointer = *address;
uint32_t reset_vector = *(address + 1);
uint32_t firmware_length = *(address + 7);
bool retval = true;

if ((firmware_length != 0) && (firmware_length <= 983036))
{
firmware_crc = *((uint32_t *)((uint32_t)address + firmware_length));
}
else
{
retval = false;
}

if (((stack_pointer > 0x1FFE8000U) && (stack_pointer < (0x1FFE8000U + 0x00058000U))) == false)
{
retval = false;
}

if (((reset_vector >= 0x08010000U) && (reset_vector < 0x08100000U)) == false)
{
retval = false;
}

/* Enable FCE module */
XMC_FCE_Enable();

/* Initialize the FCE Configuration */
XMC_FCE_Init(&FCE_config0);
XMC_FCE_CalculateCRC32(&FCE_config0, address, firmware_length, &crc32_result);
XMC_FCE_GetCRCResult(&FCE_config0, &crc32_result);

XMC_FCE_Disable();

if (crc32_result != firmware_crc)
{
retval = false;
}

return retval;
}


Regards,
Jesus
0 Likes
User11996
Level 3
Level 3
Hi jferreira.

That doesn't solve the problem.

The CRC-check over the flash in the XMC is working fine. No problem.


I need to compute the same crc32 that the XMC calculates with a external program, and add it at the end of the hex or bin-file.

The given tool srec_cat computes a crc32 and add it at the end of the hex/bin file.
BUT: the calculated checksum dosn't fit with the XMC checksum.

To explain:
I create a small bin-file with only 4 bytes. (0x20000800)

I let the XMC compute the checksum over the 4 bytes. Result: 0x60A105A3.
I let srec_cat compute the checksum over the 4 bytes. Result: 0x49AFFA2A. Reverse-Byte: 0x1439AE6C

So i can't use srec_cat.

Is there no information, how the XMC computes the CRC32? It seems the XMC computes the CRC32 in a strange and unknown way....
0 Likes
User11996
Level 3
Level 3
Hi.

Has no one a idea, how the xmc calculate the crc?

The xmc apparently handles the crc calculation differently for a long than for a byte-wise computation.
But how does he do that?

Please help me.
0 Likes
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

This is the FCE configuration which is used in my example.
static const XMC_FCE_t FCE_config0 =
{
.kernel_ptr = XMC_FCE_CRC32_0, /**< FCE Kernel Pointer */
.fce_cfg_update.config_xsel = true,
.fce_cfg_update.config_refin = true,
.fce_cfg_update.config_refout = true,
.seedvalue = 0xffffffffU
};

Regards,
Jesus
0 Likes
User15370
Level 2
Level 2
First like received First solution authored
Hi,
I found here: "https://www.infineonforums.com/archive/index.php/t-2114.html" an example written by user freyes on Oct 13th, 2015, 01:30 PM, which seems to be near the method realised on the XMC4500_AB. The only difference is that the bit-wise inversion at the end is not needed. So the method would be:
/*
* https://www.infineonforums.com/archive/index.php/t-2114.html
* Arguments:
* 1 CRC_DataPtr: pointer to buffer with 32-bit-values
* 2 CRC_Len: Count of 32-bit-values in buffer
* Return: the calculated CRC32-value
*/
uint32_t MyCRC32(uint32_t * CRC_DataPtr, uint32_t CRC_Len)
{
uint32_t CRC_Value = 0; // CRC_StartValue is 0 !!
while (CRC_Len--)
{
CRC_Value ^= *CRC_DataPtr++;
for (uint32_t i = 0; i <= 31; i++)
{
if (CRC_Value & 0x80000000)
CRC_Value = (CRC_Value << 1) ^ 0x04C11DB7; // Polynomial used in Tricore
else
CRC_Value = (CRC_Value << 1);
}
}
return CRC_Value;
}

At the moment, I have only these short examples:
- from this thread above: Input: 0x20000800, CRC 0x60A105A3
- from elsewhere: Input: { 0xA5C3E10F, 0x08020000, 0xFFFFFFFF, 0xFFFFFFFF }, CRC 0xEF423163
so if there is something wrong, I would appreciate any further information.
0 Likes