#define SIGNAL 0 #define NO_SIGNAL PARPORT_CONTROL_STROBE
/* module parameters */
#define SEND_DELAY_MAX 100000
staticunsignedint send_delay = 30000;
MODULE_PARM_DESC(delay, "Delay between setting and dropping the signal (ns)");
module_param_named(delay, send_delay, uint, 0);
#define SAFETY_INTERVAL 3000/* set the hrtimer earlier for safety (ns) */
/* internal per port structure */ struct pps_generator_pp { struct pardevice *pardev; /* parport device */ struct hrtimer timer; long port_write_time; /* calibrated port write time (ns) */
};
/* We have to disable interrupts here. The idea is to prevent *otherinterruptsonthesameprocessortointroducerandom *lagswhilepollingtheclock.ktime_get_real_ts64()takes<1uson *mostmachineswhileotherinterrupthandlerscantakemuch *morepotentially. * *NB:approxtimewithblockedinterrupts= *send_delay+3*SAFETY_INTERVAL
*/
local_irq_save(flags);
/* first of all we get the time stamp... */
ktime_get_real_ts64(&ts1);
expire_time = ktime_to_timespec64(hrtimer_get_softexpires(timer));
dev = container_of(timer, struct pps_generator_pp, timer);
lim = NSEC_PER_SEC - send_delay - dev->port_write_time;
/* check if we are late */ if (expire_time.tv_sec != ts1.tv_sec || ts1.tv_nsec > lim) {
local_irq_restore(flags);
pr_err("we are late this time %lld.%09ld\n",
(s64)ts1.tv_sec, ts1.tv_nsec); goto done;
}
/* busy loop until the time is right for an assert edge */ do {
ktime_get_real_ts64(&ts2);
} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
/* set the signal */
port = dev->pardev->port;
port->ops->write_control(port, SIGNAL);
/* busy loop until the time is right for a clear edge */
lim = NSEC_PER_SEC - dev->port_write_time; do {
ktime_get_real_ts64(&ts2);
} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
/* unset the signal */
port->ops->write_control(port, NO_SIGNAL);
ktime_get_real_ts64(&ts3);
local_irq_restore(flags);
/* update calibrated port write time */
dts = timespec64_sub(ts3, ts2);
dev->port_write_time =
(dev->port_write_time + timespec64_to_ns(&dts)) >> 1;
done: /* update calibrated hrtimer error */
dts = timespec64_sub(ts1, expire_time);
delta = timespec64_to_ns(&dts); /* If the new error value is bigger then the old, use the new *value,ifnotthenslowlymovetowardsthenewvalue.This *wayitshouldbesafeinbadconditionsandefficientin *goodconditions.
*/ if (delta >= hrtimer_error)
hrtimer_error = delta; else
hrtimer_error = (3 * hrtimer_error + delta) >> 2;
MODULE_AUTHOR("Alexander Gordeev <lasaine@lvk.cs.msu.su>");
MODULE_DESCRIPTION("parallel port PPS signal generator");
MODULE_LICENSE("GPL");
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.10Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.