Skip to content

Instantly share code, notes, and snippets.

@EleotleCram
Created July 16, 2024 14:59
Show Gist options
  • Save EleotleCram/09f58e3f26a763abb761c556a5b81aae to your computer and use it in GitHub Desktop.
Save EleotleCram/09f58e3f26a763abb761c556a5b81aae to your computer and use it in GitHub Desktop.
Espressif IDF wrapper script; use any IDF version without ever installing it...
#!/bin/bash
# A generic idf-docker wrapper script.
# This script must either be named like idf-v4.4.6, idf-v5.0.5, etc. (Select a tag from: https://hub.docker.com/r/espressif/idf/tags),
# or you can rename it like idf-docker and 'busybox symlink' to it using such names. (It will automatically use the version deduced from the name.)
#
# Afterwards use it just like idf.py [ARGS, ...] but instead write e.g.: idf-v4.4.6 [ARGS, ...]
die() {
echo "$1" 1>&2
exit 1
}
if [ "${0#*-}" = "docker" ] ; then
die "This script must either be named like idf-v4.4.6, idf-v5.0.5, etc. or you can rename it like idf-docker and busybox symlink to it using such names." 1>&2
fi
DIALOUT_GID=$(grep dialout /etc/group | awk -F: '{print $3}')
DEVICE_OPT=""
CONTAINER_NAME="espressif/idf:${0#*-}" # Replace with your container name
EXEC_CMD="" # Default command if --exec is not provided
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-p)
DEVICE_PATH="$2"
DEVICE_OPT="--device=$DEVICE_PATH"
shift 2
;;
--exec)
# Execute a command into an interactive esp-idf docker container run (e.g. --exec /bin/bash)
EXEC_CMD="${@:2}"
break
;;
flash_from_dfu)
# Step 1: Put device in DFU mode (Hold button1 down during reset)
# Step 2: Call this script with arguments: -p <device> flash_from_dfu
# Step 3: Manually reset device
if [ -z "${DEVICE_OPT}" ] ; then
die "command 'flash_from_dfu' needs '-p <device>'"
fi
CONTAINER_NAME="espressif/idf:v4.4.6"
EXEC_CMD='cd /opt/esp/idf/components/esptool_py && /opt/esp/tools/cmake/3.23.1/bin/cmake -D IDF_PATH="/opt/esp/idf" -D SERIAL_TOOL="/opt/esp/python_env/idf4.4_py3.8_env/bin/python /opt/esp/idf/components/esptool_py/esptool/esptool.py --chip esp32s2" -D SERIAL_TOOL_ARGS="--after=hard_reset write_flash @flash_args" -D WORKING_DIRECTORY="/project/build" -P /opt/esp/idf/components/esptool_py/run_serial_tool.cmake'
break
;;
*)
break
;;
esac
done
DEVICE_CGROUP_RULE_OPT=""
if [ -n "$DEVICE_PATH" ] ; then
# Get the major number of the device
DEVICE_MAJOR_HEX=$(stat -c "%t" "$DEVICE_PATH")
DEVICE_MAJOR=$((16#$DEVICE_MAJOR_HEX)) # Convert from hex to decimal
if [ -z "$DEVICE_MAJOR" ] ; then
die "$DEVICE_PATH: No such device or unable to determine DEVICE_MAJOR"
fi
# Construct an array to work around the "quotes in quotes problem" (think about "$@" versus "$*")
DEVICE_CGROUP_RULE_OPT=("--device-cgroup-rule" "c $DEVICE_MAJOR:* rmw")
fi
# Run Docker container with device or specified command and set custom device rule
if [ -z "$EXEC_CMD" ]; then
# Use ${...:+"${...}"} to prevent an empty array being interpreted as '' (which is an empty positional argument and confuses docker) (See: https://unix.stackexchange.com/a/415992)
docker run ${DEVICE_CGROUP_RULE_OPT:+"${DEVICE_CGROUP_RULE_OPT[@]}"} -v "$PWD":/project -w /project -u "$UID:$DIALOUT_GID" -e HOME=/tmp -it $DEVICE_OPT $CONTAINER_NAME -- idf.py "$@"
else
# Use ${...:+"${...}"} to prevent an empty array being interpreted as '' (which is an empty positional argument and confuses docker) (See: https://unix.stackexchange.com/a/415992)
docker run ${DEVICE_CGROUP_RULE_OPT:+"${DEVICE_CGROUP_RULE_OPT[@]}"} -v "$PWD":/project -w /project -u "$UID:$DIALOUT_GID" -e HOME=/tmp -it $DEVICE_OPT $CONTAINER_NAME /bin/bash -c "$EXEC_CMD"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment