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 #include "cmsis_compiler.h"
51 #else
52 #define MBED_LFS_ENABLE_INFO false
53 #define MBED_LFS_ENABLE_DEBUG true
54 #define MBED_LFS_ENABLE_WARN true
55 #define MBED_LFS_ENABLE_ERROR true
56 #define MBED_LFS_ENABLE_ASSERT true
57 #define MBED_LFS_INTRINSICS true
58 #endif
59 
60 // Logging functions
61 #if !defined(LFS_NO_INFO) && MBED_LFS_ENABLE_INFO
62 #define LFS_INFO(fmt, ...) printf("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
63 #elif !defined(LFS_NO_INFO) && !defined(MBED_LFS_ENABLE_INFO)
64 #define LFS_INFO(fmt, ...) debug("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
65 #else
66 #define LFS_INFO(fmt, ...)
67 #endif
68 
69 #if !defined(LFS_NO_DEBUG) && MBED_LFS_ENABLE_DEBUG
70 #define LFS_DEBUG(fmt, ...) printf("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
71 #elif !defined(LFS_NO_DEBUG) && !defined(MBED_LFS_ENABLE_DEBUG)
72 #define LFS_DEBUG(fmt, ...) debug("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
73 #else
74 #define LFS_DEBUG(fmt, ...)
75 #endif
76 
77 #if !defined(LFS_NO_WARN) && MBED_LFS_ENABLE_WARN
78 #define LFS_WARN(fmt, ...) printf("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
79 #elif !defined(LFS_NO_WARN) && !defined(MBED_LFS_ENABLE_WARN)
80 #define LFS_WARN(fmt, ...) debug("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
81 #else
82 #define LFS_WARN(fmt, ...)
83 #endif
84 
85 #if !defined(LFS_NO_ERROR) && MBED_LFS_ENABLE_ERROR
86 #define LFS_ERROR(fmt, ...) printf("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
87 #elif !defined(LFS_NO_ERROR) && !defined(MBED_LFS_ENABLE_ERROR)
88 #define LFS_ERROR(fmt, ...) debug("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
89 #else
90 #define LFS_ERROR(fmt, ...)
91 #endif
92 
93 // Runtime assertions
94 #if !defined(LFS_NO_ASSERT) && MBED_LFS_ENABLE_ASSERT
95 #define LFS_ASSERT(test) assert(test)
96 #elif !defined(LFS_NO_ASSERT) && !defined(MBED_LFS_ENABLE_ASSERT)
97 #define LFS_ASSERT(test) MBED_ASSERT(test)
98 #else
99 #define LFS_ASSERT(test)
100 #endif
101 
102 
103 // Builtin functions, these may be replaced by more efficient
104 // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
105 // expensive basic C implementation for debugging purposes
106 
107 // Min/max functions for unsigned 32-bit numbers
108 static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
109  return (a > b) ? a : b;
110 }
111 
112 static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
113  return (a < b) ? a : b;
114 }
115 
116 // Find the next smallest power of 2 less than or equal to a
117 static inline uint32_t lfs_npw2(uint32_t a) {
118 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
119  defined(__GNUC__)
120  return 32 - __builtin_clz(a-1);
121 #else
122  uint32_t r = 0;
123  uint32_t s;
124  a -= 1;
125  s = (a > 0xffff) << 4; a >>= s; r |= s;
126  s = (a > 0xff ) << 3; a >>= s; r |= s;
127  s = (a > 0xf ) << 2; a >>= s; r |= s;
128  s = (a > 0x3 ) << 1; a >>= s; r |= s;
129  return (r | (a >> 1)) + 1;
130 #endif
131 }
132 
133 // Count the number of trailing binary zeros in a
134 // lfs_ctz(0) may be undefined
135 static inline uint32_t lfs_ctz(uint32_t a) {
136 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
137  defined(__GNUC__)
138  return __builtin_ctz(a);
139 #else
140  return lfs_npw2((a & -a) + 1) - 1;
141 #endif
142 }
143 
144 // Count the number of binary ones in a
145 static inline uint32_t lfs_popc(uint32_t a) {
146 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
147  defined(__GNUC__)
148  return __builtin_popcount(a);
149 #else
150  a = a - ((a >> 1) & 0x55555555);
151  a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
152  return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
153 #endif
154 }
155 
156 // Find the sequence comparison of a and b, this is the distance
157 // between a and b ignoring overflow
158 static inline int lfs_scmp(uint32_t a, uint32_t b) {
159  return (int)(unsigned)(a - b);
160 }
161 
162 // Convert from 32-bit little-endian to native order
163 static inline uint32_t lfs_fromle32(uint32_t a) {
164 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
165  (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
166  (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
167  (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
168  return a;
169 #elif !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
170  (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
171  (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
172  (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
173  return __builtin_bswap32(a);
174 #else
175  return (((uint8_t*)&a)[0] << 0) |
176  (((uint8_t*)&a)[1] << 8) |
177  (((uint8_t*)&a)[2] << 16) |
178  (((uint8_t*)&a)[3] << 24);
179 #endif
180 }
181 
182 // Convert to 32-bit little-endian from native order
183 static inline uint32_t lfs_tole32(uint32_t a) {
184  return lfs_fromle32(a);
185 }
186 
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 
202 // Calculate CRC-32 with polynomial = 0x04c11db7
203 void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
204 
205 // Allocate memory, only used if buffers are not provided to littlefs
206 static inline void *lfs_malloc(size_t size) {
207 #ifndef LFS_NO_MALLOC
208  return malloc(size);
209 #else
210  (void)size;
211  return NULL;
212 #endif
213 }
214 
215 // Deallocate memory, only used if buffers are not provided to littlefs
216 static inline void lfs_free(void *p) {
217 #ifndef LFS_NO_MALLOC
218  free(p);
219 #else
220  (void)p;
221 #endif
222 }
223 
224 
225 #ifdef __cplusplus
226 } /* extern "C" */
227 #endif
228 
229 #endif
230 #endif
Definition: lfs.h:268
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.