Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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 #include "cmsis_compiler.h"
00051 #else
00052 #define MBED_LFS_ENABLE_INFO   false
00053 #define MBED_LFS_ENABLE_DEBUG  true
00054 #define MBED_LFS_ENABLE_WARN   true
00055 #define MBED_LFS_ENABLE_ERROR  true
00056 #define MBED_LFS_ENABLE_ASSERT true
00057 #define MBED_LFS_INTRINSICS    true
00058 #endif
00059 
00060 // Logging functions
00061 #if !defined(LFS_NO_INFO) && MBED_LFS_ENABLE_INFO
00062 #define LFS_INFO(fmt, ...)  printf("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00063 #elif !defined(LFS_NO_INFO) && !defined(MBED_LFS_ENABLE_INFO)
00064 #define LFS_INFO(fmt, ...)  debug("lfs info:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00065 #else
00066 #define LFS_INFO(fmt, ...)
00067 #endif
00068 
00069 #if !defined(LFS_NO_DEBUG) && MBED_LFS_ENABLE_DEBUG
00070 #define LFS_DEBUG(fmt, ...) printf("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00071 #elif !defined(LFS_NO_DEBUG) && !defined(MBED_LFS_ENABLE_DEBUG)
00072 #define LFS_DEBUG(fmt, ...) debug("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00073 #else
00074 #define LFS_DEBUG(fmt, ...)
00075 #endif
00076 
00077 #if !defined(LFS_NO_WARN) && MBED_LFS_ENABLE_WARN
00078 #define LFS_WARN(fmt, ...)  printf("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00079 #elif !defined(LFS_NO_WARN) && !defined(MBED_LFS_ENABLE_WARN)
00080 #define LFS_WARN(fmt, ...)  debug("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00081 #else
00082 #define LFS_WARN(fmt, ...)
00083 #endif
00084 
00085 #if !defined(LFS_NO_ERROR) && MBED_LFS_ENABLE_ERROR
00086 #define LFS_ERROR(fmt, ...) printf("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00087 #elif !defined(LFS_NO_ERROR) && !defined(MBED_LFS_ENABLE_ERROR)
00088 #define LFS_ERROR(fmt, ...) debug("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
00089 #else
00090 #define LFS_ERROR(fmt, ...)
00091 #endif
00092 
00093 // Runtime assertions
00094 #if !defined(LFS_NO_ASSERT) && MBED_LFS_ENABLE_ASSERT
00095 #define LFS_ASSERT(test) assert(test)
00096 #elif !defined(LFS_NO_ASSERT) && !defined(MBED_LFS_ENABLE_ASSERT)
00097 #define LFS_ASSERT(test) MBED_ASSERT(test)
00098 #else
00099 #define LFS_ASSERT(test)
00100 #endif
00101 
00102 
00103 // Builtin functions, these may be replaced by more efficient
00104 // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
00105 // expensive basic C implementation for debugging purposes
00106 
00107 // Min/max functions for unsigned 32-bit numbers
00108 static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
00109     return (a > b) ? a : b;
00110 }
00111 
00112 static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
00113     return (a < b) ? a : b;
00114 }
00115 
00116 // Find the next smallest power of 2 less than or equal to a
00117 static inline uint32_t lfs_npw2(uint32_t a) {
00118 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00119     (defined(__GNUC__) || defined(__CC_ARM))
00120     return 32 - __builtin_clz(a-1);
00121 #else
00122     uint32_t r = 0;
00123     uint32_t s;
00124     a -= 1;
00125     s = (a > 0xffff) << 4; a >>= s; r |= s;
00126     s = (a > 0xff  ) << 3; a >>= s; r |= s;
00127     s = (a > 0xf   ) << 2; a >>= s; r |= s;
00128     s = (a > 0x3   ) << 1; a >>= s; r |= s;
00129     return (r | (a >> 1)) + 1;
00130 #endif
00131 }
00132 
00133 // Count the number of trailing binary zeros in a
00134 // lfs_ctz(0) may be undefined
00135 static inline uint32_t lfs_ctz(uint32_t a) {
00136 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00137     defined(__GNUC__)
00138     return __builtin_ctz(a);
00139 #else
00140     return lfs_npw2((a & -a) + 1) - 1;
00141 #endif
00142 }
00143 
00144 // Count the number of binary ones in a
00145 static inline uint32_t lfs_popc(uint32_t a) {
00146 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00147     (defined(__GNUC__) || defined(__CC_ARM))
00148     return __builtin_popcount(a);
00149 #else
00150     a = a - ((a >> 1) & 0x55555555);
00151     a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
00152     return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
00153 #endif
00154 }
00155 
00156 // Find the sequence comparison of a and b, this is the distance
00157 // between a and b ignoring overflow
00158 static inline int lfs_scmp(uint32_t a, uint32_t b) {
00159     return (int)(unsigned)(a - b);
00160 }
00161 
00162 // Convert from 32-bit little-endian to native order
00163 static inline uint32_t lfs_fromle32(uint32_t a) {
00164 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
00165     (defined(  BYTE_ORDER  ) &&   BYTE_ORDER   ==   ORDER_LITTLE_ENDIAN  ) || \
00166     (defined(__BYTE_ORDER  ) && __BYTE_ORDER   == __ORDER_LITTLE_ENDIAN  ) || \
00167     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
00168     return a;
00169 #elif !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && ( \
00170     (defined(  BYTE_ORDER  ) &&   BYTE_ORDER   ==   ORDER_BIG_ENDIAN  ) || \
00171     (defined(__BYTE_ORDER  ) && __BYTE_ORDER   == __ORDER_BIG_ENDIAN  ) || \
00172     (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
00173     return __builtin_bswap32(a);
00174 #else
00175     return (((uint8_t*)&a)[0] <<  0) |
00176            (((uint8_t*)&a)[1] <<  8) |
00177            (((uint8_t*)&a)[2] << 16) |
00178            (((uint8_t*)&a)[3] << 24);
00179 #endif
00180 }
00181 
00182 // Convert to 32-bit little-endian from native order
00183 static inline uint32_t lfs_tole32(uint32_t a) {
00184     return lfs_fromle32(a);
00185 }
00186 
00187 // Reverse the bits in a
00188 static inline uint32_t lfs_rbit(uint32_t a) {
00189 #if !defined(LFS_NO_INTRINSICS) && MBED_LFS_INTRINSICS && \
00190     defined(__MBED__)
00191     return __RBIT(a);
00192 #else
00193     a = ((a & 0xaaaaaaaa) >> 1) | ((a & 0x55555555) << 1);
00194     a = ((a & 0xcccccccc) >> 2) | ((a & 0x33333333) << 2);
00195     a = ((a & 0xf0f0f0f0) >> 4) | ((a & 0x0f0f0f0f) << 4);
00196     a = ((a & 0xff00ff00) >> 8) | ((a & 0x00ff00ff) << 8);
00197     a = (a >> 16) | (a << 16);
00198     return a;
00199 #endif
00200 }
00201 
00202 // Calculate CRC-32 with polynomial = 0x04c11db7
00203 void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
00204 
00205 // Allocate memory, only used if buffers are not provided to littlefs
00206 static inline void *lfs_malloc(size_t size) {
00207 #ifndef LFS_NO_MALLOC
00208     return malloc(size);
00209 #else
00210     (void)size;
00211     return NULL;
00212 #endif
00213 }
00214 
00215 // Deallocate memory, only used if buffers are not provided to littlefs
00216 static inline void lfs_free(void *p) {
00217 #ifndef LFS_NO_MALLOC
00218     free(p);
00219 #else
00220     (void)p;
00221 #endif
00222 }
00223 
00224 
00225 #ifdef __cplusplus
00226 } /* extern "C" */
00227 #endif
00228 
00229 #endif
00230 #endif