Added lfs_crc32c
crc32c, with a polynomial of 0x11edc6f41, is generally numerically superior to the more common crc32 standard. Catching more bit errors across a wider range of message messages (except 2-bit errors) without any changes to the underlying algorithm. Philip Koopman has a large body of work exploring optimal polynomials here: http://users.ece.cmu.edu/~koopman/crc/crc32.html And from his experiments we know the maximum message size where we can still detect a given number of bit errors for each polynomial: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 crc32 0x104c11db7 = ∞ 4294967263 91607 2974 268 171 91 57 34 21 12 10 10 10 - - - crc32c 0x11edc6f41 = ∞ 2147483615 2147483615 5243 5243 177 177 47 47 20 20 8 8 6 6 1 1 So really crc32c should be prefered where possible. Koopman also has alternative polynomials with slightly different properties, but crc32c is already popular enough to have a decent amount of hardware support. --- Another nice feature of crc32c is that its polynomial has even parity. It turns out that even-parity polynomials give us the nifty property parity(crc(m)) == parity(m). A quick proof: crc(m) = m(x) x^|P|-1 mod P(x) parity(m) = m(x) x mod x+1 though note: x mod x+1 = 1, by hand so: parity(m) = m(x)*1 mod x+1 = m(x) mod x+1 solving for parity(crc(m)): parity(crc(m)) = (m(x) x^|P|-1 mod P(x)) mod x+1 note: (a mod b) mod c = a mod c, if c divides b, aka (a mod b) mod c = a mod c, if b mod c = 0 so if P(x) mod x+1 = 0, aka if parity(P) = 0: parity(crc(m)) = m(x) x^|P|-1 mod x+1 but, like before: x^|P|-1 mod x+1 = 1, by hand so: parity(crc(m)) = m(x)*1 mod x+1 = m(x) mod x+1 = parity(m) so if parity(P) = 0: parity(crc(m)) = parity(m) This has the potential to replace the 1-bit counter in the metadata tags with a more general solution that doesn't require extra state.
This commit is contained in:
@@ -215,6 +215,15 @@ static inline uint32_t lfs_tobe32(uint32_t a) {
|
||||
// Calculate CRC-32 with polynomial = 0x04c11db7
|
||||
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size);
|
||||
|
||||
// Calculate crc32c incrementally
|
||||
//
|
||||
// polynomial = 0x11edc6f41
|
||||
// init = 0xffffffff
|
||||
// fini = 0xffffffff
|
||||
//
|
||||
uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size);
|
||||
|
||||
|
||||
// Allocate memory, only used if buffers are not provided to littlefs
|
||||
// Note, memory must be 64-bit aligned
|
||||
static inline void *lfs_malloc(size_t size) {
|
||||
|
||||
Reference in New Issue
Block a user