Mistake on this page?
Report an issue in GitHub or email us
lfs_util.h
1 /*
2  * lfs utility functions
3  *
4  * Copyright (c) 2017, Arm Limited. All rights reserved.
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef LFS_UTIL_H
8 #define LFS_UTIL_H
9 
10 // Users can override lfs_util.h with their own configuration by defining
11 // LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
12 //
13 // If LFS_CONFIG is used, none of the default utils will be emitted and must be
14 // provided by the config file. To start I would suggest copying lfs_util.h and
15 // modifying as needed.
16 #ifdef LFS_CONFIG
17 #define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
18 #define LFS_STRINGIZE2(x) #x
19 #include LFS_STRINGIZE(LFS_CONFIG)
20 #else
21 
22 // System includes
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include <string.h>
26 
27 #ifndef LFS_NO_MALLOC
28 #include <stdlib.h>
29 #endif
30 #ifndef LFS_NO_ASSERT
31 #include <assert.h>
32 #endif
33 #if !defined(LFS_NO_INFO) || !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR)
34 #include <stdio.h>
35 #endif
36 
37 #ifdef __cplusplus
38 extern "C"
39 {
40 #endif
41 
42 
43 // Macros, may be replaced by system specific wrappers. Arguments to these
44 // macros must not have side-effects as the macros can be removed for a smaller
45 // code footprint
46 
47 #ifdef __MBED__
48 #include "mbed_debug.h"
49 #include "mbed_assert.h"
50 #else
51 #define MBED_LFS_ENABLE_INFO false
52 #define MBED_LFS_ENABLE_DEBUG true
53 #define MBED_LFS_ENABLE_WARN true
54 #define MBED_LFS_ENABLE_ERROR true
55 #define MBED_LFS_ENABLE_ASSERT true
56 #define MBED_LFS_INTRINSICS true
57 #endif
58 
59 // Logging functions
60 #if !defined(LFS_NO_INFO) && MBED_LFS_ENABLE_INFO
61 #define LFS_INFO(fmt, ...) printf("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
62 #elif !defined(LFS_NO_INFO) && !defined(MBED_LFS_ENABLE_INFO)
63 #define LFS_INFO(fmt, ...) debug("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
64 #else
65 #define LFS_INFO(fmt, ...)
66 #endif
67 
68 #if !defined(LFS_NO_DEBUG) && MBED_LFS_ENABLE_DEBUG
69 #define LFS_DEBUG(fmt, ...) printf("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
70 #elif !defined(LFS_NO_DEBUG) && !defined(MBED_LFS_ENABLE_DEBUG)
71 #define LFS_DEBUG(fmt, ...) debug("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
72 #else
73 #define LFS_DEBUG(fmt, ...)
74 #endif
75 
76 #if !defined(LFS_NO_WARN) && MBED_LFS_ENABLE_WARN
77 #define LFS_WARN(fmt, ...) printf("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
78 #elif !defined(LFS_NO_WARN) && !defined(MBED_LFS_ENABLE_WARN)
79 #define LFS_WARN(fmt, ...) debug("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
80 #else
81 #define LFS_WARN(fmt, ...)
82 #endif
83 
84 #if !defined(LFS_NO_ERROR) && MBED_LFS_ENABLE_ERROR
85 #define LFS_ERROR(fmt, ...) printf("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
86 #elif !defined(LFS_NO_ERROR) && !defined(MBED_LFS_ENABLE_ERROR)
87 #define LFS_ERROR(fmt, ...) debug("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
88 #else
89 #define LFS_ERROR(fmt, ...)
90 #endif
91 
92 // Runtime assertions
93 #if !defined(LFS_NO_ASSERT) && MBED_LFS_ENABLE_ASSERT
94 #define LFS_ASSERT(test) assert(test)
95 #elif !defined(LFS_NO_ASSERT) && !defined(MBED_LFS_ENABLE_ASSERT)
96 #define LFS_ASSERT(test) MBED_ASSERT(test)
97 #else
98 #define LFS_ASSERT(test)
99 #endif
100 
101 
102 // Builtin functions, these may be replaced by more efficient
103 // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
104 // expensive basic C implementation for debugging purposes
105 
106 // Min/max functions for unsigned 32-bit numbers
107 static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
108  return (a > b) ? a : b;
109 }
110 
111 static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
112  return (a < b) ? a : b;
113 }
114 
115 // Find the next smallest power of 2 less than or equal to a
116 static inline uint32_t lfs_npw2(uint32_t a) {
117 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
118  (defined(__GNUC__) || defined(__CC_ARM))
119  return 32 - __builtin_clz(a-1);
120 #else
121  uint32_t r = 0;
122  uint32_t s;
123  a -= 1;
124  s = (a > 0xffff) << 4; a >>= s; r |= s;
125  s = (a > 0xff ) << 3; a >>= s; r |= s;
126  s = (a > 0xf ) << 2; a >>= s; r |= s;
127  s = (a > 0x3 ) << 1; a >>= s; r |= s;
128  return (r | (a >> 1)) + 1;
129 #endif
130 }
131 
132 // Count the number of trailing binary zeros in a
133 // lfs_ctz(0) may be undefined
134 static inline uint32_t lfs_ctz(uint32_t a) {
135 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
136  defined(__GNUC__)
137  return __builtin_ctz(a);
138 #else
139  return lfs_npw2((a & -a) + 1) - 1;
140 #endif
141 }
142 
143 // Count the number of binary ones in a
144 static inline uint32_t lfs_popc(uint32_t a) {
145 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
146  (defined(__GNUC__) || defined(__CC_ARM))
147  return __builtin_popcount(a);
148 #else
149  a = a - ((a >> 1) & 0x55555555);
150  a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
151  return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
152 #endif
153 }
154 
155 // Find the sequence comparison of a and b, this is the distance
156 // between a and b ignoring overflow
157 static inline int lfs_scmp(uint32_t a, uint32_t b) {
158  return (int)(unsigned)(a - b);
159 }
160 
161 // Convert from 32-bit little-endian to native order
162 static inline uint32_t lfs_fromle32(uint32_t a) {
163 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
164  (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
165  (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
166  (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
167  return a;
168 #elif !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
169  (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
170  (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
171  (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
172  return __builtin_bswap32(a);
173 #else
174  return (((uint8_t*)&a)[0] << 0) |
175  (((uint8_t*)&a)[1] << 8) |
176  (((uint8_t*)&a)[2] << 16) |
177  (((uint8_t*)&a)[3] << 24);
178 #endif
179 }
180 
181 // Convert to 32-bit little-endian from native order
182 static inline uint32_t lfs_tole32(uint32_t a) {
183  return lfs_fromle32(a);
184 }
185 
186 // Calculate CRC-32 with polynomial = 0x04c11db7
187 void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
188 
189 // Allocate memory, only used if buffers are not provided to littlefs
190 static inline void *lfs_malloc(size_t size) {
191 #ifndef LFS_NO_MALLOC
192  return malloc(size);
193 #else
194  (void)size;
195  return NULL;
196 #endif
197 }
198 
199 // Deallocate memory, only used if buffers are not provided to littlefs
200 static inline void lfs_free(void *p) {
201 #ifndef LFS_NO_MALLOC
202  free(p);
203 #else
204  (void)p;
205 #endif
206 }
207 
208 
209 #ifdef __cplusplus
210 } /* extern "C" */
211 #endif
212 
213 #endif
214 #endif
Definition: lfs.h:262
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.