Gpsd pps移植
最近在研究GPSD相关信息,查阅到GPSD可以与NTPD相配合实现高精度时间同步功能,因此才涉及到此主题。
目前手头用的是Ublox F9P模块,UART输出NEMA数据,另外一个GPIO输出1PPS脉冲
首先看一张时序图:
1. NEMA中包含有时间信息,一般是秒级别,也有部分带有毫秒
2. 1PPS即每秒输出一个脉冲,图中以高电平触发为例(没画下降沿),接收及处理1PPS脉冲的时间也在ns级别
3. 因为NEMA是通过串口发送和接收,而且一次NEMA数据量也有KB级别大小,处理时间远比1PPS时间长
4. 通过NEMA中的秒级时间和1PPS脉冲相配合,即可实现高精度时间同步(ns级:依据1PPS的响应时间)
具体时间同步实现,以Linux为例,常用组合方式为:kenel pps.ko,GPSD,chronyd或者NTPD
当前kernel是支持pps处理的,因为我用的ublox的pps是接到gpio的,所以选择gpio方式
1. kernel timer client 是内核软件模拟的pps信号,用于测试
2. pps client using gpio 是以gpio作为pps信号源
pps-gpio.c源码实现也比较简单,主要通过注册gpio中断,当gpio电平变化时,记录当前系统运行时刻,然后post event到用户空间。
因为使用了外部GPIO,因此在使用该模块之前,需要在dts中指定相关的gpio引脚,compatible 为 "pps-gpio" 在文件cx1910_single_pmu.dts中
ublox_gps {
compatible = "pps-gpio";//与驱动中的进行匹配
gpios = <&gpio 109 0>;//引脚初始化,名字一定是gpios
pinctrl-names = "default";//
pinctrl-0 = <&gps_pps_pin>;//pinctrl配置的引脚
status = "okay";
};
因为源码中的驱动会进行匹配设备树的compatible
-
static const struct of_device_id pps_gpio_dt_ids[] = {
-
-
{ .compatible = "pps-gpio", },
-
-
{ /* sentinel */ }
-
-
};
配置后编译启动,查阅dmesg
-
root@imx8qxpmek:~# dmesg |grep pps
-
[ 0.708441] pps_core: LinuxPPS API ver. 1 registered
-
[ 0.713357] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
-
[ 1.737515] pps pps0: new PPS source ktimer
-
[ 1.741727] pps pps0: ktimer PPS source registered