Update filesystem tooling and LittleFS defaults

This commit is contained in:
2026-05-11 14:01:56 +02:00
parent 12e82d35d2
commit e85d51488e
3 changed files with 153 additions and 6 deletions

View File

@@ -15,6 +15,8 @@ DEFAULT_SAMPLE_RATE = 16000
DEFAULT_VOICE = "af_bella"
DEFAULT_BLOCK_SIZE = 4096
DEFAULT_BLOCK_COUNT = 2048
DEFAULT_READ_SIZE = 512
DEFAULT_LOOKAHEAD_SIZE = 256
DEFAULT_FILTERS = [
"highpass=f=120",
"lowpass=f=6000",
@@ -26,6 +28,7 @@ DEFAULT_SYS_PROMPTS = [
{"id": "404", "text": "No sound sample was found on the device."},
{"id": "update", "text": "Firmware updated. Awaiting confirmation."},
{"id": "confirm", "text": "State confirmed."},
{"id": "voltest", "text": "Volume test. This is a sample of the current volume level."},
]
@@ -129,18 +132,32 @@ def add_files_recursive(fs: LittleFS, local_path: Path, lfs_path: str = "/") ->
add_files_recursive(fs, item, target_path)
def build_littlefs_hex(source_folder: Path, output_hex: Path, block_size: int, block_count: int, start_addr: int) -> None:
def build_littlefs_image(source_folder: Path, block_size: int, block_count: int) -> tuple[LittleFS, int]:
fs = LittleFS(
block_size=block_size,
block_count=block_count,
read_size=256,
read_size=DEFAULT_READ_SIZE,
prog_size=256,
lookahead_size=512,
lookahead_size=DEFAULT_LOOKAHEAD_SIZE,
cache_size=4096,
)
add_files_recursive(fs, source_folder)
used_blocks = 0
lfs_buffer = fs.context.buffer
for idx in range(block_count):
offset = idx * block_size
block_data = lfs_buffer[offset : offset + block_size]
if any(byte != 0xFF for byte in block_data):
used_blocks += 1
return fs, used_blocks
def build_littlefs_hex(source_folder: Path, output_hex: Path, block_size: int, block_count: int, start_addr: int) -> int:
fs, used_blocks = build_littlefs_image(source_folder, block_size, block_count)
ih = IntelHex()
lfs_buffer = fs.context.buffer
@@ -151,6 +168,42 @@ def build_littlefs_hex(source_folder: Path, output_hex: Path, block_size: int, b
ih.frombytes(block_data, offset=start_addr + offset)
ih.tofile(str(output_hex), format="hex")
return used_blocks
def summarize_directory(directory: Path) -> tuple[int, int]:
if not directory.exists():
return 0, 0
file_count = 0
raw_bytes = 0
for file_path in directory.rglob("*"):
if file_path.is_file():
file_count += 1
raw_bytes += file_path.stat().st_size
return file_count, raw_bytes
def format_bytes(size: int) -> str:
units = ["B", "KiB", "MiB", "GiB"]
value = float(size)
for unit in units:
if value < 1024.0 or unit == units[-1]:
if unit == "B":
return f"{int(value)} {unit}"
return f"{value:.1f} {unit}"
value /= 1024.0
def report_directory_usage(label: str, directory: Path, block_size: int, block_count: int) -> None:
file_count, raw_bytes = summarize_directory(directory)
_, used_blocks = build_littlefs_image(directory, block_size, block_count)
fs_bytes = used_blocks * block_size
print(
f" {label}: files={file_count}, raw={format_bytes(raw_bytes)}, "
f"fs={format_bytes(fs_bytes)} ({used_blocks} blocks, standalone estimate)"
)
def parse_args() -> argparse.Namespace:
@@ -203,7 +256,7 @@ def main() -> None:
tts_count = build_sys_tts(prompts, out_sys, args.sample_rate)
wav_count = import_wavs_to_a(wav_dir, out_a, args.sample_rate)
build_littlefs_hex(
total_used_blocks = build_littlefs_hex(
source_folder=staging_root,
output_hex=output_hex,
block_size=args.block_size,
@@ -212,6 +265,14 @@ def main() -> None:
)
print(f"Done. TTS assets: {tts_count}, WAV imports: {wav_count}, HEX: {output_hex}")
print("Usage summary:")
report_directory_usage("sys", out_sys, args.block_size, args.block_count)
report_directory_usage("audio", out_a, args.block_size, args.block_count)
print(
f" total: raw={format_bytes(summarize_directory(staging_root)[1])}, "
f"fs={format_bytes(total_used_blocks * args.block_size)} "
f"({total_used_blocks} blocks in combined image)"
)
if not args.keep_staging and staging_root.exists():
shutil.rmtree(staging_root)