Cortex-M에서 하드폴트(HardFault) 디버깅
기술노트 23721
아키텍처:
ARM
컴포넌트:
debugger
업데이트:
2021-05-18 오전 10:36
소개
본 기술 노트에서 IAR Embedded Workbench for ARM을 활용하여 HardFault 에러들을 디버깅할 수 있는 방법에 대해 설명합니다.
HardFault 용어정의
하드폴트(HardFault)란 예외 처리 메커니즘으로 처리할 수 없는 모든 경우의 결함(faults)을 말한다. 일반적으로 하드폴트는 복구할 수 없는 시스템 오류이다.
논의
아래 예시들을 통해 다양한 오류 시나리오들을 살펴본다.
예시 1: 오버클럭된 칩(Overclocked chip)
Cortex-M3 board의 CPU을 매우 빠른 주파수 클럭으로 설정한 경우입니다. 이는 특정 코드 위치가 아닌 무작위 위치에서 발생하게 된다.
Call Stack 창에서 하드폴트가 발생했을 때 실행된 코드 라인을 확인할 수 있습니다.
Register 창에서 NVIC:CFSR
(Configurable Fault Status Register)가 부정확한 데이터 접근 오류가 발생했음을 보여준다. (BusFault Status Register, BFSR
). IMPRECISERR = 1
는 부정확한 데이터 접근 오류가 발생했음을 의미한다.
오류의 원인이 부정확하기 때문에 문제가 되는 데이터 액세스의 주소를 볼 수 없다. 이 경우에는 CPU를 잘못 실행하는 것과 관련이 있기 때문에, 문제의 실제 원인을 찾기가 매우 어렵다. 다음 캡처화면을 참조하시기 바랍니다.
예시 2: 분모가 0인 나누기 연산(Division by Zero)
CCR
레지스터에 있는 DIV_0_TRP
비트를 활성화해 ‘분모가 0인 나누기 연산’의 원인으로 하드폴트 오류가 발생했을 경우를 확인하는 방법을 보여준다. Call Stack창에서 잘못된 나누기 연산이 발생한 소스 코드 줄을 볼 수 있다. Register 창을 보면 NVIC:CFSR
플래그DIVBYZERO
가 1로 설정돼 있는 것을 볼 수 있다. 다음 캡처화면을 참조하시기 바랍니다.
예시 3: 잘못된 주소 접근(Accessing an invalid address)
잘못된 메모리에 액세스하는 경우 하드폴트가 발생한다. Call Stack창에서 잘못된 액세스가 어디에서 이뤄졌는지 확인할 수 있다. Register 창에서 NVIC:CFSR
플래그는 PRECISERR
를 표시한다. 정확한 데이터 액세스 오류가 발생했으며 프로세서가 잘못된 주소를 BFAR
레지스터에 기록한다. 다음 캡처화면을 참조하시기 바랍니다.
예시 4: 코드가 없는 위치로의 분기(Branch to an address where no code is located)
잘못된 함수 포인터를 호출하면 하드폴트 오류가 발생한다. Register 창에 NVIC:CFSR
플래그가 ‘UNDEFINSTR = 1
’과 같이 표시돼 있다. 프로세서가 정의되지 않은 명령을 실행하려고 시도한 경우다.
Call Stack 창에서 잘못된 명령어가 어디서 호출되었는지 다음과 같은 방법으로 확인할 수 있다:
- 잘못된 명령어에 대해 중단점(Breakpoint)를 설정하고 응용 프로그램을 다시 실행한다. 중단점에 도달하면 Call Stack창을 사용해 호출한 함수를 찾는다.
- Register 창에서
CPU:LR
레지스터를 확인해 이전에 호출이 있었던 위치를 찾는다. 디스어셈블리(Disassembly) 창에서LR
레지스터 주소로 이동한다. 그 곳이 바로 호출한 위치다. 다음 캡처화면을 참조하시기 바랍니다.
디버깅 도구
응용프로그램에서 발생한 하드폴트 오류의 유형을 정확하게 파악하기 위해, 최신 버전의 IAR Embedded Workbench for Arm에는 View > Fault exception viewer 창이 있습니다.
기존 버전에는 다음의 설치 디렉토리에 위치한 디버거 매크로가 있습니다:
arm\config\debugger\ARM\vector_catch.mac
참고
참고 1
Register 창의 정보는 사용 중인 코어텍스-M 유형에 따라 위의 스크린샷 예제와 다르게 보일 수 있다. 또한, 코어텍스-M0에는 다른 코어텍스-M과 같이 사용할 수 있는 모든 결함 상태 레지스터가 없다.
참고 2
폴트 핸들러에 복잡한 코드가 있는 경우, 핸들러가 실행될 때 레지스터나 버퍼가 중요한 정보를 잃지 않도록 핸들러의 중단점(Breakpoint)을 가능한 초기에 설정하는 것이 좋다. 중단점을 초기에 설정해 폴트 핸들러가 호출될 때 즉시 멈추도록 만든다.
참고 3
위의 정보들은 하드폴트를 디버깅하기 위해 트레이스(Trace) 장비를 사용하지 않는다. 당사 홈페이지의 Resources 섹션을 참고하시기 바랍니다.
맺음말
여러가지 방법으로 하드폴트를 디버깅하거나 윈도우즈 사용자는 IAR Embedded Workbench for Arm을 사용하여 디버깅합니다. 하드폴트의 원인을 더 쉽게 찾기 위해서 Fault exception viewer와 디버깅 매크로 파일을 제공하고 있습니다. 더많은 정보를 위해 Arm's Cortex-M3 Devices Generic User Guide 의 Fault types 챕터를 살펴보시기 바랍니다.
모든 제품 이름은 해당 소유자의 상표 또는 등록 상표입니다.