인터럽트 핸들러
Interrupt handler컴퓨터 시스템 프로그래밍에서 인터럽트 핸들러는 인터럽트 서비스 루틴(ISR)이라고도 하며 특정 인터럽트 조건과 관련된 특별한 코드 블록입니다.인터럽트 핸들러는 하드웨어 인터럽트, 소프트웨어 인터럽트 명령 또는 소프트웨어 예외에 의해 개시되며 디바이스 드라이버의 실장 또는 시스템콜 등 보호된 동작 모드간의 이행에 사용됩니다.
인터럽트 핸들러의 기존 형식은 하드웨어 인터럽트 핸들러입니다.하드웨어 인터럽트는 전기적 조건 또는 디지털 로직으로 구현된 저레벨 프로토콜에서 발생하며 보통 인터럽트 벡터의 하드 코딩된 테이블을 통해 (인터럽트 마스킹레벨이 허용하는 대로) 일반 실행 스트림에 비동기적으로 디스패치되며 종종 별도의 스택을 사용하여 자동으로 다른 실행 컨텍스트에 들어갑니다.인터럽트 핸들러의 실행 시간 동안 (표준 레벨)을 지정합니다.일반적으로 하드웨어 인터럽트와 그 핸들러는 프로세서가 [1][2]실행하고 있는 현재 코드의 인터럽트를 필요로 하는 고우선순위 조건을 처리하기 위해 사용됩니다.
나중에 소프트웨어가 소프트웨어 인터럽트(동기 인터럽트의 일종)를 통해 동일한 메커니즘을 트리거할 수 있다는 것을 알게 되었습니다.소프트웨어 인터럽트는 하드웨어 수준에서 하드코딩된 인터럽트 디스패치테이블을 사용하는 것이 아니라 콜백 함수의 형태로 운영체제 수준에서 구현되는 경우가 많습니다.
인터럽트 핸들러에는 인터럽트를 트리거한 원인 및 인터럽트 핸들러가 작업을 완료하는 속도에 따라 다양한 기능이 있습니다.예를 들어 컴퓨터 [1]키보드의 키를 누르거나 마우스를 움직이면 해당 키 또는 마우스 위치를 읽고 관련 정보를 컴퓨터 [2]메모리에 복사하는 인터럽트 핸들러가 호출됩니다.
인터럽트 핸들러는 이벤트핸들러의 하위 레벨입니다그러나 인터럽트 핸들러는 비정상적인 실행 컨텍스트와 많은 시공간 제약이 있으며 본질적으로 비동기적인 특성으로 인해 표준 프랙티스에 의한 디버깅이 어렵기로 악명 높다(반복 가능한 테스트 케이스는 일반적으로 존재하지 않는다).따라서 시스템 프로그래밍의 중요한 서브셋인 특수한 스킬셋을 필요로 한다.하드웨어 인터럽트 레이어에 관여하는 엔지니어입니다.
인터럽트 플래그
다른 이벤트 핸들러와 달리 인터럽트 핸들러는 핵심 기능의 일부로 인터럽트 플래그를 적절한 값으로 설정해야 합니다.
네스트된 인터럽트를 지원하는 CPU에서도 CPU 하드웨어 동작에 의해 모든 인터럽트가 글로벌하게 마스크된 상태로 핸들러에 도달하는 경우가 많습니다.이 아키텍처에서는 통상 인터럽트 핸들러는 필요한 최소한의 컨텍스트를 저장하고 첫 번째 기회에 글로벌인터럽트 디세이블플래그를 리셋하여 우선순위가 높은 인터럽트가 현재 핸들러를 인터럽트 할 수 있도록 합니다.또한 인터럽트 핸들러는 현재의 인터럽트 소스를 어떤 방법으로(종종 페리페럴레지스터의 어떤 종류의 플래그 비트를 토글) 억제하는 것이 중요합니다.이것에 의해, 핸들러의 종료시에 현재의 인터럽트가 곧바로 반복되어 무한 루프가 발생하지 않게 됩니다.
인터럽트 핸들러에서 모든 만일의 경우 인터럽트 시스템을 올바른 상태로 종료하는 것은 때로는 어렵고 까다로운 작업이 될 수 있습니다.또, 그 처리의 잘못은, 시스템을 완전하게 정지시키는 종류의 많은 심각한 버그의 원인이 되고 있습니다.이러한 버그는 때때로 간헐적으로 발생하며, 잘못 처리된 엣지 케이스는 몇 주 또는 몇 개월 동안 계속 작동되지 않습니다.인터럽트 핸들러의 정식 검증은 매우 어렵지만 테스트는 일반적으로 가장 빈번한 장애 모드만 식별하기 때문에 인터럽트 핸들러의 미묘하고 간헐적인 버그가 최종 고객에게 발송되는 경우가 많습니다.
실행 컨텍스트
최신 운영체제에서는 하드웨어 인터럽트 핸들러의 실행 컨텍스트가 미묘합니다.
성능의 이유로 핸들러는 일반적으로 특별한 접속이 없는 실행 프로세스의 메모리 및 실행 컨텍스트에서 시작됩니다(인터럽트가 본질적으로 실행 컨텍스트를 빼앗는 것입니다.프로세스 시간 어카운팅은 인터럽트를 처리하는데 많은 경우 인터럽트를 처리하는 데 소요됩니다).그러나 중단된 프로세스와 달리 인터럽트는 일반적으로 하드 코딩된 CPU 메커니즘에 의해 하드웨어 리소스에 직접 액세스하기에 충분한 권한 수준까지 높아집니다.
스택 공간에 관한 고려 사항
저레벨 마이크로컨트롤러에서는 칩에 보호모드가 없고 메모리 관리 유닛(MMU)이 없는 경우가 있습니다.이러한 칩에서 인터럽트 핸들러의 실행 컨텍스트는 인터럽트된 프로그램과 기본적으로 동일하며, 일반적으로 고정 크기의 작은 스택으로 실행됩니다(기존에는 메모리자원이 로우엔드로 극히 부족했습니다).네스트된 인터럽트가 자주 제공되기 때문에 스택 사용률이 높아집니다.이 프로그래밍에서 인터럽트 핸들러의 주요 제약사항은 최악의 경우 사용 가능한 스택을 넘지 않는 것입니다.이 때문에 프로그래머는 구현된 모든 인터럽트 핸들러 및 응용 프로그램태스크의 스택스페이스 요건을 글로벌하게 추론할 필요가 있습니다.
할당된 스택스페이스가 초과되면(스택오버플로라고 불리는 상태), 보통 이 클래스의 칩에 의해 하드웨어에서 검출되지 않습니다.스택을 다른 쓰기 가능한 메모리 영역으로 초과하면 일반적으로 핸들러는 예상대로 동작하지만 핸들러의 메모리 손상 부작용으로 인해 응용 프로그램이 나중에(때로는 훨씬 늦게) 실패합니다.스택이 기입 불가능한(또는 보호되고 있는) 메모리영역에 도달했을 경우, 통상은 핸들러 자체의 내부에서 장해가 발생합니다(통상은 나중에 디버깅하기 쉬운 경우).
기입 가능한 경우, Sentinel 스택가드를 실장할 수 있습니다.이 값은 리걸스택의 끝을 바로 넘어 덮어쓸 수 있지만, 시스템이 정상적으로 동작하고 있는 경우는 실장할 수 없습니다.일종의 워치독 메커니즘을 사용하여 스택 가드의 손상을 정기적으로 관찰하는 것이 일반적입니다.이것은, 문제의 조작에 가까운 시점에서, 대부분의 스택오버플로우 상태를 포착합니다.
멀티태스킹 시스템에서는 일반적으로 실행 스레드마다 자체 스택이 있습니다.인터럽트에 특별한 시스템스택이 제공되지 않는 경우 인터럽트는 인터럽트된 실행 스레드에서 스택스페이스를 소비합니다.이러한 설계에는 보통 MMU가 포함되어 있으며, 일반적으로 사용자 스택은 시스템오류(디버깅용) 또는 메모리 재매핑으로 MMU에 의해 스택오버플로우가 트랩되도록 설정됩니다.이 마이크로 컨트롤러 수준의 메모리 리소스는 일반적으로 훨씬 덜 제약되기 때문에 충분한 안전 여유로 스택을 할당할 수 있습니다.
스레드 수가 많은 시스템에서는 하드웨어 인터럽트 메커니즘이 스택을 특별한 시스템스택으로 전환하여 최악의 경우 네스트된 인터럽트 사용을 고려할 필요가 없도록 하는 것이 좋습니다.1978년부터 8비트 Motorola 6809까지 작은 CPU는 별도의 시스템 및 사용자 스택 포인터를 제공했습니다.
시간과 동시성 제약
많은 이유로 인터럽트핸들러는 가능한 한 짧게 실행하는 것이 매우 바람직하며 하드웨어 인터럽트가 잠재적으로 차단되는 시스템콜을 호출하는 것은 매우 권장되지 않습니다(또는 금지되어 있습니다).여러 실행 코어가 있는 시스템에서는 재진입에 대한 고려 사항도 가장 중요합니다.시스템이 하드웨어 DMA를 제공하는 경우 CPU 코어가 1개밖에 없는 경우에도 동시성 문제가 발생할 수 있습니다(미드레인지 마이크로 컨트롤러에 보호 수준과 MMU가 없는 경우는 드물지 않지만 다수의 채널을 갖춘 DMA 엔진이 있습니다.이 시나리오에서는 대부분의 인터럽트는 보통 DMA 엔진 자체와 관련된 에 의해 트리거됩니다.terrupt 핸들러는 신중하게 움직여야 합니다.)
하드웨어 인터럽트 핸들러를 앞부분과 뒷부분의 요소로 분할하는 것이 현대의 관례입니다.전반(또는 첫 번째 레벨)은 실행 중인 프로세스의 컨텍스트에서 첫 번째 인터럽트를 수신하고 하드웨어의 긴급성이 낮은 상태(전체 수신 버퍼의 비우기 등)로 복원하는 최소한의 작업을 한 후 적절한 스케줄링 우선순위로 가까운 장래에 실행할 수 있도록 후반(또는 두 번째 레벨)을 마킹합니다.한 번 호출되면백하프는 그 자체의 프로세스 컨텍스트에서 보다 적은 제한으로 동작하며 핸들러의 논리 조작(운영체제 데이터 큐에 새로 수신된 데이터를 전송하는 등)을 완료합니다.
최신 운영 체제에서 분할된 핸들러
Linux, Unix, macOS, Microsoft Windows, z/OS, DESQview 등의 여러 운영체제시스템에서 인터럽트 핸들러는 FLIH(First-Level Interrupt Handler)와 SLIH(Second-Level Interrupt Handler)의 두 부분으로 나뉩니다.FLIH 는 하드 인터럽트 핸들러 또는 퍼스트 인터럽트 핸들러라고도 불리며, SLIH 는 저속/소프트 인터럽트 핸들러 또는 Windows 에서는 지연 프로시저 콜이라고도 불립니다.
FLIH는 인터럽트 루틴과 마찬가지로 플랫폼 고유의 최소 인터럽트 처리를 구현합니다.인터럽트에 응답하여 컨텍스트 스위치가 있으며 인터럽트용 코드가 로드되어 실행된다.FLIH의 역할은 인터럽트를 신속하게 처리하거나 인터럽트 시에만 사용 가능한 플랫폼 고유의 중요한 정보를 기록하고 SLIH 실행을 스케줄링하여 인터럽트 처리를 [2]더 오래 하는 것입니다.
FLIH는 프로세스 실행 시 지터를 발생시킵니다.FLIH는 인터럽트도 마스킹합니다.지터를 줄이는 것은 실시간오퍼레이팅시스템에서 가장 중요합니다.지터는 특정 코드의 실행이 합의된 시간 내에 완료됨을 보증해야 하기 때문입니다.지터를 줄이고 마스크된 인터럽트에 의한 데이터 손실 가능성을 줄이기 위해 프로그래머는 가능한 한 SLIH로 이동하면서 FLIH의 실행 시간을 최소화하려고 합니다.최신 컴퓨터의 속도에 따라 FLIH는 모든 디바이스와 플랫폼에 의존하는 처리를 구현할 수 있으며 플랫폼에 의존하지 않는 장기간의 처리를 위해 SLIH를 사용할 수 있습니다.
일반적으로 서비스 하드웨어는 실행이 완료될 때까지 관련 인터럽트를 마스킹(또는 경우에 따라 마스킹된 상태로 유지)합니다.관련된 인터럽트가 완료되기 전에 마스크 해제되는 (비정상적인) FLIH를 재진입 인터럽트 핸들러라고 부릅니다.재진입 인터럽트 핸들러는 같은 인터럽트 벡터에 의한 복수의 프리엠프션으로부터의 스택오버플로를 일으킬 수 있기 때문에, 통상은 회피됩니다.priority interrupt 시스템에서는 FLIH는 priority가 같거나 낮은 다른 인터럽트도 (간단히) 마스킹합니다.
SLIH는 프로세스와 마찬가지로 긴 인터럽트 처리 태스크를 완료합니다.SLIH는 각 핸들러의 전용 커널 스레드를 가지거나 커널 워커 스레드 풀에 의해 실행됩니다.이러한 스레드는 인터럽트 처리를 수행하기 위해 프로세서 시간을 사용할 수 있을 때까지 운영 체제의 실행 큐에 저장됩니다.SLIH는 실행 시간이 길기 때문에 일반적으로 스레드 및 프로세스와 동일하게 스케줄 됩니다.
Linux 에서는 FLIH는 상반,[1][2] SLIH는 하반 또는 하반이라고 불립니다.이는 둘 다 하위 [clarification needed]절반의 일부인 다른 Unix 계열 시스템에서 사용되는 이름과는 다릅니다.
「 」를 참조해 주세요.
- Advanced Programmable Interrupt Controller(APIC)
- Inter-Processor Interrupt(IPI; 프로세서간 인터럽트)
- 인터럽트 레이텐시
- 65xx 프로세서의 인터럽트
- IRQL(Windows)
- Non-Maskable Interrupt(NMI; 마스크 불가능 인터럽트)
- 프로그래머블 인터럽트 컨트롤러(PIC)
- 레드 존
레퍼런스
- ^ a b c "The Linux Kernel Module Programming Guide, Chapter 12. Interrupt Handlers". The Linux Documentation Project. May 18, 2007. Retrieved February 20, 2015.
- ^ a b c d Jonathan Corbet; Alessandro Rubini; Greg Kroah-Hartman (January 27, 2005). "Linux Device Drivers, Chapter 10. Interrupt Handling" (PDF). O'Reilly Media. Retrieved February 20, 2015.