인 서킷 에뮬레이션(In-circuit emulation, ICE)은 임베디드 시스템의 소프트웨어를 디버그하는 데 사용되는 하드웨어 장치 또는 인 서킷 에뮬레이터이다. 시스템의 주요 기능 수행뿐만 아니라 디버깅 작업을 지원하는 추가 기능을 갖춘 프로세서를 사용하여 작동한다. 특히 구형 시스템의 경우 제한된 프로세서로 인해 일반적으로 프로세서를 임시로 하드웨어 에뮬레이터(더 강력하지만 더 비싼 버전)로 대체해야 했다. 역사적으로 디버깅을 위해 많은 내부 신호를 인출한 본드아웃 프로세서 형태였다. 이러한 신호는 프로세서의 상태에 대한 정보를 제공한다.
최근에는 JTAG 기반 하드웨어 디버거도 이 용어에 포함된다. 표준 생산 칩에 온칩 디버깅 하드웨어를 사용하여 동등한 접근을 제공한다. 맞춤형 본드아웃 버전 대신 표준 칩을 사용하면 기술이 보편화되고 저렴해지며 개발 환경과 런타임 환경 간의 대부분의 차이가 사라진다. 이 일반적인 경우에 인 서킷 에뮬레이터 용어는 오해를 일으키는 이름이며, 에뮬레이션이 더 이상 포함되지 않기 때문에 혼란스러울 수 있다.
임베디드 시스템은 일반적으로 키보드, 컴퓨터 모니터, 디스크 드라이브 및 컴퓨터에 있는 다른 사용자 인터페이스가 부족하기 때문에 프로그래머에게 특별한 문제를 제기한다. 이러한 단점은 많은 일반적인 개발 작업에 인 서킷 소프트웨어 디버깅 도구를 필수적으로 만든다.
인 서킷 에뮬레이터(ICE)는 임베디드 시스템 내부를 볼 수 있는 창을 제공한다. 프로그래머는 에뮬레이터를 사용하여 프로그램을 임베디드 시스템에 로드하고 실행하며, 천천히 스텝별로 실행하고 시스템 소프트웨어에서 사용하는 데이터를 보고 변경한다.
에뮬레이터는 임베디드 시스템 컴퓨터의 중앙 처리 장치(CPU)를 에뮬레이트(모방)하기 때문에 이름이 붙었다. 전통적으로 CPU 집적 회로 칩이 일반적으로 배치되는 소켓에 삽입되는 플러그가 있었다. 대부분의 최신 시스템은 특수 JTAG 기반 디버그 접근 방식을 사용하여 대상 시스템의 CPU를 직접 사용한다. 프로세서 에뮬레이션 또는 직접 JTAG 접근을 통해 ICE는 프로세서가 할 수 있는 모든 것을 소프트웨어 개발자의 제어하에 수행할 수 있다.
ICE는 단말기 또는 개인용 컴퓨터(PC)를 임베디드 시스템에 연결한다. 단말기 또는 PC는 프로그래머가 임베디드 시스템을 조사하고 제어하기 위한 대화형 사용자 인터페이스를 제공한다. 예를 들어, JTAG 어댑터(에뮬레이터)를 통해 그래픽 사용자 인터페이스가 없는 임베디드 대상 시스템과 통신하는 그래픽 창 인터페이스가 있는 소스 코드 수준 디버거를 갖는 것이 일반적이다.
주목할 점은 프로그램이 실패하면 대부분의 임베디드 시스템은 단순히 벽돌 상태가 된다는 것이다. 임베디드 시스템은 종종 메모리 접근 오류를 포착하는 메모리 관리 장치(MMU)와 같은 소프트웨어 오류 징후를 감지하는 기본 기능이 부족하다. ICE가 없으면 임베디드 시스템 개발은 매우 어려울 수 있다. 무엇이 잘못되었는지 알 수 있는 방법이 보통 없기 때문이다. ICE를 사용하면 프로그래머는 일반적으로 코드 조각을 테스트한 다음 오류를 특정 코드 섹션으로 격리하고 오류가 발생한 코드를 검사하고 다시 작성하여 문제를 해결할 수 있다.
사용 중 ICE는 프로그래머에게 실행 브레이크포인트, 메모리 표시 및 모니터링, 입출력 제어를 제공한다. 이 외에도 ICE는 오류의 원인을 식별하기 위해 일치하는 모든 범위를 찾도록 프로그래밍하여 일시 중지할 수 있다.
대부분의 최신 마이크로컨트롤러는 다른 특수 에뮬레이션 버전(즉, 본드아웃)의 대상 마이크로컨트롤러가 필요 없이 장치 프로그래밍, 에뮬레이션 및 디버깅 기능을 위해 제조된 마이크로컨트롤러 버전에 제공된 리소스를 사용한다.[1] ICE 장치가 실제로 대상 마이크로컨트롤러를 에뮬레이트하는 대신 에뮬레이션만 관리하기 때문에 비용 효율적인 방법이지만, 제조 시 가격을 낮게 유지하고 (상대적으로 적은) 에뮬레이션 응용 프로그램에 충분한 에뮬레이션 기능을 제공하기 위해 타협이 필요하다.
거의 모든 임베디드 시스템에는 하드웨어 요소와 소프트웨어 요소가 있으며, 이들은 분리되어 있지만 긴밀하게 상호 의존적이다. ICE는 소프트웨어 요소가 실행될 하드웨어에서 실행되고 테스트되도록 허용하는 동시에 프로그래머 편의를 제공하여 소스 수준 디버깅(프로그램이 원래 작성된 대로 표시) 및 단일 스텝 실행(프로그래머가 오류를 찾기 위해 프로그램을 단계별로 실행하도록 허용)과 같은 오류가 있는 코드를 격리하는 데 도움이 된다.
대부분의 ICE는 ICE 호스트 컴퓨터와 테스트할 시스템 사이에 위치하는 어댑터 장치로 구성된다. 핀 헤더와 케이블 어셈블리는 어댑터를 실제 중앙 처리 장치(CPU) 또는 마이크로컨트롤러가 임베디드 시스템 내에 장착되는 소켓에 연결한다. 최신 ICE는 프로그래머가 JTAG 또는 배경 디버그 모드 인터페이스(BDM)를 통해 CPU에 통합된 온칩 디버그 회로에 접근하여 임베디드 시스템의 소프트웨어를 디버그할 수 있도록 한다. 이러한 시스템은 종종 CPU 칩의 표준 버전을 사용하며, 생산 시스템의 디버그 포트에 간단히 연결할 수 있다. 이들은 CPU의 기능을 복제하지 않고 이미 존재하는 표준 CPU를 제어한다는 사실을 구별하기 위해 인 서킷 디버거 또는 ICD라고도 불린다. CPU를 교체할 필요가 없으므로 CPU가 납땜되어 교체할 수 없는 생산 장치에서 작동할 수 있다. x86 펜티엄에서는 디버깅을 돕기 위해 ICE가 특수 '프로브 모드'를 사용한다.[2]
임베디드 시스템의 맥락에서 ICE는 하드웨어를 에뮬레이트하는 것이 아니다. 오히려 실제 CPU에 직접적인 디버그 접근을 제공한다. 테스트 중인 시스템은 개발자가 코드를 직접 로드, 디버그 및 테스트할 수 있도록 완벽하게 제어된다.
대부분의 호스트 시스템은 개발에 사용되는 CPU와 관련이 없는 일반적인 상업용 컴퓨터이다. 예를 들어 리눅스 PC는 리눅스를 실행할 수 없는 프리스케일 68HC11 칩을 사용하는 시스템의 소프트웨어를 개발하는 데 사용될 수 있다.
프로그래머는 보통 호스트 시스템에서 임베디드 시스템의 코드를 편집하고 컴파일한다. 호스트 시스템에는 임베디드 시스템을 위한 실행 코드를 생성하는 특수 컴파일러가 있으며, 이를 크로스 컴파일러 또는 크로스 어셈블러라고 한다.
온칩 디버깅은 인 서킷 에뮬레이션의 대안이다. 비슷한 목표를 달성하기 위해 다른 접근 방식을 사용한다.
온칩 디버깅은 종종 느슨하게 JTAG(Joint Test Action Group)라고도 불리며, 생산 시스템의 실제 하드웨어에 추가 디버깅 인터페이스를 제공하는 것을 사용한다. 내부 상태 또는 변수 검사와 같은 인 서킷 디버깅과 동일한 기능을 제공하며 체크포인트, 브레이크포인트 및 워치포인트를 설정하는 기능도 가질 수 있다. 차이점은 이것이 오프보드 디버깅 에뮬레이터를 위해 프로세서를 바꾸는 대신 생산 프로세서 내의 추가 실리콘으로 제공된다는 점이다. 이러한 이유로 ICE의 일부 기능은 프로세서 사양에 따라 변경된다. 추가 JTAG 인터페이스가 컨트롤러 보드에 추가되며 모든 생산 시스템에 필요하지만 몇 개의 신호 핀만 필요하므로 추가 비용은 미미하다. JTAG 인터페이스는 원래 생산 테스트 최종 단계에 개발되었으며 여전히 유용하다.
인텔 286에서 인 서킷 에뮬레이터(ICE) 디버깅을 지원하기 위해 프로세서에 5개의 추가 핀이 제공되었다. ICE 브레이크포인트를 외부에서 강제하는 입력 핀 하나(ICEBP#
)와 사용자 메모리 대신 ICE 버스를 통해 작업을 선택하는 대체 출력 핀 쌍 두 개가 있다.[3] 80286에는 완전한 CPU 상태를 메모리 오프셋 0x800으로 덤프/복원하는 두 개의 명령어(0F 04
, 0F 05
)와 사용자 메모리에 접근하기 위해 ICE 모드를 활성화하는 단일 바이트 오버라이드 접두사(F1
)가 존재한다.