### LittleFS Filesystem Example Source: https://github.com/littlefs-project/littlefs/blob/master/README.md This C example demonstrates mounting, formatting, reading, writing, and closing a file in LittleFS. It includes essential setup for the filesystem configuration and handles potential mounting errors by reformatting. ```c #include "lfs.h" // variables used by the filesystem lfs_t lfs; lfs_file_t file; // configuration of the filesystem is provided by this struct const struct lfs_config cfg = { // block device operations .read = user_provided_block_device_read, .prog = user_provided_block_device_prog, .erase = user_provided_block_device_erase, .sync = user_provided_block_device_sync, // block device configuration .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, }; // entry point int main(void) { // mount the filesystem int err = lfs_mount(&lfs, &cfg); // reformat if we can't mount the filesystem // this should only happen on the first boot if (err) { lfs_format(&lfs, &cfg); lfs_mount(&lfs, &cfg); } // read current count uint32_t boot_count = 0; lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // update boot count boot_count += 1; lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count)); // remember the storage is not updated until the file is closed successfully lfs_file_close(&lfs, &file); // release any resources we were using lfs_unmount(&lfs); // print the boot count printf("boot_count: %d\n", boot_count); } ``` -------------------------------- ### Complete Example - Boot Counter Application Source: https://context7.com/littlefs-project/littlefs/llms.txt A full working example demonstrating LittleFS filesystem initialization, basic file operations (reading and writing a boot counter), and showcasing power-loss resilience. It includes user-provided block device operations and the main application logic. ```APIDOC ## Complete Example - Boot Counter Application ### Description Full working example demonstrating filesystem initialization, file operations, and power-loss resilience. ### Method N/A (C main function) ### Endpoint N/A (C main function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include "lfs.h" #include // User-provided block device operations extern int user_provided_block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); extern int user_provided_block_device_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); extern int user_provided_block_device_erase(const struct lfs_config *c, lfs_block_t block); extern int user_provided_block_device_sync(const struct lfs_config *c); // Filesystem state lfs_t lfs; lfs_file_t file; // Configuration const struct lfs_config cfg = { .read = user_provided_block_device_read, .prog = user_provided_block_device_prog, .erase = user_provided_block_device_erase, .sync = user_provided_block_device_sync, .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, }; int main(void) { // Mount the filesystem int err = lfs_mount(&lfs, &cfg); if (err) { // First boot: format and mount lfs_format(&lfs, &cfg); lfs_mount(&lfs, &cfg); } // Read boot count uint32_t boot_count = 0; lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // Increment and write back boot_count += 1; lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count)); // Commit to storage (power-safe after this) lfs_file_close(&lfs, &file); // Clean up lfs_unmount(&lfs); printf("boot_count: %lu\n", (unsigned long)boot_count); return 0; } ``` ### Response #### Success Response (int) - **0** on successful execution of the main function. #### Response Example ``` boot_count: 5 ``` ``` -------------------------------- ### Complete Example - Boot Counter Application Source: https://context7.com/littlefs-project/littlefs/llms.txt A full working example demonstrating LittleFS filesystem initialization, file operations, and power-loss resilience for a boot counter application. Requires user-provided block device operations. ```c #include "lfs.h" #include // User-provided block device operations extern int user_provided_block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); extern int user_provided_block_device_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); extern int user_provided_block_device_erase(const struct lfs_config *c, lfs_block_t block); extern int user_provided_block_device_sync(const struct lfs_config *c); // Filesystem state lfs_t lfs; lfs_file_t file; // Configuration const struct lfs_config cfg = { .read = user_provided_block_device_read, .prog = user_provided_block_device_prog, .erase = user_provided_block_device_erase, .sync = user_provided_block_device_sync, .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, }; int main(void) { // Mount the filesystem int err = lfs_mount(&lfs, &cfg); if (err) { // First boot: format and mount lfs_format(&lfs, &cfg); lfs_mount(&lfs, &cfg); } // Read boot count uint32_t boot_count = 0; lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); // Increment and write back boot_count += 1; lfs_file_rewind(&lfs, &file); lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count)); // Commit to storage (power-safe after this) lfs_file_close(&lfs, &file); // Clean up lfs_unmount(&lfs); printf("boot_count: %lu\n", (unsigned long)boot_count); return 0; } ``` -------------------------------- ### Get File/Directory Info - C Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves information about a file or directory, such as type and size. Handles cases where the file does not exist. ```c #include "lfs.h" struct lfs_info info; int err = lfs_stat(&lfs, "myfile.txt", &info); if (err == LFS_ERR_NOENT) { printf("File does not exist\n"); } else if (err) { printf("Stat failed: %d\n", err); } else { printf("Name: %s\n", info.name); printf("Type: %s\n", info.type == LFS_TYPE_DIR ? "directory" : "file"); printf("Size: %lu bytes\n", (unsigned long)info.size); } // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### Get Filesystem Info - C Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves information about the mounted filesystem, including its version, block size, block count, and maximum name/file lengths. Check for errors during the operation. ```c #include "lfs.h" struct lfs_fsinfo fsinfo; int err = lfs_fs_stat(&lfs, &fsinfo); if (err) { printf("fs_stat failed: %d\n", err); } else { printf("Disk version: %u.%u\n", fsinfo.disk_version >> 16, fsinfo.disk_version & 0xFFFF); printf("Block size: %lu\n", (unsigned long)fsinfo.block_size); printf("Block count: %lu\n", (unsigned long)fsinfo.block_count); printf("Name max: %lu\n", (unsigned long)fsinfo.name_max); printf("File max: %lu\n", (unsigned long)fsinfo.file_max); } // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### lfs_stat - Get File/Directory Info Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves information about a file or directory including type and size. ```APIDOC ## lfs_stat ### Description Retrieves information about a file or directory, such as its name, type, and size. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c #include "lfs.h" struct lfs_info info; int err = lfs_stat(&lfs, "myfile.txt", &info); if (err == LFS_ERR_NOENT) { printf("File does not exist\n"); } else if (err) { printf("Stat failed: %d\n", err); } else { printf("Name: %s\n", info.name); printf("Type: %s\n", info.type == LFS_TYPE_DIR ? "directory" : "file"); printf("Size: %lu bytes\n", (unsigned long)info.size); } ``` ### Response #### Success Response (200) Populates the provided `lfs_info` struct with file/directory details. Returns `LFS_ERR_OK` (0) on success. #### Response Example ```json { "name": "myfile.txt", "type": "file", "size": 1024 } ``` ``` -------------------------------- ### Filesystem Initialization Source: https://context7.com/littlefs-project/littlefs/llms.txt Functions for formatting, mounting, and unmounting the littlefs filesystem. ```APIDOC ## lfs_format - Format Block Device ### Description Formats a block device with the littlefs filesystem structure. This operation clobbers the filesystem object and must be called before first use of a new storage device. The configuration struct defines block device operations and geometry. ### Method `lfs_format` ### Parameters - **lfs** (*lfs_t*) - Pointer to the littlefs filesystem object. - **cfg** (*const lfs_config*) - Pointer to the configuration struct defining block device operations and geometry. ### Request Example ```c #include "lfs.h" // Block device configuration const struct lfs_config cfg = { // Block device callbacks .read = my_block_read, .prog = my_block_prog, .erase = my_block_erase, .sync = my_block_sync, // Block device geometry .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, }; lfs_t lfs; // Format the filesystem int err = lfs_format(&lfs, &cfg); if (err) { printf("Format failed: %d\n", err); return err; } ``` ### Response - **Return Value** (*int*) - LFS_ERR_OK (0) on success, or an error code on failure. ``` ```APIDOC ## lfs_mount - Mount Filesystem ### Description Mounts an existing littlefs filesystem. Multiple filesystems can be mounted simultaneously using different lfs_t objects. Both the lfs_t and config struct must remain allocated while mounted. ### Method `lfs_mount` ### Parameters - **lfs** (*lfs_t*) - Pointer to the littlefs filesystem object. - **cfg** (*const lfs_config*) - Pointer to the configuration struct defining block device operations and geometry. ### Request Example ```c #include "lfs.h" lfs_t lfs; // Mount the filesystem int err = lfs_mount(&lfs, &cfg); if (err) { // First mount may fail if not formatted, try formatting lfs_format(&lfs, &cfg); err = lfs_mount(&lfs, &cfg); if (err) { printf("Mount failed: %d\n", err); return err; } } printf("Filesystem mounted successfully\n"); ``` ### Response - **Return Value** (*int*) - LFS_ERR_OK (0) on success, or an error code on failure. ``` ```APIDOC ## lfs_unmount - Unmount Filesystem ### Description Unmounts a mounted filesystem and releases any allocated resources. Should be called when filesystem operations are complete. ### Method `lfs_unmount` ### Parameters - **lfs** (*lfs_t*) - Pointer to the littlefs filesystem object. ### Request Example ```c #include "lfs.h" // Unmount when done int err = lfs_unmount(&lfs); if (err) { printf("Unmount failed: %d\n", err); } ``` ### Response - **Return Value** (*int*) - LFS_ERR_OK (0) on success, or an error code on failure. ``` -------------------------------- ### lfs_fs_stat - Get Filesystem Info Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves information about the mounted filesystem including version and limits. ```APIDOC ## lfs_fs_stat ### Description Retrieves overall information about the LittleFS filesystem, such as block size, block count, and maximum name/file lengths. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c #include "lfs.h" struct lfs_fsinfo fsinfo; int err = lfs_fs_stat(&lfs, &fsinfo); if (err) { printf("fs_stat failed: %d\n", err); } else { printf("Disk version: %u.%u\n", fsinfo.disk_version >> 16, fsinfo.disk_version & 0xFFFF); printf("Block size: %lu\n", (unsigned long)fsinfo.block_size); printf("Block count: %lu\n", (unsigned long)fsinfo.block_count); printf("Name max: %lu\n", (unsigned long)fsinfo.name_max); printf("File max: %lu\n", (unsigned long)fsinfo.file_max); } ``` ### Response #### Success Response (200) Populates the provided `lfs_fsinfo` struct with filesystem details. Returns `LFS_ERR_OK` (0) on success. #### Response Example ```json { "disk_version": 65537, "block_size": 256, "block_count": 1024, "name_max": 255, "file_max": 2147483647 } ``` ``` -------------------------------- ### Atomic Directory Move States in LittleFS Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Demonstrates the state transitions for an atomic directory move operation in LittleFS. This shows how directories are moved similarly to files, maintaining the integrity of the file system structure. ```text .--------. gstate = no move (m1^~m1) .| root |-. || | | .-------------|| | -' | |'--------' | '--|-|-| -' | .------' | '-------. | v v v | .--------. .--------. .--------. '->| dir A |->| dir B |->| dir C | || gdelta | || | || gdelta | || =~m1 | || | || =m1 | |'--------' |'--------' |'--------' '--------' '--------' '----|---' v .--------. | file D | | | | | '--------' begin move, add reference in dir C, change gstate to have move => .--------. gstate = moving dir B in root (m1^~m1^m2) .| root |-. || | | .--------------|| | -' | |'--------' | '--|-|-| -' | .-------' | '----------. | v | v | .--------. | .--------. '->| dir A |-. | .->| dir C | || gdelta | | | | || gdelta | || =~m1 | | | | || =m1^m2 | |'--------' | | | |'--------' '--------' | | | '---|--|-' | | .-------' | | v v | v | .--------. | .--------. ``` -------------------------------- ### lfs_getattr - Get Custom Attribute Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves a custom attribute from a file or directory. Attributes are identified by an 8-bit type. ```APIDOC ## lfs_getattr ### Description Retrieves a custom attribute associated with a file or directory. Attributes are identified by a unique 8-bit type. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```c #include "lfs.h" // Read a custom attribute (type 0x01) uint32_t created_time = 0; lfs_ssize_t size = lfs_getattr(&lfs, "myfile.txt", 0x01, &created_time, sizeof(created_time)); if (size == LFS_ERR_NOATTR) { printf("Attribute not found\n"); } else if (size < 0) { printf("Error: %d\n", (int)size); } else { printf("Created: %u\n", created_time); } // Check if attribute exists without buffer size = lfs_getattr(&lfs, "myfile.txt", 0x01, NULL, 0); printf("Attribute size: %d bytes\n", (int)size); ``` ### Response #### Success Response (200) Returns the size of the attribute in bytes on success. If the attribute does not exist, `LFS_ERR_NOATTR` is returned. Negative values indicate an error. #### Response Example ```json { "attribute_size": 4 } ``` ``` -------------------------------- ### Adding a Directory: Allocating New Directory Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Illustrates the state after allocating a new directory ('dir B') but before it's integrated into the tree structure. ```text .--------. .| root | -. || | | .-------|| | -' | |'--------' | '---|--|--' | .-' '-. | v v | .--------. .--------. '->| dir A |--->| dir C | || | .->| | || | | || | |'--------' | |'--------' '--------' | '--------' | .--------. | .| dir B | -' || | || | |'--------' '--------' ``` -------------------------------- ### Adding a Directory: Initial State Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Represents the state of the directory tree before adding a new directory, showing the 'root' and 'dir A'. ```text .--------. .| root | -. || | | .-------|| | -' | |'--------' | '---|--|--' | .-' '-. | v v | .--------. .--------. '->| dir A |->| dir C | || | || | || | || | |'--------' |'--------' '--------' '--------' ``` -------------------------------- ### Configure and Format Block Device with littlefs Source: https://context7.com/littlefs-project/littlefs/llms.txt Defines the block device configuration and formats it with littlefs. Ensure the configuration struct accurately reflects the block device's geometry and callbacks. ```c #include "lfs.h" // Block device configuration const struct lfs_config cfg = { // Block device callbacks .read = my_block_read, .prog = my_block_prog, .erase = my_block_erase, .sync = my_block_sync, // Block device geometry .read_size = 16, .prog_size = 16, .block_size = 4096, .block_count = 128, .cache_size = 16, .lookahead_size = 16, .block_cycles = 500, }; lfs_t lfs; // Format the filesystem int err = lfs_format(&lfs, &cfg); if (err) { printf("Format failed: %d\n", err); return err; } // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### Get Filesystem Size - lfs_fs_size Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves the number of blocks currently in use by the filesystem. Returns a negative error code on failure. ```c #include "lfs.h" lfs_ssize_t blocks_used = lfs_fs_size(&lfs); if (blocks_used < 0) { printf("Error: %d\n", (int)blocks_used); } else { uint32_t total_blocks = cfg.block_count; uint32_t used_bytes = blocks_used * cfg.block_size; uint32_t total_bytes = total_blocks * cfg.block_size; printf("Used: %lu / %lu blocks (%lu / %lu bytes)\n", (unsigned long)blocks_used, (unsigned long)total_blocks, (unsigned long)used_bytes, (unsigned long)total_bytes); } // Returns blocks in use, or negative error code ``` -------------------------------- ### Create Directory - lfs_mkdir Source: https://context7.com/littlefs-project/littlefs/llms.txt Creates a new directory at the specified path. Parent directories must already exist. Handles cases where the directory already exists. ```c #include "lfs.h" // Create a single directory int err = lfs_mkdir(&lfs, "configs"); if (err == LFS_ERR_EXIST) { printf("Directory already exists\n"); } else if (err) { printf("mkdir failed: %d\n", err); } // Create nested directories (parent must exist) lfs_mkdir(&lfs, "data"); lfs_mkdir(&lfs, "data/logs"); lfs_mkdir(&lfs, "data/logs/2024"); // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### lfs_fs_size - Get Filesystem Size Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves the number of blocks currently in use by the filesystem. Returns the count of used blocks or a negative error code. ```APIDOC ## lfs_fs_size - Get Filesystem Size ### Description Returns the number of blocks currently in use by the filesystem. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include "lfs.h" lfs_ssize_t blocks_used = lfs_fs_size(&lfs); if (blocks_used < 0) { printf("Error: %d\n", (int)blocks_used); } else { uint32_t total_blocks = cfg.block_count; uint32_t used_bytes = blocks_used * cfg.block_size; uint32_t total_bytes = total_blocks * cfg.block_size; printf("Used: %lu / %lu blocks (%lu / %lu bytes)\n", (unsigned long)blocks_used, (unsigned long)total_blocks, (unsigned long)used_bytes, (unsigned long)total_bytes); } ``` ### Response #### Success Response (int) - **blocks_used** (lfs_ssize_t) - The number of blocks in use by the filesystem. #### Error Response (int) - Negative error code indicating the type of error. #### Response Example ``` Used: 10 / 128 blocks (40960 / 524288 bytes) ``` ``` -------------------------------- ### Display Test Script Help Source: https://github.com/littlefs-project/littlefs/blob/master/README.md Display the help message for the test script, listing all available flags and options. Use this to explore all testing capabilities. ```bash ./scripts/test.py --help ``` -------------------------------- ### Get Custom Attribute - C Source: https://context7.com/littlefs-project/littlefs/llms.txt Retrieves a custom attribute from a file or directory, identified by an 8-bit type. Can be used to check attribute existence by providing a NULL buffer and zero size. ```c #include "lfs.h" // Read a custom attribute (type 0x01) uint32_t created_time = 0; lfs_ssize_t size = lfs_getattr(&lfs, "myfile.txt", 0x01, &created_time, sizeof(created_time)); if (size == LFS_ERR_NOATTR) { printf("Attribute not found\n"); } else if (size < 0) { printf("Error: %d\n", (int)size); } else { printf("Created: %u\n", created_time); } // Check if attribute exists without buffer size = lfs_getattr(&lfs, "myfile.txt", 0x01, NULL, 0); printf("Attribute size: %d bytes\n", (int)size); // Returns attribute size, or negative error code ``` -------------------------------- ### Atomic File Move States in LittleFS Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Illustrates the state transitions of an atomic file move operation, from initial state to during the move, and finally to completion. This is useful for understanding the lifecycle of an atomic file operation. ```text .--------. gstate = no move .| root |-. || | | .-------------|| | -' | |'--------' | '--|-|-| -' | .------' | '-------. | v v v | .--------. .--------. .--------. '->| dir A |->| dir B |->| dir C | || | || | || | || | || | || | |'--------' |'--------' |'--------' '----|---' '--------' '--------' v .--------. | file D | | | | | '--------' begin move, add reference in dir C, change gstate to have move => .--------. gstate = moving file D in dir A (m1) .| root |-. || | | .-------------|| | -' | |'--------' | '--|-|-| -' | .------' | '-------. | v v v | .--------. .--------. .--------. '->| dir A |->| dir B |->| dir C | || | || | || gdelta | || | || | || =m1 | |'--------' |'--------' |'--------' '----|---' '--------' '----|---' | .----------------' v v .--------. | file D | | | | | '--------' complete move, remove reference in dir A, change gstate to no move => .--------. gstate = no move (m1^~m1) .| root |-. || | | .-------------|| | -' | |'--------' | '--|-|-| -' | .------' | '-------. | v v v | .--------. .--------. .--------. '->| dir A |->| dir B |->| dir C | || gdelta | || | || gdelta | || =~m1 | || | || =m1 | |'--------' |'--------' |'--------' '--------' '--------' '----|---' v .--------. | file D | | | | | '--------' ``` -------------------------------- ### Block-based Filesystem Structure Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Illustrates the hierarchical structure of a simple block-based filesystem, similar to FAT or ext2. This design is fast and small but lacks power-loss resilience and wear leveling. ```text .--------. | root | | | | | '--------' .-' '-. v v .--------. .--------. | A | | B | | | | | | | | | '--------' '--------' .-' .-' '-. v v v .--------. .--------. .--------. | C | | D | | E | | | | | | | | | | | | | '--------' '--------' '--------' ``` -------------------------------- ### Run LittleFS Tests Source: https://github.com/littlefs-project/littlefs/blob/master/README.md Execute the test suite for LittleFS on a PC using an emulated block device. Assumes a Linux environment. ```bash make test ``` -------------------------------- ### Open File with Custom Configuration in littlefs Source: https://context7.com/littlefs-project/littlefs/llms.txt Opens a file using a custom configuration, allowing for a static buffer and custom attributes. This is useful for avoiding dynamic memory allocation and storing metadata. ```c #include "lfs.h" lfs_file_t file; uint8_t file_buffer[256]; // Static buffer for file cache // Custom attribute to store file metadata uint32_t file_version = 0; struct lfs_attr attrs[] = { {.type = 0x01, .buffer = &file_version, .size = sizeof(file_version)}, }; const struct lfs_file_config file_cfg = { .buffer = file_buffer, // Static file buffer .attrs = attrs, // Custom attributes .attr_count = 1, }; int err = lfs_file_opencfg(&lfs, &file, "versioned.dat", LFS_O_RDWR | LFS_O_CREAT, &file_cfg); if (err) { printf("Open with config failed: %d\n", err); return err; } // Attribute is read from disk on open (if file exists) printf("File version: %u\n", file_version); // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### LittleFS Wear Leveling Visualization Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md This diagram illustrates the process of detecting a bad block and relocating data in LittleFS. It shows the initial state, the detection of a bad block, and the subsequent relocation of data to a new block. ```text .----. |root| | | '----' v--' '----------------------v .----. .----. | A | | B | | | | | '----' '----' . . v---' . . . .----. . . . | C | . . . | | . . . '----' . . . . . . .----.----.----.----.----.----.----.----.----.----. | A |root| | C | B | | | | | | | | | '----'----'----'----'----'----'----'----'----'----' update C => .----. |root| | | '----' v--' '----------------------v .----. .----. | A | | B | | | | | '----' '----' . . v---' . . . .----. . . . |bad | . . |blck| . . '----' . . . . . . .----.----.----.----.----.----.----.----.----.----. | A |root| |bad | B | | | | | |blck| | | '----'----'----'----'----'----'----'----'----'----' oh no! bad block! relocate C => .----. |root| | | '----' v--' '----------------------v .----. .----. | A | | B | | | | | '----' ``` ```text . . v---' . . . .----. . . . |bad | . . |blck| . . '----' . . . . . . .----.----.----.----.----.----.----.----.----.----. | A |root| |bad | B |bad | | | | | |blck| |blck| | '----'----'----'----'----'----'----'----'----'----' ---------> oh no! bad block! relocate C => .----. |root| | | '----' v--' '----------------------v .----. .----. | A | | B | | | | | '----' '----' . . v---' . . . .----. . .----. . . |bad | . | C' | . . |blck| . | | . . '----' . '----' . . . . . . . .----.----.----.----.----.----.----.----.----.----. | A |root| |bad | B |bad | C' | | | | | |blck| |blck| | | '----'----'----'----'----'----'----'----'----'----' --------------> successfully relocated C, update B => .----. |root| | | '----' v--' '----------------------v .----. .----. | A | |bad | | | |blck| '----' '----' . . v---' . . . .----. . .----. . . |bad | . | C' | . . |blck| . | | . . '----' . '----' ``` -------------------------------- ### Updating Global State with Changes Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Demonstrates how to update the global state by XORing the current state with both the desired changes and the existing delta in a metadata pair. This operation is committed to the metadata pair, effectively updating the filesystem's global state. ```text .--------. .--------. .--------. .--------. .--------. .| |->| gdelta |->| |->| gdelta |->| gdelta | || | || 0x23 | || | || 0xff | || 0xce | || | || | || | || | || | |'--------' |'--------' |'--------' |'--------' |'--------' '--------' '----|---' '--------' '--|---|-' '----|---' v v | v 0x00 --> xor ----------------> xor -|------> xor --> gstate = 0x12 | | | | change gstate to 0xab --> xor <------------|--------------------------' => | v '------------> xor | v .--------. .--------. .--------. .--------. .--------. .| |->| gdelta |->| |->| gdelta |->| gdelta | || | || 0x23 | || | || 0x46 | || 0xce | || | || | || | || | || | |'--------' |'--------' |'--------' |'--------' |'--------' '--------' '----|---' '--------' '----|---' '----|---' v v v 0x00 --> xor ------------------> xor ------> xor --> gstate = 0xab ``` -------------------------------- ### List Available Test Suites Source: https://github.com/littlefs-project/littlefs/blob/master/README.md List all available test suites for the LittleFS test runner. Useful for understanding the test organization. ```bash ./scripts/test.py -l runners/test_runner ``` -------------------------------- ### List Available Test Cases Source: https://github.com/littlefs-project/littlefs/blob/master/README.md List all available test cases within a specific test suite. Helps in identifying individual tests for focused execution. ```bash ./scripts/test.py -L runners/test_runner test_dirs ``` -------------------------------- ### Directory Tree Structure Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Illustrates the hierarchical structure of directories and files within the filesystem, showing parent-child relationships. ```text .--------. .| root | || | || | |'--------' '---|--|--' .-' '------------------------- v v .--------. .--------. .--------. .| dir A |------->| dir A | .| dir B | || | || | || | || | || | || | |'--------' |'--------' |'--------' '---|--|-' '----|---' '---|--|--' .-' '-. | .-' '-. v v v v v .--------. .--------. .--------. .--------. .--------. | file C | | file D | | file E | | file F | | file G | | | | | | | | | | | | | | | | | | | | | '--------' '--------' '--------' '--------' '--------' ``` -------------------------------- ### Open Directory - lfs_dir_open Source: https://context7.com/littlefs-project/littlefs/llms.txt Opens a directory for reading its contents. Returns LFS_ERR_OK (0) on success. ```c #include "lfs.h" lfs_dir_t dir; int err = lfs_dir_open(&lfs, &dir, "/"); if (err) { printf("Failed to open directory: %d\n", err); return err; } // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### Adding a Directory: Parent Directory Update Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Depicts the final state after 'dir B' has been added to its parent directory, completing the integration into the filesystem tree. ```text .--------. .| root | -. ``` -------------------------------- ### Open Files with littlefs Source: https://context7.com/littlefs-project/littlefs/llms.txt Opens files using various flags for different operations like reading, writing, creating, truncating, or appending. Flags can be combined using bitwise OR. ```c #include "lfs.h" lfs_file_t file; // Open for reading only int err = lfs_file_open(&lfs, &file, "config.txt", LFS_O_RDONLY); if (err == LFS_ERR_NOENT) { printf("File does not exist\n"); } // Open for writing, create if not exists err = lfs_file_open(&lfs, &file, "data.bin", LFS_O_WRONLY | LFS_O_CREAT); if (err) { printf("Open failed: %d\n", err); return err; } // Open for read/write, create and truncate err = lfs_file_open(&lfs, &file, "log.txt", LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC); // Open for appending err = lfs_file_open(&lfs, &file, "events.log", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND); // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### Mount littlefs Filesystem Source: https://context7.com/littlefs-project/littlefs/llms.txt Mounts an existing littlefs filesystem. If the initial mount fails (e.g., not formatted), it attempts to format and then mount. Both the lfs_t object and config struct must remain valid while the filesystem is mounted. ```c #include "lfs.h" lfs_t lfs; // Mount the filesystem int err = lfs_mount(&lfs, &cfg); if (err) { // First mount may fail if not formatted, try formatting lfs_format(&lfs, &cfg); err = lfs_mount(&lfs, &cfg); if (err) { printf("Mount failed: %d\n", err); return err; } } printf("Filesystem mounted successfully\n"); // Returns LFS_ERR_OK (0) on success ``` -------------------------------- ### Threaded Linked-List for Traversal Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Demonstrates how a linked-list is threaded through the directory tree to enable efficient traversal of the entire filesystem with constant RAM. ```text .--------. .| root |-. || | | .-------|| |-' | |'--------' | '---|--|--' | .-' '------------------------- | v v | .--------. .--------. .--------. '->| dir A |------->| dir A |------->| dir B | || | || | || | || | || | || | |'--------' |'--------' |'--------' '---|--|-' '----|---' '---|--|--' .-' '-. | .-' '-. v v v v v .--------. .--------. .--------. .--------. .--------. | file C | | file D | | file E | | file F | | file G | | | | | | | | | | | | | | | | | | | | | '--------' '--------' '--------' '--------' '--------' ``` -------------------------------- ### LittleFS Block Allocation Simulation Source: https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md Simulates the process of allocating blocks on a busy filesystem using a lookahead buffer and scanning for free blocks. ```text boot... lookahead: fs blocks: fffff9fffffffffeffffffffffff0000 scanning... lookahead: fffff9ff fs blocks: fffff9fffffffffeffffffffffff0000 alloc = 21 lookahead: fffffdff fs blocks: fffffdfffffffffeffffffffffff0000 alloc = 22 lookahead: ffffffff fs blocks: fffffffffffffffeffffffffffff0000 scanning... lookahead: fffffffe fs blocks: fffffffffffffffeffffffffffff0000 alloc = 63 lookahead: ffffffff fs blocks: ffffffffffffffffffffffffffff0000 scanning... lookahead: ffffffff ```