Nathan Wride
Nathan Wride

Reputation: 965

Getting CRC-32 over STM32 flash and consistency with other CRC-32 tools

I'm moving my STM32F1xx project to a solution with a bootloader. Part of this is that I want to be able to compute a CRC value over the existing bootloader and application flash ranges to compare existing and possible upload candidates.

Using a simple implementation on the STM32 which just does the following steps:

uint32_t get_crc(void) {
    RCC->AHBENR |= RCC_AHBENR_CRCEN;
    CRC->CR |= CRC_CR_RESET;

    for(uint32_t *n = (uint32_t *)FLASH_BASE; n < (uint32_t *)(FLASH_BANK1_END + 1u); n ++) {
        CRC->DR = *n;
    }

    return CRC->DR;
}

The value I get from this is 0x0deddeb3.

To compare this value with something I am running the .bin file through two tools.

The value I get from npm's crc-32 is 0x776b0ea2

The value I get from a zip file's CRC-32 is also 0x776b0ea2

What could be causing this? Is there a difference between iterating over the entire flash range and the contents of the bin file (smaller than entire flash range)? The polynomial used by the STM32 is 0x04c11db7 which seems to be fairly standard for a CRC-32. Would the zip tool and npm crc-32 be using a different polynomial?

I have also tried iterating over bytes and half-words as well as words on the STM32 in case the other tools used a different input format.

There is a similar question on here already, but I'm hoping to use a node-js solution because that is the platform my interface application is being developed on.

Upvotes: 0

Views: 2755

Answers (2)

the busybee
the busybee

Reputation: 12600

Calculating CRCs is a mine field. Your question already has some points to look at:

Is there a difference between iterating over the entire flash range and the contents of the bin file (smaller than entire flash range)?

Yes, of course.

Would the zip tool and npm crc-32 be using a different polynomial?

The documentation will tell you. And I'm sure that you can use another polynomial with this tools by an option.

Anyway, these are the things to consider when calculating CRCs:

  1. The amount of bytes (words, ...) to "sum up".
  2. The contents of the flash not covered by the binary file, most probably all bits set to 1.
  3. Width of the polynomial (in your case fixed to 32 bits).
  4. Value of the polynomial.
  5. Initial value for the register.
  6. Whether the bits of each byte are reflected before being processed.
  7. Whether the algorithm feeds input bytes through the register or xors them with a byte from one end and then straight into the table.
  8. Whether the final register value should be reversed (as in reflected versions).
  9. Value to XOR with the final register value.

The points 3 to the last are shamelessly copied from "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS" that I suggest to read.

Upvotes: 4

Mark Adler
Mark Adler

Reputation: 112239

The polynomial is only one of several parameters that define a CRC. In this case the CRC is not reflected, whereas the standard zip CRC, using the same polynomial is reflected. Also that zip CRC is exclusive-or'ed with 0xffffffff at the end, whereas yours isn't. They do both get initialized the same, which is with 0xffffffff.

Upvotes: 2

Related Questions