임베디드 면접 용어 사전
디버깅·신뢰성

SWD

2선(SWCLK·SWDIO)으로 동작하는 ARM 디버그 인터페이스. 핀이 적어 소형 보드에 유리하다.

ARM이 만든 2선 디버그 인터페이스(Serial Wire Debug). JTAG의 디버그 기능을 최소 핀으로 구현한 것이다.

신호선

SWDIO — 데이터 (양방향) SWCLK — 클럭 (+ GND 필수, VREF 권장, nRESET 선택)

2선만으로 JTAG의 디버깅 기능을 모두 제공한다. 핀이 부족한 소형 MCU에서 결정적 장점이다.

JTAG 핀과 공유

  • Cortex-M의 SWJ-DP(Serial Wire / JTAG Debug Port)
  • 같은 핀을 두 모드로 사용
  • 특정 시퀀스를 보내면 JTAG ↔ SWD 전환

SWDIO = JTAG의 TMS SWCLK = JTAG의 TCK

프로토콜

  • 요청 (8비트) — : 디버거 → 타깃. 읽기/쓰기, AP/DP, 주소
  • 턴어라운드 — : 방향 전환 (SWDIO가 양방향이므로)
  • 응답 (3비트) — : OK / WAIT / FAULT
  • ④ 데이터 (33비트): 32비트 + 패리티

응답 코드

  • OK — (001) — 정상
  • WAIT — (010) — 아직 준비 안 됨. 재시도
  • FAULT (100) — 오류. 상태 레지스터 확인

WAIT가 반복되면 타깃이 저전력 모드이거나 코어 클럭이 멈춘 것이다.

SWO — 추가 출력 핀

SWDIO + SWCLK + SWO (3선)

SWO(Serial Wire Output)는 타깃 → 디버거 단방향 고속 출력

무엇에 쓰나

  • ① printf 대체 (ITM) — UART보다 빠르고 핀 하나만 추가
  • ② 실행 추적 (ETM/ITM) — 어떤 코드가 실행됐는지
  • ③ 성능 프로파일링 — PC 샘플링
  • ④ 이벤트 타임스탬프
// ITM으로 문자 출력 — UART보다 훨씬 빠르다
ITM_SendChar('A');

// printf 를 ITM으로 리다이렉트
int _write(int fd, char *ptr, int len) {
    for (int i = 0; i < len; i++) ITM_SendChar(ptr[i]);
    return len;
}

UART printf는 115200bps에서 문자당 약 87μs가 걸려 ISR에서 쓰면 타이밍이 완전히 깨진다. ITM은 수 사이클이라 훨씬 덜 방해한다.

디버그 구성 요소 (CoreSight)

유닛기능
DWT데이터 워치포인트, 사이클 카운터, PC 샘플링
FPB플래시 브레이크포인트 (플래시 코드에 중단점)
ITM소프트웨어 계측 출력
ETM명령어 추적 (전체 실행 흐름 기록)
TPIU추적 데이터를 외부로 출력

DWT 사이클 카운터가 실무에서 유용하다.

DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
uint32_t t0 = DWT->CYCCNT;
function_to_measure();
uint32_t cycles = DWT->CYCCNT - t0;

추가 하드웨어 없이 정확한 실행 시간 측정이 가능하다.

하드웨어 브레이크포인트 개수 제한

Cortex-M3/M4 : FPB 비교기 6개 (명령 6 또는 명령 2 + 리터럴 4 구성) Cortex-M0/M0+: 4개

  • Cortex-M7 — : 8개

플래시에 있는 코드는 명령을 바꿔 넣을 수 없으므로 하드웨어 비교기를 써야 한다. 개수를 넘으면 디버거가 "브레이크포인트를 설정할 수 없다"고 거부한다.

RAM에서 실행하는 코드는 소프트웨어 브레이크포인트(BKPT 명령 삽입)가 가능해 개수 제한이 없다.

흔한 문제

연결 실패
→ 펌웨어가 SWD 핀을 GPIO로 재설정했다 → connect under reset
→ 저전력 모드 진입 → 디버그 유지 옵션(DBGMCU) 활성화
→ 클럭 속도가 너무 높다 → SWD 클럭을 낮춘다
→ 배선 길이·노이즈 → 짧게, GND를 함께

SWO 출력이 안 나온다
→ SWO는 코어 클럭에 동기화된다. 디버거에 정확한 클럭을 알려야 한다
→ 클럭을 바꾸면 SWO 보율도 바뀐다

디버그 유지 설정

__HAL_DBGMCU_FREEZE_IWDG();     // 정지 시 워치독도 멈춤
DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY;

저전력 모드에서도 디버거 연결을 유지한다. 개발 중에만 켠다 (전력 소모가 늘어난다).

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 디버깅·신뢰성 — JTAG/SWD·HardFault(fault 레지스터)·트레이스·watchdog·EMC