그라운드 임베디드 유튜브 구독

노트 / 기계어와 어셈블리

하드폴트 분석: 어느 줄에서 죽었나

하드폴트가 나면 스택에 저장된 PC와 LR, 그리고 폴트 상태 레지스터로 원인과 위치를 찾습니다.

GROUND EMBEDDED · 정리 노트기계어 08하드폴트 분석 1void HardFault_Handler(void) { 2 __asm volatile ("tst lr, #4\n ite e… 3} 4void hf_c(uint32_t *sp) {

흔한 원인

  • 널 포인터나 해제된 메모리 접근
  • 클럭을 켜지 않은 주변장치 레지스터 접근
  • 스택 넘침
  • 정렬되지 않은 접근, 0으로 나누기(설정에 따라)
  • 잘못된 함수 포인터 호출 (Thumb 비트가 0인 주소)

찾는 방법

예외에 들어갈 때 CPU가 스택에 r0~r3, r12, lr, pc, xPSR을 저장합니다. 저장된 pc가 문제를 일으킨 명령어 주소입니다.

void HardFault_Handler(void) {
    __asm volatile ("tst lr, #4\n ite eq\n mrseq r0, msp\n mrsne r0, psp\n b hf_c");
}
void hf_c(uint32_t *sp) {
    volatile uint32_t pc = sp[6], lr = sp[5];
    volatile uint32_t cfsr = SCB->CFSR, bfar = SCB->BFAR;
    while (1);   // 디버거로 pc, lr, cfsr 확인
}

폴트 레지스터

레지스터 알려 주는 것
CFSR 폴트 종류 (버스 / 메모리 / 사용 오류의 세부 비트)
BFAR 버스 오류를 낸 데이터 주소
MMFAR 메모리 관리 오류 주소

pc 주소를 맵 파일이나 addr2line -e firmware.elf 0x080012AC로 소스 줄로 바꾸면 위치가 나옵니다. 현장 제품에서는 이 값들을 .noinit RAM이나 Flash에 기록해 두었다가 재부팅 후 읽어 오면 재현이 어려운 고장도 추적할 수 있습니다.