인터럽트 - 개념
이번 글에서는 프로그램이 정상적인 흐름대로 실행되고 있는 도중에, 어떤 이유에 의해서 수행중인 프로그램을 멈추고 특정 위치에서 명령어를 읽어 와서 실행하는 인터럽트에 대해서 설명하도록 하겠다. 사실, 인터럽트는 이게 전부다. 수행중인 프로그램을 멈추고 지정된 주소에서 프로그램을 실행하도록 하는거. 문제를 해결한 다음엔 멈춘 위치로 다시 돌아가 아무일 없는듯이 정상적인 동작을 계속하도록 한다.
그럼 AVR에서는 어떤 경우에 수행중인 프로그램을 중단시키는지 그 이유를 알아보겠다.
위에 보이는 표가 ATmega328에서 사용가능한 인터럽트 종류이다. 모두 26개의 인터럽트가 있다. 만약 UART로 데이터가 수신되면 19번 인터럽트가 발생하고 그에 따라 CPU는 0x0024번지에서부터 명령어를 수행하게 된다. 물론 여기에 보여지는 주소는 바이트 주소가 아니고 워드 주소이다. 바이트 주소는 곱하기 2를 하여야 한다.
AVR의 경우에는 이렇게 인터럽트마다 정해진 벡터 주소를 가지고 있다. 그러나 32비트 구조의 일반적인 CPU는 AVR과는 조금 다른 인터럽트 구조를 가지고 있다. ARM CPU를 예로 들어 설명하겠다.
정상적인 흐름의 프로그램을 멈추고 정해진 주소에서 프로그램을 실행하도록 하는것을 exception이라고 부른다. 인터럽트는 exception의 한 종류일 뿐이다.
ARM CPU는 7개의 exception이 있다. 어떤 종류의 CPU라도 가지고 있는 Reset exception을 비롯하여, Undefined instructions, SWI, Prefetch Abort, Data Abort, IRQ, FIQ가 있다. PowerPC와 MIPS CPU는 이보다 좀더 많은 exception이 있다. CPU에 exception이 발생했다는 것은 뭔가 굉장히 중요한 일이 발생했다는 것을 의미하므로, 현재 수행중인 프로그램을 즉시 멈추고 exception의 원인에 따라 지정된 주소에서 프로그램을 시작하는 것이다.
ARM CPU는 위의 그림과 같이 외부에 Interrupt controller라는 HW 모듈이 있다. 모든 외부장치에서 발생하는 인터럽트 신호는 interrupt controller로 모인다. 프로그램으로 각각의 인터럽트를 사용할 지, 사용하지 않을지 선택할 수 있다. Interrupt controller에 원하는 인터럽트를 enable 시킨 상태에서 인터럽트가 들어오면 IRQ 혹은 FIQ를 통해서 CPU에게 인터럽트시그널을 보낸다. 이때 CPU에서는 IRQ 혹은 FIQ exception이 발생하게 되고, 특정 벡터 주소에서 프로그램이 실행된다. 물론 CPU 내부에 있는 program status register(CPSR)에 IRQ, FIQ 인터럽트를 enable할 수 있는 제어 비트가 있다. 이 비트를 disable 시키면 interrupt에 의한 exception이 발생하지 않게 된다. IRQ/FIQ exception이 발생하면 어떤 인터럽트가 발생했는지 interrupt controller 안에 있는 interrupt status register를 스캔하여 어떤 주변 장치에서 인터럽트가 들어왔는지 알 수 있게 된다.
AVR은 마이크로컨트롤러라는 구조상 제약이 있으므로 interrupt controller를 생략하고 CPU에서 직접 인터럽트를 처리하도록 하는 것이 일반적인 인터럽트 처리 절차와 다른 점이다.
위에서 잠깐 언급했듯이 모든 CPU에는 reset exception이 있고 이를 위한 reset vector 주소가 정해져 있다. Reset vector주소는 cpu가 reset 상태에서 깨어나면서 첫번째 명령어를 읽어 오는 주소가 된다. 만약 reset exception vector 주소에 유효한 명령어가 없으면 정상적인 프로그램이 실행 될 수 없게 된다. 따라서 프로그램의 시작 부분이 항상 reset vector 주소에 놓일 수 있도록 프로그램을 만들어야 한다.
참고로 AVR에는 네개의 reset 을 제공한다. Power-on Reset, External Reset, Watchdog Reset, Brown-out Reset이 있다. 각 Reset이 발생하는 이유는 datasheet 문서를 보면 알수 있다.
다음 글에서 실제 AVR에서 어떻게 인터럽트를 처리하는지 실습을 통해서 배워보도록 하겠다.