Embedded Vol.184 - Technical Report

[테크월드=정환용 기자] 하드폴트(HardFault)란 일반적인 예외 처리 메커니즘으로 처리할 수 없는 모든 경우의 결함을 말한다. 일반적으로 하드폴트는 복구할 수 없는 시스템 오류다. 하드폴트는 다양한 원인에 의해 발생할 수 있고, 하드폴트 오류가 발생한 경우 명확한 원인 분석과 문제 해결이 쉽지 않다. 이렇게 다양한 하드폴트 오류를 살펴보고 IAR 임베디드 워크벤치(Embedded Workbench)를 활용해 하드폴트 오류를 수정할 수 있는 방법을 알아보자.

 

예제 1. CPU 오버클럭
코어텍스 M3(Cortex-M3) 코어 보드를 매우 빠른 주파수의 클럭으로 설정한 경우 하드폴트가 발생할 수 있다. 이런 경우에는 특정 코드위치가 아닌 무작위 위치에서 발생하게 된다. 스택 호출(CallStack) 창에서 하드폴트가 발생했을 때 실행된 코드 줄을 확인할 수 있다. 또한, 레지스터(Register) 창에서 NVIC : CFSR(Configurable Fault Status Register)가 데이터 액세스 오류가 발생했음을 보여준다. (BusFaultStatusRegister, BFSR) IMPRECISER=1는 부정확한 데이터 액세스 오류가 발생했음을 의미한다.

오류의 원인이 부정확하기 때문에 문제가 되는 데이터 액세스의 주소를 볼 수 없다. 이 경우에는 CPU를 잘못 실행하는 것과 관련이 있기 때문에, 문제의 실제 원인을 찾기가 매우 어렵다. [그림 1]을 참조하자.

[그림 1]

 

예제 2. 분모가 0인 나누기 연산
CCCR 레지스터에 있는 DIV_0_TRP 비트를 활성화해 ‘분모가 0인 나누기 연산’의 원인으로 하드폴트 오류가 발생했을 경우를 확인하는 방법을 보여준다. CallStack 창에서 잘못된 나누기 연산이 발생한 소스 코드 줄을 볼 수 있다. Resister 창을 보면 NVIC:CFSR 플래그DIVBYZERO가 1로 설정돼 있는 것을 볼 수 있다. [그림 2]를 참조하자.

[그림 2]

잘못된 메모리에 액세스하는 경우 하드폴트가 발생한다. CallStack 창에서 잘못된 액세스가 어디에서 이뤄졌는지 확인할 수 있다. Resister 창에서 NVIC:CFSR 플래그는 PRECISERR를 표시한다. 정확한 데이터 액세스 오류가 발생했으며 프로세서가 잘못된 주소를 BFAR 레지스터에 기록한다. [그림 3], [그림 4]를 참조하자.

[그림 3]
[그림 4]

 

예제 4. 코드가 없는 위치로 분기
잘못된 함수 포인터를 호출하면 하드폴트 오류가 발생한다. Register 창에 NVIC:CFSR 플래그가 ‘UNDEFINSTR =1’과 같이 표시돼 있다. 프로세서가 정의되지 않은 명령을 실행하려고 시도한 경우다.

CallStack 창에서는 잘못된 명령어가 어디서 왔는지 다음과 같은 방법으로 확인할 수 있다.
▲잘못된 명령어에 대해 브레이크포인트(Breakpoint)를 설정하고 응용 프로그램을 다시 실핸한다. Breakpoint에 도달하면 CallStack 창을 사용해 호출한 함수를 찾는다.
▲Register 창에서 CPU : LR 레지스터를 확인해 이전에 호출이 있었던 위치를 찾는다. 디스어셈블리(Disassembly) 창에서 LR 레지스터 주소로 이동한다. 그 곳이 바로 호출한 위치다. [그림 5], [그림 6], [그림 7]을 확인하자.

[그림 5]
[그림 6]
[그림 7]

 

매크로를 활용한 디버깅
응용 프로그램에 발생한 하드폴트 오류의 유형을 정확하게 파악하기 위해, 최근 버전의 IAR 임베디드 워크벤치에 사용할 수 있는 디버거 매크로가 있다. 매크로 파일은 다음과 같은 설치 디렉토리에 위치한다.

armconfigdebuggerARMvector_catch.mac

매크로를 불러오기 위해 ‘View > Macros > Macro Registration’을 선택한다. 하드폴트가 발생하면 매크로가 디버깅 로그 창에서 원인 파악을 위한 유용한 정보를 출력한다. [그림 8]을 참조하자.

 

오류 예외 뷰어(Fault Exception Viewer) 창
Fault E xception Viewer창은 ‘View→FaultExceptionViewer’를 선택해 사용할 수 있다. 하드폴트를 포함한 다양한 폴트 예외가 발생하면, 실행을 멈추고 Fault Exception Viewer 창이 자동으로 열린다. 코어텍스-M 디바이스를 사용하는 경우만 Fault Exception Viewer가 활성화되며, 폴트의 대략적인 설명이 출력되기 때문에 폴트의 원인파악과 문제 해결에 도움이 될 수 있다.

 

참고 사항
▲Register 창의 정보는 사용 중인 코어텍스-M 유형에 따라 위의 스크린샷 예제와 다르게 보일 수 있다. 또한, 코어텍스-M0에는 다른 코어텍스-M과 같이 사용할 수 있는 모든 결함 상태 레지스터가 없다.
▲폴트 핸들러에 복잡한 코드가 있는 경우, 핸들러가 실행될 때 레지스터나 버퍼가 중요한 정보를 잃지 않도록 핸들러의 브레이크포인트(Breakpoint)를 가능한 초기에 설정하는 것이 좋다. 브레이크포인트를 초기에 설정해 폴트 핸들러가 호출될 때 즉시 멈추도록 만든다.
▲위의 정보들은 하드폴트를 디버깅하기 위해 트레이스(Trace) 장비를 사용하지 않는다. 하지만 트레이스 장비를 사용하면 좀 더 원활하게 하드폴트 오류의 원인을 찾고 디버깅할 수 있다.

[그림 8]
[그림 9]

 

맺음말
하드폴트가 발생하면 명확한 원인을 찾아 해결하는데 매우 긴 시간이 필요할 수 있다. 가능한 문제 해결 시간을 최소화하기 위해 여러 디버깅 도구를 사용해야 한다. ‘IAR Embedded Workbench for ARM’에서 여러 방법과 디버깅 창을 사용하여 문제 해결이 어려운 하드폴트를 디버깅하는 데 많은 도움을 얻을 수 있다.

만일 트레이스 기능의 디버깅 장비를 사용하는 경우, 폴트 발생 이전의 코드수행 이력의 검토로 이 방법보다 쉽게 원인을 찾아 해결할 수 있을 것이다. 하지만 트레이스 장비가 없는 경우 디버깅 매크로 ‘vector_catch.mac’와 Fault exception viewer 창을 디버깅 중 활용하면 하드폴트의 원인과 해결에 큰 도움이 될 수 있다.

 

작성: IAR 시스템즈 이현도 과장 Hyun-Do.Lee@iar.com

이 기사를 공유합니다
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지