부트로더: 펌웨어가 스스로 업데이트하는 구조
Flash를 부트로더와 앱으로 나누고, 새 펌웨어를 받아 검증한 뒤 앱으로 점프합니다. 점프 순서와 실패 대비.
메모리 분할 예
| 영역 | 주소 | 크기 |
|---|---|---|
| 부트로더 | 0x0800_0000 | 32KB |
| 앱 | 0x0800_8000 | 나머지 |
| (선택) 새 앱 임시 영역 | 뒤쪽 | 앱과 같은 크기 |
부트로더 흐름
- 리셋 → 부트로더 실행
- 업데이트 요청(버튼, 플래그, 통신 명령)이 있으면 UART/CAN/USB로 새 이미지 수신
- 앱 영역을 지우고 쓰기, CRC나 서명 검증
- 앱이 유효하면 앱으로 점프
앱으로 점프하는 순서
uint32_t sp = *(uint32_t *)APP_ADDR, pc = *(uint32_t *)(APP_ADDR + 4);
__disable_irq();
// 사용한 주변장치와 SysTick 끄기, 펜딩 인터럽트 지우기
SCB->VTOR = APP_ADDR;
__set_MSP(sp);
((void (*)(void))pc)();
앱은 링커 스크립트의 FLASH 시작 주소를 0x0800_8000으로 바꿔 빌드합니다.
실패 대비
- 쓰는 도중 전원이 꺼져도 부트로더는 남아 있어야 합니다. 부트로더 영역은 쓰기 보호합니다.
- 앱 끝에 "유효" 표시를 마지막에 쓰고, 표시가 없으면 부트로더에 머뭅니다.
- 이미지 두 개를 번갈아 쓰는 A/B 방식이면 새 앱이 부팅에 실패할 때 이전 앱으로 되돌릴 수 있습니다.
STM32에는 ROM에 내장된 시스템 부트로더(BOOT0 핀)도 있어서 공장 초기 굽기에 씁니다.