Re: [PATCH 1/9] LinuxPPS core support.

From: Michael Kerrisk
Date: Tue Nov 25 2008 - 11:25:17 EST


Rodolfo,

Some fixes and comments below.

On Mon, Nov 24, 2008 at 11:00 AM, Rodolfo Giometti <giometti@xxxxxxxx> wrote:
> This patch adds the kernel side of the PPS support currently named
> "LinuxPPS".
>
> PPS means "pulse per second" and a PPS source is just a device which
> provides a high precision signal each second so that an application
> can use it to adjust system clock time.
>
> Common use is the combination of the NTPD as userland program with a
> GPS receiver as PPS source to obtain a wallclock-time with
> sub-millisecond synchronisation to UTC.
>
> To obtain this goal the userland programs shoud use the PPS API
> specification (RFC 2783 - Pulse-Per-Second API for UNIX-like Operating
> Systems, Version 1.0) which in part is implemented by this patch. It
> provides a set of chars devices, one per PPS source, which can be used
> to get the time signal. The RFC's functions can be implemented by
> accessing to these char devices.
>
> Signed-off-by: Rodolfo Giometti <giometti@xxxxxxxx>
> ---
> Documentation/ABI/testing/sysfs-pps | 73 ++++++++
> Documentation/ioctl-number.txt | 2 +
> Documentation/pps/pps.txt | 172 ++++++++++++++++++
> MAINTAINERS | 7 +
> drivers/Kconfig | 2 +
> drivers/Makefile | 1 +
> drivers/pps/Kconfig | 33 ++++
> drivers/pps/Makefile | 8 +
> drivers/pps/kapi.c | 322 +++++++++++++++++++++++++++++++++
> drivers/pps/pps.c | 335 +++++++++++++++++++++++++++++++++++
> drivers/pps/sysfs.c | 104 +++++++++++
> include/linux/Kbuild | 1 +
> include/linux/pps.h | 202 +++++++++++++++++++++
> 13 files changed, 1262 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/ABI/testing/sysfs-pps
> create mode 100644 Documentation/pps/pps.txt
> create mode 100644 drivers/pps/Kconfig
> create mode 100644 drivers/pps/Makefile
> create mode 100644 drivers/pps/kapi.c
> create mode 100644 drivers/pps/pps.c
> create mode 100644 drivers/pps/sysfs.c
> create mode 100644 include/linux/pps.h
>
> diff --git a/Documentation/ABI/testing/sysfs-pps b/Documentation/ABI/testing/sysfs-pps
> new file mode 100644
> index 0000000..8cba1d9
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-pps
> @@ -0,0 +1,73 @@
> +What: /sys/class/pps/
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ directory will contain files and
> + directories that will provide a unified interface to
> + the PPS sources.
> +
> +What: /sys/class/pps/ppsX/
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/ directory is related to X-th
> + PPS source into the system. Each directory will
> + contain files to manage and control its PPS source.
> +
> +What: /sys/class/pps/ppsX/assert
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/assert file reports the assert events
> + and the assert sequence number of the X-th source in the form:
> +
> + <secs>.<nsec>#<sequence>
> +
> + If the source has no assert events the content of this file
> + is void.

Does "the content of this file is void" mean "the file is empty". If
so, the latter is clearer, IMO.

> +What: /sys/class/pps/ppsX/clear
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/clear file reports the clear events
> + and the clear sequence number of the X-th source in the form:
> +
> + <secs>.<nsec>#<sequence>
> +
> + If the source has no clear events the content of this file
> + is void.

See comment above.

> +What: /sys/class/pps/ppsX/mode
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/mode file reports the functioning
> + mode of the X-th source in hexadecimal encoding.
> +
> + Please, refer to linux/include/linux/pps.h for further
> + info.
> +
> +What: /sys/class/pps/ppsX/echo
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/echo file reports if the X-th source
> + supports or not an "echo" function.

Better: "does or does not support an "echo" function"

> +
> +What: /sys/class/pps/ppsX/name
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/name file reports the name of the
> + X-th source.
> +
> +What: /sys/class/pps/ppsX/path
> +Date: February 2008
> +Contact: Rodolfo Giometti <giometti@xxxxxxxx>
> +Description:
> + The /sys/class/pps/ppsX/path file reports the path name of
> + the device connected with the X-th source.
> +
> + If the source is not connected with any device the content
> + of this file is void.

See my comment above.

> diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
> index b880ce5..be021b5 100644
> --- a/Documentation/ioctl-number.txt
> +++ b/Documentation/ioctl-number.txt
> @@ -147,6 +147,8 @@ Code Seq# Include File Comments
> 'p' 40-7F linux/nvram.h
> 'p' 80-9F user-space parport
> <mailto:tim@xxxxxxxxxxxx>
> +'p' a0-a4 linux/pps.h LinuxPPS
> + <mailto:giometti@xxxxxxxx>
> 'q' 00-1F linux/serio.h
> 'q' 80-FF Internet PhoneJACK, Internet LineJACK
> <http://www.quicknet.net>
> diff --git a/Documentation/pps/pps.txt b/Documentation/pps/pps.txt
> new file mode 100644
> index 0000000..c558ec3
> --- /dev/null
> +++ b/Documentation/pps/pps.txt
> @@ -0,0 +1,172 @@
> +
> + PPS - Pulse Per Second
> + ----------------------
> +
> +(C) Copyright 2007 Rodolfo Giometti <giometti@xxxxxxxxxxxx>
> +
> +This program is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 2 of the License, or
> +(at your option) any later version.
> +
> +This program is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +GNU General Public License for more details.
> +
> +
> +
> +Overview
> +--------
> +
> +LinuxPPS provides a programming interface (API) to define into the
> +system several PPS sources.

"define into" is not correct English. But I'm not sure what you do
mean to say here.

> +PPS means "pulse per second" and a PPS source is just a device which
> +provides a high precision signal each second so that an application
> +can use it to adjust system clock time.
> +
> +A PPS source can be connected to a serial port (usually to the Data
> +Carrier Detect pin) or to a parallel port (ACK-pin) or to a special
> +CPU's GPIOs (this is the common case in embedded systems) but in each
> +case when a new pulse comes the system must apply to it a timestamp

s/comes/arrives/
or
s/comes/occurs/

> +and record it for the userland.

"for userland"

> +
> +Common use is the combination of the NTPD as userland program with a
> +GPS receiver as PPS source to obtain a wallclock-time with
> +sub-millisecond synchronisation to UTC.

Add a couple of commas here.

Common use is the combination of the NTPD as userland program, with a
GPS receiver as PPS source, to obtain a wallclock-time with
sub-millisecond synchronisation to UTC.

> +
> +
> +RFC considerations
> +------------------
> +
> +While implementing a PPS API as RFC 2783 defines and using an embedded
> +CPU GPIO-Pin as physical link to the signal, I encountered a deeper
> +problem:
> +
> + At startup it needs a file descriptor as argument for the function
> + time_pps_create().
> +
> +This implies that the source has a /dev/... entry. This assumption is
> +ok for the serial and parallel port, where you can do something
> +useful besides(!) the gathering of timestamps as it is the central
> +task for a PPS-API. But this assumption does not work for a single
> +purpose GPIO line. In this case even basic file-related functionality
> +(like read() and write()) makes no sense at all and should not be a
> +precondition for the use of a PPS-API.
> +
> +The problem can be simply solved if you consider that a PPS source is
> +not always connected with a GPS data source.
> +
> +So your programs should check if the GPS data source (the serial port
> +for instance) is a PPS source too, otherwise they should provide the

s/otherwise/and if not/

> +possibility to open another device as PPS source.
> +
> +In LinuxPPS the PPS sources are simply char devices usually mapped
> +into files /dev/pps0, /dev/pps1, etc..
> +
> +
> +Coding example
> +--------------
> +
> +To register a PPS source into the kernel you should define a struct
> +pps_source_info_s as follow:

s/follow/follows/

> +
> + static struct pps_source_info pps_ktimer_info = {
> + .name = "ktimer",
> + .path = "",
> + .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \
> + PPS_ECHOASSERT | \
> + PPS_CANWAIT | PPS_TSFMT_TSPEC,
> + .echo = pps_ktimer_echo,
> + .owner = THIS_MODULE,
> + };
> +
> +and then calling the function pps_register_source() in your
> +intialization routine as follow:

s/follow/follows/

> + source = pps_register_source(&pps_ktimer_info,
> + PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
> +
> +The pps_register_source() prototype is:
> +
> + int pps_register_source(struct pps_source_info_s *info, int default_params)
> +
> +where "info" is a pointer to a structure that describes a particular
> +PPS source, "default_params" tells the system what the initial default
> +parameters for the device should be (is obvious that these parameters

s/is/it is/

> +must be a subset of ones defined into the struct

"defined into" is not English -- do you mean "defined in"

> +pps_source_info_s which describe the capabilities of the driver).
> +
> +Once you have registered a new PPS source into the system you can
> +signal an assert event (for example in the interrupt handler routine)
> +just using:
> +
> + pps_event(source, &ts, PPS_CAPTUREASSERT, ptr)
> +
> +where "ts" is the event's timestamp.
> +
> +The same function may also run the defined echo function
> +(pps_ktimer_echo(), passing to it the "ptr" pointer) if the user
> +asked for that... etc..
> +
> +Please see the file drivers/pps/clients/ktimer.c for example code.
> +
> +
> +SYSFS support
> +-------------
> +
> +If the SYSFS filesystem is enabled in the kernel it provides a new class:
> +
> + $ ls /sys/class/pps/
> + pps0/ pps1/ pps2/
> +
> +Every directory is the ID of a PPS sources defined into the system and
> +inside you find several files:
> +
> + $ ls /sys/class/pps/pps0/
> + assert clear echo mode name path subsystem@ uevent
> +
> +Inside each "assert" and "clear" file you can find the timestamp and a
> +sequence number:
> +
> + $ cat /sys/class/pps/pps0/assert
> + 1170026870.983207967#8
> +
> +Where before the "#" is the timestamp in seconds and after it is the

Before the "#" is the timestamp in seconds; after it is the

> +sequence number. Other files are:
> +
> +* echo: reports if the PPS source has an echo function or not;
> +
> +* mode: reports available PPS functioning modes;
> +
> +* name: reports the PPS source's name;
> +
> +* path: reports the PPS source's device path, that is the device the
> + PPS source is connected to (if it exists).
> +
> +
> +Testing the PPS support
> +-----------------------
> +
> +In order to test the PPS support even without specific hardware you can use
> +the ktimer driver (see the client subsection in the PPS configuration menu)
> +and the userland tools provided into Documentaion/pps/ directory.
> +
> +Once you have enabled the compilation of ktimer just modprobe it (if
> +not statically compiled):
> +
> + # modprobe ktimer
> +
> +and the run ppstest as follow:
> +
> + $ ./ppstest /dev/pps0
> + trying PPS source "/dev/pps1"
> + found PPS source "/dev/pps1"
> + ok, found 1 source(s), now start fetching data...
> + source 0 - assert 1186592699.388832443, sequence: 364 - clear 0.000000000, sequence: 0
> + source 0 - assert 1186592700.388931295, sequence: 365 - clear 0.000000000, sequence: 0
> + source 0 - assert 1186592701.389032765, sequence: 366 - clear 0.000000000, sequence: 0
> +
> +Please, note that to compile userland programs you need the file timepps.h
> +(see Documentation/pps/).
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d643e86..7fd676e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3376,6 +3376,13 @@ P: James Chapman
> M: jchapman@xxxxxxxxxxx
> S: Maintained
>
> +PPS SUPPORT
> +P: Rodolfo Giometti
> +M: giometti@xxxxxxxxxxxx
> +W: http://wiki.enneenne.com/index.php/LinuxPPS_support
> +L: linuxpps@xxxxxxxxxxxxxxx (subscribers-only)
> +S: Maintained
> +
> PREEMPTIBLE KERNEL
> P: Robert Love
> M: rml@xxxxxxxxx
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index 2f557f5..4b679d2 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -52,6 +52,8 @@ source "drivers/i2c/Kconfig"
>
> source "drivers/spi/Kconfig"
>
> +source "drivers/pps/Kconfig"
> +
> source "drivers/gpio/Kconfig"
>
> source "drivers/w1/Kconfig"
> diff --git a/drivers/Makefile b/drivers/Makefile
> index fceb71a..da6329a 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -67,6 +67,7 @@ obj-$(CONFIG_INPUT) += input/
> obj-$(CONFIG_I2O) += message/
> obj-$(CONFIG_RTC_LIB) += rtc/
> obj-y += i2c/
> +obj-$(CONFIG_PPS) += pps/
> obj-$(CONFIG_W1) += w1/
> obj-$(CONFIG_POWER_SUPPLY) += power/
> obj-$(CONFIG_HWMON) += hwmon/
> diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig
> new file mode 100644
> index 0000000..cc2eb8e
> --- /dev/null
> +++ b/drivers/pps/Kconfig
> @@ -0,0 +1,33 @@
> +#
> +# PPS support configuration
> +#
> +
> +menu "PPS support"
> +
> +config PPS
> + tristate "PPS support"
> + depends on EXPERIMENTAL
> + ---help---
> + PPS (Pulse Per Second) is a special pulse provided by some GPS
> + antennae. Userland can use it to get a high-precision time

Antennas is I believe the more common English plural.

> + reference.
> +
> + Some antennae's PPS signals are connected with the CD (Carrier

Antennas'

> + Detect) pin of the serial line they use to communicate with the
> + host. In this case use the SERIAL_LINE client support.
> +
> + Some antennae's PPS signals are connected with some special host

Antennas'

> + inputs so you have to enable the corresponding client support.
> +
> + To compile this driver as a module, choose M here: the module
> + will be called pps_core.ko.
> +
> +config PPS_DEBUG
> + bool "PPS debugging messages"
> + depends on PPS
> + help
> + Say Y here if you want the PPS support to produce a bunch of debug
> + messages to the system log. Select this if you are having a
> + problem with PPS support and want to see more of what is going on.

Cheers,

Michael

--
Michael Kerrisk Linux man-pages maintainer;
http://www.kernel.org/doc/man-pages/ Found a documentation bug?
http://www.kernel.org/doc/man-pages/reporting_bugs.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/