This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DFU controller firmware data object CRC computation

Hi,

I'm trying to create a DFU controller on a secondary board, and have been referencing the info center and nrf toolbox android app to get started. I've run into an issue where the dfu controller does not compute the same CRC as the app/dfu target.

For example, I'm using nRF5_SDK_17.0.2, and when I send the hrs_application_s140.zip package (examples\dfu\secure_dfu_test_images\ble\nrf52840) through the toolbox app, I see the following CRCs from the app log messages.

Init packet: Checksum received (Offset = 144, CRC = 5FA750B0)
Data 1/25: Checksum received (Offset = 4096, CRC = 0778FF30)
Data 2/25: Checksum received (Offset = 8192, CRC = 452F0AC2)

In contrast, when I try computing the values on the DFU controller (unzipped .dat and .bin file), I see the following CRCs.

Init packet: 5FA750B0
Data 1/25: 0778FF30
Data 2/25: 8E858D45

The fact that I am successfully computing the CRC for the init packet, as well as the first 4096 bytes of the firmware image lead me to think it's not a problem with the actual CRC function I am using. Additionally, if I use an online CRC calculator (https://crccalc.com/), it gives me the same CRC results as the test code on my DFU controller when taking 4096 bytes at a time. What do I need to do in order to get the data CRC's to match?

Here's the code I am testing with on the secondary board for reference. It opens the firmware bin file, then splits it into chunks by reading 4096 bytes at a time. The CRC of the 4096 bytes is then calculated. The loop stops after 2 iterations just for testing purposes since all other CRCs after the first 4096 bytes do not match.

const size_t maxSize = 4096;
f = open("/nrf52840_xxaa.bin", "r");
size_t binSize = f.size();
size_t chunks = (binSize + maxSize - 1) / maxSize;
size_t readBytes = 0;
for (uint8_t i = 0; i < 2/*chunks*/; i++)
{
	size_t delta = binSize - readBytes;
	size_t _read = (delta >= maxSize) ? maxSize : delta;
	uint8_t *b = (uint8_t *)malloc(_read);
	memset(b, 0, _read);
	readBytes += f.read(b, _read);
	DEBUG("%u/%u | Read bytes %u, %u\n", i, chunks - 1, _read, readBytes);
	crc = crc32(b, _read);
	DEBUG("               CRC %08X\n", crc);
	free(b);
}
f.close();

Parents
  • Hi, 

    The CRC is always computed from offset 0 (i.e. first data object). You must include the previous CRC when computing the next. The function CRC32 compute() is the API we use in our SDK. Notice we have a third optional input parameter that lets you continue CRC computation from a previous checksum.

    Regards,
    Amadna

Reply
  • Hi, 

    The CRC is always computed from offset 0 (i.e. first data object). You must include the previous CRC when computing the next. The function CRC32 compute() is the API we use in our SDK. Notice we have a third optional input parameter that lets you continue CRC computation from a previous checksum.

    Regards,
    Amadna

Children
Related