takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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. All rights reserved.
00005  * SPDX-License-Identifier: BSD-3-Clause
00006  */
00007 #ifndef LFS_UTIL_H
00008 #define LFS_UTIL_H
00009 
00010 // Users can override lfs_util.h with their own configuration by defining
00011 // LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
00012 //
00013 // If LFS_CONFIG is used, none of the default utils will be emitted and must be
00014 // provided by the config file. To start I would suggest copying lfs_util.h and
00015 // modifying as needed.
00016 #ifdef LFS_CONFIG
00017 #define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
00018 #define LFS_STRINGIZE2(x) #x
00019 #include LFS_STRINGIZE(LFS_CONFIG)
00020 #else
00021 
00022 // System includes
00023 #include <stdint.h>
00024 #include <stdbool.h>
00025 #include <string.h>
00026 
00027 #ifndef LFS_NO_MALLOC
00028 #include <stdlib.h>
00029 #endif
00030 #ifndef LFS_NO_ASSERT
00031 #include <assert.h>
00032 #endif
00033 #if !defined(LFS_NO_INFO) || !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR)
00034 #include <stdio.h>
00035 #endif
00036 
00037 #ifdef __cplusplus
00038 extern "C"
00039 {
00040 #endif
00041 
00042 
00043 // Macros, may be replaced by system specific wrappers. Arguments to these
00044 // macros must not have side-effects as the macros can be removed for a smaller
00045 // code footprint
00046 
00047 #ifdef __MBED__
00048 #include "mbed_debug.h"
00049 #include "mbed_assert.h"
00050 #else
00051 #define MBED_LFS_ENABLE_INFO   false
00052 #define MBED_LFS_ENABLE_DEBUG  true
00053 #define MBED_LFS_ENABLE_WARN   true
00054 #define MBED_LFS_ENABLE_ERROR  true
00055 #define MBED_LFS_ENABLE_ASSERT true
00056 #define MBED_LFS_INTRINSICS    true
00057 #endif
00058 
00059 // Logging functions
00060 #if !defined(LFS_NO_INFO) && MBED_LFS_ENABLE_INFO
00061 #define LFS_INFO(fmt, ...)  printf("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00062 #elif !defined(LFS_NO_INFO) && !defined(MBED_LFS_ENABLE_INFO)
00063 #define LFS_INFO(fmt, ...)  debug("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00064 #else
00065 #define LFS_INFO(fmt, ...)
00066 #endif
00067 
00068 #if !defined(LFS_NO_DEBUG) && MBED_LFS_ENABLE_DEBUG
00069 #define LFS_DEBUG(fmt, ...) printf("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00070 #elif !defined(LFS_NO_DEBUG) && !defined(MBED_LFS_ENABLE_DEBUG)
00071 #define LFS_DEBUG(fmt, ...) debug("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00072 #else
00073 #define LFS_DEBUG(fmt, ...)
00074 #endif
00075 
00076 #if !defined(LFS_NO_WARN) && MBED_LFS_ENABLE_WARN
00077 #define LFS_WARN(fmt, ...)  printf("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00078 #elif !defined(LFS_NO_WARN) && !defined(MBED_LFS_ENABLE_WARN)
00079 #define LFS_WARN(fmt, ...)  debug("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00080 #else
00081 #define LFS_WARN(fmt, ...)
00082 #endif
00083 
00084 #if !defined(LFS_NO_ERROR) && MBED_LFS_ENABLE_ERROR
00085 #define LFS_ERROR(fmt, ...) printf("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00086 #elif !defined(LFS_NO_ERROR) && !defined(MBED_LFS_ENABLE_ERROR)
00087 #define LFS_ERROR(fmt, ...) debug("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00088 #else
00089 #define LFS_ERROR(fmt, ...)
00090 #endif
00091 
00092 // Runtime assertions
00093 #if !defined(LFS_NO_ASSERT) && MBED_LFS_ENABLE_ASSERT
00094 #define LFS_ASSERT(test) assert(test)
00095 #elif !defined(LFS_NO_ASSERT) && !defined(MBED_LFS_ENABLE_ASSERT)
00096 #define LFS_ASSERT(test) MBED_ASSERT(test)
00097 #else
00098 #define LFS_ASSERT(test)
00099 #endif
00100 
00101 
00102 // Builtin functions, these may be replaced by more efficient
00103 // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
00104 // expensive basic C implementation for debugging purposes
00105 
00106 // Min/max functions for unsigned 32-bit numbers
00107 static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
00108     return (a > b) ? a : b;
00109 }
00110 
00111 static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
00112     return (a < b) ? a : b;
00113 }
00114 
00115 // Find the next smallest power of 2 less than or equal to a
00116 static inline uint32_t lfs_npw2(uint32_t a) {
00117 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00118     (defined(__GNUC__) || defined(__CC_ARM))
00119     return 32 - __builtin_clz(a-1);
00120 #else
00121     uint32_t r = 0;
00122     uint32_t s;
00123     a -= 1;
00124     s = (a > 0xffff) << 4; a >>= s; r |= s;
00125     s = (a > 0xff  ) << 3; a >>= s; r |= s;
00126     s = (a > 0xf   ) << 2; a >>= s; r |= s;
00127     s = (a > 0x3   ) << 1; a >>= s; r |= s;
00128     return (r | (a >> 1)) + 1;
00129 #endif
00130 }
00131 
00132 // Count the number of trailing binary zeros in a
00133 // lfs_ctz(0) may be undefined
00134 static inline uint32_t lfs_ctz(uint32_t a) {
00135 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00136     defined(__GNUC__)
00137     return __builtin_ctz(a);
00138 #else
00139     return lfs_npw2((a & -a) + 1) - 1;
00140 #endif
00141 }
00142 
00143 // Count the number of binary ones in a
00144 static inline uint32_t lfs_popc(uint32_t a) {
00145 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00146     (defined(__GNUC__) || defined(__CC_ARM))
00147     return __builtin_popcount(a);
00148 #else
00149     a = a - ((a >> 1) & 0x55555555);
00150     a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
00151     return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
00152 #endif
00153 }
00154 
00155 // Find the sequence comparison of a and b, this is the distance
00156 // between a and b ignoring overflow
00157 static inline int lfs_scmp(uint32_t a, uint32_t b) {
00158     return (int)(unsigned)(a - b);
00159 }
00160 
00161 // Convert from 32-bit little-endian to native order
00162 static inline uint32_t lfs_fromle32(uint32_t a) {
00163 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
00164     (defined(  BYTE_ORDER  ) &&   BYTE_ORDER   ==   ORDER_LITTLE_ENDIAN  ) || \
00165     (defined(__BYTE_ORDER  ) && __BYTE_ORDER   == __ORDER_LITTLE_ENDIAN  ) || \
00166     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
00167     return a;
00168 #elif !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
00169     (defined(  BYTE_ORDER  ) &&   BYTE_ORDER   ==   ORDER_BIG_ENDIAN  ) || \
00170     (defined(__BYTE_ORDER  ) && __BYTE_ORDER   == __ORDER_BIG_ENDIAN  ) || \
00171     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
00172     return __builtin_bswap32(a);
00173 #else
00174     return (((uint8_t*)&a)[0] <<  0) |
00175            (((uint8_t*)&a)[1] <<  8) |
00176            (((uint8_t*)&a)[2] << 16) |
00177            (((uint8_t*)&a)[3] << 24);
00178 #endif
00179 }
00180 
00181 // Convert to 32-bit little-endian from native order
00182 static inline uint32_t lfs_tole32(uint32_t a) {
00183     return lfs_fromle32(a);
00184 }
00185 
00186 // Calculate CRC-32 with polynomial = 0x04c11db7
00187 void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
00188 
00189 // Allocate memory, only used if buffers are not provided to littlefs
00190 static inline void *lfs_malloc(size_t size) {
00191 #ifndef LFS_NO_MALLOC
00192     return malloc(size);
00193 #else
00194     (void)size;
00195     return NULL;
00196 #endif
00197 }
00198 
00199 // Deallocate memory, only used if buffers are not provided to littlefs
00200 static inline void lfs_free(void *p) {
00201 #ifndef LFS_NO_MALLOC
00202     free(p);
00203 #else
00204     (void)p;
00205 #endif
00206 }
00207 
00208 
00209 #ifdef __cplusplus
00210 } /* extern "C" */
00211 #endif
00212 
00213 #endif
00214 #endif