Advanced Debugging & Observability

JTAG과 SWD의 동작 원리: TAP 스테이트 머신과 ARM CoreSight 디버그 아키텍처 분석

임베디드 친구 2026. 6. 28. 18:17
반응형

내용 요약

현상: 디버거 연결 시 Target Not Found, Cannot Connect to Target 오류, MCU가 Debug Mode로 진입하지 못하고 락업(Lock-up)되는 현상

원인: JTAG/SWD 물리 핀 연결은 정상이나, TAP(Test Access Port) State Machine의 동기화 실패 또는 CoreSight ROM Table 탐색 중 버스 에러(Bus Error) 발생.

해법: TMS/SWDIO 라인의 홀드 타임(Hold Time)을 확보하여 TAP State를 Test-Logic-Reset으로 강제 초기화하고, DP(Debug Port)와 AP(Access Port) 레지스터를 순차적으로 제어.

JTAG/SWD 디버그 연결 실패 및 타깃 인식 불량 증상 (Target Connection Failure Symptoms)

임베디드 시스템 개발 중 디버거(J-Link, ST-Link 등)를 연결했을 때 Target Not Found, Failed to connect to CPU, 또는 Low-Level JTAG/SWD Communication Error 등의 메시지를 가끔 봅니다.
물리적인 핀 맵(Pinout) 확인과 풀업/풀다운(Pull-up/Pull-down) 저항을 확인 했지만, 디버그 세션이 끊기거나 MCU가 HardFault_Handler 상태에 머물 때 레지스터 레벨의 제어가 불가능해지는 증상이 발생합니다. 이는 물리 계층(Physical Layer)을 넘어 하위 TAP State Machine의 전이(Transition) 오류나 ARM 내부 CoreSight DP/AP 버스 상의 데드락(Deadlock)으로 인해 발생합니다.

JTAG TAP 스테이트 머신과 ARM CoreSight 아키텍처의 상호작용 원리 (JTAG TAP State Machine & ARM CoreSight Architecture)

디버그 라인 너머의 통신은 물리적인 신호 토글링을 넘어 내부 하드웨어 유한 상태 머신(FSM)을 제어하는 과정입니다.

JTAG TAP FSM (Test Access Port Finite State Machine)

JTAG(IEEE 1149.1) 인터페이스는 TCKTMS 신호를 바탕으로 16-State FSM을 구동합니다.

  • TMS 신호가 고레벨(1)을 유지한 채 TCK가 5번 이상 라이징 에지(Rising Edge)를 치면, TAP은 현재 어떤 상태에 있든 상관없이 항상 Test-Logic-Reset 상태로 강제 전이됩니다.
  • 이 상태에서 Run-Test/Idle을 거쳐 IR(Instruction Register) Scan 경로로 진입하여 디버그 명령을 주입하고, DR(Data Register) Scan 경로를 통해 실제 데이터를 시프트(Shift-IN/OUT)합니다.

    ARM CoreSight Debug Port (DP) & Access Port (AP)

    JTAG 또는 SWD 프로토콜이 전달하는 페이로드(Payload)는 ARM의 CoreSight 아키텍처 내부에 존재하는 레지스터를 타깃으로 합니다.
  • DP (Debug Port): 외부 디버거 인터페이스(JTAG/SWD)와 직접 통신하며, 통신 프로토콜을 선택하고 내부 디버그 전원을 켜는 역할을 합니다. 주요 레지스터로는 DP-CTRL/STAT (Control/Status Register)이 있습니다.
  • AP (Access Port): MCU 내부 Bus Matrix(AHB/APB)에 접근하기 위한 가교 역할을 합니다. AHB-AP를 통해 코어 레지스터 및 전체 메모리 맵(SRAM, Flash)에 접근할 수 있습니다.

하드웨어 디버깅이 실패하는 주 원인은 DP에서 AP로 통신을 넘겨주는 과정에서 내부 버스 클록이 비활성화되어 있거나, AHB-APCSW (Control/Status Word Register) 설정을 잘못하여 메모리 접근 크기(Size Alignment) 불일치로 버스 오류(Bus Fault)가 발생하기 때문입니다.

문제를 유발하는 잘못된 디버그 시퀀스 제어 C 코드 예시 (Incorrect Debug Port Initialization Sequence)

하드웨어 디버거의 내부 동작을 소프트웨어적으로 에뮬레이션할 때, TAP State 동기화 및 디버그 전원(Debug Power Domain) 활성화를 누락하여 통신에 실패하는 Bad Case입니다.

#include <stdint.h>

// Mock definitions for Debug Port Registers
#define DP_CTRL_STAT_REG  0x04
#define AP_SELECT_REG     0x08

// Bad implementation omitting TAP Reset and Power-Up acknowledgment
void Incorrect_Debug_Init(void) {
    // Missing: JTAG TAP Reset Sequence (5 TMS clocks high)
    // Missing: Line Reset Sequence for SWD

    // Directly attempting to select AP without checking DP status
    uint32_t ap_select_payload = 0x00000000; // Select AP bank 0
    Write_DP_Register(AP_SELECT_REG, ap_select_payload);

    // Attempting to read core memory immediately via AHB-AP
    // This will cause a system hang or Timeout because the Debug Power Domain is still powered down.
    uint32_t mem_val = Read_AHB_AP_Memory(0x20000000); 
}

정상적인 연결을 보장하는 레지스터 수준의 디버그 제어 C 코드 (Robust Debug Port & CoreSight Initialization)

안정적인 디버그 세션을 확립하기 위해서는 반드시 물리 프로토콜 리셋, DP Power Domain 활성화 체크, AP 선택 및 CSW 설정이 순차적으로 이루어져야 합니다.

#include <stdint.h>
#include <stdbool.h>

// CoreSight DP Register Addresses
#define DP_IDCODE_REG     0x00
#define DP_CTRL_STAT_REG  0x04
#define DP_SELECT_REG     0x08

// Bit Definitions
#define CSYSPWRUPREQ      (1UL << 30)
#define CSYSPWRUPACK      (1UL << 31)
#define CDBGPWRUPREQ      (1UL << 28)
#define CDBGPWRUPACK      (1UL << 29)

// High-level safe initialization sequence
bool Robust_Debug_CoreSight_Init(void) {
    uint32_t reg_val = 0;
    uint32_t timeout = 10000;

    // Step 1: Force JTAG TAP/SWD Line Reset 
    // Pulse TMS/SWDIO HIGH for more than 5/50 cycles respectively to reach Reset State
    Send_Interface_Reset_Sequence(); 

    // Step 2: Read IDCODE to verify lowest-level physical connection
    if (!Read_DP_Register(DP_IDCODE_REG, &reg_val) || reg_val == 0) {
        return false; // Hardware Layer connection failed
    }

    // Step 3: Request Debug and System Power Domain Power-Up
    uint32_t pwr_req = CSYSPWRUPREQ | CDBGPWRUPREQ;
    if (!Write_DP_Register(DP_CTRL_STAT_REG, pwr_req)) {
        return false;
    }

    // Step 4: Poll DP-CTRL/STAT until Power-Up Acknowledge flags are set
    do {
        if (!Read_DP_Register(DP_CTRL_STAT_REG, &reg_val)) {
            return false;
        }
        if (--timeout == 0) {
            return false; // Timeout Error: Debug power domain not responding
        }
    } while ((reg_val & (CSYSPWRUPACK | CDBGPWRUPACK)) != (CSYSPWRUPACK | CDBGPWRUPACK));

    // Step 5: Configure Access Port (AP) - Enable Auto-Increment & 32-bit transfer size
    // Address 0x00 on AHB-AP typically represents the Control/Status Word (CSW)
    Write_DP_Register(DP_SELECT_REG, 0x00000000); // Select AP 0, Bank 0

    uint32_t csw_setting = 0x23000002; // MasterType: Debug, Size: 32-bit, Auto-Increment
    if (!Write_AP_Register(0x00, csw_setting)) {
        return false;
    }

    return true; // Successfully initialized and attached to CoreSight Bus Matrix
}

핵심 수정 포인트 (Key Implementation Details)

  • Interface Reset Sequence: 하드웨어 라인 가라앉히기 단계를 추가하여 엉켜있던 TAP FSM을 안정적인 초기화 상태로 되돌립니다.
  • Handshake Polling: 레지스터에 전원 요청(REQ)만 던지고 넘어가는 것이 아니라, 마이크로컨트롤러 내부 내부 전원이 완전히 켜졌는지 확인하는 응답(ACK) 비트를 Polling 검증합니다.
  • CSW Configuration: AHB-AP 접근 전 버스 폭(Size: 32-bit Word)과 자동 주소 증가(Auto-Increment) 설정을 명확히 지정해 오정렬(Alignment) 예외를 차단합니다.

하드웨어 레벨 디버깅 및 트러블슈팅 가이드 (Debugging Tips)

디버거 연결에 문제가 발생하면 아래의 체크리스트를 통해 하위 계층부터 단계적으로 역추적해야 합니다.

  • 물리 파형 스코프 실측 (Signal Integrity Analysis): 오실로스코프로 TCK/SWCLK 신호의 오버슈트(Overshoot) 및 링잉(Ringing) 현상을 확인하십시오. 특히 클록 라인의 신호 왜곡은 TAP State Machine이 원치 않는 분기로 오작동하게 만드는 주범입니다. 필요한 경우 클록 속도를 낮추거나 수십 옴 단위의 직렬 종단 저항(Series Termination Resistor)을 배치해야 합니다.
  • MCU Low-Power State 진입 여부 검증 (Low-Power State Bypass): 펌웨어가 코어 내 가동률을 줄이기 위해 STOP, STANDBY, 또는 SLEEP 모드로 진입하면 CoreSight 디버그 도메인 클록이 차단되어 디버거가 강제 이탈합니다. 디버거 설정에서 Connect under Reset 옵션을 활성화하여 코어가 기동 직후 코드를 실행하기 전 브레이크포인트(Breakpoint)를 걸거나, 보드의 NRST(Reset 핀) 물리 제어를 디버거 하드웨어 하에 두어야 합니다.
  • Option Byte 및 DBGMCU 레지스터 확인 (Option Bytes & Debug Control Registers): 칩 락(Readout Protection, ROP)이 걸려있거나 MCU 내부 DBGMCU_CR 등의 레지스터에서 저전력 모드 디버그 기능(DBG_STOP, DBG_STANDBY)이 비활성화되어 있는지 MAP 파일과 메모리 덤프를 통해 역산해야 합니다.
반응형