This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nuttx-ntfc.git
commit 1fe209f7eef583e29412036c1369419c9053866d Author: raiden00pl <[email protected]> AuthorDate: Tue Aug 4 17:22:26 2026 +0200 coreconfig.py: add per-core kernel-mode options Options needed to describe kernel-mode targets, where applications are standalone ELF binaries installed on the target filesystem and resolved from PATH rather than linked into the kernel image: - is_kernel_build: core .config selects CONFIG_BUILD_KERNEL - exec_cwd: working directory for spawned sim/qemu processes; a semihosting hostfs mount (qemu arm/riscv) resolves relative to it - boot_timeout: seconds to wait for the first shell prompt (default 5) - app_bindir: application binaries, bin/ next to the ELF unless set Signed-off-by: raiden00pl <[email protected]> Assisted-by: Claude Code --- Documentation/config-yaml.rst | 11 ++++++++ Documentation/config.yaml | 7 +++++ src/ntfc/coreconfig.py | 32 ++++++++++++++++++++++ tests/test_coreconfig.py | 62 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) diff --git a/Documentation/config-yaml.rst b/Documentation/config-yaml.rst index 5b2ffb8..294f1ba 100644 --- a/Documentation/config-yaml.rst +++ b/Documentation/config-yaml.rst @@ -419,6 +419,17 @@ These fields are parsed by :class:`ntfc.coreconfig.CoreConfig`. etc.) * - ``exec_args`` - QEMU arguments or serial settings + * - ``exec_cwd`` + - (Optional) Working directory for the spawned sim/qemu process. + Kernel-mode hostfs mounts resolve relative to this directory. + Defaults to the core build directory for kernel-mode builds + * - ``boot_timeout`` + - (Optional) Seconds to wait for the first shell prompt after device + start. Defaults to ``5`` + * - ``app_bindir`` + - (Optional) Directory with kernel-mode application binaries. Defaults + to the ``bin/`` directory next to the NuttX ELF for kernel-mode + builds (``CONFIG_BUILD_KERNEL=y``) * - ``defconfig`` - Path to NuttX defconfig (auto-build) * - ``elf_path`` diff --git a/Documentation/config.yaml b/Documentation/config.yaml index bbeb957..1b38027 100644 --- a/Documentation/config.yaml +++ b/Documentation/config.yaml @@ -70,6 +70,13 @@ product: # many products can be supported in tests (pro exec_args: '' # Args for emulator execution for QEMU tragets. # Serial port configuration for serial targets, eg '9600,n,8,1' # Empty for simulator. + exec_cwd: '' # (optional) working directory for the spawned sim/qemu process. + # Kernel-mode hostfs mounts resolve relative to this directory. + # Defaults to the core build directory for kernel-mode builds. + boot_timeout: 5 # (optional) seconds to wait for the first shell prompt. Defaults to 5 + app_bindir: '' # (optional) directory with kernel-mode application binaries. + # Defaults to the bin/ directory next to the NuttX ELF + # for kernel-mode builds. # NTFC can use pre-build image or build it from defconfig # the behavior will depend on the parameters specified in config. diff --git a/src/ntfc/coreconfig.py b/src/ntfc/coreconfig.py index 2283c55..1d54090 100644 --- a/src/ntfc/coreconfig.py +++ b/src/ntfc/coreconfig.py @@ -20,6 +20,7 @@ """Product core configuration handler.""" +import os from typing import Any, Dict, Optional, Union from ntfc.lib.elf.elf_parser import ElfParser @@ -144,6 +145,37 @@ class CoreConfig: """ return bool(self._config.get("flash_only", False)) + @property + def is_kernel_build(self) -> bool: + """Return True when the core .config has CONFIG_BUILD_KERNEL=y.""" + return self.kv_check("CONFIG_BUILD_KERNEL") is True + + @property + def exec_cwd(self) -> Optional[str]: + """Return working directory for spawned sim/qemu processes. + + Kernel-mode hostfs mounts resolve relative to this directory. + """ + return self._config.get("exec_cwd", None) + + @property + def boot_timeout(self) -> int: + """Return seconds to wait for the first shell prompt after start.""" + return int(self._config.get("boot_timeout", 5)) + + @property + def app_bindir(self) -> Optional[str]: + """Return directory with kernel-mode application binaries. + + Defaults to the bin/ directory next to the NuttX ELF. + """ + bindir = self._config.get("app_bindir", None) + if bindir: + return str(bindir) + if self.is_kernel_build and self.elf_path: + return os.path.join(os.path.dirname(self.elf_path), "bin") + return None + def kv_check(self, cfg: str) -> Any: """Check Kconfig option and return its value. diff --git a/tests/test_coreconfig.py b/tests/test_coreconfig.py index 2ee0c93..1fa1c38 100644 --- a/tests/test_coreconfig.py +++ b/tests/test_coreconfig.py @@ -97,6 +97,68 @@ def test_core_config_flash_only_property(): assert CoreConfig({"name": "test"}).flash_only is False +def test_core_config_is_kernel_build(tmp_path): + cfg_file = tmp_path / "kv_config" + cfg_file.write_text("CONFIG_BUILD_KERNEL=y\n") + assert ( + CoreConfig({"name": "t", "conf_path": str(cfg_file)}).is_kernel_build + is True + ) + + cfg_file.write_text("CONFIG_BUILD_FLAT=y\n") + assert ( + CoreConfig({"name": "t", "conf_path": str(cfg_file)}).is_kernel_build + is False + ) + + # no .config at all + assert CoreConfig({"name": "t"}).is_kernel_build is False + + +def test_core_config_exec_cwd(): + assert ( + CoreConfig({"name": "t", "exec_cwd": "/some/dir"}).exec_cwd + == "/some/dir" + ) + assert CoreConfig({"name": "t"}).exec_cwd is None + + +def test_core_config_boot_timeout(): + assert CoreConfig({"name": "t", "boot_timeout": 15}).boot_timeout == 15 + assert CoreConfig({"name": "t"}).boot_timeout == 5 + + +def test_core_config_app_bindir(tmp_path): + kernel_cfg = tmp_path / "kv_config" + kernel_cfg.write_text("CONFIG_BUILD_KERNEL=y\n") + + # explicit YAML value always wins + conf = {"name": "t", "app_bindir": "/custom/bin"} + assert CoreConfig(conf).app_bindir == "/custom/bin" + + # kernel build: derived from elf_path sibling bin/ + conf = { + "name": "t", + "conf_path": str(kernel_cfg), + "elf_path": "./tests/resources/nuttx/sim/nuttx", + } + assert CoreConfig(conf).app_bindir == "./tests/resources/nuttx/sim/bin" + + # kernel build without elf_path: nothing to derive from + assert ( + CoreConfig({"name": "t", "conf_path": str(kernel_cfg)}).app_bindir + is None + ) + + # flat build: never derived + conf = { + "name": "t", + "conf_path": "./tests/resources/nuttx/sim/kv_config", + "elf_path": "./tests/resources/nuttx/sim/nuttx", + } + assert CoreConfig(conf).app_bindir is None + + def test_core_config_prompt(): # Test with explicit prompt in YAML config conf = {
