부트로더 개발하면서 만난 문제들 정리.


앱으로 점프 안 됨

증상

jump_to_app() 호출 후 HardFault.

원인 1: VTOR 설정 안 함

// 빠뜨림
SCB->VTOR = APP_ADDR;

원인 2: 앱 시작 주소 틀림

링커 스크립트와 부트로더의 APP_ADDR 불일치.

원인 3: Thumb 비트

Reset Handler 주소에 & ~1 하면 안 됨.


Flash 쓰기 안 됨

증상

flash_program_halfword() 실패.

원인 1: Unlock 안 함

flash_unlock();  // 빠뜨림

원인 2: 이미 값 있음

지우지 않고 쓰기 시도.

// 쓰기 전 삭제 필수
flash_erase_page(addr);

원인 3: 쓰기 보호

Option Bytes 확인.


CAN 메시지 안 옴

증상

can_receive() 타임아웃.

원인 1: 필터 설정

// 모든 메시지 받기
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;

원인 2: Bitrate 불일치

양쪽 500kbps인지 확인.

원인 3: 터미네이션

CAN 버스 양 끝에 120Ω 저항.


업로드 중간에 멈춤

증상

몇 페이지 전송 후 응답 없음.

원인 1: PC 너무 빠름

time.sleep(0.001)  # 패킷 사이 딜레이

원인 2: BMS 처리 못 따라감

Flash 쓰기 중 다음 패킷 와서 놓침.

원인 3: CAN 버퍼 오버플로우

FIFO 빨리 비워야 함.


CRC 불일치

증상

PAGE_END 후 CRC 에러.

원인 1: 엔디안

// Little endian으로 맞추기
uint32_t crc = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

원인 2: 다항식 다름

STM32 내장 CRC vs IEEE CRC32 다름.

원인 3: 초기값

iap.crc = 0xFFFFFFFF;  // 초기값 확인

리셋 후 앱 실행 안 됨

증상

업로드 성공, 리셋하면 부트로더로 감.

원인 1: 앱 유효성 검사 실패

// SP, Reset Handler 주소 확인
printf("SP: 0x%08X\n", *(uint32_t*)APP_ADDR);
printf("Reset: 0x%08X\n", *(uint32_t*)(APP_ADDR+4));

원인 2: Buffer → App 복사 안 함

수신만 하고 복사 안 했을 때.

원인 3: 부트 조건에 걸림

GPIO 핀 상태, RAM 플래그 확인.


업로드 후 앱 이상 동작

증상

앱 실행되는데 기능 이상.

원인 1: 인터럽트 정리 안 함

// 점프 전 정리
__disable_irq();
SysTick->CTRL = 0;
for (int i = 0; i < 8; i++) {
    NVIC->ICER[i] = 0xFFFFFFFF;
    NVIC->ICPR[i] = 0xFFFFFFFF;
}

원인 2: 주변장치 상태

부트로더에서 쓴 주변장치 DeInit 필요할 수 있음.


디버깅 체크리스트

확인 항목방법
APP_ADDR 일치링커 스크립트 vs 부트로더 매크로
Flash 내용ST-Link로 메모리 뷰
CAN 통신PCAN-View 스니핑
VTOR 값디버거로 SCB->VTOR 확인
SP 값APP_ADDR 첫 4바이트
Reset HandlerAPP_ADDR+4 값

시리즈 끝

20개 글에 걸쳐 STM32 CAN 부트로더 개발 과정을 정리했다.

요약:

  • 메모리 맵과 링커 스크립트
  • 앱 유효성 검사, VTOR, 점프
  • Flash Unlock/Erase/Program
  • CAN IAP 프로토콜과 상태 머신
  • Python 업로더
  • 보안과 트러블슈팅

Ghidra 시리즈가 “역분석"이었다면, 이 시리즈는 “처음부터 만들기”.


#1 - 왜 커스텀 부트로더인가로 돌아가기