보드를 쓸 때 사용자의 입력을 polling/interrupt 방식에 의해 감지할 수 있다.
2가지 방식으로 구현하기에 앞서 개념을 정의해보자.
polling은 하드웨어의 변화를 지속적으로 읽어 들이며 이벤트의 수행 여부를 주기적으로 검사하여 해당 신호를 받았을때 이벤트를 실행하는 방식이다.
Interrupt는 하드웨어의 변화를 감지하여 외부로부터의 입력을 CPU가 알아채는 방법이다. 인터럽트는 이벤트를 수행하라는 IRQ를 받으면, 인터럽트 핸들러를 통해 ISR이 동작하게 된다.
polling은 진짜 하염없이 기다리는 거고, interrupt는 IRQ라는 메시지를 준 후에 오는 친구를 기다리는 거라고 볼 수 있다.
폴링 방식은 CPU가 직접 일을 하기 때문에 입출력 처리 시간이 오래 걸린다.
UART (BufferedSerial)에서는 pc.readable()
을 통해 구현할 수 있다. 하지만, 이를 사용하지 않고 방법2와 같이 구현할 수도 있는데, 이는 polling 방식의 정의와 같다. (하 염 없 이 기 다 려)
while(1) {
if (pc.readable()) {
led = !led;
int num = pc.read(buf, sizeof(buf));
pc.write(buf, num);
if (buf[0] == '\r'){
pc.write("\n", 1);
}
}
} // end of while
while(1) {
led = !led;
// 문자 입력될 때까지 기다림
int num = pc.read(buf, sizeof(buf));
// 문자 출력
pc.write(buf, num);
// enter 입력 시, line 변경
if (buf[0] == '\r') pc.write("\n", 1);
} // end of while
void sigio ( Callback <void() > func )
- 상태 변화에 대한 callback 함수를 등록한다.
(쓸 수 있거나, 읽을 수 있는 것과 같이 상태 변화가 있을 때에 콜백 함수가 실행된다. )- callback 함수 내에서 heavy job을 수행하지 않아야 한다.
(어떤 인터럽트 컨텍스트 안에서 콜백 함수가 불리워진다. )
serial_port.sigio(&rx_handler);
위와 같이 선언하면 인터럽트가 발생했을 때 rx_handler 함수를 실행하게 된다. 단, 위 함수는 rx, tx 모두에 대한 상태변화를 가져오기 때문에 rx에 대해서만 핸들링하고 싶다면 따로 체크해줘야 하는 부분이 있음을 간과하지 않아야 한다.
go에서 polling사용하려다가 고생했죠,, 총총