부트로더가 매번 실행되면 안 된다. 특정 조건에서만 IAP 모드로 진입해야 한다.

Reset_Handler 이후 main() 초반부를 보자.


진입 조건 체크

void main(void) {
    // 클럭, GPIO 초기화
    RCC_Init();
    GPIO_Init();
    
    // 부트 진입 조건 체크
    if (Check_BootCondition() == 0) {
        // 조건 불충족 → 앱으로 점프
        Jump_To_App();
    }
    
    // IAP 모드 진입
    CAN_Init();
    IAP_Main();
}

Check_BootCondition() 함수를 찾아보자.


조건 1: GPIO 체크

uint8_t Check_BootCondition(void) {
    // PB2 버튼 체크 (Active Low)
    if ((*(uint32_t *)0x40010C08 & 0x04) == 0) {
        return 1;  // 버튼 눌림 → 부트 모드
    }

0x40010C08은 GPIOB_IDR. PB2가 눌려있으면 부트 모드.


조건 2: 매직 플래그

    // RAM 매직 값 체크
    if (*(uint32_t *)0x20000000 == 0xDEADBEEF) {
        *(uint32_t *)0x20000000 = 0;  // 클리어
        return 1;  // 매직 값 → 부트 모드
    }

앱에서 부트로더로 진입하고 싶을 때 RAM에 0xDEADBEEF 쓰고 리셋하면 된다.


조건 3: 앱 유효성

    // 앱 영역 Stack Pointer 검증
    uint32_t app_sp = *(uint32_t *)0x08042800;
    if ((app_sp < 0x20000000) || (app_sp > 0x20010000)) {
        return 1;  // 유효하지 않음 → 부트 모드
    }
    
    return 0;  // 모든 조건 불충족 → 앱 실행
}

앱 시작 주소의 첫 4바이트(Stack Pointer)가 RAM 범위인지 확인한다. Flash가 비어있으면 0xFFFFFFFF라서 부트 모드로 들어간다.


정리

조건결과
PB2 버튼LOW부트 모드
RAM 매직0xDEADBEEF부트 모드
앱 SPRAM 범위 밖부트 모드
위 모두 아님-앱 실행

다음 글에서 앱 유효성 검사 상세 분석.

#20 - 앱 유효성 검사