EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lfs.h Source File

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