Skip to content

Commit 5d62ee6

Browse files
committed
LittleFS: correct CRC calculation
When using MbedCRC, init value must be non-reversed, regardless of `reflect_data` or `reflect_out` settings. This means we need to reflect the intermediate output before passing using it as the next init value. (In GCC this ends up putting in two `RBIT` instructions back-to-back, because it's implemented as assembler, so it doesn't know how to optimise. In ARMC6, `__RBIT` is implemented as an intrinsic, so adding this reflection cancels the existing reflection and makes the code smaller).
1 parent a183033 commit 5d62ee6

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

features/storage/filesystem/littlefs/LittleFileSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace mbed {
2424

2525
extern "C" void lfs_crc(uint32_t *crc, const void *buffer, size_t size)
2626
{
27-
uint32_t initial_xor = *crc;
27+
uint32_t initial_xor = lfs_rbit(*crc);
2828
// lfs_cache_crc calls lfs_crc for every byte individually, so can't afford
2929
// start-up overhead for hardware acceleration. Limit to table-based.
3030
MbedCRC<POLY_32BIT_ANSI, 32, CrcMode::TABLE> ct(initial_xor, 0x0, true, true);

features/storage/filesystem/littlefs/littlefs/lfs_util.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern "C"
4747
#ifdef __MBED__
4848
#include "mbed_debug.h"
4949
#include "mbed_assert.h"
50+
#include "cmsis_compiler.h"
5051
#else
5152
#define MBED_LFS_ENABLE_INFO false
5253
#define MBED_LFS_ENABLE_DEBUG true
@@ -183,6 +184,20 @@ static inline uint32_t lfs_tole32(uint32_t a) {
183184
return lfs_fromle32(a);
184185
}
185186

187+
// Reverse the bits in a
188+
static inline uint32_t lfs_rbit(uint32_t a) {
189+
#if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS
190+
return __RBIT(a);
191+
#else
192+
a = ((a & 0xaaaaaaaa) >> 1) | ((a & 0x55555555) << 1);
193+
a = ((a & 0xcccccccc) >> 2) | ((a & 0x33333333) << 2);
194+
a = ((a & 0xf0f0f0f0) >> 4) | ((a & 0x0f0f0f0f) << 4);
195+
a = ((a & 0xff00ff00) >> 8) | ((a & 0x00ff00ff) << 8);
196+
a = (a >> 16) | (a << 16);
197+
return a;
198+
#endif
199+
}
200+
186201
// Calculate CRC-32 with polynomial = 0x04c11db7
187202
void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
188203

0 commit comments

Comments
 (0)