PPS output using Linux on a PC - Page 1
Forum section: electronics / general

author: MarkMLl
author_rank: Frequent Contributor
timestamp: April 27, 2021, 02:23:02 pm
content: Has anybody had any success with the pps_gen_parport module on 4.x? I'm trying to get PPS pulses from a PC to compare against more accurate sources of timing, so that when the PC puts timestamps on stuff it's logging I'm able to relate it to some sort of reality.I've copied the pps_gen_parport module out of the Linux kernel sources, applied the polarity and failure_iterations patches manually, packaged it using DKMS so I can build it (and it stays built) out-of-tree, and blacklisted lp so that the parport device is free. Using debugging messages I can see that it's running and is trying to set/reset a port bit at the right times, but I'm seeing no physical output that I can detect using a scope or analyzer.I think I've only got one computer that's got a real parallel port on it...MarkMLl

author: PKTKS
author_rank: Super Contributor
timestamp: April 27, 2021, 03:22:13 pm
content: Did you really loaded the whole PARPORT stack ? e.g.Code:modprobe -a 8250_pcimodprobe -a parport_pcmodprobe -a ppdevmodprobe -a ppain the example above the *last* module talks scsi dialect over parport...the order **MAY** be crucial depending on the MOBO/BIOSand kernel combinations...Paul

author: MarkMLl
author_rank: Frequent Contributor
timestamp: April 27, 2021, 03:53:41 pm
content: It's got parport_pc and ppdev, the other two modules don't exist... this is a stock Debian x86-64 system and I'd be surprised if it weren't able to drive a printer. Not that it's the first time I've been surprised by dodgy assumptions, but even so...I'm fairly confident that the module is built and installed properly, since added debugging messages show it progressing past the lower-level calls which in principle should be setting/resetting bits. I can see the kernel detecting a printer port at 0x378 as parport0.The printer port is enabled in the BIOS, but I suppose that there's a chance that the physical output is blown. The levels don't look too bad... ISTR that at least some ports had a gate for selftest but I haven't a clue how to exploit that.I think I've got two more systems that might be usable, but one's an underpowered laptop and the other can't easily be moved to near the kit I'm testing (or vice versa).https://github.com/twteamware/raspberrypi-ptphas GPIO output on an RPi which might be usable.MarkMLl

author: PKTKS
author_rank: Super Contributor
timestamp: April 28, 2021, 09:43:07 am
content: If they are not "there" check if serial tty 8250(aka 16550 on modern BIOS Super I/O)are *BUILT_IN* kernel.These vanilla stock kernels are huge beastsThey try to fit all banana Joe average PCs andcustom setups are very hard.Anything "serial" over the Super I/O should have 16550driver pre loaded.The other parport related drivers are specific to thedialect intended to the clients and should becompiled ... if not already there..Paul

author: MarkMLl
author_rank: Frequent Contributor
timestamp: April 28, 2021, 10:50:05 am
content: I can't immediately see why serial port stuff is relevant to something which is supposed to ackle a bit on a parallel port. I can say however that the machines I've tested have fully-functional onboard serial hardware... it's stuff I use fairly heavily.Wasn't PPA the interface used by Iomega for things like Zip disks? Thanks for the hint, I'll take a look at that presently as an example of how these ports should be driven.I've compiled the pps_gen_parport module on a much older kernel on a laptop, and similarly get no output. My suspicion is that the timing and error-handling aspects are OK, but that there's something wrong with the call which is supposed to be twiddling bits on the port... this will probably turn out to have not been tested since it was introduced in Linux 2.6.31 :-)I'm sure I'll find some way round it, one thing I've not investigated yet is using a GPIO bit on an RPi which of course is a completely different API.I've got various PPS-related stuff arriving, being checked statistically and logged. Every minute I get a report, and according to that there's a 57 mSec offset somewhere. Now I've got various lines of attack, but the objective of getting a PPS output from the computer would have been to highlight internal latencies... and obviously potential crappiness of Debian's timeserver pool :-)I'll report back if I make progress.MarkMLl

author: PKTKS
author_rank: Super Contributor
timestamp: April 28, 2021, 11:05:22 am
content: On modern PCs the ports are emulated on the Super I/ODepending on the MOBO BIOS you *should* be prudentby initializing the Super I/O (in particular these modernprogrammable ITE/ENE ones) firmware.Putting the modules there will ensure the properSuper I/O initialization - assuming the BIOS is alreadyproperly set .. options do exist to void these ports..on all BIOS I am aware.. you can setup on/off andfeatures..So it is fairly prudent initialize the Super I/O withall relevant options - parports can talk *alot* of stuff..(RS232 included)Paulps> *ports* in the latter case refer to the "legacy" ISA busdevice addressing schema of first PC/Xt/At eras.. now totallycrammed in the Super I/O firmware

author: MarkMLl
author_rank: Frequent Contributor
timestamp: April 28, 2021, 11:44:33 am
content: Quote from: PKTKS on April 28, 2021, 11:05:22 amThanks, rationale noted.MarkMLl

author: SuntUnMorcov
author_rank: Contributor
timestamp: April 29, 2021, 06:24:50 pm
content: Quote from: MarkMLl on April 27, 2021, 02:23:02 pmI've not done so as of yet, but wanted to do something similar in the near future. My intention was to make use of a PCIe parallel port interface device though (for some low-cost 'wet finger in the air' type experimentation, suitable for certain needs). I'll be looking to compare the generated PPS signal against that from the host's time reference source (an IEEE1588v2 PTP GM).Quote from: MarkMLl on April 27, 2021, 02:23:02 pmQuote from: MarkMLl on April 27, 2021, 03:53:41 pmIt sounds like you're wanting to quantify the characteristics of some kind of event timestamping. But from what you've said so far, it doesn't sound like you're going about it in entirely the right manner.Although this is slightly tangential to your original query, it might be useful to provide further information on your application and your intentions for experimentation (such that your current approach may be critiqued/discussed and potentially improved). That, and I'm a nosey bugger with a piqued interest.Jack

author: MarkMLl
author_rank: Frequent Contributor
timestamp: April 30, 2021, 09:35:37 am
content: Quote from: SuntUnMorcov on April 29, 2021, 06:24:50 pmIt's more to get a one-off confirmation that NTP is resulting in the PC's clock being set accurately, and an indication of the latency of debugging messages where these relate to timing from external equipment. This definitely wouldn't be something that got anywhere near a customer, but I think that a "reality check" of this nature is important on occasion... and the fact that PPS output isn't getting any attention suggests that people are brushing a potential problem under the carpet.I've uploaded my code tohttps://github.com/MarkMLl/pps_gen_parportfor discussion purposes. If my understanding is correct it uses the Linux "parport0" device i.e. should use a PCIe card if that's the only port or should be fairly easily modifiable to select from multiple ports (the patches show how this sort of thing is done).MarkMLl

author: SuntUnMorcov
author_rank: Contributor
timestamp: April 30, 2021, 05:23:19 pm
content: Quote from: MarkMLl on April 30, 2021, 09:35:37 amAh, I see. I like to do the exact same thing where time synchronisation and/or latency is concerned. In my experience, bringing out a signal to hardware to verify time synchronisation or latencies is always invaluable, provided:The method of generating the signal is understood and suitable; andHowever you use the signal is understood and suitable; andAny experimentation is representative of the final application.I'm probably teaching you to suck eggs now, but don't forget that just because your system's clock synchronisation is 'good' (this will depend on the requirements of the application, implementation, etc), it doesn't mean your software timestamping of events (using said system clock) will be any good. The software which undertakes the timestamping of events will be subject to sources of latency and jitter, which will vary depending on a wide range of variables. Where a maximum error for timestamping is mandated/required, your application now has real-time constraints and with that usually comes the complexity of ensuring those constraints are met (although this complexity can vary greatly).Quote from: MarkMLl on April 30, 2021, 09:35:37 amThanks for sharing what you've got. I'll take a look over the course of this long weekend, although I don't currently have any hardware to test with. I am going to look to obtain a PCIe parallel port device to do my own testing with, although this won't be representative of your setup (using a Super I/O parallel port native to your system's motherboard, etc).A quick skim of the code suggests your note on the port used by thepps_gen_parportmodule is correct - the parallel port used by the module will be the first within the kernel's list of registered parallel ports. Adding to the module's interface such that a port can be specified, etc, *should* be relatively trivial.Jack

author: MarkMLl
author_rank: Frequent Contributor
timestamp: April 30, 2021, 06:39:31 pm
content: Quote from: SuntUnMorcov on April 30, 2021, 05:23:19 pmWhich is of course why I have a "genuine"- albeit elderly- logic analyser, not just something plugged into a PC.I'm fairly confident that (Debian's) NTP synchronisation is good to better than 10 mSec. I'd like (and expect) to see it around 1 mSec, and since the pps_gen_parport module claims to be better than 10 uSec I think that I should be able to verify this against GPS and other sources.QuoteObviously I can't take substantial credit for that: the only real things I've done are prepare a DKMS configuration by rote and apply the patches by hand... I think they're OK but I'd suggest treating everything as suspect.Quoteparport=1 or whatever.MarkMLl

author: MarkMLl
author_rank: Frequent Contributor
timestamp: May 02, 2021, 05:14:05 pm
content: The original pps_gen_xxx is ./pps-gen-parport/pps_gen_parport-prepatch.c:* Copyright (C) 2009 Alexander Gordeev <lasaine@lvk.cs.msu.su>The file ./raspberrypi-ptp-master/patches/scratch/pps_gen_gpio.c aligns closely with this:* Copyright (C) 2015 Juan Solano <jsm@jsolano.com>* 2009 Alexander Gordeev <lasaine@lvk.cs.msu.su>Slightly more recent is ./pps-gen-gpio-master/pps_gen_gpio.c* Copyright (C) 2009 Alexander Gordeev <lasaine@lvk.cs.msu.su>* 2018 Juan Solano <jsm@jsolano.com>The Github projecthttps://github.com/twteamware/raspberrypi-ptpis, unsurprisingly, for a Raspberry Pi. The Github projecthttps://github.com/topics/pps-generatoris for a BeagleBoard. Both have some measure of discussion of DeviceTree files, neither has any DKMS support.As regards the original pps_gen_parport, there are three sets of patches applied to (a) update the time API, (b) select polarity, and (c) add a safety timeout. These have long been public but none has been applied to the implementations using GPIO.As regards the GPIO implementations, the later (2018) one aligns fairly well with the older (2009) one, but there have been a lot of detailed changes including much comment editing etc. which make following the precise sequence difficult.I am not able to judge whether any changes in the core algorithm between the 2009 and 2018 variants are sufficiently perceptive to make them worth backporting into the parport variant.MarkMLl

author: SuntUnMorcov
author_rank: Contributor
timestamp: May 05, 2021, 04:04:35 pm
content: Firstly, I apologise, Mark. I tried (and failed) to obtain a suitable parallel port interface device, but to no avail (I thought I had access to one, but it appears to have been commandeered by another recently). I'm ordering a similar PCIe card which is based on the Oxford OXPCIe952 chip (a PCIe to Dual Serial and Single Parallel Port Bridge IC, which is a common component on such PCIe interface devices).Quote from: MarkMLl on May 02, 2021, 05:14:05 pmThe link you posted for the BeagleboneGPIO PPS generator project is for a Github topic page which may vary in time, potentially becoming less useful to future readers of this post (we all know how Microsoft likes to 'fix' working products). The URL to the Beaglebone GPIO PPS generator project is as follows:https://github.com/jsln/pps-gen-gpioIrrespective of the merits and pitfalls of the method used to generate a PPS output on a GPIO pin within the Beaglebone kernel module, the kernel module itself should be useable across a range of platforms. All that would be required is to ensure that any pin control settings are defined as appropriate for the target GPIO pin (platform specific) and the relevant settings for the driver (mostly platform-agnostic) are defined within the Device Tree for the target system.Both the Raspberry Pi and Beaglebone GPIO PPS generator projects make use of Device Tree for the very reasons you'd expect them too - to decouple the kernel module from the platform hardware. And regarding DKMS, not everyone makes use of it. In fact, a lot of individuals and companies don't. To be honest, I could do with learning more about DKMS myself.Quote from: MarkMLl on May 02, 2021, 05:14:05 pmWell, the first patch in your repo (0-timespec64.patch) replaces data structures and function calls for obtaining system time via now deprecated components of the in-kernel API. From the PPS kernel module perspective, this patch doesn't really affect any functional change. If it were down to me, I'd add some conditional compilation such that the kernel module can be built for old and new kernels alike (the deprecated API was removed in Linux v5.6). This addition could be one potential improvement to both the Raspberry Pi and Beaglebone GPIO PPS projects. After some testing, I might even submit a pull request with these changes incorporated.However, the latter two patches (1-polarity.patchand2-iterations.patch) *do* affect a functional change to the kernel module, as both patches add a new feature.In the words of the original author, Alexander GQ Gerasiov <gq@cs.msu.su>, the second patch (1-polarity.patch) adds the following functionality:QuoteIn my opinion, this functionality is not essential, but is nice to have. It gives more flexibility to the user of the kernel module without any real cost. Hence, it could also be useful to apply a similar change to the GPIO PPS kernel modules.The third patch (2-iterations.patch) adds functionality to prevent a hard-lock situation within the two busy looping sections of the high-resolution timer callback which generates the PPS output (in the event of the system real-time clock not progressing as expected). The absolute value and update frequency offset of this clock, etc, may be adjusted from within both kernel-space and user-space (by applications with the right capabilities - seeman adjtimex(2)). So the failure mode this patch aims to provide some protection against is a very real risk. As thehrtimerevent callback is executed within a hard interrupt context on both standard and real-time (PREEMPT_RT) Linux kernels, you want to avoid this kind of lock-up from occurring. Hence, I would say that a similar change ought to be applied to all PPS generator kernel modules where this failure mode applies (which will likely be most of those in existence).Regarding the 'core algorithm' changes, as you called them, I am still undertaking static analysis of the different kernel modules' source. If time permits, I'd also like to undertake some dynamic analysis/testing of the different kernel modules (likely with and without some modifications applied). I'll look to provide separate feedback from static and dynamic analysis, such that I can trickle back my findings a bit at a time. As always, this kind of stuff falls under the category of Your Mileage May Vary (YMMV), so I'd also recommend that any testing undertaken on my systems be repeated on yours.Do you have a drop-dead date to get this work completed? I'm currently doing this in my spare time (of which I have very little), but I'd like to be able to help you in the required timescales if practicable.Note that after June, I'll also be available to provide professional support on these matters via consultancy.Jack

author: MarkMLl
author_rank: Frequent Contributor
timestamp: May 07, 2021, 09:48:09 am
content: Abolutely no apologies needed.Quote from: SuntUnMorcov on May 05, 2021, 04:04:35 pmI'm an utter beginner at it, but had used it a few months ago to re-implement some PC drivers (https://github.com/MarkMLl/i2c-ch341-usbplus the matching SPI one) and concluded that its "institutionalised" support of out-of-tree builds made it useful. The makefile etc. in my tentative PPS project is derived from that, and if I've done it properly it should detect whether the OS (i.e. distro and site) has DKMS support automagically.QuoteAbsolutely no target. In practice I've been able to account for the bulk of the timing discrepancy using "dead reckoning", so much of my interest is along the lines of "the kernel really ought to have this working"... which again takes us to out-of-tree builds since it's unlikely that Linux et al. would revoke the "BROKEN" dependency.There is of course a dichotomy there: the intent of DKMS is to ensure that a live server always gets appropriate out-of-tree modules when the kernel is upgraded, but Doctrine has it that live servers shouldn't have development tools on them since they make it easier for an attacker to promote himself to root.Good luck with the consultancy etc. :-)MarkMLl

author: MarkMLl
author_rank: Frequent Contributor
timestamp: July 10, 2021, 05:25:21 pm
content: Apropos generating a PPS signal. I've been playing with the Raspberry Pi based one, and found that the things that were really needed were (a) minimal indication that the devicetree has actually been consulted, (b) kicking the signal active during initialisation and leaving it there to verify that the correct port is being used, and (c) toggling the signal every second rather than generating a short pulse. That got me something that mostly worked (some pulses might be lost), but it was enormously easier to see on a 'scope if the maximum width was increased to around 0.25 secs.Moving back to a PC, the same hacks allowed me to see that the parallel port strobe signal could be set and toggled. However it also showed up some sort of timing problem on the pulse width which I can partially work around by using udelay() or mdelay() rather than a busy wait.When the spirit moves me I'll see if I can merge the source of the two modules, and tidy up some of the timing maths... I've camped on that sort of thing before. In particular I don't see that the pulse-width stuff really needs a busy-wait, particularly on a modern processor which is likely to have plenty of threads.The bottom line is that while it's not brilliant, what's coming out allows reasonable verification that the internal clock of a PC hence the time fetched off the Internet has some reasonable credibility relative to e.g. GPS.MarkMLl