# 1. NuttX 커널 구조 및 PX4 시스템 아키텍처

# 1. NuttX 커널 구조 및 PX4 시스템 아키텍처

NuttX는 코어 용량이 수십 KB에 불과한 마이크로커널(Microkernel) 지향적 설계를 가지면서도, 리눅스가 표방하는 모놀리식(Monolithic) OS의 파일 시스템 레이어 범용성을 동시에 제공하는 변태적인 하이브리드 커널이다. PX4 소스 코드가 이 커널 위에 어떻게 뿌리를 내리고 기생하는지 그 단면도를 들여다본다.

아키텍처 레이어 다이어그램
PX4 시스템은 철저하게 아래에서 위로 쌓인 레이어 케이크 구조를 띠고 있으며, 각 층은 엄격한 경계선(Boundary)에 의해 단절되어 있다.

  1. 하드웨어 계층 (Hardware Layer): STM32H7 등 ARM Cortex-M 코어, UART/SPI 페리퍼럴, 물리적 메모리(RAM, Flash).
  2. 보드 지원 패키지 (BSP / Board Support Package): NuttX 하위 디렉토리에 은닉되어 하드웨어 칩셋의 레지스터 인터럽트 초기화, 클럭 트리 셋업을 전담하는 최하단 C 스크립트들.
  3. NuttX 커널 코어 (Kernel Core): 스케줄러(Scheduler), 램프(Heap/Stack) 메모리 매니저, 그리고 인터럽트 디스패처(Interrupt Dispatcher). 컨텍스트 스위칭(Context Switching)의 핵심 논리가 박혀있는 커널의 심장부.
  4. VFS (Virtual File System) 및 디바이스 노드: 리눅스처럼 모든 하드웨어 장치를 /dev/spi1, /dev/i2c-2 처럼 트리 기반 파일 노드로 매핑해주는 중간계 레이어.
  5. PX4 시스템 의존 추상화 계층 (OSAL: OS Abstraction Layer): PX4의 platforms/nuttx 폴더에 구현되어, 커널 계층과 PX4 비행 로직 계층 사이를 이어주는 어댑터 브리지.
  6. 사용자 응용 계층 (Application Layer / Modules): 우리가 src/modules/ 에 코딩하는 ekf2, mc_att_control 등의 C++ 클래스들. 이들은 커널의 존재조차 모르며 오직 OSAL 인터페이스(예: px4_task_spawn) 만을 맹목적으로 호출한다.

단일 주소 공간(Flat Memory Space) 구조의 패널티
리눅스 커널과 NuttX의 가장 결정적 차이는 메모리 보호 단위(MMU) 의 유무다.
리눅스는 가상 메모리 관리 장치(MMU)를 통해 카카오톡 프로세스와 유튜브 프로세스가 쓰는 램(RAM)의 가상 주소 공간을 물리적으로 철저히 격리한다. 하나가 미쳐서 허튼 주소를 건드려도(Segmentation Fault) 해당 앱만 죽고 운영체제 전체는 멀쩡하다.
하지만 Pixhawk의 Cortex-M MPU(Memory Protection Unit)는 한정적이므로, NuttX에서 구동되는 PX4 시스템은 기본적으로 플랫(Flat) 메모리 모델을 쓴다. 즉 ekf2 스레드와 logger 스레드가 2MB 남짓한 하나의 물리적 RAM 공간을 완전히 생얼로 공유(Memory Sharing)한다. 만약 당신이 짠 커스텀 모듈에서 포인터 배열 인덱스를 1픽셀만 엇갈리게 침범(Overflow)하여 옆방에 있던 mc_att_control의 변수값을 덮어쓰면? 기체는 즉시 추락한다. 따라서 PX4 개발은 리눅스 앱 개발보다 100배 더 엄격한 메모리 포인터 규율과 정적 할당(Static Allocation) 철학을 강요받는 것이다.