tan-cli 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tan/__init__.py +0 -0
- tan/__main__.py +120 -0
- tan/cli.py +939 -0
- tan/command_table.py +265 -0
- tan/commands/__init__.py +8 -0
- tan/commands/bootstrap_cmd.py +4856 -0
- tan/commands/bootstrap_patches.py +164 -0
- tan/commands/bootstrap_toolchain_fetch.py +155 -0
- tan/commands/bootstrap_toolchain_pin.py +36 -0
- tan/commands/build/__init__.py +1 -0
- tan/commands/build/configure_inputs.py +277 -0
- tan/commands/build/execute.py +1852 -0
- tan/commands/build/host_python.py +59 -0
- tan/commands/build/link_stale.py +78 -0
- tan/commands/build/manifest.py +428 -0
- tan/commands/build/materialise.py +81 -0
- tan/commands/build/token_substitution.py +381 -0
- tan/commands/build/toolchain.py +482 -0
- tan/commands/build/user_defines_wipe.py +115 -0
- tan/commands/build/workspace_patches.py +65 -0
- tan/commands/build_cmd.py +2236 -0
- tan/commands/build_output.py +331 -0
- tan/commands/clean_cmd.py +1183 -0
- tan/commands/completion_cmd.py +786 -0
- tan/commands/debug_config_cmd.py +2425 -0
- tan/commands/diff_cmd.py +940 -0
- tan/commands/doctor_cmd.py +4767 -0
- tan/commands/examples_cmd.py +644 -0
- tan/commands/explain_cmd.py +1319 -0
- tan/commands/faultdecode_cmd.py +931 -0
- tan/commands/flash_atoc_guard.py +240 -0
- tan/commands/flash_cmd.py +5731 -0
- tan/commands/flash_mram_guard.py +150 -0
- tan/commands/flash_ram.py +578 -0
- tan/commands/flash_raw.py +583 -0
- tan/commands/generate_cmd.py +1456 -0
- tan/commands/image_cmd.py +753 -0
- tan/commands/init_cmd.py +1740 -0
- tan/commands/inspect_cmd.py +377 -0
- tan/commands/kconfig_cmd.py +734 -0
- tan/commands/model_cmd.py +1514 -0
- tan/commands/model_device_cmd.py +351 -0
- tan/commands/model_device_live.py +234 -0
- tan/commands/model_host_cmd.py +430 -0
- tan/commands/model_zoo_cmd.py +363 -0
- tan/commands/monitor_actions.py +125 -0
- tan/commands/monitor_cmd.py +626 -0
- tan/commands/monitor_session.py +505 -0
- tan/commands/new_som_cmd.py +1522 -0
- tan/commands/pinmux_cmd.py +568 -0
- tan/commands/presets_cmd.py +1123 -0
- tan/commands/probe_cmd.py +421 -0
- tan/commands/reset_cmd.py +354 -0
- tan/commands/reset_confirm.py +168 -0
- tan/commands/run_cmd.py +637 -0
- tan/commands/scaffold_cmd.py +490 -0
- tan/commands/sdk_cmd.py +1723 -0
- tan/commands/size_cmd.py +1020 -0
- tan/commands/support_bundle_cmd.py +1073 -0
- tan/commands/trace_cmd.py +341 -0
- tan/commands/validate_cmd.py +2009 -0
- tan/commands/west_forward_cmd.py +736 -0
- tan/commands/workspace_patch_check.py +296 -0
- tan/core/__init__.py +1 -0
- tan/core/alp_conf_pregen.py +100 -0
- tan/core/artifact_provenance.py +240 -0
- tan/core/atoc_guard.py +276 -0
- tan/core/atoc_guard_messages.py +232 -0
- tan/core/atoc_replacement.py +118 -0
- tan/core/atomic_write.py +178 -0
- tan/core/board_context.py +351 -0
- tan/core/board_diagnostic.py +111 -0
- tan/core/board_files.py +221 -0
- tan/core/board_validator.py +542 -0
- tan/core/board_validator_compat.py +196 -0
- tan/core/board_validator_run.py +129 -0
- tan/core/board_validator_schema.py +186 -0
- tan/core/board_validator_skew.py +46 -0
- tan/core/board_yaml_edit.py +295 -0
- tan/core/board_yaml_pos.py +118 -0
- tan/core/bootstrap.py +2572 -0
- tan/core/build_plan.py +625 -0
- tan/core/consent.py +104 -0
- tan/core/console_filter.py +245 -0
- tan/core/debug_launch.py +1803 -0
- tan/core/devicetree_lint.py +168 -0
- tan/core/dir_removal.py +229 -0
- tan/core/doctor_git.py +172 -0
- tan/core/doctor_libraries.py +253 -0
- tan/core/doctor_render.py +185 -0
- tan/core/doctor_scope.py +66 -0
- tan/core/doctor_setools.py +237 -0
- tan/core/doctor_stale.py +180 -0
- tan/core/document_guards.py +723 -0
- tan/core/dp_id.py +97 -0
- tan/core/elf_load.py +63 -0
- tan/core/error_catalog.py +171 -0
- tan/core/example_catalog.py +499 -0
- tan/core/example_facets.py +151 -0
- tan/core/faultdecode.py +521 -0
- tan/core/flash_plan.py +2501 -0
- tan/core/flow_d_report.py +381 -0
- tan/core/flow_d_uptime.py +164 -0
- tan/core/fs_confine.py +130 -0
- tan/core/global_flags.py +230 -0
- tan/core/host_python.py +210 -0
- tan/core/image_bundle.py +247 -0
- tan/core/inert.py +147 -0
- tan/core/jlink_binary.py +128 -0
- tan/core/jlink_probe.py +481 -0
- tan/core/jsonc_splice.py +404 -0
- tan/core/launch_provenance.py +257 -0
- tan/core/link_refusal.py +76 -0
- tan/core/metadata_schema.py +376 -0
- tan/core/model_check.py +227 -0
- tan/core/model_device.py +449 -0
- tan/core/model_doctor.py +198 -0
- tan/core/model_host.py +48 -0
- tan/core/model_list.py +112 -0
- tan/core/model_zoo.py +353 -0
- tan/core/module_template.py +340 -0
- tan/core/mram_link.py +87 -0
- tan/core/new_som_ospi.py +94 -0
- tan/core/os_class.py +159 -0
- tan/core/patch_paths.py +87 -0
- tan/core/pending.py +40 -0
- tan/core/plain_zephyr_plan.py +138 -0
- tan/core/plan_exec.py +373 -0
- tan/core/plan_tokens.py +600 -0
- tan/core/probe.py +155 -0
- tan/core/probe_plan.py +237 -0
- tan/core/proxy.py +168 -0
- tan/core/publish.py +31 -0
- tan/core/python_floor.py +178 -0
- tan/core/ram_run.py +694 -0
- tan/core/ram_watch.py +231 -0
- tan/core/raw_write.py +160 -0
- tan/core/reset_plan.py +56 -0
- tan/core/run.py +161 -0
- tan/core/scaffold.py +2203 -0
- tan/core/scaffold_selftest_identity.py +225 -0
- tan/core/sdk_default_registry.py +565 -0
- tan/core/sdk_discovery.py +996 -0
- tan/core/sdk_removal.py +465 -0
- tan/core/serial_actions.py +175 -0
- tan/core/serial_capture.py +185 -0
- tan/core/serial_url.py +45 -0
- tan/core/setools.py +608 -0
- tan/core/setools_scratch.py +243 -0
- tan/core/shapes.py +194 -0
- tan/core/size.py +610 -0
- tan/core/som_buildability.py +204 -0
- tan/core/som_schema_version.py +62 -0
- tan/core/subprocess_env.py +201 -0
- tan/core/sysbuild_image.py +94 -0
- tan/core/system_manifest.py +827 -0
- tan/core/text_layout.py +73 -0
- tan/core/timestamp.py +182 -0
- tan/core/tool_lookup.py +383 -0
- tan/core/toolchain_pin.py +117 -0
- tan/core/toolchain_provision.py +1224 -0
- tan/core/trusted_path.py +134 -0
- tan/core/uboot_breakin.py +154 -0
- tan/core/uri_reference.py +415 -0
- tan/core/user_defines.py +152 -0
- tan/core/venv.py +332 -0
- tan/core/west_patches.py +143 -0
- tan/core/west_workspace_refusal.py +159 -0
- tan/core/zephyr_env.py +124 -0
- tan/env.py +185 -0
- tan/envelope.py +647 -0
- tan/exit_codes.py +12 -0
- tan/lazy_typer.py +185 -0
- tan/model/__init__.py +2 -0
- tan/model/_gen_fixture.py +132 -0
- tan/model/adapters/__init__.py +116 -0
- tan/model/adapters/cpu.py +26 -0
- tan/model/adapters/deepx.py +94 -0
- tan/model/adapters/drpai.py +242 -0
- tan/model/adapters/ethos_u.py +951 -0
- tan/model/adapters/executorch.py +55 -0
- tan/model/analyze.py +694 -0
- tan/model/build.py +304 -0
- tan/model/check.py +682 -0
- tan/model/manifest.py +625 -0
- tan/model/measure.py +216 -0
- tan/model/npu_ops_validate.py +130 -0
- tan/model/package.py +125 -0
- tan/model/perf.py +635 -0
- tan/model/perf_apply.py +721 -0
- tan/model/prep.py +193 -0
- tan/model/sram_fit.py +502 -0
- tan/model/targets.py +374 -0
- tan/model/tensorio.py +287 -0
- tan/net.py +73 -0
- tan/output_format.py +213 -0
- tan/planner/__init__.py +219 -0
- tan/planner/aperture.py +202 -0
- tan/planner/buildplan.py +1092 -0
- tan/planner/camera_owner.py +192 -0
- tan/planner/cameras.py +132 -0
- tan/planner/carveout.py +755 -0
- tan/planner/cli.py +274 -0
- tan/planner/headers.py +315 -0
- tan/planner/kconfig.py +2435 -0
- tan/planner/kconfig_symbols.py +473 -0
- tan/planner/libraries.py +677 -0
- tan/planner/link_target.py +237 -0
- tan/planner/linux_ownership.py +216 -0
- tan/planner/loader.py +1525 -0
- tan/planner/manifest.py +116 -0
- tan/planner/memory.py +161 -0
- tan/planner/memregion.py +56 -0
- tan/planner/models.py +533 -0
- tan/planner/orchestrator.py +874 -0
- tan/planner/ownership.py +203 -0
- tan/planner/partition.py +1160 -0
- tan/planner/paths.py +32 -0
- tan/planner/plain_slice.py +139 -0
- tan/planner/project_emit/__init__.py +60 -0
- tan/planner/project_emit/bom_netlist.py +375 -0
- tan/planner/project_emit/dts.py +580 -0
- tan/planner/project_emit/hw_info.py +221 -0
- tan/planner/project_emit/native_sim.py +136 -0
- tan/planner/project_emit/west_libs.py +213 -0
- tan/planner/project_loader.py +264 -0
- tan/planner/sdk_capability.py +203 -0
- tan/planner/sdk_compat.py +395 -0
- tan/planner/secure.py +350 -0
- tan/planner/slugs.py +394 -0
- tan/planner/som_metadata.py +325 -0
- tan/planner/strict_loaders.py +131 -0
- tan/planner/template.py +1037 -0
- tan/planner/template_pins.py +535 -0
- tan/planner/template_rewrite.py +714 -0
- tan/planner/topology.py +208 -0
- tan/planner/validate.py +365 -0
- tan/planner/whole_device_alias.py +67 -0
- tan/planner/zephyr_board.py +3510 -0
- tan/planner_cli.py +97 -0
- tan/planner_emit.py +617 -0
- tan/planner_root.py +119 -0
- tan/soc_ref.py +58 -0
- tan/templates/__init__.py +34 -0
- tan/templates/vendored/MANIFEST.md +1862 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
- tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
- tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
- tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
- tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
- tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
- tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
- tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
- tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
- tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
- tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
- tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
- tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
- tan/version.py +102 -0
- tan_cli-0.7.0.dist-info/METADATA +125 -0
- tan_cli-0.7.0.dist-info/RECORD +330 -0
- tan_cli-0.7.0.dist-info/WHEEL +5 -0
- tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
- tan_cli-0.7.0.dist-info/top_level.txt +1 -0
tan/planner/slugs.py
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
"""Kconfig / board-define slug derivation -- a shared leaf.
|
|
4
|
+
|
|
5
|
+
The slug + symbol helpers the per-slice config emitters (alp.conf, cmake-args)
|
|
6
|
+
share: the board-define slug, the on-module / helper-firmware Kconfig slug
|
|
7
|
+
derivation (+ the non-chip field set they skip), and the two Kconfig-mapping
|
|
8
|
+
tables (peripheral -> symbol bundle, chip -> subsystem dependency). A leaf that
|
|
9
|
+
reaches only for `paths`, so every per-slice emitter pulls them from one place
|
|
10
|
+
instead of duplicating. Extracted as a #285 leaf seam (the paths.py /
|
|
11
|
+
memregion.py move) ahead of the kconfig emitter.
|
|
12
|
+
|
|
13
|
+
`peripheral_kconfig` is RELOCATED from alp-sdk's `scripts/alp_registries.py` and
|
|
14
|
+
`_CHIP_SUBSYSTEMS` from `scripts/alp_project_emit/__init__.py` -- the last two
|
|
15
|
+
edges this leaf and `kconfig.py` made into the SDK's Python. The peripheral
|
|
16
|
+
table is still READ from the SDK's `metadata/registries/peripheral-kconfig.json`
|
|
17
|
+
(the fact stays there, ADR-0017); `_CHIP_SUBSYSTEMS` has no registry file to
|
|
18
|
+
read from today, so it moves with its one and only consumer -- see the note
|
|
19
|
+
above the table.
|
|
20
|
+
|
|
21
|
+
`peripheral_kconfig` used to be a module-level constant computed once at
|
|
22
|
+
import time from the SDK's own in-tree metadata/ -- a project's own
|
|
23
|
+
`--metadata-root` override never reached it (alp-sdk #1485). It now takes
|
|
24
|
+
*metadata_root* as a required argument; callers pass
|
|
25
|
+
`project.effective_metadata_root()` at the point of use.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import functools
|
|
31
|
+
import json
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
|
|
34
|
+
from .paths import REPO
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@functools.lru_cache(maxsize=None)
|
|
38
|
+
def peripheral_kconfig(metadata_root: Path) -> dict[str, tuple[str, ...]]:
|
|
39
|
+
"""Return board.yaml peripheral tokens -> Zephyr Kconfig symbol bundles.
|
|
40
|
+
|
|
41
|
+
*metadata_root* is REQUIRED -- every caller must pass the project's own
|
|
42
|
+
``project.effective_metadata_root()`` (or the SDK's own in-tree
|
|
43
|
+
``METADATA_ROOT`` for a repo self-check). A module-level default here
|
|
44
|
+
is exactly the shape that let this registry silently ignore a project's
|
|
45
|
+
`--metadata-root` override (#1485); the cache is keyed on
|
|
46
|
+
*metadata_root* so a second root in the same process doesn't reuse the
|
|
47
|
+
first root's table.
|
|
48
|
+
|
|
49
|
+
The validation below is alp-sdk#1545's, re-rooted at *metadata_root*.
|
|
50
|
+
Upstream wrote it for two import-time callers; in tan the one caller is
|
|
51
|
+
`kconfig._emit_subsystems`, and it now reads the table at RENDER time
|
|
52
|
+
rather than at import (that is what #1485's move bought). A malformed
|
|
53
|
+
on-disk registry therefore lands here mid-render, where a raw
|
|
54
|
+
`JSONDecodeError`/`KeyError`/`AttributeError` would name neither the
|
|
55
|
+
file nor the problem -- and where `tan generate` turns an exception into
|
|
56
|
+
an envelope, so the message IS the diagnosis a customer gets. Raise a
|
|
57
|
+
`ValueError` naming the real problem instead.
|
|
58
|
+
|
|
59
|
+
A consequence tan owns and alp-sdk does not: `planner_emit.unavailable()`
|
|
60
|
+
measures in-process availability by IMPORTING `tan.planner`, so while
|
|
61
|
+
this table was a module constant, a checkout missing the registry
|
|
62
|
+
disabled the in-process engine for EVERY target. It no longer does --
|
|
63
|
+
only the emits that actually need the table fail, and they fail with the
|
|
64
|
+
message above (`tests/parity/test_planner_emit_parity.py::
|
|
65
|
+
test_a_fallback_on_an_incomplete_checkout_says_so` moved to a different
|
|
66
|
+
trigger for exactly this reason, tan-cli#868).
|
|
67
|
+
"""
|
|
68
|
+
registry = Path(metadata_root) / "registries" / "peripheral-kconfig.json"
|
|
69
|
+
try:
|
|
70
|
+
rel = registry.relative_to(REPO).as_posix()
|
|
71
|
+
except ValueError:
|
|
72
|
+
# `metadata_root` legitimately points outside REPO (a scratch root
|
|
73
|
+
# under `--metadata-root`, or a test fixture) -- `relative_to()`
|
|
74
|
+
# raises its own confusing "is not in the subpath of" there, which
|
|
75
|
+
# would mask whatever the caller actually did wrong. Fall back to
|
|
76
|
+
# the raw path string.
|
|
77
|
+
rel = str(registry)
|
|
78
|
+
try:
|
|
79
|
+
text = registry.read_text(encoding="utf-8")
|
|
80
|
+
except OSError as e:
|
|
81
|
+
# A missing/unreadable file is not "invalid JSON" -- report the
|
|
82
|
+
# real failure instead of mislabeling every OSError that way.
|
|
83
|
+
raise ValueError(f"{rel}: cannot read registry ({e})") from e
|
|
84
|
+
try:
|
|
85
|
+
data = json.loads(text)
|
|
86
|
+
except json.JSONDecodeError as e:
|
|
87
|
+
raise ValueError(f"{rel}: invalid JSON ({e})") from e
|
|
88
|
+
if not isinstance(data, dict):
|
|
89
|
+
raise ValueError(
|
|
90
|
+
f"{rel}: expected a top-level object (got {type(data).__name__})")
|
|
91
|
+
if "peripherals" not in data:
|
|
92
|
+
raise ValueError(f"{rel}: missing top-level `peripherals` key")
|
|
93
|
+
peripherals = data["peripherals"]
|
|
94
|
+
if not isinstance(peripherals, dict):
|
|
95
|
+
raise ValueError(
|
|
96
|
+
f"{rel}: `peripherals` must be an object "
|
|
97
|
+
f"(got {type(peripherals).__name__})")
|
|
98
|
+
result: dict[str, tuple[str, ...]] = {}
|
|
99
|
+
for token, symbols in peripherals.items():
|
|
100
|
+
if not isinstance(symbols, list):
|
|
101
|
+
raise ValueError(
|
|
102
|
+
f"{rel}: peripherals[{token!r}] must be an array of "
|
|
103
|
+
f"Zephyr Kconfig symbols (got {type(symbols).__name__})")
|
|
104
|
+
result[token] = tuple(symbols)
|
|
105
|
+
return result
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _is_tbd(value: object) -> bool:
|
|
109
|
+
"""Case/whitespace-insensitive `TBD` placeholder match ("tbd", "Tbd",
|
|
110
|
+
" TBD " all match, alp-sdk #1048) -- the two chip-slug extractors below
|
|
111
|
+
both used a bare `== "TBD"` before, so an all-lowercase board.yaml
|
|
112
|
+
value silently fell through as a real chip slug instead of being
|
|
113
|
+
dropped as the placeholder it was hand-typed to mean."""
|
|
114
|
+
return isinstance(value, str) and value.strip().upper() == "TBD"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _board_define_slug(name: str) -> str:
|
|
118
|
+
"""'E1M-X-EVK' -> 'E1M_X_EVK': the ALP_BOARD_* compile-define suffix.
|
|
119
|
+
|
|
120
|
+
Mirrors gen_board_header._board_slug (lower + '-'->'_') then uppercases
|
|
121
|
+
for the C macro. Used by <alp/board.h>'s board-selection facade.
|
|
122
|
+
"""
|
|
123
|
+
return name.lower().replace("-", "_").upper()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _som_define_slug(sku: str) -> str:
|
|
127
|
+
"""'E1M-AEN801' -> 'E1M_AEN801': the ALP_SOM_* compile-define suffix.
|
|
128
|
+
|
|
129
|
+
Same transform as _board_define_slug; kept as its own name so the
|
|
130
|
+
SoM-selection define (per-SKU capability restrictions in
|
|
131
|
+
<alp/soc_caps.h>, gen_soc_caps.som_token) reads distinctly from the
|
|
132
|
+
board facade define at call sites.
|
|
133
|
+
"""
|
|
134
|
+
return _board_define_slug(sku)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# on_module fields that carry non-chip-slug values — skip them when
|
|
138
|
+
# walking the block for chip-driver enables. Numeric fields, silicon
|
|
139
|
+
# identifiers, and structured sub-blocks are excluded by name rather
|
|
140
|
+
# than by type so the logic stays explicit and easy to audit.
|
|
141
|
+
_ON_MODULE_NON_CHIP_FIELDS: frozenset[str] = frozenset({
|
|
142
|
+
"silicon", # e.g. "renesas:rzv2n:n44" — SoC identifier, not a driver
|
|
143
|
+
"ethernet_phy_count", # integer count, not a chip slug
|
|
144
|
+
"i2c_devices", # sub-block: handled by extracting chip: entries below
|
|
145
|
+
"dxm1", # sub-block: DX-M1 strap/reset pins, not chip slugs
|
|
146
|
+
"ospi_memories", # sub-block: storage parts (flash/HyperRAM); MPNs have no chips/ driver -- excluded like nor_flash/emmc below
|
|
147
|
+
# Storage-class fields encode the SoC controller / peripheral name
|
|
148
|
+
# that reaches the on-module storage (e.g. `nor_flash: xspi` -> the
|
|
149
|
+
# NOR flash is wired to the xSPI controller; `emmc: sd0` -> eMMC on
|
|
150
|
+
# SD/MMC controller 0). They are routing annotations, not chip
|
|
151
|
+
# slugs, and have no `chips/<part>/` driver behind them; emitting
|
|
152
|
+
# them as CHIP_<NAME> trips the Zephyr build with an undefined-symbol
|
|
153
|
+
# warning (no CONFIG_ALP_SDK_CHIP_XSPI / SD0 declaration exists).
|
|
154
|
+
"nor_flash",
|
|
155
|
+
"emmc",
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
# Any `<x>_driver_status` field (nor_flash_driver_status, emmc_driver_status,
|
|
159
|
+
# and whatever the next one is) is a maturity tier -- none/planned/partial/
|
|
160
|
+
# complete -- never a chip slug. A denylist entry per field re-opens this
|
|
161
|
+
# leak every time a new one is added (it did once already: the literal
|
|
162
|
+
# string "none" reached CONFIG_ALP_SDK_CHIP_NONE=y before this suffix check
|
|
163
|
+
# existed). Matched by suffix, not enumerated by name, so it can't miss the
|
|
164
|
+
# next one (alp-sdk #1169).
|
|
165
|
+
_DRIVER_STATUS_SUFFIX = "_driver_status"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _slugs_from_on_module(on_module: dict) -> list[str]:
|
|
169
|
+
"""Extract unique, non-TBD chip slugs from an ``on_module:`` block.
|
|
170
|
+
|
|
171
|
+
Walks every scalar field that is NOT in ``_ON_MODULE_NON_CHIP_FIELDS``,
|
|
172
|
+
then recurses into the ``i2c_devices`` sub-block (extracting the
|
|
173
|
+
``chip:`` field from each device entry). ``ospi_memories`` and the
|
|
174
|
+
``hyperram`` block are storage parts (NOR flash / HyperRAM) with no
|
|
175
|
+
``chips/<part>/`` driver, so their MPNs are NOT extracted as chip
|
|
176
|
+
slugs (emitting them as ``CONFIG_ALP_SDK_CHIP_<X>`` would trip
|
|
177
|
+
Zephyr's undefined-symbol guard). Duplicate slugs and values of
|
|
178
|
+
``TBD`` / ``null`` are silently dropped.
|
|
179
|
+
|
|
180
|
+
A chip can ALSO be named by a plain top-level scalar field (e.g.
|
|
181
|
+
``secure_element: optiga_trust_m``) naming which part the design
|
|
182
|
+
carries, distinct from the ``i2c_devices`` entry that records whether
|
|
183
|
+
THIS SKU actually has it fitted. Where both exist for the same chip,
|
|
184
|
+
``i2c_devices[].assembled`` is the more precise source and wins: a
|
|
185
|
+
device marked ``assembled: false`` (hard DNP, e.g. E1M-AEN801's
|
|
186
|
+
Optiga -- footprint shared with E1M-AEN803, DNP=1 on this batch) or
|
|
187
|
+
``assembled: optional`` (BOM-variant; the customer opts in via
|
|
188
|
+
`board.populated:`) must not auto-enable as a chip driver EVEN when
|
|
189
|
+
a scalar field also names the same chip (#1980 follow-up -- fixing
|
|
190
|
+
only the `i2c_devices` loop left the scalar-field path still leaking
|
|
191
|
+
`optiga_trust_m` into `_resolve_chip_states`' always-True SoM-intrinsic
|
|
192
|
+
set).
|
|
193
|
+
|
|
194
|
+
Returns a sorted, deduplicated list of slug strings.
|
|
195
|
+
"""
|
|
196
|
+
seen: set[str] = set()
|
|
197
|
+
not_auto_enable: set[str] = set()
|
|
198
|
+
|
|
199
|
+
def _add(val: object) -> None:
|
|
200
|
+
if not val or _is_tbd(val):
|
|
201
|
+
return
|
|
202
|
+
if not isinstance(val, str):
|
|
203
|
+
return
|
|
204
|
+
seen.add(val)
|
|
205
|
+
|
|
206
|
+
# 1. Scalar fields — every key whose value is a plain string and
|
|
207
|
+
# is not in the exclusion list (or a `*_driver_status` field).
|
|
208
|
+
for key, val in on_module.items():
|
|
209
|
+
if key in _ON_MODULE_NON_CHIP_FIELDS or key.endswith(_DRIVER_STATUS_SUFFIX):
|
|
210
|
+
continue
|
|
211
|
+
if isinstance(val, str):
|
|
212
|
+
_add(val)
|
|
213
|
+
|
|
214
|
+
# 2. i2c_devices sub-block — each bus entry contains a `devices:`
|
|
215
|
+
# list; extract the `chip:` field from each device.
|
|
216
|
+
# Devices marked `assembled: false` (hard DNP) or `optional`
|
|
217
|
+
# (BOM variant) must NOT be auto-enabled as chip drivers — the
|
|
218
|
+
# customer explicitly enables an optional one via
|
|
219
|
+
# `board.populated:`, and a hard-DNP one never auto-enables at all.
|
|
220
|
+
i2c_buses = on_module.get("i2c_devices")
|
|
221
|
+
if isinstance(i2c_buses, dict):
|
|
222
|
+
for _bus, bus_entry in i2c_buses.items():
|
|
223
|
+
if not isinstance(bus_entry, dict):
|
|
224
|
+
continue
|
|
225
|
+
for dev in bus_entry.get("devices") or []:
|
|
226
|
+
if not isinstance(dev, dict):
|
|
227
|
+
continue
|
|
228
|
+
chip = dev.get("chip")
|
|
229
|
+
assembled = dev.get("assembled", True)
|
|
230
|
+
if assembled is False or assembled == "optional":
|
|
231
|
+
if isinstance(chip, str):
|
|
232
|
+
not_auto_enable.add(chip)
|
|
233
|
+
continue
|
|
234
|
+
_add(chip)
|
|
235
|
+
|
|
236
|
+
seen -= not_auto_enable
|
|
237
|
+
return sorted(seen)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _slugs_from_helper_firmware(helper_firmware: list) -> list[str]:
|
|
241
|
+
"""Extract unique, non-TBD chip slugs from a ``helper_firmware:`` list.
|
|
242
|
+
|
|
243
|
+
Each entry is a dict; we pull the ``chip:`` field. TBD values and
|
|
244
|
+
missing fields are skipped. Returns a sorted, deduplicated list.
|
|
245
|
+
"""
|
|
246
|
+
seen: set[str] = set()
|
|
247
|
+
for entry in helper_firmware or []:
|
|
248
|
+
if not isinstance(entry, dict):
|
|
249
|
+
continue
|
|
250
|
+
chip = entry.get("chip")
|
|
251
|
+
if chip and not _is_tbd(chip):
|
|
252
|
+
seen.add(chip)
|
|
253
|
+
return sorted(seen)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
# Slugs that map to BLOCK_ Kconfig symbols rather than CHIP_.
|
|
257
|
+
# These live under blocks/ + <alp/blocks/*.h> because they are
|
|
258
|
+
# SDK-level *block* utilities (`alp_button_led_*`, `alp_pdm_mic_*`)
|
|
259
|
+
# rather than third-party-IC chip drivers; see blocks/README.md.
|
|
260
|
+
#
|
|
261
|
+
# Single source of truth -- kconfig.py's emitter, check_example_portability.py
|
|
262
|
+
# and alp_cli/validator.py's ALP-B008 chip-token check all consult this same
|
|
263
|
+
# set rather than each carrying its own copy (a prior state that had drifted
|
|
264
|
+
# into three independent copies). Only the emitter's consumer relocated into
|
|
265
|
+
# `tan`; the two SDK gates keep reading alp-sdk's own copy.
|
|
266
|
+
_BLOCK_SLUGS = frozenset({"button_led", "pdm_mic"})
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# Chip name -> Zephyr subsystem CONFIG_* keys the chip driver
|
|
270
|
+
# depends on. Mirrors the `depends on ...` line in each
|
|
271
|
+
# `config ALP_SDK_CHIP_<NAME>` entry in zephyr/Kconfig: enabling
|
|
272
|
+
# a chip driver doesn't auto-select its subsystem, so the loader
|
|
273
|
+
# emits the matching `CONFIG_<SUBSYS>=y` here.
|
|
274
|
+
#
|
|
275
|
+
# RELOCATED from alp-sdk's `scripts/alp_project_emit/__init__.py`, whose only
|
|
276
|
+
# consumer was ever `_emit_chips` in this package's `kconfig.py`.
|
|
277
|
+
#
|
|
278
|
+
# DEBT, stated plainly: this IS a hardware fact and it now lives in `tan`
|
|
279
|
+
# (ADR-0017 / I-26 says facts stay in `metadata/**`). It moved because no
|
|
280
|
+
# metadata file carries it -- a chip manifest's `bus: i2c` cannot distinguish
|
|
281
|
+
# `lsm6dso` -> `("I2C",)` from `tas2563` -> `("I2C", "GPIO")`, so deriving it
|
|
282
|
+
# from existing metadata would change the emitted Kconfig. Retires when a
|
|
283
|
+
# registry (`metadata/registries/chip-subsystems.json`, alongside
|
|
284
|
+
# peripheral-kconfig.json) declares it and this table becomes a loader like
|
|
285
|
+
# `peripheral_kconfig` above.
|
|
286
|
+
_CHIP_SUBSYSTEMS: dict[str, tuple[str, ...]] = {
|
|
287
|
+
# GPIO-only
|
|
288
|
+
"button_led": ("GPIO",),
|
|
289
|
+
"cam_mux_pi3wvr626": ("GPIO",),
|
|
290
|
+
# SPI + GPIO
|
|
291
|
+
"ssd1331": ("SPI", "GPIO"),
|
|
292
|
+
"cc3501e": ("SPI", "GPIO"),
|
|
293
|
+
# I2C + GPIO
|
|
294
|
+
"tas2563": ("I2C", "GPIO"),
|
|
295
|
+
# I2C-only
|
|
296
|
+
"lsm6dso": ("I2C",),
|
|
297
|
+
"ssd1306": ("I2C",),
|
|
298
|
+
"bme280": ("I2C",),
|
|
299
|
+
"lis2dw12": ("I2C",),
|
|
300
|
+
"ov5640": ("I2C",),
|
|
301
|
+
"icm42670": ("I2C",),
|
|
302
|
+
"bmi323": ("I2C",),
|
|
303
|
+
"bmp581": ("I2C",),
|
|
304
|
+
"tmp112": ("I2C",),
|
|
305
|
+
"rv3028c7": ("I2C",),
|
|
306
|
+
"optiga_trust_m": ("I2C",),
|
|
307
|
+
"eeprom_24c128": ("I2C",),
|
|
308
|
+
"tcal9538": ("I2C",),
|
|
309
|
+
"ina228": ("I2C",),
|
|
310
|
+
"ina236": ("I2C",),
|
|
311
|
+
# pdm_mic helper has no subsystem dep declared in Kconfig
|
|
312
|
+
# (uses <alp/i2s.h> when enabled at v0.2+).
|
|
313
|
+
# v0.5 §D.AI batch -- 18 vision / display / accelerator chips.
|
|
314
|
+
"ov2640": ("I2C",),
|
|
315
|
+
"ov5645": ("I2C",),
|
|
316
|
+
"ov7670": ("I2C",),
|
|
317
|
+
"ov9281": ("I2C",),
|
|
318
|
+
"ar0234": ("I2C",),
|
|
319
|
+
"imx219": ("I2C",),
|
|
320
|
+
"imx477": ("I2C",),
|
|
321
|
+
"gc2145": ("I2C",),
|
|
322
|
+
"ti_ds90ub953_954": ("I2C",),
|
|
323
|
+
"maxim_max9295_9296": ("I2C",),
|
|
324
|
+
"st7789": ("SPI", "GPIO"),
|
|
325
|
+
"ili9341": ("SPI", "GPIO"),
|
|
326
|
+
"ili9488": ("SPI", "GPIO"),
|
|
327
|
+
"ra8875": ("SPI",),
|
|
328
|
+
"sh1106": ("I2C",),
|
|
329
|
+
"il3820": ("SPI", "GPIO"),
|
|
330
|
+
"gdew0154t8": ("SPI", "GPIO"),
|
|
331
|
+
"hailo_8l": ("GPIO",),
|
|
332
|
+
# v0.5 §D.industrial batch -- 18 industrial sensing / control chips.
|
|
333
|
+
"bmp390": ("I2C",),
|
|
334
|
+
"ms5611": ("I2C",),
|
|
335
|
+
"lps22hb": ("I2C",),
|
|
336
|
+
"vl53l1x": ("I2C",),
|
|
337
|
+
"vl53l5cx": ("I2C",),
|
|
338
|
+
"a02yyuw": ("SERIAL",),
|
|
339
|
+
"drv8833": ("PWM",),
|
|
340
|
+
"drv8825": ("PWM", "GPIO"),
|
|
341
|
+
"tmc2209": ("SERIAL",),
|
|
342
|
+
"a4988": ("PWM", "GPIO"),
|
|
343
|
+
"as5048a_b": ("I2C",),
|
|
344
|
+
"mt6701": ("I2C",),
|
|
345
|
+
"hx711": ("GPIO",),
|
|
346
|
+
"max31855": ("SPI",),
|
|
347
|
+
"max31865": ("SPI",),
|
|
348
|
+
"tsl2591": ("I2C",),
|
|
349
|
+
"qmc5883l": ("I2C",),
|
|
350
|
+
"veml7700": ("I2C",),
|
|
351
|
+
# v0.5 §D.iot batch -- 9 IoT / connectivity chips.
|
|
352
|
+
"quectel_bg95": ("SERIAL",),
|
|
353
|
+
"quectel_bg77": ("SERIAL",),
|
|
354
|
+
"ublox_sara_r5": ("SERIAL",),
|
|
355
|
+
"semtech_sx1262": ("SPI", "GPIO"),
|
|
356
|
+
"semtech_sx1276": ("SPI", "GPIO"),
|
|
357
|
+
"ublox_neo_m9n": ("SERIAL",),
|
|
358
|
+
"ublox_max_m10s": ("SERIAL",),
|
|
359
|
+
"atgm336h": ("SERIAL",),
|
|
360
|
+
"atecc608b": ("I2C",),
|
|
361
|
+
# v0.5 §D.audio batch -- 6 audio chips.
|
|
362
|
+
"ics_43434": (), # no Zephyr subsystem dep; sample flow via <alp/i2s.h>
|
|
363
|
+
"inmp441": (),
|
|
364
|
+
"wm8960": ("I2C",),
|
|
365
|
+
"tlv320aic3204": ("I2C",),
|
|
366
|
+
"max98357a": ("GPIO",),
|
|
367
|
+
"es8388": ("I2C",),
|
|
368
|
+
# SoM-intrinsic batch (issue #1487) -- act8760/tps628640/
|
|
369
|
+
# da9292/clk_5l35023b are I2C-only PMIC/clock parts; pi3dbs12212/
|
|
370
|
+
# murata_lbee5hy2fy/deepx_dxm1/gd32_swd are GPIO-only. All nine were
|
|
371
|
+
# missing from this table despite each having a `config
|
|
372
|
+
# ALP_SDK_CHIP_<NAME>` / `depends on` entry in
|
|
373
|
+
# zephyr/kconfigs/chips.kconfig, so the loader turned the chip on
|
|
374
|
+
# without turning its dependency on, and Kconfig silently dropped
|
|
375
|
+
# the chip assignment as unmet (issue #1487).
|
|
376
|
+
"act8760": ("I2C",),
|
|
377
|
+
"tps628640": ("I2C",),
|
|
378
|
+
"pi3dbs12212": ("GPIO",),
|
|
379
|
+
"da9292": ("I2C",),
|
|
380
|
+
"clk_5l35023b": ("I2C",),
|
|
381
|
+
"murata_lbee5hy2fy": ("GPIO",),
|
|
382
|
+
"deepx_dxm1": ("GPIO",),
|
|
383
|
+
"gd32_swd": ("GPIO",),
|
|
384
|
+
# gd32g553 declares `depends on (SPI || I2C)` -- an OR, not an AND:
|
|
385
|
+
# the driver's bridge protocol is genuinely hybrid (both transports
|
|
386
|
+
# compiled in, either usable at runtime; see chips/gd32g553/
|
|
387
|
+
# gd32g553.c and docs/gd32-bridge-protocol.md), so there is no
|
|
388
|
+
# single right subsystem to force on. Deliberately over-inclusive
|
|
389
|
+
# here rather than under (issue #1487's own bug class): turning on
|
|
390
|
+
# both is always sufficient for the `||`, whereas picking only one
|
|
391
|
+
# would silently drop the other transport the same way the missing
|
|
392
|
+
# entries above did.
|
|
393
|
+
"gd32g553": ("SPI", "I2C"),
|
|
394
|
+
}
|