linuxptp中clock_gettime的实现

在使用linuxptp的phc2sys程序的时候,有一种使用方式是:
phc2sys -d /dev/pps -s /dev/ptp -c CLOCK_REALTIME -m -O 0
这种方式会指定pps设置作为源来矫正系统时间,-s指定了ptp设备,作用是获取phc时间,phc时间提供绝对时间值,并不对矫正偏差产生作用。

如何通过设备名称来获取系统时间呢(gettime)?
首先需要进行初始化

ptp_qoriq_probe;// ptp_qoriq.c
	ptp_qoriq_init(ptp_poriq,base,&ptp_qoriq_caps)
		ptp_clock_register()//创建了ptp_clock ptp,并填充它的成员
			ptp->clock.ops = ptp_clock_ops;				
			posix_clock_register(&ptp->clock, &ptp->dev)//创建 posix_clock
				cdev_init(&clk->cdev, &posix_clock_file_operations)//用于初始化cdev的成员,并建立cdev和file_operations之间的连接
					cdev->ops = fops;
				cdev_device_add();向系统添加一个cdev
			    //至此 ptp->info->adjtime = ptp_qoriq_adjtime
					   ptp->info->enable = ptp_qoriq_enable
					   ptp->info->pps->cdev = pps_cdev_fops
					   ptp->clock.ops = ptp_clock_ops;	
					   ptp->clock->cdev->ops = &posix_clock_file_operations
					   ptp->clock->dev = &ptp->dev
			      也就是posix_clock  clk->dev = &ptp->dev
				                     clk->ops = &posix_clock_file_operations

其次需要根据设备名称来open设备,进而获取或者修改系统时间。
例如通过-c指定的ptp设备,会执行如下过程

clock_add()
	posix_clock_open//通过设备/dev/ptp*或者eth*,走下面不同的分支,返回clkid
		phc_open//返回clkid
			fd = open(phc,O_RDWR)//怎么对应上posix_clock_open
				posix_clock_open(struct inode *inode, struct file *fp)//这部分为驱动代码posix-clock.c,file结构体由内核在打开文件时创建,这是 posix_clock_file_operations 的成员函数
					clk->opt.open()//对应于ptp_clock_ops.open
						ptp_open()//return 0;
					fp->private_date = clk;//clk是posix_clock
			FD_TO_CLOCKID(fd)//由文件描述符得到clkid
			clock_gettime()------------------------以下为驱动代码
				SYSCALL_DEFINE2(clock_gettime...)//posix-timers.c,内核态执行该函数
					clockid_to_kclock()//clkid < 0 获取到clock_posix_dynamic
						kc->clock_get()//使用这组函数进行时钟获取
							pc_clock_gettime()
								cd.clk->ops.clock_gettime
									ptp_clock_gettime()
										ptp->info->gettime64()
											ptp_qoriq_caps.ptp_qoriq_gettime()
												tmr_cnt_read()//读取寄存器
			clock_adjtime(clkid,&tx)获取tx------------------------以下为驱动代码
				syscall(__NR_clock_adjtime,id,tx);//用户态执行系统调用,__NR_clock_adjtime是系统调用号,内核中有与系统调用号对应的系统调用表
					SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock, struct timex __user *, utx)//posix-timers.c,内核态执行该函数
						do_clock_adjtime()
							clockid_to_kclock()//clkid <0 (打印出来看就是负的) 获取到clock_posix_dynamic,选择了一组函数
							kc->clock_adj()//使用这组函数进行频率调整
								pc_clock_adjtime(id,tx)
									get_clock_desc(id,&cd)//根据id获得fd,根据fd获取posix_clock, posix_clock = fp->private_date
										fget(clockid_to_fd(id))//由fd获取到file结构体
										cd->clk = get_posix_clock(fp)
									cd.clk->ops.clock_adjtime//对应的就是 ptp_clock_ops.clock_adjtime = ptp_clock_adjtime
										ptp_clock_adjtime()//根据posix_clock得到ptp_clock
											ptp->info->adjtime()//info对应的是ptp_qoriq->caps
												ptp_qoriq_caps.ptp_qoriq_adjtime()//ptp_qoriq_caps 是全局变量
													tmr_cnt_write()写寄存器----最底层
		
		在直接使用了posix_clock_file_operations.posix_clock_open函数之后,想要修改时间,通过系统调用执行到kc、   ptp_clock_ops    ptp_qoriq_caps  写寄存器。
		posix_clock_file_operations除了open之外的函数使用的都是 ptp_clock_ops的成员函数。

如果是系统时钟(CLOCK_REALTIME),则执行一下过程

clock_add()
	posix_clock_open()//该函数返回clockid_t, 如果是CLOKC_REALTIME则直接返回CLOKC_REALTIME = 0
在使用clock_gettime(sysclk, &tdst1)时的调用栈
clock_gettime(sysclk, &tdst1)
	SYSCALL_DEFINE2(clock_gettime...)//posix-timers.c,内核态执行该函数
		clockid_to_kclock()//clkid = 0 获取到clock_realtime,选择了一组函数
			kc->clock_get()//使用这组函数进行时钟获取
				posix_get_realtime_get
					ktime_get_real_ts64//获取系统时间
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值