STM32의 System memory에는 Embeded bootloader가 공장 초기 상태 때부터 실장 되어있다. 이를 흔히 System bootloader라 칭하기도 한다. 이 bootloader를 이용하면 아래와 같이 ST에서 제공하는 PC 프로그램을 이용해 FW download가 가능하다. (STM32 Flash loader demonstrator)
FLASHER-STM32 - STMicroelectronics
FLASHER-STM32 - STM32 Flash loader demonstrator (UM0462) (replaced by STM32CubeProgrammer), FLASHER-STM32, STMicroelectronics
www.st.com
System memory를 실행하기 위한 두 가지 방법이 있다.
1. H/W 적으로 boot mode를 설정하여 System reset 시 System memory를 실행시키는 방법.
2. H/W 적으로 boot mode를 설정하지 않고 오로지 Software에서만 관련 register를 설정한 후 System memory로 address jump 하는 방법.
이번 문서에서는 2번 방법을 이용한 System memory 실행 방법에 대해 설명하겠다. 설명에 사용되는 MCU는 STM32F446xx를 사용한다.
먼저 ST가 제공하는 AN2606 문서를 확인해보자. STM32 microcontroller system memory boot mode에 관해 자세히 나와있다.
해당 문서의 이 table에 따르면, STM32F446xx는 USART1, USART3, CAN2, DFU(USB device FS), I2C1, I2C2, I2C3, SPI1, SPI2, SPI4를 통해 Embedded bootloader를 사용할 수 있다고 한다. 즉 나열된 통신 방법으로 이 bootloader를 이용하면 FW download가 가능하다는 뜻이다. 그리고, 이 MCU의 Bootloader ID Memory location은 0x1FFF76DE라고 한다.
주의, Bootloader ID Memory location은 STM32 Flash demonstrator가 읽기 위한 'Bootloader ID' 값이 저장된 memory address이다. 우리가 jump 하고자 하는 System memory address가 아니다.
이번에는 System memory의 Memory address를 알아보자.
STM32F446xx의 System memory address는 0x1FFF0000부터 시작한다고 한다. 그러므로 우리가 jump 해야 할 address는 0x1FFF0000이 된다.
이번에는 boot pin 설정과 관련있는 register를 살펴보자. STM32F446xx의 reference 문서인 RM0390을 확인해보면 아래와 같이 SYSCFG_MEMRMP라는 register를 찾을 수 있다.
주의, 각 MCU마다 BOOT pin 관련 register 이름이 다를 수 있으므로 SYSCFG_MEMRMP를 reference 문서에서 찾을 수 없다면, SYSCFG 내에서 같은 역할을 하는 register를 찾아야 한다. (ex, STM32F0: SYSCFG_CFGR1)
설명과 같이 System reset 후 BOOT pin의 상태에 따라 SYSCFG_MEMRMP register의 값이 변경된다. 그 값으로 실행되는 boot mode가 정해진다. 그러므로 우리는 이 register에 우리가 원하는 값을 넣어주고 address jump를 해야 하는 것이다.
주의, System reset을 하게 되면 또 BOOT pin의 상태를 읽어오게 되므로 꼭 address jump를 해야 한다.
이 register의 자세한 설명은 아래와 같다.
이 MEM_MODE 영역에 위에서 보이는 바와 같이 001 값을 넣으면 System memory로 진입을 위한 register 설정이 끝이 난다. 0x0000 0000에 System memory를 remap 하여 사용하겠다는 뜻이다. 아래 table을 보면 이해하기 쉬울 듯하다.
MEM_MODE가 어떻게 설정되느냐에 따라 0x0000 0000~ 0x001F FFFF에 remap 되는 내용이 달라지게 된다.
이제 address jump code를 보자. stm32f4-discovery라는 해외 사이트에서 가져온 code이다. 막상 실행해보니 address jump에 문제가 있어서 조금 수정했다. 원본은 이 문서 맨 마지막에 링크를 걸었으니 참고하기 바란다.
void JumpToBootloader(void) {
void (*SysMemBootJump)(void); //함수 포인터 선언
volatile uint32_t addr = 0x1FFF0000; //System memory address
//RCC Deinit
#if defined(USE_HAL_DRIVER)
HAL_RCC_DeInit();
#endif
#if defined(USE_STDPERIPH_DRIVER)
RCC_DeInit();
#endif
//systick disable //나는 필요치 않은듯하여 주석 처리함
//SysTick->CTRL= 0;
//SysTick->LOAD= 0;
//SysTick->VAL= 0;
//IRQ disable
//__disable_irq(); //이게 있으면 정상적으로 System memory로 jump하지 못하는 경우 있어서 주석 처리함
SYSCFG->MEMRMP = 0x01; //System memory를 0x0000 0000에 remap 하기로 설정
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); //점프하고자 하는 위치 주소 설정
__set_MSP(*(uint32_t *)addr); //main stack pointer 설정
SysMemBootJump(); //함수 포인터를 통해 설정된 위치로 Jump
}
나는 __disable_irq()만 추가하면 정상적으로 jump를 하지 못했다. 차후 이유를 알게 되면 수정하겠다.
JumptoBootloader 함수 원본 코드 출처:
Tutorial - Jump to system memory from software on STM32 - STM32F4 Discovery
One of you are already familiar with STM32 feature of embedded bootloader for software download to flash. This memory is called system memory and is normally accessible with BOOT configuration (either pin hardware or option bytes (later OB) in flash soft
stm32f4-discovery.net
댓글