#!/usr/bin/env bash # Builds/flashes for a specific board variant. This project targets two: # # devkit ESP32-C6-DevKitC-1 (8MB flash) -- the dev board. This is # also the plain `idf.py` default (sdkconfig/build/), so this # script's devkit mode is mostly for symmetry -- normal # `idf.py build`/`flash` work fine too. # xiao Seeed XIAO ESP32-C6 (4MB flash) -- the production board. # # The two need different partition tables (the XIAO's 4MB doesn't fit # the dev board's two 2MB OTA app slots -- see partitions_xiao.csv, # 1.875MB slots instead) and a different flash-size Kconfig. Rather # than hand-editing the shared sdkconfig back and forth (fragile, easy # to leave it in the wrong state for whichever board you flash next), # each board gets its own build directory and its own generated # sdkconfig, seeded from sdkconfig.defaults (shared) with the board's # override file layered on top via ESP-IDF's own SDKCONFIG_DEFAULTS # mechanism. Switching boards is just switching which one you invoke -- # neither ever touches the other's config or build output. # # Usage: # ./build_for_board.sh xiao build # ./build_for_board.sh xiao flash -p /dev/ttyUSB0 # ./build_for_board.sh xiao flash monitor -p /dev/ttyUSB0 # ./build_for_board.sh devkit build # # Defaults to "build" if no idf.py subcommand is given. set -euo pipefail script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$script_dir" if [ $# -lt 1 ]; then echo "Usage: $0 [idf.py args...]" >&2 exit 1 fi board="$1" shift case "$board" in xiao) build_dir="$script_dir/build_xiao" sdkconfig_path="$script_dir/sdkconfig.xiao_local" defaults="$script_dir/sdkconfig.defaults;$script_dir/sdkconfig.xiao" ;; devkit) build_dir="$script_dir/build" sdkconfig_path="$script_dir/sdkconfig" defaults="$script_dir/sdkconfig.defaults" ;; *) echo "Unknown board '$board' -- expected 'devkit' or 'xiao'" >&2 exit 1 ;; esac args=("$@") if [ ${#args[@]} -eq 0 ]; then args=(build) fi # idf.py is normally a shell *function* (defined by ESP-IDF's # activate/export script), not a real executable on PATH -- that # function isn't inherited by this script's own subshell even if you # sourced the activation script first. IDF_PATH (an exported env var, # which *is* inherited) lets this work the same way regardless: call # the underlying Python module directly. if [ -z "${IDF_PATH:-}" ]; then echo "IDF_PATH is not set -- source your ESP-IDF activation/export.sh first" >&2 exit 1 fi echo "==> Board: $board (build dir: $(basename "$build_dir"), sdkconfig: $(basename "$sdkconfig_path"))" exec python "$IDF_PATH/tools/idf.py" -B "$build_dir" -D "SDKCONFIG=$sdkconfig_path" -D "SDKCONFIG_DEFAULTS=$defaults" "${args[@]}"