#!/usr/bin/env bash # NuEclipse/IAR 없이 Nuvoton NANO100 (Cortex-M0) 펌웨어 빌드 / 플래시 / 디버그. # 이 프로젝트는 자체 Makefile (ARM-GCC) 을 사용하며, 본 스크립트는 PATH 설정 + # make 래퍼 + openocd(Nu-Link) 플래시/디버그 진입점입니다. # (참조: Nova/program/Main/build.sh 를 HERV 구조에 맞게 적응) # # 사용법: # bash build.sh : 빌드 (기본 = rebuild, clean 후 전체 빌드 → 모든 컴파일 과정 표시) # bash build.sh all : 증분 빌드 (변경된 파일만, 빠름) # bash build.sh clean : clean # bash build.sh rebuild : clean 후 재빌드 (기본과 동일) # bash build.sh size : 메모리 사용량 출력 # bash build.sh flash : Nu-Link(openocd) 로 내부 flash 쓰기 (ELF) # bash build.sh erase : 칩 erase # bash build.sh gdbserver : OpenOCD GDB server 시작 (포어그라운드, port 3333) # bash build.sh debug : GDB 클라이언트 띄움 (gdbserver 별도 실행 필요) # 환경: Windows + Git Bash / msys64 bash / VS Code Bash terminal. set -e # 출력이 너무 빨리 지나가거나 창이 바로 닫히지 않도록, 종료 시 키 입력 대기. # 성공/실패(빌드 에러로 set -e 종료) 모두 멈춰서 결과를 확인할 수 있음. # 단, 터미널이 아닌 경우(파이프/자동화)에는 멈추지 않음. pause_on_exit() { local code=$? if [ -t 0 ]; then echo "" if [ "$code" -eq 0 ]; then echo "=== 완료 (exit $code) ===" else echo "=== 실패 (exit $code) ===" fi read -n 1 -s -r -p "아무 키나 누르면 종료합니다..." echo "" fi } trap pause_on_exit EXIT # 프로젝트 디렉터리 (이 스크립트 위치 기준). PROJ_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BUILD_DIR="$PROJ_DIR/build" # Makefile 의 PROJECT 값에서 산출물 이름 추출 (예: HERV). PROJECT="$(sed -n 's/^PROJECT[[:space:]]*:=[[:space:]]*//p' "$PROJ_DIR/Makefile" | head -1)" ELF="$BUILD_DIR/$PROJECT.elf" # 툴체인 경로 (필요시 자기 환경에 맞게 수정). ARM_GCC_BIN="/c/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin" MSYS_BIN="/c/msys64/usr/bin" # 디버그/플래시: OpenOCD-Nuvoton 포크 (Nu-Link/Nu-Link-Pro 정식 지원). OPENOCD_BIN="/c/Nuvoton/OpenOCD/bin" export PATH="$ARM_GCC_BIN:$MSYS_BIN:$OPENOCD_BIN:$PATH" # 공통 함수: 빌드 툴 가용성. check_build_tools() { if ! command -v arm-none-eabi-gcc >/dev/null; then echo "ERROR: arm-none-eabi-gcc not found. PATH 에 ARM toolchain 확인 (예상: $ARM_GCC_BIN)." exit 1 fi if ! command -v make >/dev/null; then echo "ERROR: make not found. msys64 설치 확인 (예상: $MSYS_BIN/make.exe)." exit 1 fi } check_openocd() { if ! command -v openocd >/dev/null; then echo "ERROR: openocd not found. PATH 에 openocd 확인 (예상: $OPENOCD_BIN)." echo " Nu-Link 사용 시 OpenOCD-Nuvoton 포크가 필요할 수 있습니다." exit 1 fi } # 빌드: make 래퍼 (Makefile 이 elf/hex/bin/size 까지 생성). 인자로 타겟 전달 (기본 all). do_build() { check_build_tools cd "$PROJ_DIR" local target="${1:-all}" echo "=== Building: make -j8 $target ===" make -j8 "$target" } # 플래시 (내부 flash, Nu-Link/openocd). Makefile flash 타겟 사용. do_flash() { check_build_tools check_openocd if [ ! -f "$ELF" ]; then echo "ELF 가 없습니다. 먼저 빌드: bash build.sh" exit 1 fi cd "$PROJ_DIR" echo "=== Flashing internal flash via Nu-Link (openocd) ===" echo "Image: $ELF" make flash } # 칩 erase. do_erase() { check_openocd cd "$PROJ_DIR" echo "=== Chip erase via Nu-Link (openocd) ===" make erase } # GDB server 시작 (OpenOCD, foreground; 별도 터미널에서 gdb 클라이언트 연결). do_gdbserver() { check_openocd cd "$PROJ_DIR" echo "=== OpenOCD GDB Server (port 3333) — Ctrl+C 종료 ===" make debug-server } # GDB 클라이언트 (인터랙티브 디버그) — OpenOCD gdbserver 가 이미 실행 중이어야 함. do_debug() { check_build_tools if [ ! -f "$ELF" ]; then echo "ELF 가 없습니다. 먼저 빌드: bash build.sh" exit 1 fi local port="${1:-3333}" echo "=== GDB client (OpenOCD gdbserver 가 port $port 에서 떠 있어야 함) ===" arm-none-eabi-gdb \ -ex "target extended-remote localhost:$port" \ -ex "monitor reset halt" \ -ex "load" \ -ex "monitor reset halt" \ "$ELF" } # 서브커맨드 디스패치. (기본 = rebuild: clean 후 전체 빌드라 모든 컴파일 과정이 보임) CMD="${1:-rebuild}" case "$CMD" in all|clean|rebuild|size|"") do_build "$CMD" ;; flash) do_flash ;; erase) do_erase ;; gdbserver) do_gdbserver "${2:-3333}" ;; debug) do_debug "${2:-3333}" ;; *) echo "Unknown command: $CMD" echo "Usage: bash build.sh [all|clean|rebuild|size|flash|erase|gdbserver|debug]" exit 1 ;; esac