2015년 4월 19일 일요일

아두이노 인터럽트 개요

 보통 프로세서가 사용되는 디지털 시스템(아두이노 등)에서는 만약 계통에 특정한 이벤트가 발생했을 경우에는 수행 중인 작업을 중단하고 발생한 이벤트를 처리한 다음, 다시 원래 수행하던 작업으로 되돌아가 계속 처리하게 된다. 이러한 ‘즉시 처리해야 하는 특수한 이벤트의 발생’을 인터럽트라고 한다. 인터럽트가 발생하면 아두이노는 그 이벤트를 처리할 작업들이 수록된 함수를 호출하는데 이 함수를 인터럽트 서비스 루틴 (interrupt service routine, 이하 ISR)이라고 한다.

  • 인터럽트 : 즉시 처리해야 하는 특수한 이벤트의 발생
  • ISR : 인터럽트 서비스 루틴, 인터럽트가 발생했을 때 호출되는 함수

 이 인터럽트는 마이크로프로세서 시스템에서 굉장히 중요한 비중을 차지한다. 비유를 들어서 설명하자면 어떤 전화기가 있는데 전화가 걸려왔는데도 벨소리도 안 나고 진동도 안 된다고 가정해보자. 이 전화기로 꼭 받아야만 하는 중요한 전화가 올 예정이라면 그 사람은 다른 일은 못 하고 몇 초에 한 번씩 전화가 왔나 안 왔나 들어서 확인해 봐야 할 것이다. 하지만 전화가 걸려왔을 때 벨소리가 나거나 진동하는 전화라면 편하게 다른 일을 하고 있다가 전화가 오면 벨소리를 듣고(인터럽트 요구) 전화를 받아 용무를 처리한 후 하던 일을 계속할 것이다.

 터치 버튼을 가지고 부연 설명을 하면 ‘터치되었다’라는 특수한 이벤트를 감지하려면 기본적으로 아두이노가 loop()함수 내에서 항상 이 버튼의 상태를 검사해야 한다. 하지만 이것을 인터럽트로 처리하면 소프트웨어적으로 이 버튼의 상태를 항상 검사할 필요가 없이 다른 일을 할 수가 있는 것이다. 다른 작업을 하고 있다가 ‘버튼이 눌려지면’ 그 즉시 (하드웨어적으로) 인터럽트를 발생하여 하던 일을 멈추고 이를 처리할 ISR을 호출한 뒤 ISR이 끝나면 하던 일을 다시 하면 되는 것이다. 이와 같이 (외장 혹은 내장) 주변기기와 아두이노가 통신을 수행하는데 있어서 아두이노가 주변기기의 상태를 loop()함수에서 상시 검사하지 않고 인터럽트로 처리하면 전체적인 시스템의 운용 효율이 매우 높아지게 된다.

 아두이노 우노의 경우 인터럽트를 처리할 수 있는 핀은 2번과 3번 핀인데 각각 INT0, INT1이라고 부른다. (인터럽트 0번, 인터럽트 1번 이다.)

[표 1] 아두이노 우노의 인터럽트핀

INT0
INT1
핀번호
2번 핀
3번 핀

 좀 더 구체적으로 설명하면 인터럽트라는 것은 이 핀들의 특정한 신호 상태를 의미한다. 예를 들면 신호가 0에서 1로 바뀌는 순간 (또는 그 반대의 경우도) 에 하던 일을 멈추고 연결된 특정한 함수(ISR)를 수행할 수 있다. 신호가 0에서 1로 변하는 순간을 ‘rising edge’ 라고 하고 1에서 0으로 변하는 순간을 ‘falling edge’라고 한다.

ISR을 등록하기 위한 아두이노 함수로 attachInterrup()라는 함수가 있다.

   attachInterrupt( pin, ISR, mode) 함수
  • 인터럽트핀에 처리 함수를 붙이는 일을 수행한다.
  • pin 값은 우노의 경우 0(또는 INT0 ), 1 (또는 INT1) 둘 중 하나이다.
  • 2번 핀의 경우 0을, 3번 핀의 경우 1을 입력해야 한다는 것에 주의해야 한다. 혼동을 피하기 위해서 INT0, INT1 상수를 이용할 것을 권한다.
  • ISR은 인터럽트가 걸렸을 때 호출할 함수의 이름이다.
  • mode 는 RISING / FALLING / CHANGE / LOW 중 하나이다. (아래 표 참조)


RISING
FALLING
CHANGE
LOW
[그림 1] 아두이노에서 사용되는 인터럽트의 종류

 ISR은 입력 인수를 받을 수 없고 출력도 void형이어야 한다. 이 attatchInterrupt() 함수는 통상 setup() 함수 안에서 사용되어 초기에 인터럽트를 설정한다.


댓글 없음:

댓글 쓰기