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.c
	pps_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_PPS
	ptp_clock_event()
		pps_get_ts
			ktime_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 event
					hardpps(&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.h
	ioctl(handle,PPS_KC_BIND,&__bind_args)
		pps_cdev_ioctl()//pps.c
		case 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的呢?

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值