DUJINLABS.COM

전자회로 실무 / 펌웨어

인터럽트(interrupt)에서는 발생 사실만 기록하고, 오래 걸리는 처리는 메인 루프(main loop)로 넘깁니다

인터럽트(interrupt) 안에서 기다리거나 많은 데이터를 출력하면 다른 작업이 늦어질 수 있습니다. 인터럽트에서는 필요한 정보만 저장하고, 시간이 걸리는 처리는 메인 루프(main loop)에서 이어서 하도록 나눕니다.

먼저 알아둘 용어

ISR(Interrupt Service Routine)·메인 루프(main loop) — ISR은 인터럽트가 발생할 때 실행되는 처리 함수입니다. 메인 루프는 입력 확인과 출력 갱신 등을 반복하는 프로그램(program)의 기본 실행 부분입니다. ISR을 짧게 끝내면 다른 작업이 오래 지연되는 것을 줄일 수 있습니다.

이벤트(event)·플래그(flag)·큐(queue) — 이벤트는 버튼(button) 입력처럼 프로그램에서 처리해야 하는 변화나 동작입니다. 플래그는 이벤트가 있었다는 참·거짓 표시입니다. 큐는 여러 이벤트를 순서대로 담는 저장 공간입니다. 이벤트의 수와 순서가 필요하면 플래그 하나로 대체할 수 없습니다.

원자성·임계 구역·volatile — 원자성은 다른 실행 흐름이 중간 상태를 끼어들어 보지 못하게 하는 성질입니다. 임계 구역은 공유 상태를 짧게 보호하는 구간입니다. volatile 선언만으로 여러 단계의 처리나 다중 코어(core) 동기화가 원자적으로 되지는 않습니다.

RTOS(Real-Time Operating System) — 실시간 운영체제로, 작업과 인터럽트 사이 전달을 위한 큐·알림 기능 등을 제공합니다. ISR에서는 그 환경이 허용한 전용 기능을 사용해야 합니다.

인터럽트가 이벤트를 큐에 넣고 메인 루프가 나중에 꺼내 처리하는 순서입니다. 재생 속도와 움직임의 크기는 설명을 위한 것입니다.
정지 그림 확대
인터럽트가 이벤트를 큐에 넣고 메인 루프가 나중에 꺼내 처리하는 순서입니다. 재생 속도와 움직임의 크기는 설명을 위한 것입니다. · 그림을 클릭하면 확대됩니다.

먼저 보존해야 할 이벤트의 정보를 정합니다

버튼을 누른 뒤 1초 동안 표시를 바꾸려는 경우, ISR에서 1초를 기다리는 대신 이벤트 표시를 남기고 바로 돌아옵니다. 메인 루프에서 표시를 시작하고, 경과 시간이 끝나면 표시를 종료합니다. 하지만 참·거짓 플래그 하나는 처리 전에 두 번 발생한 이벤트를 하나로 합친다는 한계가 있습니다.

ISR이 필요한 최소 정보만 저장하고 메인 루프가 안전하게 가져간 뒤 실제 작업을 수행하도록 구성합니다. “한 번 이상 발생했습니다”만 필요할 때는 플래그를 사용할 수 있습니다. 모든 펄스 수가 필요하면 카운터, 순서나 개별 데이터가 필요하면 큐를 검토합니다. 저장 공간을 초과했을 때 버림·오류 표시·누적 횟수 기록 중 무엇을 할지도 정합니다.

AVR 같은 단일 코어 MCU(Microcontroller Unit)에서는 플래그를 읽고 지우는 사이에 ISR이 다시 실행되는 경합을 고려합니다. 기존 인터럽트 상태를 보존하면서 짧은 임계 구역 안에서 플래그를 읽고 지웁니다. 오래 걸리는 작업은 그 구역을 벗어난 뒤 수행합니다. 공유 변수에 붙이는 volatile은 컴파일러가 변수 접근을 임의로 생략하거나 이전 값으로 대체하지 않도록 지정하는 데 쓰입니다. 그러나 여러 단계의 작업이 중간 개입 없이 끝나는 원자성(atomicity)이나 여러 코어 사이의 동기화까지 보장하지는 않습니다. RTOS·다중 코어에서는 해당 환경의 ISR용 큐·알림 등 허용된 수단을 따릅니다.

ISR 안에서는 지연 함수, 시간 함수, 출력 함수가 메인 루프에서 호출할 때와 같은 방식으로 동작한다고 가정하지 않습니다. 다른 인터럽트에 의존하는 함수는 대기에서 빠져나오지 못할 수 있습니다. 사용 플랫폼에서 허용하는 기능과 중첩·우선순위 규칙을 확인하고 긴 작업은 공유 상태를 보호하는 구간 밖에서 수행합니다.

확인 시험은 단일 이벤트, 빠른 연속 이벤트, 메인 루프가 바쁜 동안의 이벤트를 나눕니다. 플래그를 쓴다면 합쳐지는 이벤트가 의도와 맞는지, 카운터·큐라면 손실과 넘침을 알아낼 수 있는지 봅니다. “ISR에서 빠져나왔다”와 “필요한 일을 모두 처리했다”는 서로 다른 완료 조건입니다.

작업 순서를 다시 확인합니다

인터럽트에서는 발생 사실만 기록하고, 오래 걸리는 처리는 메인 루프로 넘깁니다 — 설명용 도해
인터럽트에서는 발생 사실만 기록하고, 오래 걸리는 처리는 메인 루프로 넘깁니다 — 설명용 도해 · 클릭하면 확대됩니다.