Awesome
Optimized CRC32 library for Arduino
This is a target independent, flash and RAM size optimized CRC32 library for Arduino without CRC tables.
Library features
- Compatible with standard CRC32 algorithms
- Small flash footprint
- No RAM buffer allocations
- 32-bit table-less CRC32 calculation on:
- Arduino String object
- Single null-terminated character array
- Single buffer
- Multiple null-terminated character arrays
- Multiple buffers
- No buffer alignment needed
- Buffer input length in Bytes
- Big and little endian input buffers
- Arduino C library, compatible with C and C++ applications
- CRC32 polynomial: 0xEDB88320
Hardware
This library can be used on any 8 or 32-bit target and is optimized for small flash/RAM footprints without CRC table allocations in RAM.
Examples and benchmarks
Arduino IDE | Examples | Erriez CRC32:
Benchmark results on buffers
The benchmark results below may be different for each target and run. Lower duration means faster CRC calculation.
Board | F_CPU | 4 Bytes | 64 Bytes | 512 Bytes | 1024 Bytes |
---|---|---|---|---|---|
Arduino UNO (ATMega328) | 16MHz | 80us | 1172us | 9000us | 17112us |
ESP8266 (WeMOS D1 R2) | 160MHz | 3us | 35us | 279us | 557us |
ESP32 (WeMOS Lolin32) | 80MHz | 2us | 15us | 111us | 223us |
DUE (SAM3X8E ARM Cortex-M3) | 84MHz | 6us | 70us | 547us | 1103us |
Benchmarks performed with the following versions:
- Arduino IDE v1.8.5
- Arduino AVR Boards v1.6.21 (Arduino UNO)
- esp8266 v2.4.2
- Arduino SAM Boards (32-bits ARM Cortex-M3) v1.6.11
Unit tests
This library contains extensive unit tests on a various number of buffer types and lengths:
Library documentation
Usage
Introduction
The library consists of four C-functions for CRC calculation:
// Calculate CRC32 on null-terminated character array (string)
uint32_t crc32String(const char *buffer);
// Calculate CRC32 on one single buffer
uint32_t crc32Buffer(const void *buffer, size_t bufferLength);
// Calculate CRC32 on multiple buffers
// First crc32Update() call should start with argument crc = CRC32_INITIAL
// Next crc32Update() calls should set argument crc = previousCRC
uint32_t crc32Update(const void *buffer, size_t bufferLength, uint32_t crc);
// Call crc32Update() at the end after the last crc32Update()
uint32_t crc32Final(uint32_t crc);
Initialization
Only an include file is required. No object allocation or library initialization required.
#include <ErriezCRC32.h>
Calculate CRC32 on Arduino String
String msg = "Hello world String!";
uint32_t crc = crc32String(msg.c_str());
Calculate CRC32 on null-terminated character array
char msg[] = "Hello world char array!";
uint32_t crc = crc32String(msg);
Calculate CRC32 on single character buffer
char msg[] = "Hello world single buffer!";
uint32_t crc = crc32Buffer(msg, strlen(msg));
Calculate CRC32 on multiple characters
uint32_t crc;
crc = crc32Update("Hello ", 6, CRC32_INITIAL);
crc = crc32Update("world ", 6, crc);
crc = crc32Update("multiple ", 9, crc);
crc = crc32Update("buffers!", 8, crc);
crc = crc32Final(crc);
Calculate CRC32 on multiple buffers
const uint8_t testBuffer1[3] = { 0xEB, 0xE5, 0x51 };
const uint8_t testBuffer2[5] = { 0x87, 0x7F, 0xB8, 0x18, 0x4E };
uint32_t crc;
crc = crc32Update(testBuffer1, sizeof(testBuffer1), CRC32_INITIAL);
crc = crc32Update(testBuffer2, sizeof(testBuffer2), crc);
crc = crc32Final(crc);
Check CRC
void checkCRC(uint32_t crcCalculated, uint32_t crcExpected)
{
printCRC(crcCalculated);
Serial.print(F("..."));
if (crcCalculated == crcExpected) {
Serial.println(F("OK"));
} else {
Serial.print(F("FAILED! Expected: "));
printCRC(crcExpected);
Serial.println(F(""));
}
}
Print 32-bit CRC value
Printing a uint32_t
value is not implemented on some targets which is a limitation of Serial.print()
or sprintf()
.
This is a workaround to print a 32-bit hex value:
void printCRC(uint32_t crc)
{
Serial.print("0x");
for (int8_t i = 3; i >= 0; i--) {
uint8_t c = crc >> (i * 8);
if (c < 0x10) {
Serial.print("0");
}
Serial.print(c, HEX);
}
}
CRC-calculation with Python
>>> import binascii
>>> hex(binascii.crc32(b'Hello world String!') & 0xffffffff)
'0x55df869b'
Library dependencies
- ErriezCRC32Benchmark.ino: ErriezTimestamp.h
- ErriezCRC32UnitTest.ino: ArduinoUnit.h
Library installation
Please refer to the Wiki page.