Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
lfs.h
00001 /* 00002 * The little filesystem 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_H 00019 #define LFS_H 00020 00021 #include <stdint.h> 00022 #include <stdbool.h> 00023 00024 00025 /// Definitions /// 00026 00027 // Type definitions 00028 typedef uint32_t lfs_size_t; 00029 typedef uint32_t lfs_off_t; 00030 00031 typedef int32_t lfs_ssize_t; 00032 typedef int32_t lfs_soff_t; 00033 00034 typedef uint32_t lfs_block_t; 00035 00036 // Max name size in bytes 00037 #ifndef LFS_NAME_MAX 00038 #define LFS_NAME_MAX 255 00039 #endif 00040 00041 // Possible error codes, these are negative to allow 00042 // valid positive return values 00043 enum lfs_error { 00044 LFS_ERR_OK = 0, // No error 00045 LFS_ERR_IO = -5, // Error during device operation 00046 LFS_ERR_CORRUPT = -52, // Corrupted 00047 LFS_ERR_NOENT = -2, // No directory entry 00048 LFS_ERR_EXIST = -17, // Entry already exists 00049 LFS_ERR_NOTDIR = -20, // Entry is not a dir 00050 LFS_ERR_ISDIR = -21, // Entry is a dir 00051 LFS_ERR_INVAL = -22, // Invalid parameter 00052 LFS_ERR_NOSPC = -28, // No space left on device 00053 LFS_ERR_NOMEM = -12, // No more memory available 00054 }; 00055 00056 // File types 00057 enum lfs_type { 00058 LFS_TYPE_REG = 0x11, 00059 LFS_TYPE_DIR = 0x22, 00060 LFS_TYPE_SUPERBLOCK = 0x2e, 00061 }; 00062 00063 // File open flags 00064 enum lfs_open_flags { 00065 // open flags 00066 LFS_O_RDONLY = 1, // Open a file as read only 00067 LFS_O_WRONLY = 2, // Open a file as write only 00068 LFS_O_RDWR = 3, // Open a file as read and write 00069 LFS_O_CREAT = 0x0100, // Create a file if it does not exist 00070 LFS_O_EXCL = 0x0200, // Fail if a file already exists 00071 LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size 00072 LFS_O_APPEND = 0x0800, // Move to end of file on every write 00073 00074 // internally used flags 00075 LFS_F_DIRTY = 0x10000, // File does not match storage 00076 LFS_F_WRITING = 0x20000, // File has been written since last flush 00077 LFS_F_READING = 0x40000, // File has been read since last flush 00078 LFS_F_ERRED = 0x80000, // An error occured during write 00079 }; 00080 00081 // File seek flags 00082 enum lfs_whence_flags { 00083 LFS_SEEK_SET = 0, // Seek relative to an absolute position 00084 LFS_SEEK_CUR = 1, // Seek relative to the current file position 00085 LFS_SEEK_END = 2, // Seek relative to the end of the file 00086 }; 00087 00088 00089 // Configuration provided during initialization of the littlefs 00090 struct lfs_config { 00091 // Opaque user provided context that can be used to pass 00092 // information to the block device operations 00093 void *context; 00094 00095 // Read a region in a block. Negative error codes are propogated 00096 // to the user. 00097 int (*read)(const struct lfs_config *c, lfs_block_t block, 00098 lfs_off_t off, void *buffer, lfs_size_t size); 00099 00100 // Program a region in a block. The block must have previously 00101 // been erased. Negative error codes are propogated to the user. 00102 // The prog function must return LFS_ERR_CORRUPT if the block should 00103 // be considered bad. 00104 int (*prog)(const struct lfs_config *c, lfs_block_t block, 00105 lfs_off_t off, const void *buffer, lfs_size_t size); 00106 00107 // Erase a block. A block must be erased before being programmed. 00108 // The state of an erased block is undefined. Negative error codes 00109 // are propogated to the user. 00110 int (*erase)(const struct lfs_config *c, lfs_block_t block); 00111 00112 // Sync the state of the underlying block device. Negative error codes 00113 // are propogated to the user. 00114 int (*sync)(const struct lfs_config *c); 00115 00116 // Minimum size of a block read. This determines the size of read buffers. 00117 // This may be larger than the physical read size to improve performance 00118 // by caching more of the block device. 00119 lfs_size_t read_size; 00120 00121 // Minimum size of a block program. This determines the size of program 00122 // buffers. This may be larger than the physical program size to improve 00123 // performance by caching more of the block device. 00124 lfs_size_t prog_size; 00125 00126 // Size of an erasable block. This does not impact ram consumption and 00127 // may be larger than the physical erase size. However, this should be 00128 // kept small as each file currently takes up an entire block . 00129 lfs_size_t block_size; 00130 00131 // Number of erasable blocks on the device. 00132 lfs_size_t block_count; 00133 00134 // Number of blocks to lookahead during block allocation. A larger 00135 // lookahead reduces the number of passes required to allocate a block. 00136 // The lookahead buffer requires only 1 bit per block so it can be quite 00137 // large with little ram impact. Should be a multiple of 32. 00138 lfs_size_t lookahead; 00139 00140 // Optional, statically allocated read buffer. Must be read sized. 00141 void *read_buffer; 00142 00143 // Optional, statically allocated program buffer. Must be program sized. 00144 void *prog_buffer; 00145 00146 // Optional, statically allocated lookahead buffer. Must be 1 bit per 00147 // lookahead block. 00148 void *lookahead_buffer; 00149 00150 // Optional, statically allocated buffer for files. Must be program sized. 00151 // If enabled, only one file may be opened at a time. 00152 void *file_buffer; 00153 }; 00154 00155 00156 // File info structure 00157 struct lfs_info { 00158 // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR 00159 uint8_t type; 00160 00161 // Size of the file, only valid for REG files 00162 lfs_size_t size; 00163 00164 // Name of the file stored as a null-terminated string 00165 char name[LFS_NAME_MAX+1]; 00166 }; 00167 00168 00169 /// littlefs data structures /// 00170 typedef struct lfs_entry { 00171 lfs_off_t off; 00172 00173 struct lfs_disk_entry { 00174 uint8_t type; 00175 uint8_t elen; 00176 uint8_t alen; 00177 uint8_t nlen; 00178 union { 00179 struct { 00180 lfs_block_t head; 00181 lfs_size_t size; 00182 } file; 00183 lfs_block_t dir[2]; 00184 } u; 00185 } d; 00186 } lfs_entry_t; 00187 00188 typedef struct lfs_cache { 00189 lfs_block_t block; 00190 lfs_off_t off; 00191 uint8_t *buffer; 00192 } lfs_cache_t; 00193 00194 typedef struct lfs_file { 00195 struct lfs_file *next; 00196 lfs_block_t pair[2]; 00197 lfs_off_t poff; 00198 00199 lfs_block_t head; 00200 lfs_size_t size; 00201 00202 uint32_t flags; 00203 lfs_off_t pos; 00204 lfs_block_t block; 00205 lfs_off_t off; 00206 lfs_cache_t cache; 00207 } lfs_file_t; 00208 00209 typedef struct lfs_dir { 00210 struct lfs_dir *next; 00211 lfs_block_t pair[2]; 00212 lfs_off_t off; 00213 00214 lfs_block_t head[2]; 00215 lfs_off_t pos; 00216 00217 struct lfs_disk_dir { 00218 uint32_t rev; 00219 lfs_size_t size; 00220 lfs_block_t tail[2]; 00221 } d; 00222 } lfs_dir_t; 00223 00224 typedef struct lfs_superblock { 00225 lfs_off_t off; 00226 00227 struct lfs_disk_superblock { 00228 uint8_t type; 00229 uint8_t elen; 00230 uint8_t alen; 00231 uint8_t nlen; 00232 lfs_block_t root[2]; 00233 uint32_t block_size; 00234 uint32_t block_count; 00235 uint32_t version; 00236 char magic[8]; 00237 } d; 00238 } lfs_superblock_t; 00239 00240 typedef struct lfs_free { 00241 lfs_block_t begin; 00242 lfs_block_t end; 00243 lfs_block_t off; 00244 uint32_t *buffer; 00245 } lfs_free_t; 00246 00247 // The littlefs type 00248 typedef struct lfs { 00249 const struct lfs_config *cfg; 00250 00251 lfs_block_t root[2]; 00252 lfs_file_t *files; 00253 lfs_dir_t *dirs; 00254 00255 lfs_cache_t rcache; 00256 lfs_cache_t pcache; 00257 00258 lfs_free_t free; 00259 bool deorphaned; 00260 } lfs_t; 00261 00262 00263 /// Filesystem functions /// 00264 00265 // Format a block device with the littlefs 00266 // 00267 // Requires a littlefs object and config struct. This clobbers the littlefs 00268 // object, and does not leave the filesystem mounted. 00269 // 00270 // Returns a negative error code on failure. 00271 int lfs_format(lfs_t *lfs, const struct lfs_config *config); 00272 00273 // Mounts a littlefs 00274 // 00275 // Requires a littlefs object and config struct. Multiple filesystems 00276 // may be mounted simultaneously with multiple littlefs objects. Both 00277 // lfs and config must be allocated while mounted. 00278 // 00279 // Returns a negative error code on failure. 00280 int lfs_mount(lfs_t *lfs, const struct lfs_config *config); 00281 00282 // Unmounts a littlefs 00283 // 00284 // Does nothing besides releasing any allocated resources. 00285 // Returns a negative error code on failure. 00286 int lfs_unmount(lfs_t *lfs); 00287 00288 /// General operations /// 00289 00290 // Removes a file or directory 00291 // 00292 // If removing a directory, the directory must be empty. 00293 // Returns a negative error code on failure. 00294 int lfs_remove(lfs_t *lfs, const char *path); 00295 00296 // Rename or move a file or directory 00297 // 00298 // If the destination exists, it must match the source in type. 00299 // If the destination is a directory, the directory must be empty. 00300 // 00301 // Note: If power loss occurs, it is possible that the file or directory 00302 // will exist in both the oldpath and newpath simultaneously after the 00303 // next mount. 00304 // 00305 // Returns a negative error code on failure. 00306 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath); 00307 00308 // Find info about a file or directory 00309 // 00310 // Fills out the info structure, based on the specified file or directory. 00311 // Returns a negative error code on failure. 00312 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info); 00313 00314 00315 /// File operations /// 00316 00317 // Open a file 00318 // 00319 // The mode that the file is opened in is determined 00320 // by the flags, which are values from the enum lfs_open_flags 00321 // that are bitwise-ored together. 00322 // 00323 // Returns a negative error code on failure. 00324 int lfs_file_open(lfs_t *lfs, lfs_file_t *file, 00325 const char *path, int flags); 00326 00327 // Close a file 00328 // 00329 // Any pending writes are written out to storage as though 00330 // sync had been called and releases any allocated resources. 00331 // 00332 // Returns a negative error code on failure. 00333 int lfs_file_close(lfs_t *lfs, lfs_file_t *file); 00334 00335 // Synchronize a file on storage 00336 // 00337 // Any pending writes are written out to storage. 00338 // Returns a negative error code on failure. 00339 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file); 00340 00341 // Read data from file 00342 // 00343 // Takes a buffer and size indicating where to store the read data. 00344 // Returns the number of bytes read, or a negative error code on failure. 00345 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file, 00346 void *buffer, lfs_size_t size); 00347 00348 // Write data to file 00349 // 00350 // Takes a buffer and size indicating the data to write. The file will not 00351 // actually be updated on the storage until either sync or close is called. 00352 // 00353 // Returns the number of bytes written, or a negative error code on failure. 00354 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, 00355 const void *buffer, lfs_size_t size); 00356 00357 // Change the position of the file 00358 // 00359 // The change in position is determined by the offset and whence flag. 00360 // Returns the old position of the file, or a negative error code on failure. 00361 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, 00362 lfs_soff_t off, int whence); 00363 00364 // Return the position of the file 00365 // 00366 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) 00367 // Returns the position of the file, or a negative error code on failure. 00368 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file); 00369 00370 // Change the position of the file to the beginning of the file 00371 // 00372 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) 00373 // Returns a negative error code on failure. 00374 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file); 00375 00376 // Return the size of the file 00377 // 00378 // Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END) 00379 // Returns the size of the file, or a negative error code on failure. 00380 lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file); 00381 00382 00383 /// Directory operations /// 00384 00385 // Create a directory 00386 // 00387 // Returns a negative error code on failure. 00388 int lfs_mkdir(lfs_t *lfs, const char *path); 00389 00390 // Open a directory 00391 // 00392 // Once open a directory can be used with read to iterate over files. 00393 // Returns a negative error code on failure. 00394 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path); 00395 00396 // Close a directory 00397 // 00398 // Releases any allocated resources. 00399 // Returns a negative error code on failure. 00400 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir); 00401 00402 // Read an entry in the directory 00403 // 00404 // Fills out the info structure, based on the specified file or directory. 00405 // Returns a negative error code on failure. 00406 int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info); 00407 00408 // Change the position of the directory 00409 // 00410 // The new off must be a value previous returned from tell and specifies 00411 // an absolute offset in the directory seek. 00412 // 00413 // Returns a negative error code on failure. 00414 int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off); 00415 00416 // Return the position of the directory 00417 // 00418 // The returned offset is only meant to be consumed by seek and may not make 00419 // sense, but does indicate the current position in the directory iteration. 00420 // 00421 // Returns the position of the directory, or a negative error code on failure. 00422 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir); 00423 00424 // Change the position of the directory to the beginning of the directory 00425 // 00426 // Returns a negative error code on failure. 00427 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir); 00428 00429 00430 /// Miscellaneous littlefs specific operations /// 00431 00432 // Traverse through all blocks in use by the filesystem 00433 // 00434 // The provided callback will be called with each block address that is 00435 // currently in use by the filesystem. This can be used to determine which 00436 // blocks are in use or how much of the storage is available. 00437 // 00438 // Returns a negative error code on failure. 00439 int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); 00440 00441 // Prunes any recoverable errors that may have occured in the filesystem 00442 // 00443 // Not needed to be called by user unless an operation is interrupted 00444 // but the filesystem is still mounted. This is already called on first 00445 // allocation. 00446 // 00447 // Returns a negative error code on failure. 00448 int lfs_deorphan(lfs_t *lfs); 00449 00450 00451 #endif
Generated on Tue Jul 12 2022 13:02:56 by
