### 0.0.1 드라이버 모듈화 및 스레드 병렬 처리 모델 비교
센서 데이터를 읽고 해석하는 행위는 비행 제어 시스템 입장에서 꽤 성가신 I/O(Input/Output) 작업이다.
수십에서 수백 밀리초마다 무작위로 도착하는 시리얼 포트 바이트 스트림을 조립하고 NMEA나 u-blox 프로토콜의 체크섬(Checksum)을 검증하는 이 저수준(Low-level) I/O 태스크를, 눈썹 휘날리게 돌아가야 할 기체 제어 루프(Control Loop)와 어떻게 격리시킬 것인가?
이 지점에서 철저한 수평 배분을 택한 PX4와 집중형 계층 마스터 방식을 고수하는 Ardupilot의 스레드 병렬 처리(Thread Parallelism) 철학이 정면으로 엇갈리게 된다.
0.1 PX4의 ‘1 드라이버 = 1 프로세스(Task)’ 철학
POSIX 스탠다드를 추구하는 NuttX RTOS 기반의 PX4는 유닉스 계열 운영체제의 디자인 패턴인 수평적 모듈화(Horizontal Modularity) 를 비행 펌웨어에 그대로 이식했다.
- PX4 시스템 내에서
gps모듈은 메인 스케줄러에 기생하는 함수가 아니라, 자신만의 전용 메모리 공간과 CPU 할당량(Quota)을 부여받은 완전히 독립된 백그라운드 데몬(Background Daemon) 처럼 작동한다. - 다중 GPS 환경이라면,
/dev/ttyS0포트를 물고 있는gps데몬 하나와/dev/ttyS1을 물고 있는gps데몬이 운영체제 상에서 두 개의 개별적인 스레드로 창설된다. - 이 두 프로세스는 각자가 알아서(Asynchronously) 시리얼 포트에서 바이트를 긁어오고 파싱한다. 한쪽 GPS 모듈에서 배선 불량으로 타임아웃 락(Lock)이 걸리거나, 파싱 로직에서 무한 루프 버그가 터져 해당 태스크가 크래시(Crash)되더라도, 다른 GPS 데몬이나 중앙의 비행 제어 루프는 이를 전혀 눈치채지 못하고 제 갈 길을 간다.
- 이는 탁월한 오류 격리(Fault Isolation) 성능을 제공하며, 각 드라이버 개발자가 코드를 수정할 때 다른 모듈의 상태를 신경 쓰지 않아도 되는 이상적인 독립성을 보장한다.
0.2 Ardupilot의 ‘스케줄러 주도형’ 백엔드 관리
반면 Ardupilot(정확히는 ChibiOS 베이스의 메인 브랜치 트렌드)은 하나의 강력한 지휘자(Scheduler)가 모든 센서를 지휘하는 수직적 통합(Vertical Integration) 을 택했다.
- Ardupilot에도 수많은 스레드(Thread)가 존재하지만, 센서 I/O 처리만을 전담하는 커다란 I/O 스레드가 여러 센서(GPS 1, GPS 2, 지자기 센서, 기압계 등)의 레지스터나 포트를 숨 가쁘게 순회(Round-Robin 또는 우선순위 큐 방식)하며 데이터를 거두어들인다.
AP_GPS라는 단일 프론트엔드 라이브러리 객체가 두 개의 물리적 수신기에 대한 백엔드 드라이버 인스턴스(instance 0, instance 1)를 소유(Ownership)한다.- 결과적으로 GPS 1번 포트를 파싱하는 작업과 2번 포트를 파싱하는 작업은 물리적으로 완전히 분리된 프로세스가 아니며, 라이브러리의 통합된 시간표(Timeline) 내에서
update()함수가 차례대로 호출되는 방식에 가깝다. - 이 방식의 장점은 스레드 스위칭 오버헤드가 PX4 대비 적고, 메모리 공유가 직관적이며, 모든 센서의 데이터 취득 타이밍을 메인 루프 관점에서 훨씬 결정론적(Deterministic)으로 쥐락펴락할 수 있다는 데 있다.
0.3 I/O 블로킹(Blocking)과 병목(Bottleneck) 현상의 해결
GPS 데이터를 읽는 read() POSIX 함수는 버퍼에 데이터가 찰 때까지 스레드를 잠재우는(Block) 특성이 있다.
- PX4는 드라이버가 완전히 독립된 스레드이므로,
read()함수에서 스레드가 블로킹되어 슬립(Sleep) 상태에 빠지는 것을 두려워하지 않는다. 어차피 운영체제(NuttX)가 알아서 다른 알짜배기 스레드에게 CPU 제어권을 넘겨주기 때문이다(Context Switching). 매우 우아한 비동기 I/O 모델이다. - Ardupilot은 여러 센서의 I/O를 소수의 스레드나 메인 타이머에 의존하므로 절대 블로킹 함수에 갇혀(Hang)버려서는 안 된다. 따라서 철저하게 버퍼에 읽을 거리가 있는지 먼저 묻는 넌-블로킹 로직(Non-blocking Check)과 상태 머신 중심의 I/O 처리가 깊숙이 박혀 있다.
결국 PX4가 운영체제(RTOS)의 프로세스 스케줄링 기능을 200% 활용하는 소프트웨어 엔지니어링 적인 접근이라면, Ardupilot은 임베디드 하드웨어의 한정된 자원 내에서 타이밍을 쥐어짜 내는 전통적인 펌웨어 렌더링 방식에 뿌리를 두고 있다. 이 철학적 출발선의 차이는 다음 장에서 살펴볼 센서 데이터 통신(IPC) 방식에서 더욱 극명하게 벌어지게 된다.