diff --git a/arch/arm/src/common/ameba/tools/ameba_build_np.sh b/arch/arm/src/common/ameba/tools/ameba_build_np.sh index b62f63a8a17b8..fbfd6f01434dd 100755 --- a/arch/arm/src/common/ameba/tools/ameba_build_np.sh +++ b/arch/arm/src/common/ameba/tools/ameba_build_np.sh @@ -101,15 +101,23 @@ collect() { cp "$src" "$OUT/$name" } -"$VENV_PY" "$SDK/ameba.py" soc "$SOC" -# --set needs an existing .config; -r generates the default one first (so this -# works on a clean tree). Result is deterministic: default config + SHELL=n. -"$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" -r -"$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" --set SHELL=n +# Materialize the SDK config = default + the board overlay ($AMEBA_SDK_CONF, +# e.g. CONFIG_SHELL=n). Guarded so it only regenerates when the SDK revision +# or the overlay changed; otherwise reused as-is, so a steady-state build does +# NOT rewrite .config (which would make the SDK reconfigure and rebuild most of +# the NP/boot image). See ameba_sdk_config.sh. +"$(dirname "$0")/ameba_sdk_config.sh" "$SDK" "$SOC" "${AMEBA_SDK_CONF:-}" + +# Silence -Wint-conversion for the vendored SDK build: the SDK passes NULL to +# irq_register()'s u32 "Data" (interrupt context) argument in many places -- an +# intentional NULL-as-context idiom. Injected via CMAKE_C_FLAGS so no SDK +# source or flag file is edited and every current + future SDK source is +# covered. Kept constant so it does not churn the cmake cache between builds. +SDK_BUILD_DEFS="-D CMAKE_C_FLAGS=-Wno-int-conversion" # Build the NP/device image2 (with AMEBA_AP_ASM-driven noused, so it stays # aligned with exactly the host WiFi APIs NuttX references). -"$VENV_PY" "$SDK/ameba.py" build "$SOC" --core "$NP_TARGET" +"$VENV_PY" "$SDK/ameba.py" build "$SOC" --core "$NP_TARGET" $SDK_BUILD_DEFS # Collect the NP image2 NOW, before the boot build: an isolated `-g boot` (which # succeeds on amebadplus) reconfigures and cleans the OTHER core's image dir, @@ -125,10 +133,10 @@ collect "${NP_TARGET}_image2_all.bin" "project_${NP_TARGET}/image/${NP_TARGET}_i # noused set (the SDK's own AP image is built too and simply discarded). Both # the NP and boot are therefore freshly rebuilt every NuttX build; nothing is # reused stale across the two cores. -if ! "$VENV_PY" "$SDK/ameba.py" build "$SOC" -g boot; then +if ! "$VENV_PY" "$SDK/ameba.py" build "$SOC" -g boot $SDK_BUILD_DEFS; then echo "ameba_build_np.sh: '-g boot' not buildable in isolation on $SOC;" \ "doing a full SoC build to produce boot (AMEBA_AP_ASM kept)" >&2 - "$VENV_PY" "$SDK/ameba.py" build "$SOC" + "$VENV_PY" "$SDK/ameba.py" build "$SOC" $SDK_BUILD_DEFS fi collect boot.bin project_km4/image/boot.bin diff --git a/arch/arm/src/common/ameba/tools/ameba_gen_autoconf.sh b/arch/arm/src/common/ameba/tools/ameba_gen_autoconf.sh index e13bd3961a189..4990cb9416192 100755 --- a/arch/arm/src/common/ameba/tools/ameba_gen_autoconf.sh +++ b/arch/arm/src/common/ameba/tools/ameba_gen_autoconf.sh @@ -60,10 +60,13 @@ unset MAKEFLAGS MAKELEVEL MFLAGS MAKEOVERRIDES 2>/dev/null || true # ameba.py resolves build_/ relative to the CWD, so run from the SDK root. cd "$SDK" || { echo "ameba_gen_autoconf.sh: cannot cd to $SDK" >&2; exit 1; } -# Select the SoC and write the default config + regenerate the per-core headers. -# -r is deterministic (default config), so a clean clone reproduces it exactly. -"$VENV_PY" "$SDK/ameba.py" soc "$SOC" >/dev/null -"$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" -r >/dev/null +# Materialize the SDK config (default + the board overlay $AMEBA_SDK_CONF) and +# regenerate the per-core headers. Guarded (ameba_sdk_config.sh) so it only +# runs when the SDK revision or the overlay changed; a steady-state build reuses +# the existing config and headers. --apply-file re-resolves the config (which +# regenerates project_/platform_autoconf.h), so $GEN below is fresh. +# Deterministic, so a clean clone reproduces it exactly. +"$(dirname "$0")/ameba_sdk_config.sh" "$SDK" "$SOC" "${AMEBA_SDK_CONF:-}" GEN="$SDK/build_$SOC/menuconfig/project_$AP_PROJECT/platform_autoconf.h" if [ ! -f "$GEN" ]; then diff --git a/arch/arm/src/common/ameba/tools/ameba_sdk_config.sh b/arch/arm/src/common/ameba/tools/ameba_sdk_config.sh new file mode 100755 index 0000000000000..5a8702ad3498f --- /dev/null +++ b/arch/arm/src/common/ameba/tools/ameba_sdk_config.sh @@ -0,0 +1,103 @@ +#!/bin/sh +############################################################################ +# arch/arm/src/common/ameba/tools/ameba_sdk_config.sh +# +# Materialize the SDK menuconfig .config = SDK default + the board's optional +# prj.conf-style overlay fragment, but ONLY when the inputs actually change. +# +# Why the guard: the SDK's `menuconfig -r` / `--apply-file` rewrites .config +# every time it runs, which makes the SDK build reconfigure and rebuild most of +# the NP/boot image (~hundreds of objects, ~10s+) on EVERY NuttX build -- even +# when nothing changed. The resulting config is deterministic (SDK default + +# a fixed overlay), so it only needs regenerating when the SDK revision or the +# overlay fragment changes. We stamp those inputs; a steady-state build finds +# the stamp unchanged and skips regeneration entirely, so only the AP-driven +# "noused" file is rebuilt. This is also what makes `make ameba_menuconfig` +# edits take effect: editing the fragment changes the stamp -> next build +# regenerates the SDK config and rebuilds. +# +# usage: ameba_sdk_config.sh [] +# sdk_dir - ameba-rtos checkout +# soc - ameba.py SoC id (RTL8721Dx / RTL8720F / ...) +# overlay_frag - optional prj.conf-style fragment (CONFIG_*=... lines, +# diff vs SDK default) applied on top of the default config. +# If absent, the plain SDK default is used. +# +# Idempotent and safe to call from both the PREBUILD (autoconf generation) and +# the POSTBUILD (NP build): the first call materializes the config + writes the +# stamp, the second sees the stamp match and returns immediately. +############################################################################ + +set -e + +SDK="$1" +SOC="$2" +FRAG="$3" + +if [ -z "$SDK" ] || [ -z "$SOC" ]; then + echo "usage: ameba_sdk_config.sh []" >&2 + exit 1 +fi + +# Resolve the SDK python (real .venv if present, else system python3), matching +# the other ameba tool scripts. +PYDIR=$(cat "$SDK/.amebapy/bindir" 2>/dev/null) +VENV_PY="$PYDIR/python" +[ -x "$VENV_PY" ] || VENV_PY=python3 +PATH="${PYDIR:+$PYDIR:}$PATH" +export PATH + +# Isolate from NuttX's Kconfig environment (which otherwise leaks into the SDK's +# own kconfiglib and breaks its Kconfig path resolution), and drop the make +# jobserver fds. Same prologue as ameba_build_np.sh / ameba_gen_autoconf.sh. +unset srctree BINDIR APPSDIR APPSBINDIR EXTERNALDIR EXTERNDIR KCONFIG_CONFIG \ + ARCHDIR DRIVERDIR BOARDDIR 2>/dev/null || true +unset MAKEFLAGS MAKELEVEL MFLAGS MAKEOVERRIDES 2>/dev/null || true + +MC="$SDK/build_$SOC/menuconfig/.config" +STAMP="$SDK/build_$SOC/.nuttx_sdkcfg_stamp" + +# Two overlays are layered on the SDK default, in order (later wins): +# 1. user overlay = $FRAG (ameba_sdk.conf) -- editable via TUI +# 2. forced overlay = /ameba_sdk_force.conf -- always wins, not +# user-editable (e.g. CONFIG_SHELL=n). Applied LAST so it overrides both +# the SDK default and the user overlay. +FORCE="" +if [ -n "$FRAG" ]; then + FORCE="$(dirname "$FRAG")/ameba_sdk_force.conf" +fi + +# Collect the overlays that actually exist, in apply order (user then forced). +OVERLAYS="" +[ -n "$FRAG" ] && [ -f "$FRAG" ] && OVERLAYS="$OVERLAYS $FRAG" +[ -n "$FORCE" ] && [ -f "$FORCE" ] && OVERLAYS="$OVERLAYS $FORCE" + +# Stamp = pinned SDK revision + the content of both overlays. A change in any +# (SDK bump, or editing either overlay) invalidates it and forces a regen. +sdkrev=$(git -C "$SDK" rev-parse HEAD 2>/dev/null || echo nogit) +if [ -n "$OVERLAYS" ]; then + ovhash=$(cat $OVERLAYS 2>/dev/null | sha1sum | cut -d' ' -f1) +else + ovhash=nooverlay +fi +want="$sdkrev:$ovhash" + +if [ -f "$MC" ] && [ "$(cat "$STAMP" 2>/dev/null)" = "$want" ]; then + exit 0 +fi + +# ameba.py resolves build_/ relative to CWD, so run from the SDK root. +cd "$SDK" || { echo "ameba_sdk_config.sh: cannot cd to $SDK" >&2; exit 1; } + +"$VENV_PY" "$SDK/ameba.py" soc "$SOC" >/dev/null +if [ -n "$OVERLAYS" ]; then + # --apply-file resets to the SDK default and layers the overlays on top in + # order (forced last), re-resolving dependencies (kconfiglib), so an overlay + # only needs to carry intent (e.g. CONFIG_SHELL=n); dependents cascade. + "$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" --apply-file $OVERLAYS +else + "$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" -r +fi + +echo "$want" > "$STAMP" +echo "GEN: SDK .config <- default${OVERLAYS:+ +$(for f in $OVERLAYS; do printf ' %s' "$(basename "$f")"; done)} ($SOC)" diff --git a/arch/arm/src/rtl8720f/ameba_board.mk b/arch/arm/src/rtl8720f/ameba_board.mk index bb01a0d4d91d8..dffb80e3cd989 100644 --- a/arch/arm/src/rtl8720f/ameba_board.mk +++ b/arch/arm/src/rtl8720f/ameba_board.mk @@ -117,7 +117,14 @@ AMEBA_FWLIB_SRCS += $(TOPDIR)/arch/arm/src/rtl8720f/ameba_app_start.c \ ifeq ($(CONFIG_RTL8720F_FLASH_FS),y) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_flash_ram.c endif -AMEBA_FWLIB_INC = -I$(TOPDIR)/arch/arm/src/common/ameba/sdk_shim \ +# -Wno-int-conversion: the vendored SDK passes NULL to irq_register()'s u32 +# "Data" (interrupt context) argument in many places -- an intentional +# NULL-as-context idiom. Silence -Wint-conversion for the SDK fwlib sources +# here rather than editing every call site (which also re-breaks whenever a new +# SDK file/site is added). Scoped to this fwlib compile, so it never relaxes +# NuttX's own warning set. +AMEBA_FWLIB_INC = -Wno-int-conversion \ + -I$(TOPDIR)/arch/arm/src/common/ameba/sdk_shim \ -I$(AMEBA_SOC)/fwlib/include \ -I$(AMEBA_SOC)/fwlib/include/rom \ -I$(AMEBA_SOC)/swlib \ @@ -228,8 +235,16 @@ AMEBA_BUILD_NP_SH = $(AMEBA_COMMON_DIR)$(DELIM)tools$(DELIM)ameba_build_np.sh # AMEBA_AP_PROJECT is the AP-core SDK project subdir (km4tz on RTL8720F). AMEBA_AP_PROJECT = km4tz AMEBA_GEN_AUTOCONF = $(AMEBA_COMMON_DIR)$(DELIM)tools$(DELIM)ameba_gen_autoconf.sh + +# Board overlay applied on top of the SDK default config (prj.conf-style, e.g. +# CONFIG_SHELL=n). Fed to the SDK-config materializer (ameba_sdk_config.sh) via +# the AMEBA_SDK_CONF env var, by both the PREBUILD autoconf gen and the NP build. +# Edit it with `make ameba_menuconfig` (native SDK menuconfig UI). +AMEBA_SDK_CONF = $(BOARD_DIR)$(DELIM)ameba_sdk.conf + AMEBA_NP_PREBUILD = true -AMEBA_NP_POSTBUILD = $(AMEBA_BUILD_NP_SH) $(AMEBA_SDK) $(AMEBA_PY_SOC) \ +AMEBA_NP_POSTBUILD = AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ + $(AMEBA_BUILD_NP_SH) $(AMEBA_SDK) $(AMEBA_PY_SOC) \ $(AMEBA_PREBUILT) $(AMEBA_PKGDIR)$(DELIM)target_img2.asm \ km4ns $(AMEBA_AP_PROJECT) @@ -247,7 +262,8 @@ define PREBUILD { echo "ERROR: AMEBA_SDK is not set. Export it to your ameba-rtos checkout."; exit 1; } $(Q) $(AMEBA_FETCH_TOOLCHAIN) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) $(Q) $(AMEBA_SETUP_ENV) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) - $(Q) $(AMEBA_GEN_AUTOCONF) $(AMEBA_SDK) $(AMEBA_PY_SOC) $(AMEBA_AP_PROJECT) \ + $(Q) AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ + $(AMEBA_GEN_AUTOCONF) $(AMEBA_SDK) $(AMEBA_PY_SOC) $(AMEBA_AP_PROJECT) \ $(AMEBA_AUTOCONF) $(Q) $(AMEBA_NP_PREBUILD) $(Q) echo "GEN: libameba_fwlib.a (fwlib from SDK source)" diff --git a/arch/arm/src/rtl8721dx/ameba_board.mk b/arch/arm/src/rtl8721dx/ameba_board.mk index fe08c1b425390..64966fd116a6f 100644 --- a/arch/arm/src/rtl8721dx/ameba_board.mk +++ b/arch/arm/src/rtl8721dx/ameba_board.mk @@ -116,7 +116,13 @@ AMEBA_FWLIB_SRCS += $(TOPDIR)/arch/arm/src/rtl8721dx/ameba_app_start.c \ ifeq ($(CONFIG_RTL8721DX_FLASH_FS),y) AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_flash_ram.c endif -AMEBA_FWLIB_INC = -mcmse \ +# -Wno-int-conversion: the vendored SDK passes NULL to irq_register()'s u32 +# "Data" (interrupt context) argument in many places -- an intentional +# NULL-as-context idiom. Silence -Wint-conversion for the SDK fwlib sources +# here rather than editing every call site (which also re-breaks whenever a new +# SDK file/site is added). Scoped to this fwlib compile, so it never relaxes +# NuttX's own warning set. +AMEBA_FWLIB_INC = -Wno-int-conversion -mcmse \ -I$(TOPDIR)/arch/arm/src/common/ameba/sdk_shim \ -I$(AMEBA_SOC)/fwlib/include \ -I$(AMEBA_SOC)/fwlib/include/rom \ @@ -229,8 +235,16 @@ AMEBA_BUILD_NP_SH = $(AMEBA_COMMON_DIR)$(DELIM)tools$(DELIM)ameba_build_np.sh # AMEBA_AP_PROJECT is the AP-core SDK project subdir (km4 on amebadplus). AMEBA_AP_PROJECT = km4 AMEBA_GEN_AUTOCONF = $(AMEBA_COMMON_DIR)$(DELIM)tools$(DELIM)ameba_gen_autoconf.sh + +# Board overlay applied on top of the SDK default config (prj.conf-style, e.g. +# CONFIG_SHELL=n). Fed to the SDK-config materializer (ameba_sdk_config.sh) via +# the AMEBA_SDK_CONF env var, by both the PREBUILD autoconf gen and the NP build. +# Edit it with `make ameba_menuconfig` (native SDK menuconfig UI). +AMEBA_SDK_CONF = $(BOARD_DIR)$(DELIM)ameba_sdk.conf + AMEBA_NP_PREBUILD = true -AMEBA_NP_POSTBUILD = $(AMEBA_BUILD_NP_SH) $(AMEBA_SDK) $(AMEBA_PY_SOC) \ +AMEBA_NP_POSTBUILD = AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ + $(AMEBA_BUILD_NP_SH) $(AMEBA_SDK) $(AMEBA_PY_SOC) \ $(AMEBA_PREBUILT) $(AMEBA_PKGDIR)$(DELIM)target_img2.asm \ km0 $(AMEBA_AP_PROJECT) @@ -248,7 +262,8 @@ define PREBUILD { echo "ERROR: AMEBA_SDK is not set. Export it to your ameba-rtos checkout."; exit 1; } $(Q) $(AMEBA_FETCH_TOOLCHAIN) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) $(Q) $(AMEBA_SETUP_ENV) $(AMEBA_SDK) $(AMEBA_TOOLCHAIN_DIR) - $(Q) $(AMEBA_GEN_AUTOCONF) $(AMEBA_SDK) $(AMEBA_PY_SOC) $(AMEBA_AP_PROJECT) \ + $(Q) AMEBA_SDK_CONF=$(AMEBA_SDK_CONF) \ + $(AMEBA_GEN_AUTOCONF) $(AMEBA_SDK) $(AMEBA_PY_SOC) $(AMEBA_AP_PROJECT) \ $(AMEBA_AUTOCONF) $(Q) $(AMEBA_NP_PREBUILD) $(Q) echo "GEN: libameba_fwlib.a (fwlib from SDK source)" diff --git a/boards/arm/rtl8720f/rtl8720f_evb/ameba_sdk.conf b/boards/arm/rtl8720f/rtl8720f_evb/ameba_sdk.conf new file mode 100644 index 0000000000000..0d3485045d525 --- /dev/null +++ b/boards/arm/rtl8720f/rtl8720f_evb/ameba_sdk.conf @@ -0,0 +1,10 @@ +# User-editable Ameba SDK options for this board (prj.conf-style, diff vs SDK +# default). Applied on top of the SDK default when building the NP / bootloader +# images; dependents cascade automatically via kconfiglib. +# +# Edit interactively with `make ameba_menuconfig` (writes the diff back here), +# or add CONFIG_* lines by hand. Picked up on the next build. +# +# Options that MUST stay at a fixed value (e.g. CONFIG_SHELL=n) live in +# ameba_sdk_force.conf, which is applied last and re-applied after the TUI +# saves -- so they cannot be overridden from here or the menuconfig UI. diff --git a/boards/arm/rtl8720f/rtl8720f_evb/ameba_sdk_force.conf b/boards/arm/rtl8720f/rtl8720f_evb/ameba_sdk_force.conf new file mode 100644 index 0000000000000..9e02a021a3077 --- /dev/null +++ b/boards/arm/rtl8720f/rtl8720f_evb/ameba_sdk_force.conf @@ -0,0 +1,11 @@ +# Forced Ameba SDK options for this board (prj.conf-style, diff vs SDK default). +# +# These are applied LAST -- after the SDK default and the user overlay +# (ameba_sdk.conf), on every build AND again after `make ameba_menuconfig` +# saves -- so they always win and cannot be turned on from the TUI. Use this +# file (not ameba_sdk.conf) for options that MUST stay at a fixed value for the +# port to work. +# +# CONFIG_SHELL: the SDK's NP-side shell conflicts with NuttX owning the +# LOG-UART console, so it must stay disabled. +CONFIG_SHELL=n diff --git a/boards/arm/rtl8721dx/pke8721daf/ameba_sdk.conf b/boards/arm/rtl8721dx/pke8721daf/ameba_sdk.conf new file mode 100644 index 0000000000000..fc3c2ab010fdb --- /dev/null +++ b/boards/arm/rtl8721dx/pke8721daf/ameba_sdk.conf @@ -0,0 +1,5 @@ +# This file is generated automatically by : python menuconfig.py -s /home/raul_chen/nuttx/nuttx/boards/arm/rtl8721dx/pke8721daf/ameba_sdk.conf +CONFIG_SHELL=n +CONFIG_SUPPORT_ATCMD=n +CONFIG_ATCMD_NETWORK=n +CONFIG_LOGUART_AGG_EN=y diff --git a/boards/arm/rtl8721dx/pke8721daf/ameba_sdk_force.conf b/boards/arm/rtl8721dx/pke8721daf/ameba_sdk_force.conf new file mode 100644 index 0000000000000..9e02a021a3077 --- /dev/null +++ b/boards/arm/rtl8721dx/pke8721daf/ameba_sdk_force.conf @@ -0,0 +1,11 @@ +# Forced Ameba SDK options for this board (prj.conf-style, diff vs SDK default). +# +# These are applied LAST -- after the SDK default and the user overlay +# (ameba_sdk.conf), on every build AND again after `make ameba_menuconfig` +# saves -- so they always win and cannot be turned on from the TUI. Use this +# file (not ameba_sdk.conf) for options that MUST stay at a fixed value for the +# port to work. +# +# CONFIG_SHELL: the SDK's NP-side shell conflicts with NuttX owning the +# LOG-UART console, so it must stay disabled. +CONFIG_SHELL=n diff --git a/tools/ameba/Config.mk b/tools/ameba/Config.mk index df67a96aa810b..5dbea1d0e301f 100644 --- a/tools/ameba/Config.mk +++ b/tools/ameba/Config.mk @@ -72,3 +72,30 @@ define FLASH --baudrate "$(or $(AMEBA_BAUD),1500000)" \ --log-level info endef + +# ameba_menuconfig -- edit the vendor SDK menuconfig for this board using the +# SDK's own native menuconfig UI, and save the result as the board overlay +# fragment (boards/.../ameba_sdk.conf). The counterpart to NuttX's own +# `make menuconfig`, for the SDK-side options (Wi-Fi/BT firmware, flash layout, +# feature switches). The next build applies the change automatically (the +# fragment is hashed into the SDK-config stamp; see ameba_sdk_config.sh). +# +# Reachable as a top-level target because this fragment is included via the +# board scripts/Make.defs (the $(TOPDIR)/Make.defs symlink), like the flash +# target's FLASH macro. The logic lives in the standalone script so it can +# also be run directly. + +# This fragment is pulled in (via the board Make.defs / the $(TOPDIR)/Make.defs +# symlink) BEFORE the main build makefile defines its `all` rule, so a plain +# target here would become make's default goal and `make` with no argument +# would run it instead of building. Save the default goal, define the target, +# then restore it (falling back to `all`, NuttX's default, when nothing was set +# yet). The flash target avoids this because it lives in tools/Unix.mk, after +# `all`; this one lives here, so it must guard the default goal itself. +AMEBA_PREV_GOAL := $(.DEFAULT_GOAL) + +.PHONY: ameba_menuconfig +ameba_menuconfig: + $(Q) $(TOPDIR)$(DELIM)tools$(DELIM)ameba$(DELIM)ameba_menuconfig.sh + +.DEFAULT_GOAL := $(or $(AMEBA_PREV_GOAL),all) diff --git a/tools/ameba/ameba_menuconfig.sh b/tools/ameba/ameba_menuconfig.sh new file mode 100755 index 0000000000000..8034fe0d77c5c --- /dev/null +++ b/tools/ameba/ameba_menuconfig.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +############################################################################ +# tools/ameba/ameba_menuconfig.sh +# +# Edit the Realtek Ameba SDK menuconfig for the currently-configured board, +# using the SDK's own native menuconfig UI, and persist the result as the +# board's prj.conf-style overlay fragment (boards/...//ameba_sdk.conf). +# +# This is the SDK-configuration counterpart to NuttX's own `make menuconfig`: +# whatever the vendor SDK exposes is shown (no hand-maintained option mapping), +# and only the diff-vs-default is saved back to the committed fragment. The +# next build picks up the change automatically (the fragment is hashed into the +# SDK-config stamp; see ameba_sdk_config.sh), regenerates the SDK .config and +# rebuilds. +# +# Normally invoked via `make ameba_menuconfig` (the target lives in the board's +# tools/ameba/Config.mk). Can also be run directly from the NuttX top-level +# directory after configuring a board: +# +# ./tools/configure.sh pke8721daf:nsh +# make ameba_menuconfig # or: ./tools/ameba/ameba_menuconfig.sh +# +# The logic is kept here (rather than inline in the make target) so it stays +# readable and directly runnable; the target is a thin wrapper. +############################################################################ + +set -e + +TOPDIR=$(cd "$(dirname "$0")/../.." && pwd) +CONFIG="$TOPDIR/.config" + +if [ ! -f "$CONFIG" ]; then + echo "error: $CONFIG not found -- configure a board first" \ + "(./tools/configure.sh :)" >&2 + exit 1 +fi + +getcfg() { sed -n "s/^$1=\"\?\([^\"]*\)\"\?$/\1/p" "$CONFIG" | head -1; } +CHIP=$(getcfg CONFIG_ARCH_CHIP) +BOARD=$(getcfg CONFIG_ARCH_BOARD) + +case "$CHIP" in + rtl8721dx|rtl8720f) ;; + *) echo "error: not an Ameba board (CONFIG_ARCH_CHIP='$CHIP')" >&2; exit 1;; +esac + +BOARDMK="$TOPDIR/arch/arm/src/$CHIP/ameba_board.mk" +FRAG="$TOPDIR/boards/arm/$CHIP/$BOARD/ameba_sdk.conf" + +# The ameba.py SoC id (RTL8721Dx / RTL8720F) is defined once per IC in the +# board.mk; read it there instead of hardcoding a mapping. +SOC=$(sed -n 's/^AMEBA_PY_SOC[[:space:]]*=[[:space:]]*\([^[:space:]]*\).*/\1/p' "$BOARDMK" | head -1) +if [ -z "$SOC" ]; then + echo "error: could not read AMEBA_PY_SOC from $BOARDMK" >&2 + exit 1 +fi + +# Resolve the SDK: explicit AMEBA_SDK, else the in-tree auto-fetched checkout. +SDK="${AMEBA_SDK:-$TOPDIR/arch/arm/src/common/ameba/ameba-rtos}" +if [ ! -f "$SDK/ameba.py" ]; then + echo "error: SDK not found at $SDK (build the board once to auto-fetch it," \ + "or export AMEBA_SDK)" >&2 + exit 1 +fi + +# SDK python + isolated Kconfig env, matching the other ameba tool scripts. +PYDIR=$(cat "$SDK/.amebapy/bindir" 2>/dev/null) +VENV_PY="$PYDIR/python" +[ -x "$VENV_PY" ] || VENV_PY=python3 +PATH="${PYDIR:+$PYDIR:}$PATH" +export PATH +unset srctree BINDIR APPSDIR APPSBINDIR EXTERNALDIR EXTERNDIR KCONFIG_CONFIG \ + ARCHDIR DRIVERDIR BOARDDIR MAKEFLAGS MAKELEVEL MFLAGS MAKEOVERRIDES \ + 2>/dev/null || true + +cd "$SDK" +"$VENV_PY" "$SDK/ameba.py" soc "$SOC" >/dev/null + +# Forced overlay (same dir, fixed name): options that must stay at a fixed value +# regardless of what is done in the TUI (e.g. CONFIG_SHELL=n). Applied LAST at +# load and re-applied after the TUI saves, so they cannot be turned on here. +FORCE="$(dirname "$FRAG")/ameba_sdk_force.conf" + +OVERLAYS="" +[ -f "$FRAG" ] && OVERLAYS="$OVERLAYS $FRAG" +[ -f "$FORCE" ] && OVERLAYS="$OVERLAYS $FORCE" + +# 1. Materialize default + overlays (user then forced), so the TUI opens on the +# board's current effective config with the forced options in their state. +if [ -n "$OVERLAYS" ]; then + # shellcheck disable=SC2086 + "$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" --apply-file $OVERLAYS >/dev/null +else + "$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" -r >/dev/null +fi + +# 2. Native interactive menuconfig (shows everything the SDK exposes). +"$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" + +# 3. Re-apply the forced options on top of whatever the TUI saved, so a user who +# toggled one of them back on is corrected. --set edits the current .config +# in place (unlike --apply-file, which would reset all TUI edits). +if [ -f "$FORCE" ]; then + forced=$(grep -E '^[[:space:]]*CONFIG_[A-Za-z0-9_]+=' "$FORCE" | sed 's/^[[:space:]]*//') + if [ -n "$forced" ]; then + # shellcheck disable=SC2086 + "$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" --set $forced >/dev/null + fi +fi + +# 4. Save the diff-vs-default back to the USER overlay (forced options already +# corrected in step 3, so what is saved matches the effective config). +mkdir -p "$(dirname "$FRAG")" +"$VENV_PY" "$SDK/ameba.py" menuconfig "$SOC" --save-file "$FRAG" >/dev/null + +echo "Saved SDK overlay -> $FRAG" +if [ -f "$FORCE" ]; then + echo "Forced options ($FORCE) are always re-applied and cannot be overridden." +fi +echo "Rebuild the board (make / make flash) to apply; unchanged options are a no-op."