pps用户注册:linuxptp产生pps相关接口

PHC产生PPS,调用了一些PPS接口,以下为查阅分析的PPS接口资料。

一、简介

LinuxPPS提供了一个编程接口(API),用于在系统中定义多个PPS源。
PPS是指“每秒脉冲”,PPS源只是一个每秒提供高精度信号的设备,以便应用程序可以使用它来调整系统时钟时间。
PPS源可以连接到串行端口(通常连接到数据载波检测引脚)或并行端口(ACK引脚)或特殊CPU的GPIO(这是嵌入式系统中的常见情况),但在每种情况下,当新脉冲到达时,系统记录该秒脉冲的时间戳。

二、PPS接口的使用

1.注册PPS

在内核中注册PPS源,首先要定义一个pps_source_info结构体

然后在模块初始化时调用pps_register_source()


在linuxptp的应用中

ptp_clock_register()//ptp_clock.cpps_register_source(); //pps源的名字命名为ptp[index]如ptp1,可以通过cat /sys/class/pps/pps0/name查询到。

2.产生PPS事件

注册之后,可以调用pps_event()产生PPS事件,ts参数表示PPS事件的时间戳。例如可以在中断处理函数中调用pps_event,这个中断可以是外部的PPS信号触发的中断,也可以是定时器产生的中断。应用层可以读取pps事件来感知外部pps或内部pps事件。

示例代码可以查看drivers/pps/clients/pps-ktimer.c
驱动中对pps_event的调用链

dpaa2_ptp_irq_handler_thread()//ptp要产生pps信号给其他设备使用event.type = PTP_CLOCK_PPSptp_clock_event()pps_get_tsktime_get_snapshot()//获取系统时间快照pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT,NULL)//pps_event()和pps_get_ts()配合使用,pps_get_ts()用来产生pps事件的时间,pps_event()是用来产生pps事件信号ttimespec_to_pps_ktime()pps->assert_tu = ts_real;pps->assert_sequence++;pps_kc_event(pps,ts,event); //call hardpps() on pps eventhardpps(&ts->ts_real, &ts->ts_raw) //注意,这个地方是有条件进入的,当pps =pps_kc_hardpps_dev 且event& pps_kc_hardpps_mode时,hardpps()后面细讲wake_up_interruptible_all()唤醒中断,应用软件如果调用pps_read()会返回

3.读取pps事件

read()posix_clock_read()//这部分为驱动代码,将数据从内核态拷贝到用户态clk->opt.read()ptp_read()wait_event_interruptible()//等待条件是否满足,不满足则阻塞,满足则唤醒, (收到外部的PPS信号时,会读取寄存器时间放到事件队列中,然后唤醒此处的中断)唤醒后:取队列中的内容,拷贝到用户空间

4.hardpps()

而pps_kc_hardpps_dev和pps_kc_hardpps_mode这两个全局变量是何时被赋值的?可以追到timepps.h文件

time_pps_kcbind() //timepps.hioctl(handle,PPS_KC_BIND,&__bind_args)pps_cdev_ioctl()//pps.ccase PPS_KC_BIND:pps_kc_bind() //对pps_kc_hardpps_dev和pps_kc_hardpps_mode进行赋值

查遍linuxptp代码未发现调用调用ioctl(handle,PPS_KC_BIND,&__bind_args)的地方,所以在linuxptp的应用中不会调用hardpps()。

那么hardpps()是做啥用的?是ntp应用中调整系统时间用的。

上图来源于https://www.ntp.org/ntpfaq/NTP-s-config-adv.htm#Q-PPS-API
PPS API描述了关于PPS的一些列接口,PPS API是一个公共的程序接口,记录在RFC2783协议中,下述链接是关于PPS API的详细描述
https://datatracker.ietf.org/doc/html/rfc2783#section-3.4.1
linux对PPS的驱动使用描述:
https://www.kernel.org/doc/html/latest//driver-api/pps.html

三、补充phc对外部pps信号的处理

GPS的PPS通过GPIO或者其他方式连接到PHC,当GPIO电平变化触发中断,中断处理函数如下

devm_request_threaded_irq()走if (status & DPRTC_EVENT_ETS1)或if (status & DPRTC_EVENT_ETS2)extts_clean_up()ptp_qoriq->read(reg_etts_l)//读寄存器ptp_qoriq->read(reg_etts_h)//读寄存器,组合成时间放在event中ptp_clock_event()enqueue_external_timestamp(&ptp->tsevq, event);//将event数据放在ptp->tsevq队列尾部wake_up_interruptible(&ptp->tsev_wq);//唤醒等待队列中断,应用程序在read中被唤醒,唤醒ptp_read()中断

疑问:系统是在什么时候写寄存器regs->etts_regs->tmr_etts1_l和tmr_etts1_h的呢?

相关推荐

相关文章