Skip to content

GNSS trên Linux

Trang này trình bày cách đưa dữ liệu từ module GNSS vào Linux: đọc vị trí qua UART, lấy thời gian chính xác qua PPS, và cấp thời gian cho hệ thống hoặc cho PTP. Phần khái niệm nằm ở GNSS.

Luồng dữ liệu

Luồng dữ liệu GNSS trên Linux: UART tới gpsd, PPS tới chrony và ts2phc

  • Đường UART cung cấp vị trí và giây tương ứng (ngày giờ UTC).
  • Đường PPS xác định thời điểm chính xác của giây bằng cạnh xung.
  • Cần kết hợp cả hai đường để có thời gian vừa đúng giây, vừa chính xác cỡ µs.

Cạnh 1PPS đánh dấu thời điểm chính xác, câu NMEA sau đó cho biết là giây nào

Đọc dữ liệu qua UART

Module xuất theo hai kiểu giao thức:

Giao thức Đặc điểm
NMEA 0183 Văn bản ASCII, câu như $GPGGA, $GPRMC. Chuẩn chung, dễ đọc, ít thông tin. Chi tiết xem NMEA 0183
UBX Nhị phân của u-blox. Đầy đủ, cấu hình được module (tốc độ, chế độ timing, các tần số)

Kiểm tra nhanh sau khi nối dây (tốc độ mặc định thường là 9600 hoặc 38400 baud, tùy module):

stty -F /dev/ttyS1 9600 raw
cat /dev/ttyS1

Nếu xuất hiện các dòng bắt đầu bằng $G thì đường UART hoạt động. Với module USB, thiết bị thường là /dev/ttyACM0.

gpsd

gpsd là daemon đọc module và chia sẻ dữ liệu cho nhiều chương trình qua socket (cổng 2947).

gpsd -n /dev/ttyS1 /dev/pps0
  • -n yêu cầu đọc ngay khi khởi động, không chờ client kết nối. Nên dùng khi gpsd làm nguồn thời gian.
  • Truyền cả /dev/pps0 để gpsd biết thiết bị PPS đi cùng.
  • Công cụ kiểm tra: gpsmon, cgps, gpspipe -w.

PPS trong kernel

Xung 1PPS đưa vào một chân GPIO hoặc vào chân DCD của UART, kernel biểu diễn thành thiết bị /dev/ppsN.

Với Device Tree, dùng driver pps-gpio:

pps {
    compatible = "pps-gpio";
    gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
    status = "okay";
};

Cần bật CONFIG_PPS và CONFIG_PPS_CLIENT_GPIO (hoặc CONFIG_PPS_CLIENT_LDISC cho kiểu DCD). Kiểm tra bằng gói pps-tools:

ppstest /dev/pps0

Mỗi giây phải có một dòng assert mới. Nếu không có dòng nào, kiểm tra chân GPIO, mức logic, cạnh kích hoạt của module.

Lưu ý: độ trễ ngắt và cáp làm lệch thời điểm một lượng cố định. Module timing có tham số bù độ trễ cáp ăng-ten, còn phía host cần hiệu chỉnh nếu muốn chính xác dưới µs.

Cấp thời gian cho hệ thống: chrony

chrony kết hợp thời gian từ gpsd (qua SHM) và xung từ PPS:

# /etc/chrony/chrony.conf
refclock SHM 0 refid GPS precision 1e-1 offset 0.0 delay 0.2
refclock PPS /dev/pps0 refid PPS lock GPS
  • Nguồn SHM 0 do gpsd ghi vào, độ chính xác thấp (cỡ chục ms), chỉ để xác định giây.
  • Nguồn PPS chính xác cao, được khóa (lock GPS) với nguồn GPS để chọn đúng giây.
  • Kiểm tra: chronyc sources -v, chronyc tracking.

Cấp thời gian cho PTP: ts2phc

Khi thiết bị đóng vai grandmaster trong mạng PTP, PHC của NIC phải bám GNSS. ts2phc từ gói linuxptp đảm nhiệm việc này: nhận xung PPS (từ GNSS hoặc chân PPS của NIC) và hiệu chỉnh PHC.

Trình tự thường gặp:

  1. ts2phc khóa PHC theo PPS của GNSS.
  2. ptp4l phát PTP ra mạng, lấy thời gian từ PHC.
  3. phc2sys có thể đồng bộ CLOCK_REALTIME theo PHC nếu cần.

Chi tiết cấu hình xem Linux PTP. Bối cảnh trong mạng RAN (PRTC, T-GM, LLS-C4) xem Synchronization.

Các lỗi thường gặp

  • Không có fix: ăng-ten đặt trong nhà hoặc chưa nối nguồn bias. Cần đặt ăng-ten ngoài trời. Lần khởi động nguội (cold start) có thể mất vài phút.
  • Thời gian lệch đúng 1 giây: gpsd và PPS không khớp giây. Kiểm tra lock GPS trong chrony và độ trễ SHM.
  • chrony không chọn nguồn PPS: module chưa có fix nên xung PPS không đáng tin. Nhiều module chỉ xuất PPS khi đã có fix.
  • Dữ liệu UART bị lỗi: sai baud rate, hoặc mức điện áp UART (1.8 V so với 3.3 V) không khớp.
  • Nghi ngờ nhiễu/giả mạo: vị trí nhảy bất thường, số vệ tinh thay đổi đột ngột. Xem phần nhiễu và giả mạo ở GNSS.

Đọc thêm