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 = {

Reply via email to