부트로더 애플리케이션 분리

By | 2026년 1월 4일
Table of Contents

부트로더 애플리케이션 분리

STM32H563ZI와 같은 고성능 MCU에서 부트로더(Bootloader)와 사용자 애플리케이션(Application)을 분리하는 것은 펌웨어 업데이트(OTA)나 시스템 복구 기능을 위해 매우 중요합니다.

이 과정의 핵심은 "메모리 영역을 나누고, 애플리케이션의 시작 위치를 재설정하는 것"입니다.


1. 메모리 맵 설계 (Memory Partitioning)

가장 먼저 Flash 메모리(총 2MB)를 어떻게 나눌지 결정해야 합니다.

  • Bootloader 영역: 0x0800 0000부터 시작 (예: 128KB 할당)
  • Application 영역: 부트로더 바로 다음 주소부터 시작 (예: 0x0802 0000)
영역 시작 주소 (From) 끝 주소 (To) 설명
Bootloader 0x0800 0000 0x0801 FFFF 리셋 시 자동 실행
Application 0x0802 0000 0x081F FFFF 부트로더가 점프하는 위치

2. 프로젝트 설정 변경 (Application 측)

애플리케이션 프로젝트는 자신이 0x0802 0000에서 실행될 것이라는 점을 알고 있어야 합니다.

① 링커 스크립트(.ld 파일) 수정

프로젝트 내의 STM32H563ZITX_FLASH.ld 파일을 열어 MEMORY 섹션을 수정합니다.

/* 수정 전 */
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 2048K

/* 수정 후 (부트로더에 128KB를 준 경우) */
FLASH (rx)      : ORIGIN = 0x08020000, LENGTH = 1920K /* 2048 - 128 = 1920 */

② 벡터 테이블 오프셋 설정 (VectTab Offset)

애플리케이션이 시작될 때 인터럽트 벡터 테이블의 위치를 알려줘야 합니다.

  • Core/Src/system_stm32h5xx.c 파일에서 #define VECT_TAB_OFFSET 값을 찾습니다.
  • 값을 0x00020000U (부트로더 크기만큼의 오프셋)로 수정합니다.

3. 부트로더에서 애플리케이션으로 점프 (Jump Code)

부트로더의 역할이 끝나면 애플리케이션의 시작 지점으로 제어권을 넘겨줘야 합니다.

핵심 로직:

  1. 애플리케이션 영역의 스택 포인터(MSP) 주소를 읽어와 설정합니다.
  2. 애플리케이션의 리셋 핸들러(Reset Handler) 주소로 점프합니다.
typedef void (*pFunction)(void);

void Jump_To_Application(void) {
    uint32_t JumpAddress = *(__IO uint32_t*)(0x08020000 + 4);
    pFunction JumpToApp = (pFunction)JumpAddress;

    // 1. 모든 인터럽트 비활성화
    __disable_irq();

    // 2. MSP (Main Stack Pointer) 설정
    __set_MSP(*(__IO uint32_t*)0x08020000);

    // 3. 점프
    JumpToApp();
}

4. 주의사항 (중요!)

  • Peripheral Reset: 부트로더에서 사용했던 타이머나 UART 등의 주변장치는 점프하기 전에 반드시 DeInit 하거나 초기화 상태로 돌려놓아야 애플리케이션에서 충돌이 나지 않습니다.
  • H5 시리즈의 특성: STM32H5 시리즈는 TrustZoneICACHE 기능이 있으므로, 보안 설정이나 캐시 설정이 점프 후에 영향을 미치지 않도록 주의해야 합니다.

다음으로 어떤 작업을 해볼까요?

  • 부트로더에서 UART를 통해 새 펌웨어를 전송받는 방법을 알아볼까요?
  • 아니면 STM32H5의 특화 기능인 Secure Boot(SBSFU)를 사용하는 법을 확인해 볼까요?

답글 남기기