Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lfs_util.h Source File

lfs_util.h

00001 /*
00002  * lfs utility functions
00003  *
00004  * Copyright (c) 2017 ARM Limited
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 #ifndef LFS_UTIL_H
00019 #define LFS_UTIL_H
00020 
00021 #include <stdint.h>
00022 #include <stdbool.h>
00023 #include <string.h>
00024 
00025 #ifndef LFS_NO_MALLOC
00026 #include <stdlib.h>
00027 #endif
00028 #ifndef LFS_NO_ASSERT
00029 #include <assert.h>
00030 #endif
00031 #if !defined(LFS_NO_INFO) || !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR)
00032 #include <stdio.h>
00033 #endif
00034 
00035 
00036 // Macros, may be replaced by system specific wrappers. Arguments to these
00037 // macros must not have side-effects as the macros can be removed for a smaller
00038 // code footprint
00039 
00040 #ifdef __MBED__
00041 #include "mbed_debug.h"
00042 #include "mbed_assert.h"
00043 #else
00044 #define MBED_LFS_ENABLE_INFO   false
00045 #define MBED_LFS_ENABLE_DEBUG  true
00046 #define MBED_LFS_ENABLE_WARN   true
00047 #define MBED_LFS_ENABLE_ERROR  true
00048 #define MBED_LFS_ENABLE_ASSERT true
00049 #define MBED_LFS_INTRINSICS    true
00050 #endif
00051 
00052 // Logging functions
00053 #if !defined(LFS_NO_INFO) && MBED_LFS_ENABLE_INFO
00054 #define LFS_INFO(fmt, ...)  printf("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00055 #elif !defined(LFS_NO_INFO) && !defined(MBED_LFS_ENABLE_INFO)
00056 #define LFS_INFO(fmt, ...)  debug("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00057 #else
00058 #define LFS_INFO(fmt, ...)
00059 #endif
00060 
00061 #if !defined(LFS_NO_DEBUG) && MBED_LFS_ENABLE_DEBUG
00062 #define LFS_DEBUG(fmt, ...) printf("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00063 #elif !defined(LFS_NO_DEBUG) && !defined(MBED_LFS_ENABLE_DEBUG)
00064 #define LFS_DEBUG(fmt, ...) debug("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00065 #else
00066 #define LFS_DEBUG(fmt, ...)
00067 #endif
00068 
00069 #if !defined(LFS_NO_WARN) && MBED_LFS_ENABLE_WARN
00070 #define LFS_WARN(fmt, ...)  printf("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00071 #elif !defined(LFS_NO_WARN) && !defined(MBED_LFS_ENABLE_WARN)
00072 #define LFS_WARN(fmt, ...)  debug("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00073 #else
00074 #define LFS_WARN(fmt, ...)
00075 #endif
00076 
00077 #if !defined(LFS_NO_ERROR) && MBED_LFS_ENABLE_ERROR
00078 #define LFS_ERROR(fmt, ...) printf("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00079 #elif !defined(LFS_NO_ERROR) && !defined(MBED_LFS_ENABLE_ERROR)
00080 #define LFS_ERROR(fmt, ...) debug("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00081 #else
00082 #define LFS_ERROR(fmt, ...)
00083 #endif
00084 
00085 // Runtime assertions
00086 #if !defined(LFS_NO_ASSERT) && MBED_LFS_ENABLE_ASSERT
00087 #define LFS_ASSERT(test) assert(test)
00088 #elif !defined(LFS_NO_ASSERT) && !defined(MBED_LFS_ENABLE_ASSERT)
00089 #define LFS_ASSERT(test) MBED_ASSERT(test)
00090 #else
00091 #define LFS_ASSERT(test)
00092 #endif
00093 
00094 
00095 // Builtin functions, these may be replaced by more efficient
00096 // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
00097 // expensive basic C implementation for debugging purposes
00098 
00099 // Min/max functions for unsigned 32-bit numbers
00100 static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
00101     return (a > b) ? a : b;
00102 }
00103 
00104 static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
00105     return (a < b) ? a : b;
00106 }
00107 
00108 // Find the next smallest power of 2 less than or equal to a
00109 static inline uint32_t lfs_npw2(uint32_t a) {
00110 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00111     (defined(__GNUC__) || defined(__CC_ARM))
00112     return 32 - __builtin_clz(a-1);
00113 #else
00114     uint32_t r = 0;
00115     uint32_t s;
00116     a -= 1;
00117     s = (a > 0xffff) << 4; a >>= s; r |= s;
00118     s = (a > 0xff  ) << 3; a >>= s; r |= s;
00119     s = (a > 0xf   ) << 2; a >>= s; r |= s;
00120     s = (a > 0x3   ) << 1; a >>= s; r |= s;
00121     return (r | (a >> 1)) + 1;
00122 #endif
00123 }
00124 
00125 // Count the number of trailing binary zeros in a
00126 // lfs_ctz(0) may be undefined
00127 static inline uint32_t lfs_ctz(uint32_t a) {
00128 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00129     defined(__GNUC__)
00130     return __builtin_ctz(a);
00131 #else
00132     return lfs_npw2((a & -a) + 1) - 1;
00133 #endif
00134 }
00135 
00136 // Count the number of binary ones in a
00137 static inline uint32_t lfs_popc(uint32_t a) {
00138 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00139     (defined(__GNUC__) || defined(__CC_ARM))
00140     return __builtin_popcount(a);
00141 #else
00142     a = a - ((a >> 1) & 0x55555555);
00143     a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
00144     return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
00145 #endif
00146 }
00147 
00148 // Find the sequence comparison of a and b, this is the distance
00149 // between a and b ignoring overflow
00150 static inline int lfs_scmp(uint32_t a, uint32_t b) {
00151     return (int)(unsigned)(a - b);
00152 }
00153 
00154 // Convert from 32-bit little-endian to native order
00155 static inline uint32_t lfs_fromle32(uint32_t a) {
00156 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
00157     (defined(  BYTE_ORDER  ) &&   BYTE_ORDER   ==   ORDER_LITTLE_ENDIAN  ) || \
00158     (defined(__BYTE_ORDER  ) && __BYTE_ORDER   == __ORDER_LITTLE_ENDIAN  ) || \
00159     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
00160     return a;
00161 #elif !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
00162     (defined(  BYTE_ORDER  ) &&   BYTE_ORDER   ==   ORDER_BIG_ENDIAN  ) || \
00163     (defined(__BYTE_ORDER  ) && __BYTE_ORDER   == __ORDER_BIG_ENDIAN  ) || \
00164     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
00165     return __builtin_bswap32(a);
00166 #else
00167     return (((uint8_t*)&a)[0] <<  0) |
00168            (((uint8_t*)&a)[1] <<  8) |
00169            (((uint8_t*)&a)[2] << 16) |
00170            (((uint8_t*)&a)[3] << 24);
00171 #endif
00172 }
00173 
00174 // Convert to 32-bit little-endian from native order
00175 static inline uint32_t lfs_tole32(uint32_t a) {
00176     return lfs_fromle32(a);
00177 }
00178 
00179 // Calculate CRC-32 with polynomial = 0x04c11db7
00180 void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
00181 
00182 // Allocate memory, only used if buffers are not provided to littlefs
00183 static inline void *lfs_malloc(size_t size) {
00184 #ifndef LFS_NO_MALLOC
00185     return malloc(size);
00186 #else
00187     return NULL;
00188 #endif
00189 }
00190 
00191 // Deallocate memory, only used if buffers are not provided to littlefs
00192 static inline void lfs_free(void *p) {
00193 #ifndef LFS_NO_MALLOC
00194     free(p);
00195 #endif
00196 }
00197 
00198 
00199 #endif