lfs_config.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #pragma once
  2. #include <furi.h>
  3. #ifdef FURI_NDEBUG
  4. #define LFS_NO_ASSERT
  5. #define LFS_ASSERT(x)
  6. #else
  7. #define LFS_ASSERT furi_assert
  8. #endif
  9. #define LFS_TAG "Lfs"
  10. #ifdef FURI_LFS_DEBUG
  11. #define LFS_TRACE(...) FURI_LOG_T(LFS_TAG, __VA_ARGS__);
  12. #define LFS_DEBUG(...) FURI_LOG_D(LFS_TAG, __VA_ARGS__);
  13. #else
  14. #define LFS_TRACE(...)
  15. #define LFS_DEBUG(...)
  16. #endif // FURI_LFS_DEBUG
  17. #define LFS_WARN(...) FURI_LOG_W(LFS_TAG, __VA_ARGS__);
  18. #define LFS_ERROR(...) FURI_LOG_E(LFS_TAG, __VA_ARGS__);
  19. // Because crc
  20. #undef LFS_CONFIG
  21. // System includes
  22. #include <stdint.h>
  23. #include <stdbool.h>
  24. #include <string.h>
  25. #include <inttypes.h>
  26. #ifndef LFS_NO_MALLOC
  27. #include <stdlib.h>
  28. #endif
  29. #ifndef LFS_NO_ASSERT
  30. #include <assert.h>
  31. #endif
  32. #if !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR) || \
  33. defined(LFS_YES_TRACE)
  34. #include <stdio.h>
  35. #endif
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. // Builtin functions, these may be replaced by more efficient
  40. // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
  41. // expensive basic C implementation for debugging purposes
  42. // Min/max functions for unsigned 32-bit numbers
  43. static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
  44. return (a > b) ? a : b;
  45. }
  46. static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
  47. return (a < b) ? a : b;
  48. }
  49. // Align to nearest multiple of a size
  50. static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
  51. return a - (a % alignment);
  52. }
  53. static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) {
  54. return lfs_aligndown(a + alignment - 1, alignment);
  55. }
  56. // Find the smallest power of 2 greater than or equal to a
  57. static inline uint32_t lfs_npw2(uint32_t a) {
  58. #if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
  59. return 32 - __builtin_clz(a - 1);
  60. #else
  61. uint32_t r = 0;
  62. uint32_t s;
  63. a -= 1;
  64. s = (a > 0xffff) << 4;
  65. a >>= s;
  66. r |= s;
  67. s = (a > 0xff) << 3;
  68. a >>= s;
  69. r |= s;
  70. s = (a > 0xf) << 2;
  71. a >>= s;
  72. r |= s;
  73. s = (a > 0x3) << 1;
  74. a >>= s;
  75. r |= s;
  76. return (r | (a >> 1)) + 1;
  77. #endif
  78. }
  79. // Count the number of trailing binary zeros in a
  80. // lfs_ctz(0) may be undefined
  81. static inline uint32_t lfs_ctz(uint32_t a) {
  82. #if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__)
  83. return __builtin_ctz(a);
  84. #else
  85. return lfs_npw2((a & -a) + 1) - 1;
  86. #endif
  87. }
  88. // Count the number of binary ones in a
  89. static inline uint32_t lfs_popc(uint32_t a) {
  90. #if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
  91. return __builtin_popcount(a);
  92. #else
  93. a = a - ((a >> 1) & 0x55555555);
  94. a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
  95. return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
  96. #endif
  97. }
  98. // Find the sequence comparison of a and b, this is the distance
  99. // between a and b ignoring overflow
  100. static inline int lfs_scmp(uint32_t a, uint32_t b) {
  101. return (int)(unsigned)(a - b);
  102. }
  103. // Convert between 32-bit little-endian and native order
  104. static inline uint32_t lfs_fromle32(uint32_t a) {
  105. #if !defined(LFS_NO_INTRINSICS) && \
  106. ((defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && \
  107. BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \
  108. (defined(__BYTE_ORDER) && defined(__ORDER_LITTLE_ENDIAN) && \
  109. __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \
  110. (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
  111. __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
  112. return a;
  113. #elif !defined(LFS_NO_INTRINSICS) && \
  114. ((defined(BYTE_ORDER) && defined(ORDER_BIG_ENDIAN) && BYTE_ORDER == ORDER_BIG_ENDIAN) || \
  115. (defined(__BYTE_ORDER) && defined(__ORDER_BIG_ENDIAN) && \
  116. __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \
  117. (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
  118. __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
  119. return __builtin_bswap32(a);
  120. #else
  121. return (((uint8_t*)&a)[0] << 0) | (((uint8_t*)&a)[1] << 8) | (((uint8_t*)&a)[2] << 16) |
  122. (((uint8_t*)&a)[3] << 24);
  123. #endif
  124. }
  125. static inline uint32_t lfs_tole32(uint32_t a) {
  126. return lfs_fromle32(a);
  127. }
  128. // Convert between 32-bit big-endian and native order
  129. static inline uint32_t lfs_frombe32(uint32_t a) {
  130. #if !defined(LFS_NO_INTRINSICS) && \
  131. ((defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && \
  132. BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \
  133. (defined(__BYTE_ORDER) && defined(__ORDER_LITTLE_ENDIAN) && \
  134. __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \
  135. (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
  136. __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
  137. return __builtin_bswap32(a);
  138. #elif !defined(LFS_NO_INTRINSICS) && \
  139. ((defined(BYTE_ORDER) && defined(ORDER_BIG_ENDIAN) && BYTE_ORDER == ORDER_BIG_ENDIAN) || \
  140. (defined(__BYTE_ORDER) && defined(__ORDER_BIG_ENDIAN) && \
  141. __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \
  142. (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
  143. __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
  144. return a;
  145. #else
  146. return (((uint8_t*)&a)[0] << 24) | (((uint8_t*)&a)[1] << 16) | (((uint8_t*)&a)[2] << 8) |
  147. (((uint8_t*)&a)[3] << 0);
  148. #endif
  149. }
  150. static inline uint32_t lfs_tobe32(uint32_t a) {
  151. return lfs_frombe32(a);
  152. }
  153. // Calculate CRC-32 with polynomial = 0x04c11db7
  154. uint32_t lfs_crc(uint32_t crc, const void* buffer, size_t size);
  155. // Allocate memory, only used if buffers are not provided to littlefs
  156. // Note, memory must be 64-bit aligned
  157. static inline void* lfs_malloc(size_t size) {
  158. #ifndef LFS_NO_MALLOC
  159. return malloc(size);
  160. #else
  161. (void)size;
  162. return NULL;
  163. #endif
  164. }
  165. // Deallocate memory, only used if buffers are not provided to littlefs
  166. static inline void lfs_free(void* p) {
  167. #ifndef LFS_NO_MALLOC
  168. free(p);
  169. #else
  170. (void)p;
  171. #endif
  172. }
  173. #ifdef __cplusplus
  174. } /* extern "C" */
  175. #endif