21.9. 펌웨어 부트 시퀀스 연동 및 프로세스 데몬화(Daemonization) 로직

21.9. 펌웨어 부트 시퀀스 연동 및 프로세스 데몬화(Daemonization) 로직

지금까지 긴 여정에 걸쳐 우리는 “페이로드 자동 투하 모듈(payload_autodrop)” 이라는 하나의 완벽한 C++ 애플리케이션(Application)을 완성했다. uORB로 센서를 읽고, FSM으로 상태를 쪼개고, MAVLink 명령을 발송하는 이 훌륭한 두뇌는 현재 우리의 소스 코드 폴더(src/modules/payload_autodrop) 안에 다소곳이 잠들어 있다.

하지만 PX4 컴파일러(NuttX/CMake)를 돌려서 펌웨어를 빌드하고 픽스호크에 플래싱(flashing) 연 후 배터리를 꽂는다고 해서, 이 모듈이 알아서 살아 움직일까?
절대 그렇지 않다. 컴퓨터를 켰다고 해서 내 하드디스크에 깔려있는 ‘스타크래프트’ 게임이 바탕화면에서 알아서 켜지지 않는 것과 같은 이치다.

이 모듈이 비행 제어기(FC)의 전원이 켜지는 그 순간, 안드로이드의 시스템 서비스나 리눅스의 백그라운드 데몬(Daemon) 처럼 아무도 모르게 조용히 깨어나 영원히 루프를 돌게 만들려면, 우리는 픽스호크의 심연 깊숙이 자리 잡은 **‘ROMFS 부트 스크립트 트리’**에 우리 모듈의 이름을 깎아 넣어야 한다.

1. NuttX OS와 부팅의 철학

PX4가 얹혀 돌아가는 실시간 운영체제인 NuttX RTOS는 리눅스(Linux)의 철학을 뼛속까지 닮아있다.
픽스호크에 배터리 전원이 인가되고 최소한의 하드웨어 커널 초기화가 끝나면, NuttX는 가장 먼저 ROM(Read-Only Memory) 구간에 저장된 텍스트 파일 더미들, 즉 ROMFS 시스템을 뒤지기 시작한다.

그리고 그 안에 숨겨져 있는 init.d 폴더를 찾아가, 그곳에 나열된 수백 줄짜리 쉘(Shell) 스크립트들을 위에서부터 아래로 한 줄 한 줄 맹목적으로 실행(Execution)해 나간다.

이 스크립트 실행 과정(부트 시퀀스)이 진행되는 몇 초의 찰나 동안, 다음과 같은 거대한 생태계 판짜기가 순식간에 일어난다.

  1. 드라이버 로딩: I2C, SPI 버스에 묶인 자이로/기압계 센서들을 깨운다.
  2. uORB 버스 개통: 메시지가 오갈 수 있는 통신망 도로를 깐다.
  3. 코어 데몬 실행: ekf2(위치 추정기), commander(사령관), navigator(자율비행) 등 핵심 장관들을 임명한다.
  4. 사용자 데몬 실행: (바로 이 시점에 우리가 만든 모듈을 깨워야 한다!)

우리가 짜맞춘 payload_autodrop 모듈도 이 성스러운 의식의 한 자리를 차지하기 위해, init.d 스크립트의 거대한 톱니바퀴 중 정확히 어느 시점에 타이밍을 맞춰 끼어들어야 시스템과 충돌 없이 안전하게 데몬화(Daemonization)될 수 있는지, 그 진입 경로(Execution Tree)를 21.9.1장에서 본격적으로 탐험해 보자.