펌웨어 업로드 후 앱이 정상인지 확인해야 한다. 깨진 펌웨어로 점프하면 HardFault다.
Stack Pointer 검증
가장 기본적인 체크:
uint8_t Validate_App(void) {
uint32_t app_sp = *(uint32_t *)APP_START_ADDR;
// SP가 RAM 범위인지
if (app_sp < 0x20000000 || app_sp > 0x20010000) {
return 0; // 유효하지 않음
}
Vector Table 첫 번째 엔트리는 Initial Stack Pointer다. RAM 범위(0x20000000 ~ 0x2000FFFF)가 아니면 펌웨어가 없거나 깨진 거다.
Reset Handler 검증
uint32_t app_reset = *(uint32_t *)(APP_START_ADDR + 4);
// Reset Handler가 Flash 범위인지
if (app_reset < APP_START_ADDR || app_reset > 0x08080000) {
return 0;
}
// Thumb 비트 체크
if ((app_reset & 0x01) == 0) {
return 0; // ARM 모드면 안 됨
}
두 번째 엔트리는 Reset_Handler 주소. 앱 영역 내에 있어야 하고, Cortex-M은 Thumb 모드라서 LSB가 1이어야 한다.
CRC 검증
// 앱 CRC 계산
uint32_t calc_crc = CRC32_Calc(APP_START_ADDR, g_app_size);
uint32_t stored_crc = *(uint32_t *)(APP_START_ADDR + g_app_size);
if (calc_crc != stored_crc) {
return 0;
}
return 1; // 유효함
}
업로드할 때 저장해둔 CRC와 비교한다. STM32 하드웨어 CRC 사용.
검증 순서
1. SP 범위 체크 → 빠름, 기본
2. Reset 주소 체크 → 빠름, 기본
3. CRC 계산 → 느림, 정확
SP랑 Reset 주소만 봐도 빈 Flash(0xFFFFFFFF)는 걸러진다. CRC는 무결성까지 확인.
다음 글에서 앱으로 점프하는 코드 분석.