IAR Embedded Workbench for ARM(이하 EWARM)에서 SWO(Serial Wire Output)를 이용해 지원하는 다양한 C-SPY 디버깅 기능에 대해 살펴보겠습니다.
디버그 프로브는 I-Jet 장비를 이용하여 설명 드리도록 하겠습니다. SWO는 ITM 패킷을 전달하는 1핀의 출력용 시리얼 포트입니다. SWO 기능은 SWD(Serial Wire Debug) 인터페이스와 함께 사용할 수 있으며, Cortex-M3/M4 디바이스에서는 SWO 기능이 지원되나, Cortex-M0/M0+ 디바이스에서는 사용할 수 없습니다.
그림 1은 MIP-20 Connector로 JTAG/SWD 인터페이스를 함께 구성하여 두 종류의 인터페이스를 선택적으로 사용할 수 있는 구조이며 ETM Trace 연결을 위한 핀(TRACECLK, TRACEDATA[])들이 설정되어 있습니다. 만일 trace 장비를 타겟보드와 연결하여 trace 신호를 이용하려면 MIPI-20 connector를 사용해야 합니다.
ARM Cortex-M Trace System에 대한 블럭도를 그림 2에서 보여 주고 있습니다. 중앙 부분의 DWT(Data Watchpoint and Trace)와 ITM(Instrumentation Trace Macrocell)을 볼 수 있습니다.
DWT에서는 4개의 Watchpoints를 지원해 4개까지 데이터 브레이크포인터를 이용할 수 있습니다.
또한 PC Sampler를 제공하여 PC(Program Counter)의 값으로 소스 코드의 위치도 확인이 가능합니다. 그리고 intrrrupt Trace 기능은 인터럽트의 진입과 종료에 대한 자료를 제공하므로 인터럽트에 대한 정보도 파악할 수 있습니다.
또한 ITM에서는 32 채널을 가지고 있으며 Timestamp 에서는 실행 시간의 정보를 제공합니다. 이러한 정보들을 SWO를 통해 C-SPY 디버그 프로그램에서 수집하여 다양한 윈도우들을 통해 정보를 제공합니다.
다음 그림 3은 C-SPY 디버그에서 SWO에 대한 설정 화면입니다. PC Sampling rate, data Log 설정 등의 내용이 보이며, 32개의 ITM 포트 사용 여부를 지정할 수 있습니다. ITM 채널 32개 중 내부적으로 0번 채널은 Terminal I/O용으로 지정되어 있습니다.
그리고 CPU와 SWO 클럭 설정 부분, Power Sampling에 대한 설정항목을 지정할 수 있습니다. I-jet/JTagjet 메뉴(디버그 프로브)에서 SWO Configuration 메뉴를 클릭하면 다음의 SWO 설정 화면이 열립니다.
SWO를 이용한 printf()
Semihosting은 디버거가 타겟 보드과 호스트간의 I/O를 전달하기 위해 브레이크포인트(breakpoint)를 사용하여 CPU의 실행을 멈추고 해당 데이터를 송수신하며 동작하게 됩니다. 이런한 경우에는 당연히 지연 시간이 발생하게 됩니다.
어플리케이션의 stdout/stderr를 ITM stimulus port #0에 할당 할 수 있으며, 이렇게 설정이 되면 printf()문에서 사용되는 문자열을 C-SPY 디버거의 Terminal I/O 윈도우에서 SWO 포트를 통해 표시할 수 있습니다. Semihosting처럼 실행을 멈추고 동작하는 구조가 아니기 때문에 자료를 전달하는데 빠르게 처리됩니다.
그리고 USART 통신 방식과 다르게 동작을 위한 코드가 간단하며 통신 속도도 빨라 어플리케이션이 실행될 때 부하가 매우 적습니다.
C-SPY 디버그 모드에서 View > Terminal I/O를 선택하여 Terminal I/O 윈도우를 엽니다.
어플리케이션에서 printf()문을 사용하면 Terminal I/O 윈도우에 문자열을 표시할 수 있습니다.
Function Profiler
앞에서 살펴본 내용처럼 DWT에서 PC 정보를 수집할 수 있으며 이를 토대로 어느 함수가 실행되었는지를 확인할 수 있습니다. 함수 프로파일러(Function profiler)는 함수 별로 인지된 PC의 횟수와 이에 따른 퍼센트를 확인 할 수 있는 기능으로 함수의 사용 빈도를 파악할 수 있습니다.
실행 속도를 올리기 위해서는 많이 실행되는 함수를 빠른 실행 코드로 생성하거나, 플래시 메모리에서 보다는 RAM에서 실행한다면 도움이 될 수 있습니다.
빠르게 실행하고자하는 함수 바로 앞에 #pragma optimize= no_size_constraints와 같은 명령어를 사용하면 코드 크기는 늘어나지만 빠른 실행 코드를 생성해 줍니다.
Data Log
C-SPY 디버그에서 타임라인(Timeline) 윈도우를 제공하고 있습니다. 다음의 <그림 7>처럼 전역 변수의 값을 가로 축의 시간과 세로의 변수 값을 그래픽화해서 보여 주는 데이터 로그(Data Log) 기능이 있으며 수치화된 정보를 볼 수 있는 데이터 로그 윈도우도 제공됩니다. DWT에서 데이터의 엑세스 상황을 인지하여 트리거를 발생시키며, SWO 포트를 통해 시간 값과 PC 정보 그리고 데이터 엑세스 타입 및 값을 수집합니다.
사용 방법은 커서를 변수에 위치시키고 그 변수에서 마우스 오른쪽 버튼을 클릭한 후 컨텍스트 메뉴에서 Set Data Log Breakpoint for ‘---‘ 를 선택합니다. View > Breakpoints 윈도우에서 설정된 데이터 중단점을 선택 후 마우스 오른쪽 버튼 클릭하여 Edit…항목을 선택하시면 다음 <그림 8>과 같이 Access type, Size 설정이 가능하며 Trigger range 설정도 가능합니다.
Event Log
타겟 어플리케이션에서 호스트 디버거로 ITM포트를 통해 직접적으로 정보를 전달할 수 있습니다. ITM 포트는 32개의 채널을 가지고 있으며 32개 레지스터에 각각의 주소를 가지고 있습니다. 어드레스는 0xE0000000부터 시작합니다.
즉 해당 번지에 값을 입력하면 SWO포트로 해당 채널의 자료가 전송됩니다. C-SPY 디버거의 이벤트 로그에서는 1번부터 4번 채널까지 4개의 채널의 정보를 제공합니다. ITM포트를 사용하기 위해서는 어플리케이션에서 코드를 작성해야 사용할 수 있습니다.
레지스터에 특정 값을 입력하는 동작만이 필요하므로 디버깅에 많은 부하가 발생하지 않습니다. 빠른 동작으로 기능이 수행되므로 코드의 주요 부분에서 정보를 제공한다면 실행 코드의 흐름을 쉽게 파악할 수 있습니다.
I-jet/JTagjet 메뉴에서 Event Log를 클릭하여 윈도우를 열고 Event Log 윈도우에서 커서를 위치시키고 마우스 오른쪽 버튼을 클릭하면 컨텍스트 메뉴에서 Enable을 선택합니다.
또한 I-jet/JTagjet 메뉴에서 Timeline 을 선택하고 Event Log 항목에 커서를 위치 후에 마우스 오른쪽 버튼을 클릭하여 컨텍스트 메뉴에서 Enable을 선택하면 데이터를 확인할 수 있습니다.
Interrupt Log
인터럽트 로그는 인터럽트의 진입과 종료에 대한 정보를 제공합니다. 다시 말해, 인터럽트가 발생된 시점과 인터럽트 처리를 마치고 종료되는 과정을 확인 할 수 있습니다.
역시 인터럽트 로그 윈도우와 타임라인에서 인터럽트 로그 그래프 정보를 확인할 수 있습니다. 디버깅 프로브에 따라 지원 여부가 다르므로 기능 구현이 되지 않는 경우 확인하십시오.
I-jet/JTagjet 메뉴에서 Timeline 을 선택하고 Interrupt Log 항목에 커서를 위치 후에 마우스 오른쪽 버튼을 클릭하여 컨텍스트 메뉴에서 Enable을 선택하면 데이터를 확인할 수 있습니다.
I-jet/JTagjet 메뉴에서 Interrupt Log를 클릭하여 윈도우를 열고 Interrupt Log 윈도우에서 커서를 위치시키고 마우스 오른쪽 버튼을 클릭하면 컨텍스트 메뉴에서 Enable 합니다. 그림 12처럼 인터럽트 정보를 확인할 수 있습니다.
Power Debugging
EWARM에는 타겟의 전력 소비와 소스 코드와의 상관관계를 모니터 할 수 있는 파워 디버(Power Debugging - 소비 전류 디버깅) 이라는 기능이 있습니다. 응용 프로그램이 수행됨에 따라 타겟의 전력 소모를 모니터링 할 수 있고 소스 코드의 수행 별 에너지 소모를 확인 할 수 있습니다.
기능을 구현하는 방법은 PC(Program Counter) 값과 Time 값에 대한 정보를 SWO를 통해 입력 받고 이와 동기되어 전력 소비량 값을 함께 레코드화하여 그래프 표현과 로그 정보를 표시할 수 있습니다.
Timeline 창과 Power Log창에서 기록된 전류 값의 소스코드 위치를 확인하길 원하면 해당 전류 값을 더블클릭 하는 것만으로 해당 소스코드에 접근이 가능합니다.
파워 디버깅 기능으로 특정 이상의 비정상적인 피크성 전류소모를 줄일 수 있고 배터리를 더 오래 사용할 수 있도록 전류의 낭비를 줄일 수 있습니다. 전류 소모에 민감한 제품의 소프트웨어를 개발하는데에 매우 유용한 기능입니다.
SWO Trace
SWO를 통해 실행했던 명령어들을 모니터링한다면, Trace 장비처럼 정밀하지는 못하지만 간이적인 트레이스(trace) 기능을 구현할 수 있습니다. 다음의 그림 14처럼 SWO Trace 기능으로 실행되었던 명령들을 확인할 수 있어 실행 흐름을 파악하는데 도움이 됩니다.
I-jet/JTagjet 메뉴에서 SWO Trace를 선택하여 윈도우를 열고 마우스 오른쪽 버튼을 클릭 후 Enable 선택 또는 좌측의 전원 버튼을 클릭하여 활성화 시킵니다. 어플리케이션을 실행시키고 멈추게되면 SWO Trace 정보를 확인 할 수 있습니다.
맺음말
SWO를 이용한 C-SPY 디버그 기능에 대해 살펴 보았습니다. SWO의 기능들을 잘 활용하면 보다 쉽고 빠르게 잘못된 코드를 찾을 수 있습니다. 일반적으로 사용하는 시리얼 포트 방식보다 빠른 통신 속도와 처리를 위한 실행 코드가 짧아 빠르게 디버깅 정보를 수집할 수 있습니다. 감사합니다.
고성용 이사 / IAR 시스템즈
Sung-Yong.Ko@iar.com
그래도 삭제하시겠습니까?