### 0.0.1 gps_main.cpp의 모듈 초기화(start), 중지(stop), 상태 확인(status) 커맨드 라인 인터페이스(CLI) 라우팅
PX4 펌웨어는 수십 개의 독립적인 센서 드라이버와 제어 모듈들이 비동기적으로 맞물려 돌아가는 거대한 운영체제 생태계이다. 사용자가 QGroundControl의 MAVLink 콘솔이나 디버깅 셸(NSH)을 통해 gps라는 명령어를 입력했을 때, 이 단순한 텍스트가 어떻게 백그라운드 C++ 스레드의 생사(Lifecycle)를 결정짓는 함수 호출로 치환되는지 그 CLI(Command Line Interface) 라우팅(Routing) 구조를 살펴본다.
src/drivers/gps 디렉토리의 대문 역할을 하는 gps_main.cpp 최하단에는, 운영체제 커널이 gps 명령어 바이너리(Built-in App)를 실행할 때 가장 먼저 진입하는 메인 함수인 gps_main(int argc, char *argv[])이 자리 잡고 있다. 이 함수는 거대한 if-else 분기문 또는 분배기(Dispatcher) 역할을 수행한다.
0.1 start: 생명의 잉태와 매개변수 주입
사용자가 gps start -d /dev/ttyS3 -b 115200과 같은 명령을 하달하면, gps_main 함수는 입력된 argv 문자열 배열을 파싱하기 위해 POSIX의 전통적인 getopt()를 구동한다.
- 인자 파싱(Argument Parsing):
-d플래그 뒤의 문자열은 하드웨어 직렬 포트 매핑으로 추출되고,-b뒤의 문자는 115200 정수형 보드레이트로,-p옵션은 특정 프로토콜(예:ubx,nmea) 강제 지정용으로 매핑 구조체에 꼼꼼히 갈무리된다. - 중복 실행 방지: 앞 절에서 설명한 전역 싱글턴 포인터(
g_dev)를 검사하여nullptr이 아닐 경우 “이미 실행 중이다“라는 메시지를 띄우고 즉시 반환(Return)한다. - 스레드 점화: 모든 검증이 끝나면 비로소
task_spawn()API를 호출하여 백그라운드의 독립된gps_thread_main스레드를 띄운다. 이 스레드 내부에서 마스터 C++ 인스턴스인GPS객체가new키워드로 생성되며 드라이버가 박동하기 시작한다.
0.2 stop: 안전한 자원 반납과 종료(Graceful Teardown) 전파
반대로, 포트 충돌을 회피하거나 일시적인 하드웨어 리셋을 위해 사용자가 gps stop 명령을 내리면, 프로세스는 무자비하게 메모리를 날려버리는 kill() 시스템 콜 대신 매우 신사적인 플래그 오버라이딩(Flag Overriding) 기법을 사용한다.
- 종료 플래그 전이:
gps_main스레드는 백그라운드 스레드가 공유하고 있는 전역 불리언(Boolean) 변수인thread_should_exit플래그를 단순히true로 설정하고 대기한다. - 루프 탈출(Loop Break): 백그라운드 영역의 메인 폴링(Polling) 무한 루프는 매 틱(Tick)마다 이 변수 상태를 감시하고 있다. 변수가
true로 뒤집힌 것을 확인한 무한 루프는 즉시 폴링을 중단(break)하고 정리(Cleanup) 코드로 진입한다. - 자원 회수(Garbage Collection): 객체 내부에 열려 있던 파일 디스크립터(UART Port
fd)를close()로 명시적으로 닫아주고 힙(Heap) 메모리에 떠있던 파서 객체들을 소각한 뒤, 메인 프로세스에 생명주기가 완전히 만료되었음을 알리며 스레드를 자진 종료한다.
0.3 status: 살아있는 드라이버의 실시간 맥박 검사
비행 디버깅 과정에서 가장 많이 호출되는 명령어이자 파서의 건전성을 진단하는 청진기(Stethoscope)가 바로 gps status 루틴이다.
- 명령이 수신되면 CLI 라우터는 전역 포인터
g_dev가 존재하는지 먼저 확인한다. 만약 포인터가 비어 있다면 장치가 실행 중이 아님을 알리고 종료한다. - 포인터가 존재한다면, FC 프로세스는 객체의 가상(Virtual) 함수인
print_status()나print_info()를 호출한다. - 출력 메트릭(Metrics): 이 콘솔 덤프(Dump) 출력 루틴은 현재 직렬 포트 이름, 연결에 성공한 프로토콜(예:
UBX), 현재 활성화된 보드레이트(Baudrate), 지난 부팅 후 수신된 데이터 바이트 수, 파싱 중 버려진 가비지 데이터(Drop) 패킷 수, 그리고 마지막으로 성공적인 위치 데이터(Publish)가 uORB에 업로드된 지 몇 밀리초(ms)가 흘렀는지에 대한 타임스탬프 델타값을 디버깅 콘솔 창에 상세히 쏟아낸다. 이를 통해 개발자는 케이블 배선 불량부터 노이즈로 인한 보드레이트 미스매치(Mismatch)까지 단숨에 문제를 특정할 수 있다.