이 글은 디버깅의 기본 개념에 대해 소개하고 Nexus 및 ARM CoreSight 표준을 예로 들어 시스템 온 칩(SoC)에서의 구현(디버그 아키텍처라고 함)에 대해 설명한다. 하드웨어 연계 시스템을 SoC 안에 구현하는 것은 개발자의 소프트웨어 디버깅을 돕기 위한 것이며, 일반적으로 SoC의 디버그 아키텍처로 알려져 있다. 디버그 아키텍처를 자세히 살펴보기 전에 디버깅의 요구사항에 대해 먼저 알아 본다.

글: Biswaprakash Navajeevan / 시니어 디자인 엔지니어
프리스케일 반도체 / www.freescale.com

디버깅 기초

시스템 온 칩(SoC)이 점점 더 복잡해짐에 따라, 하드웨어의 발전을 완전히 활용하기 위해 소프트웨어도 더욱 복잡해지고 있으며 개발자들에게는 소프트웨어 디버깅이 점점 더 어려운 과제가 되어 가고 있다. 하드웨어 연계 시스템을 SoC 안에 구현하는 것은 개발자의 소프트웨어 디버깅을 돕기 위한 것이며, 일반적으로 SoC의 디버그 아키텍처로 알려져 있다. 디버그 아키텍처를 자세히 살펴보기 전에 디버깅의 요구사항에 대해 먼저 알아 본다.

디버깅의 요구사항은 대체로 다음과 같이 설명할 수 있다.
-시스템 레지스터 및 프로세서 상태를 보고 코드 실행 흐름에서 수정할 수 있어야 함
-필요에 따라 프로세스를 중단하고 실행할 수 있어야 함
-소프트웨어를 디버그 및 조정하여 성능을 향상할 수 있도록 SoC에서 실행되는 다양한 소프트웨어 스레드의 정보를 확인할 수 있어야 함. 특정 런타임 이벤트 발생 시 해당 정보의 수집을 트리거링해야 함.
-디버그 리소스를 사용하여 무단 액세스로부터 시스템을 보호해야 함
-시스템의 다양한 저전력 모드에서 디버그할 수 있어야 함

시스템의 다양한 상태와 매개 변수에 액세스하기 위해 프로세서를 중단하는 것을 고정/중단 모드 디버깅이라고 하며, 정상 코드 실행 흐름을 방해하지 않고 시스템에 액세스하는 것을 동적/모니터 모드 디버깅이라고 한다. 동적/모니터 모드 디버깅에서는 디버그 이벤트가 발생할 때 모니터 프로그램이 실행되는 것이 일반적이다. 그런 다음 이 프로그램은 외부 디버거와 통신하여 시스템을 정지하지 않고 요청된 액세스를 실행한다. 이 디버깅 모드는 하드 드라이브 컨트롤러의 서보 메커니즘, 엔진 컨트롤러와 같은 실시간 시스템에서 유용하다.

실행 중인 스레드와 관련 프로그램 및/또는 데이터 흐름에 대한 정보를 얻는 것을 트레이싱이이라고 한다. 이 디버깅 모드에서는 데이터가 디버깅 인터페이스로 출력되지 않고 전용 병렬 인터페이스로 출력된다.

기존에는 소프트웨어 프로그램을 주로 회로 안의 에뮬레이터(ICE) 및 정확한 사이클의 시스템 소프트웨어 모델을 사용하여 디버그하였다. ICE 디버깅 모드에서는 디버그할 구성 요소(일반적으로 프로세서)를 에뮬레이터 구성 요소로 대체하여 구성 요소의 다양한 상태 및 레지스터에 액세스하는 동시에 대체한 구성 요소의 작업을 수행하는 것이 가능했다. 이 방식이 빠르고 효율적이기는 했지만 ICE 모듈로 인해 비용 부담이 매우 컸다. 정확한 사이클의 소프트웨어 모델은 비용 효율적이긴 하지만 ICE에 비해 느렸으며, 시스템의 복잡성이 증가함에 따라 이러한 모델을 개발하려는 노력이 크게 증가하였다. 두 방법의 제약을 극복하기 위해 전용 하드웨어 연계 시스템/디버그 아키텍처를 완전한 시스템의 일부로 개발하기 위한 다양한 표준(예: Nexus, CoreSight)이 만들어졌으며, 이로써 복잡한 소프트웨어를 쉽게 디버그하고 큰 관련 비용 없이 ICE 성능을 이용할 수 있게 되었다.

디버그 아키텍처

SoC의 디버그 아키텍처 구성 요소는 다음과 같은 범주로 분류할 수 있다.

1. 디버그 인터페이스
2. 디버그를 지원하는 하드웨어 연계 시스템
3. 트레이스 메커니즘

디버그 인터페이스

디버그 인터페이스는 PC에서 실행되는 디버그 모니터가 SoC의 내부 상태를 보고 또는 수정하는 데 사용하는 포트이다. 이 인터페이스는 디버그 명령을 수신하고 필요한 응답을 전송하는 표준 통신 프로토콜에 구축된다. 일반적으로 사용되는 두 가지 디버깅 프로토콜 표준은 다음과 같다.

BDM(Background Debug Mode)
JTAG(Joint Test Action Group)

BDM(Backgroudn Debug Mode)에는 백그라운드 디버그 컨트롤러와 단권 양방향 디버그 인터페이스가 있다. 외부 인터페이스 핀은 Pull Up의 Pseudo Open Drain이며 통신은 비동기식이다. 이 프로토콜은 경계 스캔을 제외한 거의 모든 디버깅 기능(예: 중지, 실행, 읽기/쓰기 메모리, 트레이스 등)을 제공한다. 이 프로토콜은 일반적으로 핀 수가 제한적인 작은 칩에 사용된다. ARM은 이와 유사한 방식으로 외부 디버거가 2선 인터페이스를 통해 시스템과 통신하는 시리얼 와이어 디버깅(Serial Wire Debugging)이라는 프로토콜을 사용한다.

JTAG(Joint Test Action Group) 표준은 원래 PCB 제조 테스트(예: 트랙의 연속성, 납땜 연결의 연결)를 위해 개발되었으며, 여기에서 경계 Bed-of-Nails 테스트를 사용하여 테스트할 수 없는 다양한 온보드 구성 요소(특히 표면 장착 구성 요소)를 테스트하는 데 스캔 아키텍처가 사용된다.

JTAG 인터페이스는 일반적으로 클록, 데이터 인, 데이터 아웃 및 모드 선택 핀으로 구성되어 있다. JTAG 프로토콜은 IC 핀 상태(EXTEST)와 코어 로직 입력 및 출력(INTEST)을 제어하는 명령을 동기 보유한다. 이러한 JTAG 명령을 확장하여 SoC의 다양한 모듈에 액세스함으로써 ICE 대신 JTAG 표준이 사용되었다. JTAG TAP(Test Access Port)를 적절히 수정하여 확장된 명령을 수용하면 SoC의 다양한 내부 노드에 액세스할 수 있다.

디버그를 지원하는 하드웨어 연계 시스템

디버깅을 위한 하드웨어 연계 시스템의 주 목적은 SoC의 성능에 영향을 미치지 않고 디버깅의 모든 요구 사항을 충족하는 것이다. 디버깅의 가장 일반적인 방법 중 하나는 프로세서를 정지하거나 코드 실행 또는 메모리 액세스 중 특정 지점에서 시스템 상태를 가져오는 것이다. 이러한 요구사항은 중단점(Breakpoint) 또는 감시점(Watchpoint)으로 실현된다. 중단점에 부딪힐 때마다 코드 실행이 정지한다. 중단점은 일반적으로 RAM에서 소프트웨어를 실행할 때 사용한다. PC에서 실행되는 디버그 소프트웨어에 중단점을 배치하면 중단점이 있는 코드의 메모리 위치에 디버거가 명령을 삽입한다. 이 경우 삽입된 코드를 실행하면 프로세서가 정지한다.

반대로, 감시점은 특정 메모리 위치에 대한 액세스가 발생할 때 프로세서 실행을 정지하지 않는다. 프로세서가 감시점에 부딪히면 보통은 트레이스 메시지가 발생하거나 해당 포인트의 시스템 상태가 디버그 소프트웨어에 나타난다. 감시점은 감시점 레지스터의 형태로 SoC에 지원되며, 감시점이 발생해야 하는 위치에서 어드레스, 제어 및 데이터 신호 값으로 프로그래밍된다. 비교 및 마스크 회로는 신호의 현재 값을 감시점 레지스터에 프로그래밍된 값과 비교하고 일치할 경우 출력을 생성하여 감시점이 발생했음을 나타낸다. 감시점은 ROM에서 코드를 실행할 때 중단점의 역할을 하도록 프로그래밍할 수 있다. 디버그 아키텍처의 감시점 레지스터는 제한되어 있으므로 ROM에 로드된 코드를 디버깅할 경우 단 몇 개(보통 2~3개)의 중단점만 실현할 수 있다.

하드웨어 연계 시스템은 일반적으로 표준(예: Nexux, CoreSight)에 따라 만든다. 다음 섹션에서는 위의 각 표준을 준수하는 일반적 디버그 아키텍처에 대해 설명한다.

Nexus 연계 시스템

Nexus 표준에 따르면 디버그 아키텍처를 다음의 구성 요소로 구성할 수 있다.

1. JTAG 컨트롤러
2. 디버그할 SoC 구성 요소에 구현된 Nexus TAP(Test Access Port)
3. Nexus 포트 컨트롤러
4. NPC 핸드쉐이크

그림 1은 Nexus에 기초한 간단한 디버그 아키텍처를 보여 준다.

JTAG 컨트롤러는 외부 디버거와 온 칩 디버그 지원 하드웨어 사이에서 인터페이스의 역할을 한다. SoC의 다양한 모듈에 존재하는 여러 Nexus TAP는 이 기본 JTAG TAP를 통해 액세스한다. JTAG 컨트롤러는 JTAG 인터페이스를 통해 NPC(Nexus Port Controller) 및 기타 Nexus TAP와 인터페이스한다.

Nexus TAP(Test Access Port)는 디버그해야 하는 SoC 구성 요소에 구현된다. SoC 구성 요소는 JTAG 컨트롤러와 통신하는 JTAG 인터페이스, 중단점/감시점 제어, 트레이스 제어, 트레이스 데이터 저장용 메모리, 트레이스 데이터를 외부 인터페이스를 통해 NPC(Nexus Port Controller)로 전송하는 모듈로 구성되어 있다. 이 하드웨어 모듈을 사용하여 중단점/감시점을 코드에 배치하고 다양한 프로세서, IP 레지스터 공간 및 시스템 메모리에 액세스할 수 있다.

이러한 작업은 Nexus TAP를 프로세서에 구현한 다음 프로세서에 연결된 시스템 버스를 통해 나머지 시스템에 액세스하는 방식으로 실행된다. 멀티 코어 SoC의 경우 Nexus TAP를 각 프로세서의 동기식, 독립적 디버깅을 위해 각 프로세서에 구현할 수 있다. 복수 프로세서 간의 동기화는 프로세서에 있는 Nexus TAP 사이에서 크로스 트리거 채널을 통해 구현된다. Nexus TAP는 트레이스 작업을 시작하기 위해 외부 이벤트 입력을 지원한다. 메모리 스누핑 및 빠른 코드 다운로드를 위해 시스템 메모리에 직접 액세스할 수 있도록 Nexus TAP를 시스템 버스에 연결할 수 있다.

NPC(Nexus Port Controller)는 트레이스 데이터를 전송하는 데 사용되는 트레이스 포트를 제어한다. NPC에는 JTAG 컨트롤러와 통신하기 위한 JTAG 인터페이스와 다른 외부 포트의 중재/다중화가 포함되어 있다. NPC에는 트레이스 데이터가 전송되고 이벤트 발생이 전달되는 외부 메시지 및 이벤트 인터페이스가 있다.

NPC 핸드쉐이크 모듈은 SoC의 저전력 모드 사이에서 디버그 입력/종료를 담당한다.
위의 모든 Nexus 구성 요소를 NDI(Nexus Development Interface)라고 한다. NDI 리셋은 시스템 리셋과 별도로 유지되며 외부 핀(예: JCOMP)을 통해 선택적으로 제어할 수 있다. NDI에는 디버그 인터페이스를 통한 무단 시스템 액세스를 방지하는 내부 검열 기능이 있다. Nexus 기반 연계 시스템의 토폴로지가 고정되어 있으므로 외부 디버거는 SoC에 존재하는 디버그 지원 인프라에 대한 이전 정보를 가지고 있어야 한다.

CoreSight 연계 시스템

CoreSight는 ARM 기반 시스템의 디버그 아키텍처를 만드는 ARM 표준이다. 다음은 이 아키텍처에 사용되는 기본 구성 요소이다.

1. EmbeddedICE
2. DAP(Debug Access Port)
3. ROM 테이블
4. CTI(Cross Trigger Interface)
5. CTM(Cross Trigger Matrix)
6. ETM(Embedded Trace Macrocell)
7. Trace Funnel
8. 복제기
9. ETB(Embedded Trace Buffer)
10. TPIU(Trace Port Interface Unit)

그림 2와 3은 간단한 CoreSight 기반 디버그 아키텍처를 보여 준다.
DAP(Debug Access Port) 및 ROM 테이블을 제외한 위의 모든 구성 요소는 CoreSight 구성 요소라고 한다. DAP의 일부로 나와 있는 ROM 테이블은 SoC에 있는 모든 CoreSight 구성 요소의 메모리 매핑 주소를 나열한다. 한 ROM 테이블이 다른 ROM 테이블을 가리킬 수 있다는 점을 주목해야 한다.

EmbeddedICE에는 ROM 또는 플래시에서 디버깅할 때 중단점의 역할도 할 수 있는 ARM 코어에서 감시점 기능을 강화하기 위한 감시점 제어 및 상태 레지스터가 포함되어 있다.

DAP는 SoC에서 코어의 복수 도메인과 외부 디버그 클록 사이에서 브릿지의 역할을 하면서 외부 디버거와 SoC 사이에서 통신 인터페이스로 작동한다. DAP는 디버그 버스를 통해 SoC에 있는 코어에 액세스함으로써 경계 스캔 시 최대한 빠른 주파수에서 통신한다. 초고속 코드 다운로드 및 메모리 매핑 주변기기 액세스를 위해, DAP를 시스템 버스에 연결하여 외부 디버거를 버스 마스터로 만들 수 있다. 그림 2에서 DAP는 AXI-APB 및 AHB-AXI 브릿지를 통해 AMBA AXI 버스에 연결되어 있다. DAP의 외부 인터페이스는 Serial Wire Debug로 알려진 감소 핀 포트 또는 완벽한 JTAG 포트가 될 수 있다.

코어의 동시 시작과 정지를 돕는 데 CTM(Cross Trigger Matrix) 및 CTI(Cross Trigger Interface)를 이용할 수 있다. CTI는 CTM에 모든 트리거를 전달할 수 있는 인터페이스를 제공하며, CTM은 이 트리거를 나머지 CTI에 브로드캐스트하여 여러 코어 사이에서 작업을 동기화한다.
이 아키텍처에는 프로비전이 포함되어 있어 CoreSight 구성 요소에 대한 리셋 신호를 분리하고 전력 강하 신호를 무시하거나 구성 요소를 별도의 전력 도메인에 각각 유지하여 리셋 및 부분적 전력 사이클로부터 디버그한다.

CoreSight 아키텍처에는 또한 디버그 인터페이스를 통해 무단 시스템 액세스를 제한/방지하는 인증 레지스터가 포함되어 있다.
CoreSight 아키텍처에 존재하는 CoreSight 구성 요소의 토폴로지는 외부 소프트웨어로 감지한다. 감지 작업은 DAP에 존재하는 ROM 테이블을 읽어 들이고 존재하는 모든 구성 요소의 위치에 액세스하는 방식으로 이루어진다. 그 이후에는 ROM 테이블의 주변기기 ID를 저장된 시스템 설명의 목록과 비교한다. 일치하는 ID가 있으면 저장된 시스템 설명이 사용된다. 그렇지 않을 경우 디버거가 지원 인터페이스와 함께 각 구성 요소를 식별하고 메커니즘을 제어한다.

그 다음 디버거가 구성 요소의 모든 마스터 인터페이스를 구동하여 거기에 연결된 모든 슬레이브 구성 요소를 감지하여 존재하는 CoreSight 구성요소의 토폴로지를 감지한다. 토폴로지 감지 후에는 나중에 사용할 수 있도록 설명이 저장된다. 감지되지 않은 구성 요소는 외부 디버거에 의해 모두 무시된다.

트레이스 메커니즘

트레이스 메커니즘은 실시간 디버그 코드 프로파일이 및 임베디드 소프트웨어 조정을 돕기 위해 거의 모든 디버그에 존재한다. 다음 섹션에서는 Nexus 및 CoreSight 아키텍처에 존재하는 트레이스 메커니즘에 대해 설명한다.

Nexus 트레이스 메커니즘

Nexus 아키텍처에서는 SoC 모듈에 있는 Nexus TAP에 모든 트레이싱 하드웨어가 존재한다. Nexus TAP는 트레이스 기능을 지원하기 위한 트레이스 제어, 메시지 FIFO 및 메시지 트랜스미터 블록으로 구성되어 있다. 그런 다음 이러한 트레이스는 외부 인터페이스를 통해 NPC(Nexus Port Controller)로 전송된다. NPC는 다양한 Nexus TAP로부터 모든 트레이스를 수용하며 트레이스 입력에 우선 순위를 정하여 한 번에 하나의 Nexus TAP에 트레이스를 전송한다. Nexus 아키텍처는 다음 유형의 트레이스 메시지를 제공한다.

1. 프로그램 트레이스
2. 데이터 트레이스
3. 소유권 트레이스
4. 감시점 일치 메시지

프로그램 트레이스는 프로그램 흐름의 불연속(직접 및 간접 브랜치, 예외 등)을 표시함으로써 외부 디버거가 불연속 사이에 발생한 이벤트의 시퀀스를 보간할 수 있도록 한다.
데이터 트레이스는 메모리 쓰기/읽기와 관련된 데이터를 표시한다. 이러한 프로비전은 데이터 일관성 오류 및 공유 메모리 위치 손상을 디버깅하는 데 유용하다.

소유권 트레이스는 활성화되는 운영 체제 작업 또는 다양한 프로세스 ID를 보여 준다. 이 프로비전은 멀티 스레드 소프트웨어의 디버깅 및 프로파일링과 다양한 스레드에서 사용되고 있는 실시간 예산을 추측하는 데 유용하다.
감시점 일치 메시지는 프로그래밍된 감시점 발생에 전송된다.

데이터 트레이스 구현은 데이터 캡처 모듈이 더 클 뿐만 아니라 더 큰 트레이스 버퍼와 빠른 트레이스 포트가 필요하기 때문에 더 많은 비용이 든다. 따라서 프로그램 트레이스, 소유권 트레이스 및 감시점 매치 메시지는 트레이스 연계 시스템에 구현하는 것이 일반적이다.

CoreSight 트레이스 메커니즘

CoreSight 아키텍처는 소프트웨어 트레이스와 하드웨어 트레이스 메커니즘의 개념을 소개하면서 공통 아키텍처에서 두 유형의 트레이스 메커니즘을 사용할 수 있는 유연성을 제공한다.

소프트웨어 트레이스는 일반적으로 디버깅 중인 소프트웨어에서 생성된다. 이 방식에서 소프트웨어는 트레이스 데이터를 시스템 메모리 위치에 버리고 이와 동시에 별도의 프로세스가 트레이스 데이터를 비워서 사용 가능한 통신 채널(예: JTAG, ARM 디버그 통신 채널)을 통해 외부 디버거로 전송한다. 이 방법으로 수집된 트레이스 데이터에는 시스템 메모리의 트레이스 데이터에 액세스하기 위해 비우는 작업과 이를 통신 채널을 통해 전송하는 작업에 이용된 사이클 수로 인해 예측이 불가능한 측면이 있다. CoreSight 아키텍처는 ITM(Instrumentation Trace Macrocell)을 통합하여 문제를 덜어 준다. ITM을 사용하여 소프트웨어 트레이스를 정해진 사이클 시간으로 전용 트레이스 버퍼(온 칩 또는 오프 칩)에 전송할 수 있다. 이러한 기기 트레이스는 다양한 소프트웨어 스레드의 실행 컨텍스트를 이해하는 데에도 유용하다.

하드웨어 트레이스 메커니즘은 트레이스할 모듈에 연결된 ETM(Embedded Trace Macrocell)으로 구성되어 있다. ETM은 프로그램 트레이스 및 데이터 트레이스 기능 둘 다를 제공하도록 설계할 수 있다.

Trace Funnel을 사용하면 다른 트레이스 소스로부터의 다양한 비동기, 이기종 트레이스 스트림을 단일 트레이스 포트 또는 트레이스 버퍼를 통해 결합할 수 있다.

트레이스 스트림은 온 칩 트레이스 버퍼(예: 임베디드 트레이스 버퍼)에 저장하거나 인터페이스를 통해 저장해서 오프 칩 버퍼에 저장할 수 있다. 이러한 버퍼는 들어오는 트레이스 스트림을 두 개의 출력 포트로 복제하는 복제기를 사용하여 단일 트레이스 스트림에 연결할 수 있다.
그림 3은 CoreSight 트레이스 연계 시스템의 예를 보여 준다.

결론

이 논문은 Nexus, CoreSight와 같이 인정된 표준에 기초한 일반적 디버그 아키텍처에 대해 설명한다. 디버그 아키텍처는 시스템을 기준으로 필요에 따라 모델링할 수 있다. 추가 디버그 기능(예: 로직 애널라이저의 디버그 기능)도 구현할 수 있으며, 이 경우 트리거 이벤트, 네스트 트리거 이벤트 및 지연 기반 트리거 메커니즘에 기초한 프로그램/데이터 트레이스가 가능하다.

 

참고 문헌
1. Single Core or Multi Core: Debug Made Easy With Nexus
http://www.ecnmag.com/Articles/2011/05/Main-Circuit/Single-Core-or-Multi-Core/
2. IEEE Nexus 5001 Standard Version 2.0
3. Debug and Trace for Multicore SoCs(ARM 백서)
4. CoreSight Architecture Specification v1.0(ARM)
회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지