콘텐츠로 이동

AGR_BOOT V2 — XM10 부트로더 가이드

📌 이 페이지를 읽고 나면: STM32CubeIDE SWD 디버깅 vs PhAI Studio USB FTP 두 가지 펌웨어 업로드 방법 + 부트로더 파괴 방지 + 자동 롤백 메커니즘을 이해합니다. ⏱️ 예상 학습 시간: 30분 (실습 포함 60분) 🧰 사전 지식: STM32CubeIDE 설치 (docs/getting-started/02-software-setup.md) 🎯 핵심 ①: Debug Configuration Start address = 0x08040000 (기본값 0x08000000 으로 두면 부트로더 파괴) 🎯 핵심 ②: Specify vector table (hex) = 0x08040400 (Start address와 다른 값 — 틀리면 부팅 직후 signal handler 에 멈춤)

⚠️ 절대 금지: STM32CubeIDE Debug → Start address 0x08000000 설정 → 부트로더 파괴. 항상 0x08040000 사용.

버전: v1.1.0 | 대상 모듈: XM10 Extension Module (STM32H743XI) | 최초 작성: 2026-04-02


목차

  1. 개요
  2. Flash 메모리 맵
  3. 최초 설치 (부트로더 없는 상태에서)
  4. 앱 펌웨어 업로드 — STM32CubeIDE (SWD 디버깅)
  5. 앱 펌웨어 업로드 — PhAI Studio (USB FTP)
  6. 빌드 후 바이너리 생성 과정
  7. 부트로더 동작 원리
  8. 문제 해결 (Troubleshooting)
  9. 주의사항

1. 개요

XM10 Extension Module은 AGR_BOOT V2 부트로더를 탑재하여 USB를 통한 펌웨어 업데이트를 지원합니다.

부트로더가 하는 일

  • 전원 ON 시 앱 펌웨어의 유효성 검증 (시그니처 + CRC-32 + HW 리비전)
  • USB CDC FTP 프로토콜을 통한 앱 펌웨어 업로드 수신
  • 업데이트 실패 시 자동 롤백 (최대 3회 부팅 실패 시 백업 펌웨어로 복원)
  • 리셋이 계속 반복되면 앱 실행을 멈추고 업로드 대기 (v1.1.0 부터 — v2.8.1 이상 Rev 2.0 앱과 함께 쓸 때, 섹션 8)
  • Rev1.1 / Rev2.0 단일 부트로더 바이너리로 양쪽 HW 지원 (GPIO 자동 감지)

필요한 도구

도구 용도 다운로드
STM32CubeProgrammer 부트로더 최초 설치 (SWD/JTAG) st.com
STM32CubeIDE 앱 펌웨어 빌드 + SWD 디버깅 st.com
PhAI Studio USB FTP 펌웨어 업로드 studio.onephai.com
ST-Link V3 SWD 디버깅 프로브 ST-Link V2/V3 호환

2. Flash 메모리 맵

STM32H743XI는 2MB 내부 Flash (Bank1 + Bank2)를 가집니다.

┌─────────────────────────────────────────────────────────────────────────┐
│ Address         │ Size    │ Region         │ 설명                       │
├─────────────────────────────────────────────────────────────────────────┤
│ 0x08000000      │ 256 KB  │ Bootloader     │ AGR_BOOT V2                │
│                 │         │                │ (Bank1 S0-S1)              │
├─────────────────────────────────────────────────────────────────────────┤
│ 0x08040000      │ 1 KB    │ FW Header      │ 펌웨어 헤더                │
│                 │         │                │ (시그니처 + CRC + 버전)    │
├─────────────────────────────────────────────────────────────────────────┤
│ 0x08040400      │ 767 KB  │ App (Active)   │ 사용자 앱 펌웨어           │
│                 │         │                │ (Bank1 S2-S7)              │
├─────────────────────────────────────────────────────────────────────────┤
│ 0x08100000      │ 768 KB  │ Backup Slot    │ 이전 펌웨어 백업           │
│                 │         │                │ (Bank2 S0-S5)              │
├─────────────────────────────────────────────────────────────────────────┤
│ 0x081C0000      │ 128 KB  │ Boot Config    │ 부트 설정                  │
│                 │         │                │ (Bank2 S6)                 │
├─────────────────────────────────────────────────────────────────────────┤
│ 0x081E0000      │ 128 KB  │ Reserved       │ 예약 영역                  │
│                 │         │                │ (Bank2 S7)                 │
└─────────────────────────────────────────────────────────────────────────┘

중요: 부트로더(0x08000000)와 앱(0x08040000)은 완전히 분리된 영역입니다.
SWD로 앱을 플래시해도 부트로더는 손상되지 않습니다.


3. 최초 설치 (부트로더 없는 상태에서)

부트로더가 전혀 설치되지 않은 새 보드이거나, 이전에 부트로더 없이 사용하던 보드에 처음 설치하는 경우입니다.

Step 1: Full Chip Erase

왜 필요한가? 기존 펌웨어가 0x08000000부터 시작하는 단일 바이너리였다면, 부트로더 설치 후 주소가 충돌합니다. 반드시 전체 삭제 후 진행하세요.

  1. STM32CubeProgrammer 실행
  2. ST-Link를 보드에 연결
  3. 좌측 패널에서 Connect 클릭 (SWD 또는 JTAG)
  4. 좌측 메뉴에서 Erasing & Programming (다운로드 아이콘) 선택
  5. 상단 Full chip erase 버튼 클릭
  6. "Erase complete" 메시지 확인

Step 2: 부트로더 바이너리 업로드

  1. Erasing & Programming 탭에서:
  2. File path: AGR_Bootloader.bin 선택 (Release에서 다운로드)
  3. Start address: 0x08000000 (기본값 그대로)
  4. Skip flash erase before programming: 체크 해제 (기본값)
  5. Verify programming: 체크
  6. Start Programming 클릭
  7. "Download complete" + "Verification OK" 메시지 확인

Hex 파일 사용 시: AGR_Bootloader.hex를 선택하면 주소가 자동으로 설정됩니다.

Step 3: 확인

  1. 보드 전원을 리셋 (또는 전원 재투입)
  2. 부트로더가 실행되며:
  3. 유효한 앱 펌웨어가 없으므로 FTP 모드로 진입
  4. USB CDC 포트가 PC에 나타남 (COM 포트)
  5. 이제 Step 4 또는 Step 5로 앱 펌웨어를 업로드

부트로더만 바꾸기 (이미 설치된 보드)

이미 부트로더가 있는 보드를 새 부트로더로 바꿀 때는 Step 1(Full chip erase)을 하지 않습니다 — 하면 앱 펌웨어도 지워집니다.

  1. Step 2 와 같이 AGR_Bootloader.bin 을 0x08000000 에 올립니다 (부트로더 영역만 지워지고 다시 써집니다)
  2. 보드를 리셋 — 기존 앱 펌웨어가 그대로 실행되면 끝입니다

4. 앱 펌웨어 업로드 — STM32CubeIDE (SWD 디버깅)

개발 중 가장 많이 사용하는 방법입니다. SWD를 통해 직접 Flash에 기록합니다.

사전 설정 (최초 1회)

Debug Configuration 설정:

  1. Run → Debug Configurations → STM32 C/C++ Application
  2. 새 설정 생성 또는 기존 설정 선택
  3. Debugger 탭에서:
  4. Download: ✅ 체크
  5. Start address: 0x08040000 (⚠️ 기본값 0x08000000이 아닙니다! — .bin 다운로드 주소)
  6. Size: 0x000C0000 (768 KB = Active Slot)
  7. Specify vector table (hex): 0x08040400 (⚠️ Start address와 다른 값! — 실제 앱 벡터 테이블 위치)
  8. Reset behaviour: Software Reset

⚠️ 핵심 주의사항 1: Start address(다운로드 주소)를 0x08040000으로 설정해야 합니다!
기본값(0x08000000)으로 두면 부트로더를 덮어씁니다.

⚠️ 핵심 주의사항 2: Specify vector table (hex) 는 0x08040400 이어야 합니다 (Start address와 다른 값).
두 주소는 역할이 다릅니다: - Start address 0x08040000 = .bin 을 Flash 에 기록하는 위치. .bin 은 1 KB FW Header + 앱 이므로 헤더 시작 주소. - Vector table 0x08040400 = 앱의 실제 벡터 테이블(초기 SP + Reset_Handler) 위치. 1 KB 헤더 뒤.

Vector table 을 0x08040000 으로 잘못 두면, 디버거가 FW Header 바이트(AGRBOOT…)를 초기 스택 포인터/리셋 벡터로 잘못 읽어 부팅 직후 HardFault → signal handler(SIGTRAP 등)에 계속 멈춥니다. SDK ZIP 의 Extension_Module.launch 에는 0x08040400 이 이미 기본값으로 들어 있습니다.

빌드 & 디버깅

  1. STM32CubeIDE에서 프로젝트 Build (Ctrl+B)
  2. 빌드가 끝나면 후처리가 자동으로 실행됩니다:
  3. 메모리 사용량 리포트
  4. git tag 에서 버전 정보 생성
  5. 펌웨어 헤더에 크기·CRC 기록
  6. FTP 업로드용 패키징 바이너리 생성
  7. Debug (F11) 클릭 → SWD를 통해 0x08040000에 앱 펌웨어 기록
  8. 디버깅 시작 (브레이크포인트, 변수 감시 등 정상 사용 가능)

참고 — main()에서 자동 정지는 정상입니다. 디버그 시작 시 Thread #1 suspended: breakpoint main() 으로 멈추는 것은 오류가 아니라 CubeIDE 기본 동작입니다 (Debug Configuration → Startup 탭 → Set breakpoint at: main 기본 체크). Resume(F8) 를 누르면 실행됩니다. 매번 멈추는 게 싫으면 위 Set breakpoint at: main 체크를 해제하세요. (이는 벡터 테이블 오설정으로 인한 signal handler 정지와 다른 정상 정지입니다 — 섹션 4 벡터 테이블 주의사항 참조.)

SWD 디버깅이 부트로더와 호환되는 이유

  • 링커 스크립트(STM32H743XIHX_FLASH.ld)가 앱 코드를 0x08040400에 배치
  • 펌웨어 헤더가 0x08040000에 배치되어 부트로더가 시그니처를 인식
  • SDK 가 시그니처를 펌웨어에 포함시켜 SWD 플래시 후에도 부트로더가 앱을 정상 인식

5. 앱 펌웨어 업로드 — PhAI Studio (USB FTP)

SWD 디버거 없이 USB 케이블만으로 펌웨어를 업로드하는 방법입니다.
양산 환경, 현장 업데이트, 일반 사용자 대상으로 권장됩니다.

필요한 파일

빌드 완료 후 Debug/ 폴더에 생성되는 파일:

Debug/
├── Extension_Module.elf        ← SWD 디버깅용
├── Extension_Module.bin        ← SWD 플래시용 (FW Header 포함)
├── Extension_Module.hex        ← SWD 플래시용
├── Extension_Module_app.bin    ← FTP 업로드용 (FW Header 미포함)
└── XM10_X_X_X_X.bin           ← FTP 업로드용 패키징 바이너리 ★

PhAI Studio에서 사용할 파일: XM10_X_X_X_X.bin (예: XM10_2_0_1_0.bin)
이 파일은 빌드가 끝나면 자동으로 만들어지며, 1KB 펌웨어 헤더 + 앱 바이너리로 구성됩니다.

업로드 절차

  1. PhAI Studio 접속: studio.onephai.com
  2. XM10 보드를 USB 케이블로 PC에 연결
  3. PhAI Studio에서 디바이스 자동 인식 확인
  4. FW Upload 메뉴 선택
  5. XM10_X_X_X_X.bin 파일 선택
  6. Upload 시작
  7. 진행률 표시 → 완료 후 자동 리부팅
  8. 부트로더가 새 펌웨어 검증 → 앱 실행

부트로더 FTP 모드 강제 진입

앱이 정상 실행 중일 때 FTP 모드로 전환하려면: - PhAI Studio에서 Enter Bootloader 명령 전송


6. 빌드 후 바이너리 생성 과정

STM32CubeIDE에서 Build를 실행하면 컴파일 뒤에 다음 후처리가 순서대로 자동 실행됩니다:

[Build]  GCC 컴파일 + 링크 → Extension_Module.elf
           │
[Step 1]  메모리 사용량 리포트 (콘솔 출력)
           │
[Step 2]  git tag → version.h 자동 생성
           │
[Step 3]  펌웨어 헤더에 크기·CRC 기록
           │                  → .bin, .hex, _app.bin 생성
           │
[Step 4]  _app.bin + 펌웨어 헤더 → XM10_X_X_X_X.bin

각 단계 상세

단계 입력 출력 설명
1 .elf 콘솔 FLASH/RAM 사용량 시각화
2 git tag version.h FW_VER_MAJOR/MINOR/PATCH/DEBUG 정의
3 .elf .bin, .hex, _app.bin 펌웨어 헤더에 크기/CRC 기록
4 _app.bin XM10_X_X_X_X.bin 1KB 헤더 + 앱 바이너리 = FTP용

Python 3.x 필수: 빌드 후처리는 Python으로 실행됩니다. pip install pyyaml 이 필요합니다.


7. 부트로더 동작 원리

부팅 시퀀스

전원 ON → 부트로더 시작 (0x08000000)
    │
    ├─ 리셋 반복 체크 (v1.1.0, v2.8.1 이상 Rev 2.0 앱)
    │   └─ 앱이 5초를 넘기지 못한 부팅이 10번 연속: 앱을 실행하지 않고 FTP 대기 (LED 3개 함께 깜빡임)
    │
    ├─ 부트 설정 읽기 (Bank2 S6)
    │   └─ 최초 부팅: 기본값으로 설정 자동 생성
    │
    ├─ 롤백 체크 (연속 부팅 실패 3회 이상?)
    │   └─ Yes: 백업 슬롯에서 복원
    │
    ├─ 앱 펌웨어 검증
    │   ├─ 시그니처 확인
    │   ├─ CRC-32 검증 (FTP 업로드 시에만)
    │   └─ HW 리비전 호환성 확인
    │
    ├─ 검증 성공 → 앱으로 점프 (0x08040400)
    │   ├─ 앱이 정상 시작하면 SDK 가 부트로더에 알림 → 부팅 실패 횟수 초기화
    │   └─ 앱이 5초 동안 정상 동작하면 → 리셋 반복 횟수 초기화 (v1.1.0, Rev 2.0)
    │
    └─ 검증 실패 → FTP 대기 모드
        └─ USB CDC로 새 펌웨어 수신 대기

FTP 업데이트 시퀀스

PhAI Studio에서 FW Upload 시작
    │
    ├─ [1] 앱이 부트로더로 전환 (리셋)
    ├─ [2] 현재 Active FW → Backup Slot 복사
    ├─ [3] Active Slot 삭제
    ├─ [4] 새 FW 수신 + Active Slot 기록
    ├─ [5] CRC-32 검증
    ├─ [6] 부트 설정 업데이트 (새 펌웨어 확인 대기)
    └─ [7] 리셋 → 새 앱 시작 → 정상 시작 확인 → 완료

LED 표시

LED 뜻
차례로 켜졌다가 모두 꺼짐 (짧게 한 번) 부트로더 시작
하나씩 돌아가며 켜짐 FTP 대기 — 펌웨어 업로드를 기다리는 중
3개가 함께 깜빡임 리셋이 반복돼 멈춤 (v1.1.0) — 업로드를 기다리는 중 (섹션 8)
빠르게 번갈아 깜빡임 부트로더가 더 진행할 수 없는 오류

8. 문제 해결 (Troubleshooting)

"부트로더를 설치했는데 앱이 실행되지 않습니다"

원인: 앱 펌웨어가 없거나 유효하지 않습니다. 1. STM32CubeIDE에서 빌드 후 Debug(F11)로 앱 업로드 2. 또는 PhAI Studio에서 XM10_X_X_X_X.bin 업로드

"SWD 디버깅 후 부트로더가 사라졌습니다"

원인: Debug Configuration의 Start address가 0x08000000으로 되어 있었습니다. 1. 0x08040000으로 수정 (섹션 4 참조) 2. 부트로더 재설치 필요 (섹션 3 참조)

"Debug(F11) 하자마자 실행이 멈추고 signal handler(SIGTRAP 등)에 빠집니다"

원인: Debug Configuration 의 Specify vector table (hex) 가 0x08040400 이 아닙니다 (예: Start address와 같은 0x08040000 으로 설정). 디버거가 1 KB FW Header 를 벡터 테이블로 잘못 읽어 초기 SP/PC 가 깨집니다. - Debugger 탭에서 Specify vector table (hex): 0x08040400 으로 수정 (섹션 4 참조) - Download Start address 는 0x08040000 그대로 유지 — 두 값은 다릅니다. - SDK ZIP 을 그대로 임포트하면 Extension_Module.launch 기본값이 이미 0x08040400 이므로 이 문제가 없습니다.

"PhAI Studio에서 디바이스를 찾지 못합니다"

  1. USB 케이블 연결 확인
  2. Windows 장치 관리자에서 COM 포트 확인
  3. 부트로더가 FTP 모드인지 확인 (앱 실행 중이면 PhAI Studio에서 "Enter Bootloader" 먼저 실행)

"FW 업로드 후 부팅이 반복되다가 이전 버전으로 돌아갔습니다"

원인: 새 펌웨어가 정상 시작했다는 알림을 부트로더에 보내지 못해 3회 부팅 후 자동 롤백. - 이 알림은 SDK 기본 코드가 부팅 직후 자동으로 보냅니다 - 사용자가 SDK 시작 코드를 수정하지 않았는지 확인

"앱이 실행되지 않고 LED 3개가 함께 깜빡입니다"

원인 (부트로더 v1.1.0): 앱이 시작된 뒤 5초를 넘기지 못하고 다시 시작되는 일이 10번 연속 생겨, 부트로더가 앱 실행을 멈추고 펌웨어 업로드를 기다리는 중입니다. 1. 리셋이 반복된 원인(앱 코드, 전원 등)을 먼저 확인하세요. 2. PhAI Studio 로 펌웨어를 다시 올리면 풀립니다 (섹션 5). 보드는 이미 FTP 대기 상태입니다. - v2.8.1 Rev 2.0 앱을 쓰던 보드에 v2.8.0 이하 SDK 로 만든 앱을 ST-LINK 로 올려 쓰면, 보드를 10번 다시 시작한 뒤 이 상태가 될 수 있습니다(이전 앱은 5초 확인을 하지 않습니다). 이때도 PhAI Studio 로 한 번 올리면 풀립니다.

"빌드는 되는데 XM10_X_X_X_X.bin이 생성되지 않습니다"

  1. Python 3.x 설치 확인: python --version
  2. 빌드 후처리 단계의 콘솔 출력 확인 (Build Console에 에러 메시지)
  3. SDK 의 tools/build/ 폴더가 그대로 있는지 확인 (빌드 후처리 파일이 들어 있습니다)

"STM32CubeProgrammer에서 Read 하면 0x08040000에 데이터가 없습니다"

원인: SWD 디버깅이 아닌 STM32CubeProgrammer로 직접 .bin을 업로드할 때 주소를 잘못 설정한 경우. - .bin 파일 업로드 시 Start address: 0x08040000 - .hex 파일은 주소가 내장되어 있으므로 자동


9. 주의사항

절대 하면 안 되는 것

금지 사항 결과
STM32CubeIDE Debug에서 Start address를 0x08000000으로 설정 부트로더 파괴
STM32CubeProgrammer에서 Full chip erase 후 앱만 업로드 부트로더 없음 → 부팅 불가
부트로더 영역(0x08000000~0x0803FFFF)에 직접 쓰기 부트로더 파괴
Boot Config 영역(0x081C0000)을 임의로 삭제 부팅 설정 초기화 (자동 복구는 됨)

Rev1.1 / Rev2.0 공통 사항

  • 동일한 부트로더 바이너리를 사용합니다 (HW 리비전 GPIO 자동 감지)
  • 동일한 Flash 메모리 맵을 사용합니다
  • 앱 펌웨어는 각 리비전별 별도 libXM_Lib.a로 빌드하지만, 부트로더는 공통

Python 환경 설정

빌드 후처리 실행을 위해:

# Python 3.x 설치 후
pip install pyyaml

STM32CubeIDE의 Build Console에서 Python 경로가 인식되지 않는 경우: - Windows: 시스템 환경변수 PATH에 Python 경로 추가 - STM32CubeIDE 재시작 필요