Commit d3c753fb authored by Alessandro Rubini's avatar Alessandro Rubini

tools: added adjrate and documented it

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent c13f3e45
......@@ -641,6 +641,32 @@ The following example shows how on my host the kernel adjusts the time by
Previous adjustment: 0.135000 seconds
@end example
@c ==========================================================================
@node adjrate
@section adjrate
The program reads and optionally changes the clock rate of the host
system using the Linux-specific @i{adjtimex} system call (the same
being used in the core PPSi program). It is meant to check adjustment
and get acquainted with the involved values.
The numerical argument of the system call is parts-per-million scaled
by 16 bits. So for example half @i{ppm} is passed as 32768.
The following are example uses of the program on an ntp-driven host:
@example
morgana% ./tools/adjrate --help
./tools/adjrate: use "./tools/adjrate [<adj-value> [ppm]]"
morgana% ./tools/adjrate
rate: -407582 (-6.219208 ppm)
morgana% ./tools/adjrate -6
./tools/adjrate: adjtimex(rate=-6): -1 (Operation not permitted)
morgana% sudo ./tools/adjrate -6 ppm
morgana% sudo ./tools/adjrate
rate: -393216 (-6.000000 ppm)
@end example
@c ==========================================================================
@node mtp
@section mtp
......
......@@ -11,7 +11,7 @@ OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -Wall -ggdb -I../include
PROGS = ptpdump adjtime jmptime chktime
PROGS = ptpdump adjtime jmptime chktime adjrate
LDFLAGS += -lrt
all: $(PROGS)
......
/*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <sys/timex.h>
/*
* This is a simple tool to check/change the rate, for testing.
* The numeric argument is (ppm * 1000) << 16.
*/
char *retvals[] = {"OK", "Insert leap", "Delete leap", "Leap in progress",
"Leap occurred", "Clock not synchnonized"};
int main(int argc, char **argv)
{
struct timex t;
double f;
long l;
char c;
if ((argc > 1 && argv[1][0] == '-')
|| -argc > 3
|| (argc == 3 && strcmp(argv[2], "ppm"))) {
fprintf(stderr, "%s: use \"%s [<adj-value> [ppm]]\"\n",
argv[0], argv[0]);
exit(1);
}
memset(&t, 0, sizeof(t));
adjtimex(&t);
if (argc == 1) {
f = t.freq / 65536.0;
printf("rate: %li (%.06f ppm)\n", t.freq, f);
exit(0);
}
if (argc == 3) { /* "ppm": convert as float */
if (sscanf(argv[1], "%lf%c", &f, &c) != 1) {
fprintf(stderr, "%s: not a float number \"%s\"\n",
argv[0], argv[1]);
exit(1);
}
l = f * 65536;
} else {
if (sscanf(argv[1], "%li%c", &l, &c) != 1) {
fprintf(stderr, "%s: not an integer number \"%s\"\n",
argv[0], argv[1]);
exit(1);
}
}
/* to set the sate we must set the pll flag too */
t.modes = 0;
if (!t.status &STA_PLL) {
fprintf(stderr, "%s: adding STA_PLL to adjtimex.status\n",
argv[0]);
t.modes |= MOD_STATUS;
t.status |= STA_PLL;
}
t.modes |= MOD_FREQUENCY;
t.freq = l;
l = adjtimex(&t);
if (l != 0) {
fprintf(stderr, "%s: adjtimex(rate=%li): %li (%s)\n",
argv[0], t.freq, l,
l < 0 ? strerror(errno) : retvals[l]);
}
exit(0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment