21.2.2.1.3. PRIORITY 파라미터가 SCHED_FIFO 및 SCHED_RR 스케줄링 정책에 미치는 영향
px4_add_module() 매크로에서 STACK_MAIN만큼이나 심장 떨리는 파라미터가 바로 **PRIORITY**이다.
px4_add_module(
# ...
PRIORITY SCHED_PRIORITY_DEFAULT
# ...
)
이 속성은 NSH(NuttShell) 명령어로 기동되는 데몬(Daemon) 기반 독립 태스크들의 ’계급장’을 정해주는 옵션이다. (주의: Work Queue에 종속되는 모듈은 메인 워커 스레드의 우선순위를 상속받으므로, 이 PRIORITY 파라미터보다는 자신이 어느 이름의 큐에 올라타느냐가 더 중요하다.)
이 계급장이 왜 그토록 중요할까? 기체의 센서 데이터가 폭주할 때, OS 커널인 NuttX 스케줄러가 **“누구를 먼저 살리고 누구를 죽일 것인가”**를 결정하는 구명보트 티켓 발권 기준이 바로 이 PRIORITY 값과 스케줄링 정책(Scheduling Policy)의 조합이기 때문이다.
1. NuttX의 스케줄링 정책: SCHED_FIFO와 SCHED_RR
PX4 시스템은 POSIX 표준 리얼타임 스케줄링 정책(RTOS Policy)인 SCHED_FIFO(First-In, First-Out)와 SCHED_RR(Round-Robin) 둘 다 완벽하게 지원한다. 펌웨어의 코어 빌드 설정에 따라 기본 정책이 결정되지만, 대체로 고성능 비행 제어를 위해 **SCHED_FIFO**가 우세하게 쓰인다. 우선순위 파라미터가 이 두 정책에 어떻게 영향을 미치는지 살펴보자.
1.1 SCHED_FIFO (엄격한 계급주의)
- 동작 원리: 가장 높은
PRIORITY숫자를 가진 스레드가 CPU를 영원히 독점(Monopolize)한다. 이 1등 스레드가 스스로 CPU를 반납(sleep이나yield)하거나 I/O 블로킹에 걸리지 않는 이상, 2등부터 꼴등 스레드들은 죽을 때까지 CPU를 구경조차 해보지 못한다(기아 상태, Starvation). - 패러미터의 무게:
SCHED_FIFO환경에서는 우선순위를SCHED_PRIORITY_MAX(가장 높음, 보통 255)에 가깝게 부여하는 행동이 곧 시스템의 생명줄을 쥐고 흔드는 행위이다. 만약 조잡하게 짜인 커스텀 모듈에MAX우선순위를 주고 무한 루프 블로킹 에러를 발생시킨다면, EKF나 자세 제어기조차 CPU를 빼앗겨 기체는 즉각 추락한다.
1.2 SCHED_RR (타임 슬라이스 기반 계급주의)
- 동작 원리:
SCHED_FIFO와 똑같이 계급(우선순위)이 높은 스레드 그룹을 먼저 대우해 주지만, 동일한 우선순위를 가진 스레드 사이에서는 OS 스케줄러가 일정한 시간(Time slice, 퀀텀) 단위로 모가지를 치며 공평하게 번갈아 가며 실행시켜 준다. - 패러미터의 무게:
SCHED_RR환경에서도 여전히PRIORITY값은 하위 스레드들을 깔아뭉개는 절대적인 권력을 가진다. 다만, 같은 계급 간의 무한 독점은 막아준다는 점에서 데스크톱 운영체제와 털끝만큼 비슷한 안전성을 기대할 수 있다.
2. 매크로 상수 선택의 가이드라인
따라서 개발자가 px4_add_module()을 작성할 때 PRIORITY 속성에는 200, 150 같은 하드코딩된 매직 넘버(Magic Number)를 절대 적어 넣으면 안 된다. PX4 커널에 이미 정의된 계급 티어(Tier) 상수들을 사용해 시스템 체계에 순응해야 한다.
SCHED_PRIORITY_FAST_DRIVER(최상위 계급):
I2C, SPI 버스로부터 인터럽트 콜백을 받는 하단 센서 코어들만 누릴 수 있는 특권이다. 커스텀 모듈이 단순히 릴레이를 제어하거나 화면 로깅을 하는 정도라면 감히 쳐다봐서는 안 될 계급이다.SCHED_PRIORITY_MAX~SCHED_PRIORITY_HIGH(고위 계급):
자세 제어(Attitude Controller), MAVLink 수신 등 비행기 추락과 직결되는 인루프(In-loop) 고속 모듈들이 위치한다.SCHED_PRIORITY_DEFAULT(평민 계급):
대부분의 커스텀 백그라운드 데몬(Custom Background Daemon)이 위치해야 할 가장 안전하고 권장되는 층위이다. 비행 루틴을 건드리지 않고, 남는 CPU 자원을 주워 먹으면서 느긋하게 로직을 처리한다.SCHED_PRIORITY_SLOW_DRIVER(천민 계급):
주기적인 디스크 백업이나 중요도 낮은 파일 덤프 등 가장 늦게 처리되어도 무방한 작업들을 할당한다.
요약하자면, CMakeLists.txt 내의 PRIORITY 지시어는 내가 짠 모듈이 1) 기체의 추락에 얼마나 크게 관여하는지, 그리고 2) SCHED_FIFO라는 무자비한 철권통치 아래서 다른 중요한 모듈의 목을 조르지 않을 자신이 있는지 묻는 자기 성찰의 서명(Signature)과도 같다.
오직 C++ 코드 컴파일러만 설정했다면 펌웨어는 반쪽짜리다. 이렇게 번역된 모듈을 PX4 혈관망인 uORB 메시지 생태계와 어떻게 연동시킬 것인가? 그 링킹(Linking)의 결합에 대해서 다음 단원 21.2.2.2에서 속 시원히 파헤쳐 본다.