칩을 경계 스캔과 디버깅할 수 있게 하는 표준 인터페이스 (IEEE 1149.1, Joint Test Action Group).
원래 목적은 디버깅이 아니었다
-
1980년대 문제: BGA 패키지가 등장하면서 핀에 프로브를 댈 수 없게 됐다
-
기판 조립 후 납땜 불량을 어떻게 검사하나?
-
해결: 칩 내부의 각 핀 옆에 셸(cell)을 두고 사슬로 연결
-
외부에서 값을 밀어 넣고 읽어 배선 연결을 검사 ← 경계 스캔(boundary scan)
디버깅 기능은 나중에 이 인프라 위에 얹은 것이다.
신호선 (5선)
- TCK — — Test Clock
- TMS — — Test Mode Select (상태 머신 제어)
- TDI — — Test Data In
- TDO — — Test Data Out
- TRST — Test Reset (선택)
데이지 체인
디버거 ── TDI ──►[칩1]── TDO/TDI ──►[칩2]── TDO ──► 디버거
TCK, TMS 는 공유
여러 칩을 하나의 인터페이스로 접근할 수 있다
보드에 여러 개의 프로그래머블 칩(MCU + FPGA)이 있을 때 유용하다.
TAP 상태 머신
TMS 값에 따라 16개 상태를 이동한다 Test-Logic-Reset → Run-Test/Idle → Select-DR/IR → Capture → Shift → …
TCK마다 TMS를 보고 상태가 전이된다. 이 상태 머신을 통해 명령 레지스터(IR)와 데이터 레지스터(DR)를 조작한다.
디버거 소프트웨어가 처리하므로 직접 다룰 일은 드물지만, "JTAG 체인이 인식되지 않는다" 는 문제를 다룰 때 이해가 필요하다.
SWD와의 비교
| JTAG | SWD | |
|---|---|---|
| 신호선 | 5개 | 2개 |
| 데이지 체인 | ○ | ✗ (SWD 멀티드롭은 별도) |
| 경계 스캔 | ○ | ✗ |
| 디버그 기능 | 동일 | 동일 |
| 핀 소모 | 크다 | 작다 |
디버깅 기능만 놓고 보면 차이가 없다. Cortex-M에서는 핀을 아끼려고 SWD를 쓰는 것이 표준이 됐다.
무엇을 할 수 있나
- 플래시 프로그래밍
- 실행 정지·재개, 단일 스텝
- 브레이크포인트, 워치포인트
- 레지스터·메모리 읽기 쓰기
- 실행 중 메모리 접근 (Cortex-M은 코어를 멈추지 않고도 가능)
- 경계 스캔 (JTAG만)
Cortex-M의 실행 중 메모리 접근이 유용하다 — 프로그램을 멈추지 않고 변수를 관찰할 수 있어(라이브 워치), 실시간 시스템 디버깅에 필수적이다.
양산 제품에서는 잠근다
- 디버그 포트가 열려 있으면
- 펌웨어를 통째로 읽어 갈 수 있다 (역공학, IP 유출)
- 메모리를 조작해 인증을 우회할 수 있다
STM32의 RDP(Read Out Protection) Level 0 — 보호 없음 (개발용) Level 1 — 플래시 읽기 차단. 디버거 연결 시 접근 거부
- Level 0으로 되돌리면 플래시가 전부 지워진다
- Level 2 — 디버그 포트 영구 비활성화 — ★ 되돌릴 수 없다
★ Level 2는 되돌릴 수 없다. 양산에서는 필요하지만 실수로 개발 보드에 걸면 그 칩은 다시 디버깅할 수 없다.
흔한 문제
연결이 안 된다
→ 전원, GND, 리셋 배선
→ SWD/JTAG 핀을 GPIO로 재설정하는 코드가 있는가 ★
→ 저전력 모드로 들어가 코어가 멈췄는가
→ 부팅 직후 무한 루프에 빠져 디버그 진입 전에 죽는가
★ 펌웨어가 SWD 핀을 일반 GPIO로 바꾸면 다음부터 연결이 안 된다
→ "connect under reset" 옵션으로 리셋 상태에서 붙는다
→ 그래도 안 되면 BOOT 핀으로 시스템 부트로더 진입
"디버거로 한 번 잘못 플래싱하고 벽돌이 됐다" 는 대부분 이 경우이며, BOOT0 핀을 올려 내장 부트로더로 부팅하면 복구된다.