update_fw.sh: флаг --no-build — прошивка готовых артефактов из ~/firmware
host прошивается через scripts/flash-linux.sh из ~/firmware/host_klipper.elf, а не из out/, поэтому не зависит от порядка сборки. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+37
-12
@@ -5,9 +5,10 @@
|
|||||||
# toolhead — EBB SB2209 (rp2040; прошивается по CAN через katapult)
|
# toolhead — EBB SB2209 (rp2040; прошивается по CAN через katapult)
|
||||||
#
|
#
|
||||||
# Использование:
|
# Использование:
|
||||||
# update_fw.sh [-h] [--build-only] [--force] [host|mcu|toolhead ...]
|
# update_fw.sh [-h] [--build-only|--no-build] [--force] [host|mcu|toolhead ...]
|
||||||
# без целей — все три
|
# без целей — все три
|
||||||
# --build-only — только собрать прошивки в ~/firmware, ничего не прошивать
|
# --build-only — только собрать прошивки в ~/firmware, ничего не прошивать
|
||||||
|
# --no-build — не собирать, прошить уже собранные ~/firmware/<цель>_klipper.{bin,elf}
|
||||||
# --force — не останавливаться, если Moonraker недоступен для проверки печати
|
# --force — не останавливаться, если Moonraker недоступен для проверки печати
|
||||||
#
|
#
|
||||||
# Исходники Klipper НЕ обновляются (это делает Moonraker Update Manager).
|
# Исходники Klipper НЕ обновляются (это делает Moonraker Update Manager).
|
||||||
@@ -50,18 +51,21 @@ ALL_TARGETS=(host mcu toolhead)
|
|||||||
|
|
||||||
# ---------- Разбор аргументов ----------
|
# ---------- Разбор аргументов ----------
|
||||||
BUILD_ONLY=0
|
BUILD_ONLY=0
|
||||||
|
NO_BUILD=0
|
||||||
FORCE=0
|
FORCE=0
|
||||||
TARGETS=()
|
TARGETS=()
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
-h|--help) sed -n '2,15p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
-h|--help) sed -n '2,16p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||||
--build-only) BUILD_ONLY=1 ;;
|
--build-only) BUILD_ONLY=1 ;;
|
||||||
|
--no-build) NO_BUILD=1 ;;
|
||||||
--force) FORCE=1 ;;
|
--force) FORCE=1 ;;
|
||||||
host|mcu|toolhead) TARGETS+=("$arg") ;;
|
host|mcu|toolhead) TARGETS+=("$arg") ;;
|
||||||
*) echo "Неизвестный аргумент: $arg (см. -h)" >&2; exit 2 ;;
|
*) echo "Неизвестный аргумент: $arg (см. -h)" >&2; exit 2 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
[ ${#TARGETS[@]} -eq 0 ] && TARGETS=("${ALL_TARGETS[@]}")
|
[ ${#TARGETS[@]} -eq 0 ] && TARGETS=("${ALL_TARGETS[@]}")
|
||||||
|
[ "$BUILD_ONLY" = 1 ] && [ "$NO_BUILD" = 1 ] && { echo "--build-only и --no-build несовместимы" >&2; exit 2; }
|
||||||
want() { local t; for t in "${TARGETS[@]}"; do [ "$t" = "$1" ] && return 0; done; return 1; }
|
want() { local t; for t in "${TARGETS[@]}"; do [ "$t" = "$1" ] && return 0; done; return 1; }
|
||||||
|
|
||||||
# ---------- Лог и трапы ----------
|
# ---------- Лог и трапы ----------
|
||||||
@@ -119,7 +123,7 @@ mcu_versions() {
|
|||||||
# ---------- Preflight ----------
|
# ---------- Preflight ----------
|
||||||
STAGE="предварительные проверки"
|
STAGE="предварительные проверки"
|
||||||
section "Preflight"
|
section "Preflight"
|
||||||
echo "Цели: ${TARGETS[*]} build-only=$BUILD_ONLY лог: $LOG"
|
echo "Цели: ${TARGETS[*]} build-only=$BUILD_ONLY no-build=$NO_BUILD лог: $LOG"
|
||||||
|
|
||||||
[ -d "$KLIPPER" ] || die "Нет исходников Klipper: $KLIPPER"
|
[ -d "$KLIPPER" ] || die "Нет исходников Klipper: $KLIPPER"
|
||||||
[ -f "$KATAPULT" ] || die "Нет katapult flashtool: $KATAPULT"
|
[ -f "$KATAPULT" ] || die "Нет katapult flashtool: $KATAPULT"
|
||||||
@@ -130,6 +134,23 @@ want toolhead && { [ -f "$CONFIG_DIR/$TOOLHEAD_CFG" ] || die "Нет конфи
|
|||||||
KLIPPER_VER=$(git -C "$KLIPPER" describe --always --tags --long --dirty 2>/dev/null || echo unknown)
|
KLIPPER_VER=$(git -C "$KLIPPER" describe --always --tags --long --dirty 2>/dev/null || echo unknown)
|
||||||
echo "Klipper в $KLIPPER: $KLIPPER_VER"
|
echo "Klipper в $KLIPPER: $KLIPPER_VER"
|
||||||
|
|
||||||
|
# Артефакт цели: ~/firmware/<цель>_klipper.<bin|elf> (симлинк на <цель>-<версия>.<ext>)
|
||||||
|
artifact() { case "$1" in host) echo "$OUT_DIR/host_klipper.elf" ;; *) echo "$OUT_DIR/$1_klipper.bin" ;; esac; }
|
||||||
|
|
||||||
|
if [ "$NO_BUILD" = 1 ]; then
|
||||||
|
echo "Без сборки — используются готовые прошивки:"
|
||||||
|
for t in "${TARGETS[@]}"; do
|
||||||
|
f=$(artifact "$t")
|
||||||
|
[ -s "$f" ] || die "Нет готовой прошивки $f (соберите: $0 --build-only $t)"
|
||||||
|
real=$(readlink -f "$f")
|
||||||
|
echo " $t: $(basename "$real") ($(stat -c %s "$real") байт)"
|
||||||
|
case "$(basename "$real")" in
|
||||||
|
*"-${KLIPPER_VER}."*) ;;
|
||||||
|
*) echo " !!! $t: прошивка собрана не из текущего $KLIPPER_VER" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
BEFORE=""
|
BEFORE=""
|
||||||
if [ "$BUILD_ONLY" = 0 ]; then
|
if [ "$BUILD_ONLY" = 0 ]; then
|
||||||
if want mcu || want toolhead; then
|
if want mcu || want toolhead; then
|
||||||
@@ -179,14 +200,15 @@ build() { # build <цель> <конфиг> <артефакт: bin|elf>
|
|||||||
[ -s "$src" ] || die "Сборка $name не дала $src"
|
[ -s "$src" ] || die "Сборка $name не дала $src"
|
||||||
local dst="$OUT_DIR/${name}-${KLIPPER_VER}.$ext"
|
local dst="$OUT_DIR/${name}-${KLIPPER_VER}.$ext"
|
||||||
cp "$src" "$dst"
|
cp "$src" "$dst"
|
||||||
ln -sfn "$(basename "$dst")" "$OUT_DIR/${name}_klipper.$ext"
|
ln -sfn "$(basename "$dst")" "$(artifact "$name")"
|
||||||
echo "-> $dst ($(stat -c %s "$dst") байт)"
|
echo "-> $dst ($(stat -c %s "$dst") байт)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# host собирается последним: его out/ нужен для make flash
|
if [ "$NO_BUILD" = 0 ]; then
|
||||||
want mcu && build mcu "$MCU_CFG" bin
|
want mcu && build mcu "$MCU_CFG" bin
|
||||||
want toolhead && build toolhead "$TOOLHEAD_CFG" bin
|
want toolhead && build toolhead "$TOOLHEAD_CFG" bin
|
||||||
want host && build host "$HOST_CFG" elf
|
want host && build host "$HOST_CFG" elf
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$BUILD_ONLY" = 1 ]; then
|
if [ "$BUILD_ONLY" = 1 ]; then
|
||||||
section "Готово (только сборка)"
|
section "Готово (только сборка)"
|
||||||
@@ -203,9 +225,12 @@ KLIPPER_STOPPED=1
|
|||||||
if want host; then
|
if want host; then
|
||||||
STAGE="прошивка host MCU"
|
STAGE="прошивка host MCU"
|
||||||
section "Прошивка host (klipper-mcu)"
|
section "Прошивка host (klipper-mcu)"
|
||||||
# flash-linux.sh копирует out/klipper.elf в /usr/local/bin/klipper_mcu и перезапускает klipper-mcu
|
# flash-linux.sh <dir> копирует <dir>/klipper.elf в /usr/local/bin/klipper_mcu и перезапускает klipper-mcu.
|
||||||
|
# Подсовываем ему каталог с артефактом из ~/firmware, а не out/ (там может быть сборка другой цели)
|
||||||
|
mkdir -p "$BUILD_TMP/host"
|
||||||
|
cp "$(artifact host)" "$BUILD_TMP/host/klipper.elf"
|
||||||
HOST_PID_OLD=$(systemctl show -p ExecMainPID --value klipper-mcu)
|
HOST_PID_OLD=$(systemctl show -p ExecMainPID --value klipper-mcu)
|
||||||
make -C "$KLIPPER" flash KCONFIG_CONFIG="$BUILD_TMP/$HOST_CFG"
|
sudo "$KLIPPER/scripts/flash-linux.sh" "$BUILD_TMP/host"
|
||||||
[ "$(stat -c %Y "$HOST_BIN")" -ge "$START_TS" ] || die "$HOST_BIN не обновился"
|
[ "$(stat -c %Y "$HOST_BIN")" -ge "$START_TS" ] || die "$HOST_BIN не обновился"
|
||||||
host_restarted() {
|
host_restarted() {
|
||||||
[ "$(systemctl show -p ExecMainPID --value klipper-mcu)" != "$HOST_PID_OLD" ] \
|
[ "$(systemctl show -p ExecMainPID --value klipper-mcu)" != "$HOST_PID_OLD" ] \
|
||||||
@@ -230,7 +255,7 @@ if want mcu; then
|
|||||||
DEV=$(katapult_serial)
|
DEV=$(katapult_serial)
|
||||||
echo "katapult serial: $DEV"
|
echo "katapult serial: $DEV"
|
||||||
sleep 1 # порт может быть ещё не готов сразу после появления симлинка
|
sleep 1 # порт может быть ещё не готов сразу после появления симлинка
|
||||||
python3 "$KATAPULT" -d "$DEV" -f "$OUT_DIR/mcu_klipper.bin"
|
python3 "$KATAPULT" -d "$DEV" -f "$(artifact mcu)"
|
||||||
# После прошивки плата перезагружается в Klipper и снова поднимает USB-CAN мост
|
# После прошивки плата перезагружается в Klipper и снова поднимает USB-CAN мост
|
||||||
wait_for 30 "Octopus не вернулся на $CAN_IF после прошивки" can_has_uuid "$MCU_UUID"
|
wait_for 30 "Octopus не вернулся на $CAN_IF после прошивки" can_has_uuid "$MCU_UUID"
|
||||||
echo "Octopus снова на $CAN_IF"
|
echo "Octopus снова на $CAN_IF"
|
||||||
@@ -240,7 +265,7 @@ if want toolhead; then
|
|||||||
STAGE="прошивка тулхеда"
|
STAGE="прошивка тулхеда"
|
||||||
section "Прошивка toolhead (EBB SB2209, uuid $TOOLHEAD_UUID)"
|
section "Прошивка toolhead (EBB SB2209, uuid $TOOLHEAD_UUID)"
|
||||||
# flashtool сам отправляет запрос бутлоадера по UUID и заливает прошивку
|
# flashtool сам отправляет запрос бутлоадера по UUID и заливает прошивку
|
||||||
python3 "$KATAPULT" -i "$CAN_IF" -u "$TOOLHEAD_UUID" -f "$OUT_DIR/toolhead_klipper.bin"
|
python3 "$KATAPULT" -i "$CAN_IF" -u "$TOOLHEAD_UUID" -f "$(artifact toolhead)"
|
||||||
wait_for 30 "тулхед не вернулся на $CAN_IF после прошивки" can_has_uuid "$TOOLHEAD_UUID"
|
wait_for 30 "тулхед не вернулся на $CAN_IF после прошивки" can_has_uuid "$TOOLHEAD_UUID"
|
||||||
echo "Тулхед снова на $CAN_IF"
|
echo "Тулхед снова на $CAN_IF"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user