CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-littlefs-python

A Python wrapper for LittleFS filesystem designed for embedded systems with minimal RAM and flash requirements

Pending
Overview
Eval results
Files

cli.mddocs/

Command-Line Interface

Command-line tools for creating LittleFS images from directories, extracting filesystem contents, and inspecting binary images. The CLI provides essential utilities for embedded systems development, build processes, and filesystem management workflows.

Capabilities

CLI Entry Points

The package provides a command-line executable accessible through multiple methods:

# Direct executable (after pip install)
littlefs-python --help

# Python module execution
python -m littlefs --help

Global Options

Common options available across all commands:

# Global CLI options
--version           # Show package version
-v, --verbose       # Increase verbosity (can be repeated)
--name-max SIZE     # Maximum filename length (default: 255)

Create Command

Creates LittleFS binary images from files and directories with configurable filesystem parameters.

def create(source: Path, destination: Path = "lfs.bin", *, 
           block_size: int, block_count: int = None, fs_size: int = None,
           compact: bool = False, no_pad: bool = False) -> int:
    """
    Create LittleFS image from file/directory contents.
    
    Parameters:
    - source: Path, source file or directory to encode
    - destination: Path, output binary image file (default: lfs.bin)
    - block_size: int, LittleFS block size (required)
    - block_count: int, number of blocks (mutually exclusive with fs_size)
    - fs_size: int, total filesystem size (mutually exclusive with block_count)
    - compact: bool, store data in beginning blocks only
    - no_pad: bool, don't pad binary to full size (only with --compact)
    
    Returns:
    int: 0 on success, non-zero on error
    """

Command Usage:

# Create from directory
littlefs-python create my_files/ filesystem.bin --block-size 4096 --fs-size 1MB

# Create from single file  
littlefs-python create important.txt single_file.bin --block-size 512 --block-count 256

# Create compact image
littlefs-python create data/ compact.bin --block-size 1024 --fs-size 512KB --compact

# Create without padding
littlefs-python create small_data/ minimal.bin --block-size 512 --fs-size 64KB --compact --no-pad

Extract Command

Extracts LittleFS binary images to directory structures, recreating the original file hierarchy.

def extract(source: Path, destination: Path = ".", *, block_size: int) -> int:
    """
    Extract LittleFS image contents to directory.
    
    Parameters:
    - source: Path, LittleFS binary image to extract
    - destination: Path, output directory (default: current directory)
    - block_size: int, LittleFS block size (required)
    
    Returns:
    int: 0 on success, non-zero on error
    """

Command Usage:

# Extract to current directory
littlefs-python extract filesystem.bin --block-size 4096

# Extract to specific directory
littlefs-python extract image.bin extracted_files/ --block-size 512

# Extract with verbose output
littlefs-python extract -v system.bin recovery/ --block-size 1024

List Command

Lists contents of LittleFS binary images without extracting files, useful for inspection and verification.

def list(source: Path, *, block_size: int) -> int:
    """
    List LittleFS image contents.
    
    Parameters:
    - source: Path, LittleFS binary image to inspect
    - block_size: int, LittleFS block size (required)
    
    Returns:
    int: 0 on success, non-zero on error
    """

Command Usage:

# List all files and directories
littlefs-python list filesystem.bin --block-size 4096

# List with detailed output
littlefs-python list -v image.bin --block-size 512

Size Parser Utility

Built-in parser for filesystem and block sizes with unit support:

def size_parser(size_str: str) -> int:
    """
    Parse size strings with unit suffixes.
    
    Parameters:
    - size_str: str, size with optional suffix
    
    Supported formats:
    - Decimal: "1024", "2048"
    - Hexadecimal: "0x400", "0x800" 
    - With units: "1KB", "2MB", "1GB"
    - Base suffix: "1024B" (B suffix ignored)
    
    Units (case-insensitive):
    - KB: 1024 bytes
    - MB: 1024² bytes  
    - GB: 1024³ bytes
    
    Returns:
    int: Size in bytes
    """

CLI Configuration Details

Block Size Requirements

Block size must meet LittleFS constraints:

  • Minimum: 128 bytes
  • Typical: 512, 1024, 2048, 4096 bytes
  • Must match target flash memory erase block size

Filesystem Size Options

Two mutually exclusive ways to specify filesystem size:

  1. Block Count: --block-count N (direct block specification)
  2. Total Size: --fs-size SIZE (automatically calculates blocks)

The filesystem size must be a multiple of block size.

Compact Mode

When --compact is used:

  • Files are stored in the minimum number of blocks
  • Reduces image size for embedded systems
  • Can be combined with --no-pad to eliminate trailing 0xFF bytes
  • Original block count is preserved unless --no-pad is used

Usage Examples

Build System Integration

#!/bin/bash
# build_filesystem.sh - Build script for embedded project

SOURCE_DIR="firmware_files"
OUTPUT_IMAGE="firmware_fs.bin"
BLOCK_SIZE=4096
FS_SIZE="2MB"

echo "Building LittleFS image..."
littlefs-python create "$SOURCE_DIR" "$OUTPUT_IMAGE" \
    --block-size $BLOCK_SIZE \
    --fs-size $FS_SIZE \
    --compact \
    --verbose

if [ $? -eq 0 ]; then
    echo "Filesystem image created: $OUTPUT_IMAGE"
    littlefs-python list "$OUTPUT_IMAGE" --block-size $BLOCK_SIZE
else
    echo "Failed to create filesystem image"
    exit 1
fi

Development Workflow

# Development cycle: create, test, extract, modify

# 1. Create filesystem from development files
littlefs-python create dev_files/ test.bin --block-size 1024 --fs-size 256KB -v

# 2. List contents to verify
littlefs-python list test.bin --block-size 1024 -v

# 3. Extract to verify round-trip
mkdir -p extracted
littlefs-python extract test.bin extracted/ --block-size 1024 -v

# 4. Compare original and extracted
diff -r dev_files/ extracted/

Multiple Image Sizes

# Create different image sizes for different targets

# Small embedded device (64KB flash)
littlefs-python create config/ small.bin --block-size 512 --fs-size 64KB --compact

# Medium device (1MB flash)  
littlefs-python create app_data/ medium.bin --block-size 2048 --fs-size 1MB

# Large device (8MB flash)
littlefs-python create full_system/ large.bin --block-size 4096 --fs-size 8MB

# List sizes
ls -lh *.bin

CI/CD Integration

# .github/workflows/build.yml
name: Build Filesystem Images

on: [push, pull_request]

jobs:
  build-fs:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.9'
        
    - name: Install littlefs-python
      run: pip install littlefs-python
      
    - name: Create filesystem images
      run: |
        littlefs-python create firmware/ firmware.bin --block-size 4096 --fs-size 2MB --compact -v
        littlefs-python create bootloader/ boot.bin --block-size 512 --fs-size 128KB --compact -v
        
    - name: Verify images
      run: |
        littlefs-python list firmware.bin --block-size 4096 -v
        littlefs-python list boot.bin --block-size 512 -v
        
    - name: Upload artifacts
      uses: actions/upload-artifact@v3
      with:
        name: filesystem-images
        path: '*.bin'

Advanced Size Calculations

# Calculate optimal sizes for different scenarios

# Exact fit (no wasted space)
SOURCE_SIZE=$(du -sb source_files/ | cut -f1)
BLOCK_SIZE=1024
BLOCKS_NEEDED=$(( (SOURCE_SIZE + BLOCK_SIZE - 1) / BLOCK_SIZE ))  # Ceiling division
FILESYSTEM_SIZE=$(( BLOCKS_NEEDED * BLOCK_SIZE ))

echo "Source: ${SOURCE_SIZE} bytes"
echo "Blocks needed: ${BLOCKS_NEEDED}"  
echo "Filesystem size: ${FILESYSTEM_SIZE} bytes"

littlefs-python create source_files/ exact.bin \
    --block-size $BLOCK_SIZE \
    --block-count $BLOCKS_NEEDED \
    --compact

# With overhead for future additions (25% extra)
OVERHEAD_BLOCKS=$(( BLOCKS_NEEDED * 125 / 100 ))
littlefs-python create source_files/ with_overhead.bin \
    --block-size $BLOCK_SIZE \
    --block-count $OVERHEAD_BLOCKS

Validation and Testing

# Comprehensive validation script
validate_filesystem() {
    local IMAGE=$1
    local BLOCK_SIZE=$2
    local TEMP_DIR=$(mktemp -d)
    
    echo "Validating $IMAGE..."
    
    # Extract image
    littlefs-python extract "$IMAGE" "$TEMP_DIR" --block-size $BLOCK_SIZE
    
    if [ $? -eq 0 ]; then
        echo "✓ Extraction successful"
        
        # Count files
        FILE_COUNT=$(find "$TEMP_DIR" -type f | wc -l)
        echo "✓ Contains $FILE_COUNT files"
        
        # Check for corruption by re-creating and comparing
        littlefs-python create "$TEMP_DIR" test_recreate.bin --block-size $BLOCK_SIZE --fs-size 1MB
        
        # List both images to compare
        echo "Original image contents:"
        littlefs-python list "$IMAGE" --block-size $BLOCK_SIZE
        
        echo "Recreated image contents:"
        littlefs-python list test_recreate.bin --block-size $BLOCK_SIZE
        
        rm -f test_recreate.bin
    else
        echo "✗ Extraction failed"
    fi
    
    rm -rf "$TEMP_DIR"
}

# Test multiple images
validate_filesystem firmware.bin 4096
validate_filesystem config.bin 512

Install with Tessl CLI

npx tessl i tessl/pypi-littlefs-python

docs

cli.md

contexts.md

file-operations.md

filesystem.md

index.md

low-level-api.md

tile.json