인터럽트와 NVIC: 우선순위와 짧은 처리
우선순위 그룹, 선점과 서브 우선순위, 처리 함수를 짧게 유지하는 이유, 공유 변수를 안전하게 다루는 법.
NVIC 설정 세 가지
- 주변장치에서 인터럽트 허용 (예:
USART1->CR1 |= RXNEIE) - NVIC에서 그 인터럽트 번호 허용 (
NVIC_EnableIRQ(USART1_IRQn)) - 우선순위 설정 (
NVIC_SetPriority)
하나라도 빠지면 인터럽트가 들어오지 않습니다.
우선순위
STM32는 숫자가 작을수록 높은 우선순위입니다. 높은 인터럽트는 낮은 인터럽트 처리 중에도 끼어듭니다(선점).
| 인터럽트 | 우선순위 예 |
|---|---|
| 과전류 보호 | 0 (가장 높음) |
| 전류 제어 ADC 완료 | 1 |
| 통신 수신 | 5 |
| 버튼 | 10 |
RTOS를 쓰면 RTOS API를 부르는 인터럽트는 configMAX_SYSCALL_INTERRUPT_PRIORITY보다 낮은 우선순위여야 합니다.
처리 함수 원칙
- 플래그 세우기, 버퍼에 넣기, 레지스터 값 저장만 하고 나옵니다.
printf,HAL_Delay, 긴 계산 금지- 인터럽트 원인 플래그를 지웁니다
공유 변수
volatile uint32_t ticks;
uint32_t get_ticks(void) {
__disable_irq(); uint32_t t = ticks; __enable_irq(); // 32비트는 원자적이지만 구조체라면 필수
return t;
}
여러 바이트로 된 값이나 여러 변수를 한꺼번에 읽을 때는 잠깐 인터럽트를 끄거나 복사본을 씁니다.
인터럽트를 켜려면 세 곳을 모두 열어야 한다
- 주변장치: 어떤 사건에서 요청을 낼지 (예:
USART1->CR1 |= USART_CR1_RXNEIE) - NVIC: 그 요청 선을 받을지, 우선순위는 얼마인지
- 전역 허용: CPU가 인터럽트를 받는 상태인지
NVIC_SetPriority(USART1_IRQn, 2);
NVIC_EnableIRQ(USART1_IRQn);
USART1->CR1 |= USART_CR1_RXNEIE;
셋 중 하나라도 빠지면 핸들러가 불리지 않습니다. 순서는 우선순위를 먼저 정하고 나서 허용하는 쪽이 안전합니다.
3D 실험실여기까지 읽은 내용을 직접 돌려 볼 수 있습니다→우선순위: 숫자가 작을수록 급하다
Cortex-M에서는 값이 작을수록 우선순위가 높습니다. 0이 가장 급합니다.
| 예시 | 우선순위 | 이유 |
|---|---|---|
| 과전류 보호 | 0 | 늦으면 부품이 탄다 |
| 모터 전류 제어 (PWM 주기) | 1 | 주기가 흔들리면 제어가 무너진다 |
| 통신 수신 | 2 | 한 바이트 시간 안에만 읽으면 된다 |
| 시스템 틱 | 3 | 조금 늦어도 된다 |
높은 우선순위 인터럽트는 낮은 것의 핸들러를 중간에 끊고 들어옵니다(선점). 같은 우선순위끼리는 끊지 않고 차례를 기다립니다.
그림으로 보기: 선점
임계 구역은 짧게
메인 루프와 핸들러가 같은 데이터를 다룬다면, 메인 쪽에서 그 데이터를 만지는 동안만 인터럽트를 막습니다.
uint32_t prim = __get_PRIMASK();
__disable_irq();
copy = shared_value; // 몇 줄 이내
__set_PRIMASK(prim); // 원래 상태로 복원
무조건 __enable_irq()로 푸는 대신 원래 상태를 복원하는 이유는, 이 코드가 이미 인터럽트가 꺼진 곳에서 불렸을 때 멋대로 켜 버리지 않기 위해서입니다.
현업에서 자주 터지는 문제
- 우선순위 비트 수: 많은 MCU가 8비트 중 상위 4비트만 구현합니다. 직접 레지스터에 쓸 때는 자리를 맞춰야 하고,
NVIC_SetPriority를 쓰면 알아서 처리됩니다. - RTOS와 함께 쓸 때: RTOS API를 부르는 인터럽트는 RTOS가 정한 값보다 우선순위가 낮아야(숫자가 커야) 합니다. 어기면 드물게 죽는 버그가 됩니다.
- 핸들러 안의 긴 작업: 그동안 낮은 우선순위 인터럽트가 모두 밀려 UART 바이트를 놓칩니다.
- 공유 변수의
volatile누락: 최적화 빌드에서만 증상이 나타납니다.
연결된 개념
영상으로 이어 보기회로와 하드웨어 시리즈 8편전자제품 속 회로 소자는 어떻게 동작할까? · 저항 · 커패시터 · 인덕터 완벽 정리PROJECT COURSE레지스터 설정을 실제 보드에서 해 보고 싶다면밸런싱 로봇 하나를 요구사항, 회로와 PCB, 펌웨어, 앱까지 실무 순서대로 만드는 강의입니다. 10파트 165강.강의 살펴보기 →FREE PDF무료 전자책 3권 받기이 주제를 한 권으로 이어서 읽고 싶다면. BLDC 모터 제어, 직렬통신, 센서를 책 분량으로 묶었습니다. 이메일만 남기면 바로 받습니다.무료로 받기 →