### 0.0.1 `GPS_1_CONFIG` 및 `GPS_2_CONFIG` 파라미터를 통한 Serial/CAN 포트 동적 할당 소스 코드 트레이싱

### 0.0.1 GPS_1_CONFIGGPS_2_CONFIG 파라미터를 통한 Serial/CAN 포트 동적 할당 소스 코드 트레이싱

다중 GPS 환경에서 가장 흥미로운 점은, 사용자가 QGroundControl에서 GPS_1_CONFIGGPS_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 인자를 강제 주입하여 이 프로세스가 uORB sensor_gps 의 인스턴스 1번(Secondary) 출구로 배선되도록 유도한다.

0.3 gps_main.cpp 내의 포트 독점(Exclusive Access) 및 파서(Parser) 바인딩

스크립트에 의해 호출된 src/drivers/gps/gps_main.cpp 내의 C++ 코드는 자신에게 할당된 TTY 포트를 독점(Exclusive Access)하기 위해 리눅스 표준 POSIX API를 호출한다.

  1. TTY 오픈 및 속도 조정: open("/dev/ttyS0", O_RDWR | O_NOCTTY) 를 통해 포트 제어권을 획득하고, termios 구조체를 조작하여 NMEA(통상 9600 ~ 115200 bps) 혹은 u-blox(통상 38400 ~ 115200 bps) 프로토콜 구동을 위한 초기 Baud rate를 설정한다.
  2. 동적 프로토콜 탐색(Autobauding): 만약 프로토콜이 사전에 지정되지 않았다면, 드라이버는 버퍼를 열어놓고 흘러들어오는 바이트들을 감청(Sniffing)하여 NMEA의 $G 문자인지 u-blox의 0xB5 0x62 헥사 마커인지 판별해 내는 오토보딩 및 동적 파서(Dynamic Parser) 바인딩 로직을 가동한다.
  3. CAN 버스의 경우 (UAVCAN/DroneCAN):
    만약 파라미터가 Serial이 아닌 CAN GPS 생태계(UAVCAN_ENABLE)를 가리키고 있다면 작동 흐름이 아예 다르다. 이 경우 rc.sensors의 시리얼 드라이버 호출은 생략된다. 대신 uavcan 모듈 백그라운드 스레드가 버스 상에 방송(Broadcast)을 발송하여, 화답하는 CAN GNSS 노드 2개를 동적으로 발견(Discovery)한 후 그들의 메시지를 디코드하여 sensor_gps 0번과 1번 슬롯에 순차적으로 밀어 넣는다.

이러한 정교한 초기화 과정 덕분에 PX4 펌웨어는 하드코드된 핀(Pin) 맵에 얽매이지 않고, 사용자가 꽂는 대로, 파라미터를 돌리는 대로 포트의 역할을 동적으로 변환하는 강력한 유연성을 확보하게 된다.