BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 12:21:58 by
