지노랩 /JinoLab
FreeRTOS 인터럽트 우선순위 설정 제대로 이해하기 본문
**configMAX_SYSCALL_INTERRUPT_PRIORITY(또는 configMAX_API_CALL_INTERRUPT_PRIORITY)**가 도대체 무슨 의미인지 헷갈리셨다면, 이 글로 한 방에 정리해 보세요!
1. 왜 또 다른 우선순위 매크로가 있을까?
FreeRTOS 커널은 SysTick / PendSV / SVC 같은 ‘커널 전용 인터럽트’를 가장 낮은 우선순위(예: 0xF0)로 고정해 둡니다.
그러나 사용자 인터럽트(UART, ADC, TIM 등)는 상황에 따라 RTOS API를 호출해야 할 때가 있고, 또 어떤 ISR은 완전 실시간(순수 Bare-metal) 로 동작해야 하기도 합니다.
그래서 “API를 부를 수 있는 ISR”와 “절대 부르면 안 되는 ISR” 간 경계값이 필요합니다.
이 값이 바로 configMAX_SYSCALL_INTERRUPT_PRIORITY 입니다.
2. 매크로가 가리키는 ‘경계선’
구분 우선순위 값(숫자) 의미
0x00 ~ configMAX_SYSCALL_INTERRUPT_PRIORITY-1 | 가장 높은 우선RTOS 임계구역보다 우선 실행 → RTOS API 호출 금지 | |
configMAX_SYSCALL_INTERRUPT_PRIORITY ~ 0xF0 | 커널보다만 높으면 OK → …FromISR() 계열 API 호출 가능 | |
0xF0 (커널) | SysTick, PendSV, SVC |
즉, 이 숫자보다 “같거나 큰 값(=우선도가 낮은 인터럽트)” 에서만 xQueueSendFromISR(), xTaskNotifyFromISR() 같은 API를 안전하게 부를 수 있습니다.
3. STM32F4 예시로 계산해 보기
- CMSIS 확인
- #define __NVIC_PRIO_BITS 4 // 4비트 우선순위 → 16단계(0~15)
- 커널 우선순위
- #define configKERNEL_INTERRUPT_PRIORITY (15 << (8-4)) // 0xF0
- SYSCALL 한계값 설정 (보통 5~10 정도 채택)
- #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 10 #define configMAX_SYSCALL_INTERRUPT_PRIORITY (10 << (8-4)) // 0xA0
- 결과
- API 사용 ISR : 우선순위 10(0xA0) ~ 15(0xF0)
- 초고속 ISR : 우선순위 0 ~ 9 (RTOS 호출 금지)
4. 실수 방지 체크리스트 ✅
- ISR 안에서 xXXXFromISR() 호출 시 NVIC_SetPriority() 값이 0xA0 이상인지 확인.
- PendSV / SysTick 우선순위는 절대 바꾸지 않는다.
- 라이브러리 기본값(=0) 그대로 두고 API를 부르면 HardFault 날 확률 100%!
5. 한 줄 요약
“RTOS API를 쓰는 인터럽트는 configMAX_SYSCALL_INTERRUPT_PRIORITY(예: 0xA0)보다 숫자가 크거나 같은 우선순위로 설정하라.”
이 원칙만 기억하면 우선순위 충돌로 인한 데드락·HardFault 걱정 끝!
안전하고 깔끔한 FreeRTOS 프로젝트에 꼭 적용해 보세요. 🚀
'임베디드 시스템 > RTOS' 카테고리의 다른 글
FreeRTOS Hook Function (0) | 2025.06.28 |
---|---|
인터럽트 안에서 …FromISR() 버전을 꼭 써야 하는 이유 (1) | 2025.06.27 |
FreeRTOS 하드웨어 인터럽트 우선순위 정리 (2) | 2025.06.26 |
FreeRTOS Task 우선순위 vs. 하드웨어(인터럽트) 우선순위 (0) | 2025.06.26 |
FreeRTOS Task 삭제, 정말 필요할까? (0) | 2025.06.25 |