### 0.0.1 GPS_1_CONFIG 및 GPS_2_CONFIG 파라미터를 통한 Serial/CAN 포트 동적 할당 소스 코드 트레이싱
다중 GPS 환경에서 가장 흥미로운 점은, 사용자가 QGroundControl에서 GPS_1_CONFIG 와 GPS_2_CONFIG 파라미터 드롭다운을 변경하는 직후, PX4 내부적으로 텔레메트리 포트(Serial Port)의 제어권이 어떻게 GPS 드라이버로 동적 할당되는지 그 메커니즘을 이해하는 것이다.
본 절에서는 픽스호크에 전원이 인가되는 순간부터 두 개의 독립된 GPS 드라이버 스레드가 각자의 물리적 포트를 점유하기까지의 궤적을 셸(Shell) 스크립트와 C++ 소스 코드 레벨에서 트레이싱(Tracing)한다.
0.1 rc.sensors 스크립트와 부팅 타임 파라미터 쿼리
NuttX RTOS가 부팅을 시작하면 시스템 초기화 스크립트인 rcS 폴더 내부의 설정 파일들이 순차적으로 실행된다. 센서 버스를 관리하는 핵심 스크립트인 ROMFS/px4fmu_common/init.d/rc.sensors 가 바로 GPS 포트 할당의 출발점이다.
- 이 스크립트는 셸 커맨드 라인에서
param show GPS_1_CONFIG를 호출하여 사용자가 설정한 포트 매핑 값(예: 101은 TELEM 1, 102는 TELEM 2 등)을 셸 변수로 로드한다. - 만약 설정된 값이 0(Disabled)이 아니라면, 스크립트는 이 포트에 이미 예약된 다른 드라이버(예: MAVLink) 레이블이 있는지 확인하고 물리적 TTY 디바이스 노드(예:
/dev/ttyS0) 경로를 매핑해 낸다. - 곧이어
gps start -d /dev/ttyS0 -i 0형태의 커맨드를 실행하여 첫 번째 GPS C++ 모듈을 백그라운드 태스크로 론칭시킨다. 여기서-i 0은 uORB 인스턴스 0번(Primary)을 의미한다.
0.2 Secondary 드라이버의 백그라운드 론칭 로직
Primary GPS 론칭에 성공하면, rc.sensors 스크립트는 쉬지 않고 곧바로 두 번째 센서의 존재 여부를 묻는다.
param show GPS_2_CONFIG를 검사하여 역시 0이 아닌 유효한 포트 값이 반환되면, 동일한gps실행 파일을 이번에는 다른 디바이스 파일 경로인/dev/ttyS1등과 함께 실행한다.- 핵심적인 차이는 실행 인자에 있다. 두 번째 실행문은
gps start -d /dev/ttyS1 -i 1처럼-i 1인자를 강제 주입하여 이 프로세스가 uORBsensor_gps의 인스턴스 1번(Secondary) 출구로 배선되도록 유도한다.
0.3 gps_main.cpp 내의 포트 독점(Exclusive Access) 및 파서(Parser) 바인딩
스크립트에 의해 호출된 src/drivers/gps/gps_main.cpp 내의 C++ 코드는 자신에게 할당된 TTY 포트를 독점(Exclusive Access)하기 위해 리눅스 표준 POSIX API를 호출한다.
- TTY 오픈 및 속도 조정:
open("/dev/ttyS0", O_RDWR | O_NOCTTY)를 통해 포트 제어권을 획득하고,termios구조체를 조작하여 NMEA(통상 9600 ~ 115200 bps) 혹은 u-blox(통상 38400 ~ 115200 bps) 프로토콜 구동을 위한 초기 Baud rate를 설정한다. - 동적 프로토콜 탐색(Autobauding): 만약 프로토콜이 사전에 지정되지 않았다면, 드라이버는 버퍼를 열어놓고 흘러들어오는 바이트들을 감청(Sniffing)하여 NMEA의
$G문자인지 u-blox의0xB5 0x62헥사 마커인지 판별해 내는 오토보딩 및 동적 파서(Dynamic Parser) 바인딩 로직을 가동한다. - CAN 버스의 경우 (UAVCAN/DroneCAN):
만약 파라미터가 Serial이 아닌 CAN GPS 생태계(UAVCAN_ENABLE)를 가리키고 있다면 작동 흐름이 아예 다르다. 이 경우rc.sensors의 시리얼 드라이버 호출은 생략된다. 대신uavcan모듈 백그라운드 스레드가 버스 상에 방송(Broadcast)을 발송하여, 화답하는 CAN GNSS 노드 2개를 동적으로 발견(Discovery)한 후 그들의 메시지를 디코드하여sensor_gps0번과 1번 슬롯에 순차적으로 밀어 넣는다.
이러한 정교한 초기화 과정 덕분에 PX4 펌웨어는 하드코드된 핀(Pin) 맵에 얽매이지 않고, 사용자가 꽂는 대로, 파라미터를 돌리는 대로 포트의 역할을 동적으로 변환하는 강력한 유연성을 확보하게 된다.