Mbed OS Reference
Loading...
Searching...
No Matches
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
38extern "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
108static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
109 return (a > b) ? a : b;
110}
111
112static 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
117static 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
135static 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
145static 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
158static 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
163static 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
183static inline uint32_t lfs_tole32(uint32_t a) {
184 return lfs_fromle32(a);
185}
186
187// Reverse the bits in a
188static 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
203void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
204
205// Allocate memory, only used if buffers are not provided to littlefs
206static 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
216static 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