Update filesystem tooling and LittleFS defaults
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user