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
목차¶
- 개요
- Flash 메모리 맵
- 최초 설치 (부트로더 없는 상태에서)
- 앱 펌웨어 업로드 — STM32CubeIDE (SWD 디버깅)
- 앱 펌웨어 업로드 — PhAI Studio (USB FTP)
- 빌드 후 바이너리 생성 과정
- 부트로더 동작 원리
- 문제 해결 (Troubleshooting)
- 주의사항
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부터 시작하는 단일 바이너리였다면, 부트로더 설치 후 주소가 충돌합니다. 반드시 전체 삭제 후 진행하세요.
- STM32CubeProgrammer 실행
- ST-Link를 보드에 연결
- 좌측 패널에서 Connect 클릭 (SWD 또는 JTAG)
- 좌측 메뉴에서 Erasing & Programming (다운로드 아이콘) 선택
- 상단 Full chip erase 버튼 클릭
- "Erase complete" 메시지 확인
Step 2: 부트로더 바이너리 업로드¶
- Erasing & Programming 탭에서:
- File path:
AGR_Bootloader.bin선택 (Release에서 다운로드) - Start address:
0x08000000(기본값 그대로) - Skip flash erase before programming: 체크 해제 (기본값)
- Verify programming: 체크
- Start Programming 클릭
- "Download complete" + "Verification OK" 메시지 확인
Hex 파일 사용 시:
AGR_Bootloader.hex를 선택하면 주소가 자동으로 설정됩니다.
Step 3: 확인¶
- 보드 전원을 리셋 (또는 전원 재투입)
- 부트로더가 실행되며:
- 유효한 앱 펌웨어가 없으므로 FTP 모드로 진입
- USB CDC 포트가 PC에 나타남 (COM 포트)
- 이제 Step 4 또는 Step 5로 앱 펌웨어를 업로드
부트로더만 바꾸기 (이미 설치된 보드)¶
이미 부트로더가 있는 보드를 새 부트로더로 바꿀 때는 Step 1(Full chip erase)을 하지 않습니다 — 하면 앱 펌웨어도 지워집니다.
- Step 2 와 같이
AGR_Bootloader.bin을0x08000000에 올립니다 (부트로더 영역만 지워지고 다시 써집니다) - 보드를 리셋 — 기존 앱 펌웨어가 그대로 실행되면 끝입니다
4. 앱 펌웨어 업로드 — STM32CubeIDE (SWD 디버깅)¶
개발 중 가장 많이 사용하는 방법입니다. SWD를 통해 직접 Flash에 기록합니다.
사전 설정 (최초 1회)¶
Debug Configuration 설정:
- Run → Debug Configurations → STM32 C/C++ Application
- 새 설정 생성 또는 기존 설정 선택
- Debugger 탭에서:
- Download: ✅ 체크
- Start address:
0x08040000(⚠️ 기본값 0x08000000이 아닙니다! —.bin다운로드 주소) - Size:
0x000C0000(768 KB = Active Slot) - Specify vector table (hex):
0x08040400(⚠️ Start address와 다른 값! — 실제 앱 벡터 테이블 위치) - Reset behaviour: Software Reset
⚠️ 핵심 주의사항 1: Start address(다운로드 주소)를
0x08040000으로 설정해야 합니다!
기본값(0x08000000)으로 두면 부트로더를 덮어씁니다.⚠️ 핵심 주의사항 2: Specify vector table (hex) 는
0x08040400이어야 합니다 (Start address와 다른 값).
두 주소는 역할이 다릅니다: - Start address0x08040000=.bin을 Flash 에 기록하는 위치..bin은1 KB FW Header + 앱이므로 헤더 시작 주소. - Vector table0x08040400= 앱의 실제 벡터 테이블(초기 SP +Reset_Handler) 위치. 1 KB 헤더 뒤.Vector table 을
0x08040000으로 잘못 두면, 디버거가 FW Header 바이트(AGRBOOT…)를 초기 스택 포인터/리셋 벡터로 잘못 읽어 부팅 직후 HardFault → signal handler(SIGTRAP 등)에 계속 멈춥니다. SDK ZIP 의Extension_Module.launch에는0x08040400이 이미 기본값으로 들어 있습니다.
빌드 & 디버깅¶
- STM32CubeIDE에서 프로젝트 Build (Ctrl+B)
- 빌드가 끝나면 후처리가 자동으로 실행됩니다:
- 메모리 사용량 리포트
- git tag 에서 버전 정보 생성
- 펌웨어 헤더에 크기·CRC 기록
- FTP 업로드용 패키징 바이너리 생성
- Debug (F11) 클릭 → SWD를 통해 0x08040000에 앱 펌웨어 기록
- 디버깅 시작 (브레이크포인트, 변수 감시 등 정상 사용 가능)
참고 —
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 펌웨어 헤더 + 앱 바이너리로 구성됩니다.
업로드 절차¶
- PhAI Studio 접속: studio.onephai.com
- XM10 보드를 USB 케이블로 PC에 연결
- PhAI Studio에서 디바이스 자동 인식 확인
- FW Upload 메뉴 선택
XM10_X_X_X_X.bin파일 선택- Upload 시작
- 진행률 표시 → 완료 후 자동 리부팅
- 부트로더가 새 펌웨어 검증 → 앱 실행
부트로더 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에서 디바이스를 찾지 못합니다"¶
- USB 케이블 연결 확인
- Windows 장치 관리자에서 COM 포트 확인
- 부트로더가 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이 생성되지 않습니다"¶
- Python 3.x 설치 확인:
python --version - 빌드 후처리 단계의 콘솔 출력 확인 (Build Console에 에러 메시지)
- 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 환경 설정¶
빌드 후처리 실행을 위해:
STM32CubeIDE의 Build Console에서 Python 경로가 인식되지 않는 경우: - Windows: 시스템 환경변수 PATH에 Python 경로 추가 - STM32CubeIDE 재시작 필요