Skip to content

Commit 1265d76

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 7459adb commit 1265d76

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-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: 16 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,21 @@ 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+
defined(__MBED__)
191+
return __RBIT(a);
192+
#else
193+
a = ((a & 0xaaaaaaaa) >> 1) | ((a & 0x55555555) << 1);
194+
a = ((a & 0xcccccccc) >> 2) | ((a & 0x33333333) << 2);
195+
a = ((a & 0xf0f0f0f0) >> 4) | ((a & 0x0f0f0f0f) << 4);
196+
a = ((a & 0xff00ff00) >> 8) | ((a & 0x00ff00ff) << 8);
197+
a = (a >> 16) | (a << 16);
198+
return a;
199+
#endif
200+
}
201+
186202
// Calculate CRC-32 with polynomial = 0x04c11db7
187203
void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
188204

0 commit comments

Comments
 (0)