지금까지 분석한 걸 바탕으로 소스코드를 복원한다. 100% 똑같진 않겠지만 동작은 같게.
복원된 main()
#include "stm32f1xx.h"
#include "can_iap.h"
#include "flash.h"
int main(void) {
// 시스템 클럭 설정 (HSE 8MHz * PLL9 = 72MHz)
SystemClock_Config();
// GPIO 초기화
GPIO_Init();
// 부트 조건 체크
if (!Check_BootCondition()) {
if (Validate_App()) {
Jump_To_App();
}
}
// IAP 모드 진입
LED_On(LED_BOOT);
CAN_Init();
// 메인 루프
while (1) {
IAP_Process();
if (g_iap_complete) {
LED_Off(LED_BOOT);
NVIC_SystemReset();
}
}
}
SystemClock_Config
void SystemClock_Config(void) {
// HSE 켜기
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY));
// Flash latency (72MHz면 2 wait state)
FLASH->ACR |= FLASH_ACR_LATENCY_2;
// PLL 설정 (HSE / 1 * 9 = 72MHz)
RCC->CFGR |= RCC_CFGR_PLLSRC; // HSE as PLL source
RCC->CFGR |= RCC_CFGR_PLLMULL9; // x9
// PLL 켜기
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
// 시스템 클럭을 PLL로
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}
GPIO_Init
void GPIO_Init(void) {
// 클럭 활성화
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN;
// PB0, PB1: LED 출력
GPIOB->CRL &= ~0x000000FF;
GPIOB->CRL |= 0x00000022; // Push-pull, 2MHz
// PB2: 버튼 입력 (풀업)
GPIOB->CRL &= ~0x00000F00;
GPIOB->CRL |= 0x00000800; // Input pull-up
GPIOB->ODR |= (1 << 2); // Pull-up enable
}
복원 팁
- 변수명은 추정. 동작만 같으면 됨
- HAL vs 레지스터 직접 접근 중 선택
- 원본이 HAL이었으면 HAL로 복원하는 게 편함
다음 글에서 CAN IAP 모듈 복원.