Interrupt Service Routine. 다른 모든 코드를 멈춰 세우고 실행되는 함수다.
금기
블로킹 대기 다른 인터럽트와 메인이 전부 멈춘다
동적 할당 시간이 불확정이고 재진입 안전하지 않다
printf · 부동소수점 느리고, 라이브러리가 재진입 안전하지 않을 수 있다
긴 계산 지연이 그대로 다른 인터럽트에 전가된다
정석 구조
volatile uint8_t rx_flag;
void USART1_IRQHandler(void) {
if (USART1->SR & USART_SR_RXNE) {
ring_put(USART1->DR); /* 하드웨어에서 꺼내 버퍼에 넣기만 */
rx_flag = 1; /* 나머지는 메인이 한다 */
}
}
반드시 챙길 것
- 플래그 클리어 — 안 지우면 핸들러를 빠져나가자마자 다시 들어와 무한 반복한다
- 공유 변수는
volatile, 여러 바이트면 원자성까지 고려 - 하드웨어 레지스터를 읽어야 플래그가 지워지는 주변장치도 있다 — 데이터시트를 확인한다