Commit 947a5c7c authored by Jorge Machado's avatar Jorge Machado

Add fmc-dio documentation

parent 17cdfaf7
*~
*.aux
*.cp
*.cps
*.fn
*.html
*.info
*.ky
*.log
*.pdf
*.pg
*.texi
*.toc
*.tp
/*.txt
*.vr
#
# Makefile for the documentation directory
#
# Copyright 1994,2000,2010,2011 Alessandro Rubini <rubini@linux.it>
#
#################
# There is not basenames here, all *.in are considered input
INPUT = $(wildcard *.in)
TEXI = $(INPUT:.in=.texi)
INFO = $(INPUT:.in=.info)
HTML = $(INPUT:.in=.html)
TXT = $(INPUT:.in=.txt)
PDF = $(INPUT:.in=.pdf)
ALL = $(INFO) $(HTML) $(TXT) $(PDF)
MAKEINFO ?= makeinfo
RELEASE=$(shell git describe --always --dirty)
%.texi: %.in
@rm -f $@
sed s/__RELEASE_GIT_ID__/$(RELEASE)/ $< | sed -f ./infofilter > $@
emacs -batch --no-site-file -l fixinfo $@
chmod -w $@
%.pdf: %.texi
texi2pdf --batch $<
%.info: %.texi
$(MAKEINFO) $< -o $@
%.html: %.texi
$(MAKEINFO) --html --no-split -o $@ $<
%.txt: %.texi
$(MAKEINFO) --no-headers $< > $@
##############################################
.PHONY: all images check terse clean install
.INTERMEDIATE: $(TEXI)
all: images $(ALL)
$(MAKE) terse
images::
if [ -d images ]; then $(MAKE) -C images || exit 1; fi
check: _err.ps
gs -sDEVICE=linux -r320x200x16 $<
terse:
for n in cp fn ky pg toc tp vr aux log; do rm -f *.$$n; done
rm -f *~
clean: terse
rm -f $(ALL) $(TEXI)
install:
# add the other unused targets, so the rule in ../Makefile works
modules modules_install:
;; use:
;; emacs -batch -l ./fixinfo.el <file>
;; or, better:
;; emacs -batch --no-site-file -l ./fixinfo.el <file>
(defun fixinfo (file)
(find-file-other-window file)
(message (concat "Maxing texinfo tree in " file))
(texinfo-all-menus-update)
(texinfo-every-node-update)
(save-buffer)
(kill-buffer (current-buffer))
)
;; loop over command line arguments
(mapcar 'fixinfo command-line-args-left)
(kill-emacs)
\input texinfo @c -*-texinfo-*-
% fmc-dio.in - main file for the documentation
%
%
%%%%
%------------------------------------------------------------------------------
%
% NOTE FOR THE UNAWARE USER
% =========================
%
% This file is a texinfo source. It isn't the binary file of some strange
% editor of mine. If you want ASCII, you should "make spec-sw.txt".
%
%------------------------------------------------------------------------------
%
% This is not a conventional info file...
% I use three extra features:
% - The '%' as a comment marker, if at beginning of line ("\%" -> "%")
% - leading blanks are allowed (this is something I can't live without)
% - braces are automatically escaped when they appear in example blocks
%
@comment %**start of header
@documentlanguage en
@setfilename fmc-dio.info
@settitle fmc-dio
@iftex
@afourpaper
@end iftex
@comment %**end of header
@setchapternewpage off
@set update-month July 2020
@c the release name below is substituted at build time
@set release __RELEASE_GIT_ID__
@finalout
@titlepage
@title FMC DIO Software Support
@subtitle @value{update-month} (@value{release})
@subtitle A driver for the FMC DIO module
@author Alessandro Rubini for CERN (BE-CO-HT), Jorge Machado Cano (Seven Solutions)
@end titlepage
@headings single
@c ##########################################################################
@iftex
@contents
@end iftex
@paragraphindent 1
@c ##########################################################################
@node Top
@top Introduction
This is the manual for the fmc-dio device driver.
@c ##########################################################################
@node History and Overview
@chapter History and Overview
@c ##########################################################################
@node Compiling the Drivers
@chapter Compiling the Drivers
The kernel modules that are part of this package live in the @i{kernel}
subdirectory. To compile them, you need to
set the following variables in your environment:
@table @code
@item LINUX
The top directory of the kernel sources for the version you
are going to run the driver under. I'm testing mostly with 3.4,
but this version compiles against Linux-2.6.37 and later ones
(2.6.36 had a different interface for hardware timestamping,
so @i{fmc} and @i{spec} compile fine, but @i{wr-nic} does not).
@item CROSS_COMPILE
If you are cross-compiling, you need to set this variable.
It is not usually needed for the PC, but if you are using
the @i{Powec} board, you'll most likely need this. It is not
needed if you compile for a different-sized PC (see below).
@item ARCH
If you are cross-compiling, set this variable. Use @code{powerpc}
for the @i{Powec}, @code{x86-64} if you compile on a 32-bit PC
to run on a 64-bit PC and @code{i386} if you compile on a 64-bit
PC to run on a 32-bit PC.
@end table
To compile run ``@code{make}'' with the previous variables set. To
install run ``@code{make install} to install under
@code{/lib/modules/3.4.0} (or other version-based directory). You can
set @code{INSTALL_MOD_PATH} to force and installation directory
(as a prefix followed by @code{/lib/modules/...}).
For example, if your target computer's filesystem is mounted under
@code{/mnt/target} you can run
@example
make install INSTALL_MOD_PATH=/mnt/target
@end example
The modules are installed under the subdirectory @code{extra}. In
the case shown above your driver will end up being installed
(together with the other modules) as
@example
/mnt/target/lib/modules/3.4.0/extra/fmc-dio.ko
@end example
Please note that by default the package compiles an installs the
@i{fmc-bus} modules, too (the project is a @i{git} submodule).
@c ##########################################################################
@node Role of fmc-dio.ko
@chapter Role of fmc-dio.ko
The FMC-DIO driver consists of a set of functions accesible through an IOCTL
call to write on the registers of each channel of the FMC-DIO board to generate
totally configurable pulses. It also recovers timestamps of external and generated
pulses.
@c ==========================================================================
@node fmc-dio Initialization
@section fmc-dio Initialization
There is no need to explicitly initialize the FMC-DIO driver.
@c ==========================================================================
@node Interrupts in fmc-dio.ko
@section Interrupts in fmc-dio.ko
There is only an interrupt to control the number of pulses that has been generated.
@c ==========================================================================
@node Code Layout
@section Code Layout
This section is mainly for the developers who look in the code, and for
me to make order in my own mind. FMC-DIO users are expected to skip to
the next section.
The @code{fmc-dio.ko} is built using a number of headers and source files,
spread over several directories:
@table @file
@item fmc-bus/
FMC-BUS kernel driver support (see specific doc inside)
@item kernel/
This directory contains the low level functions to configure each
physical channel and the interrupt management.
@item tools/
This directory hosts the userspace tools that uses the low level
functions.
@end table
The @i{fmc-dio} driver refers to several headers, in addition to the
register definitions. This is the role of each of them:
@table @file
@item kernel/fmc-dio.c
@item kernel/fmc-dio.h
Code and headers of the driver initialization. It also detects
the version of the FPGA binary to able coherent memory accesses
through all the code.
@item kernel/fmc-dio-gpio.c
DIO GPIO support skeleton to be developed.
@item kernel/fmc-dio-internal.c
Code that excecutes the requested operations through the IOCTL.
It also implements the interrupt management.
@item kernel/fmc-dio-mdev.c
This code created the device and connects the IOCTL.
@item kernel/hw/ppsg-regs.h
@item kernel/hw/wr-dio-regs.c
@item kernel/hw/wr-dio-regs.h
@item kernel/hw/wr-dio-regs_v1.c
@item kernel/hw/wr-dio-regs_v1.h
@item kernel/hw/wr-dio-regs_v2.c
@item kernel/hw/wr-dio-regs_v2.h
Code and headers with the register map of the fmc-dio. It also
implements some functions to get the offset of each register.
@end table
The @i{tools} directory contains all the userspace tools the manage the
@i{fmc-dio} driver. This is the role of each of them:
@table @file
@item tools/net_tstamp.h
@item tools/stamp-frame.c
Code and headers of timestampig related functions.
@item tools/wr-dio-agent.c
Code to receive almosteverything that appears on the cable.
@item tools/wr-dio-cmd.c
Code that implements the userpace commands to manage the fmc-dio
channels.
@item tools/wr-dio-pps.c
Example of a PPS generation.
@item tools/wr-dio-ruler.c
Code to transmit raw Ethernet frames to the broadcast address.
@end table
@c ==========================================================================
@node Overview of the Driver
@section Overview of the Driver
TO BE WRITTEN
@c ==========================================================================
@node Accessing the DIO Channels
@section Accessing the DIO Channels
In order to access the DIO channels, user-space programs are expected
to issue device-specific @i{ioctl} commands. The driver supports two
commands, allocated at the end of the range of command numbers reserved
for device-specific use:
@table @code
@item PRIV_MEZZANINE_ID
The command is used to identify the features of the
specific NIC device. It tells user space which mezzanine is
currently plugged and also which type of carrier you are talking to.
The command exchanges a data structure with user space in order
to be able to extend its functionality over time, and such data
structure includes a sub-command
field. (For example, we may return EEPROM contents to user space
on request).
@b{Warning}: the command is not implemented because we still have
no mezzanine identification in place. The error being returned
is @code{EAGAIN}; user code can rely on that error to know it
is actually talking with a SPEC device, even if no identification
is currently possible.
@item PRIV_MEZZANINE_CMD
The command is based on the exchange of a data structure: by
means of sub-commands included in such structure user space
programs can request different services to the mezzanine driver.
In the case of the DIO mezzanine this includes generating pulses
and timestamping input events; other mezzanine drivers will
be able to use the command in a different way. The application
is expected to first run @code{PRIV_MEZZANINE_ID} to ensure the
NIC device is connected to the right mezzanine.
@end table
The data structure is defined and explained in @code{wr-dio.h} and
is not repeated here.
The structure includes a few integer fields and an array of
@code{struct timespec}. Such structures define time stamps with
nanosecond precision, but the @i{simple-DIO} mezzanine and its gateware
are able to time-stamp input events and generate output events with a
resolution of 8ns.
When the device is asked to timestamp input events, the array of
@code{struct timespec} is used
to return such events to user space. When the device is asked to
generate output pulses at specific points in time, the array is used
to pass three values: the beginning of the pulse, the duration of the
pulse and (optionally) the period of the pulse train.
Specifics about the use of individual fields are shown in the header
(in a big comment block), in the driver itself and in the user-space
programs that call @i{ioctl}.
In lab environments you may be concerned about the duration of the
@i{ioctl} implementation, because it sometimes seems to do more work
than needed. To verify whether we have an over-engineering problem in
kernel space, I provided a simple measurement of how much time is
spent in the @i{Ioctl} itself. The @i{make} variable
@code{WR_NIC_CFLAGS} can be used to pass extra flags to the compiler,
and the macro @code{DIO_STAT} enables the time measurement.
Compiling with the following command thus enable such measurement
and associated @i{printk} -- the time is usually 5 microseconds for me:
@example
make WR_NIC_FLAGS=-DDIO_STAT
@end example
Previous versions of this manual described how to command pulses on
several channels with a single @i{ioctl} command, but that feature has
never been implemented (one of the reasons is that @i{ioctl} revealed
fast, so calling it several times is acceptable).
@c ==========================================================================
@node FMC-DIO Command Tool
@section FMC-DIO Command Tool
In the @file{tools/} subdirectory of this project, you find the
@file{wr-dio-cmd} program, which is a command-line interface to the
@i{ioctl} command that acts on the @i{simple-DIO} mezzanine card. Other
@code{wr-dio-} tools are provided (and described below) but this is
the most generic one.
Please note that neither timestamping nor pulse generation work
if the WR core is not running or has an invalid time: it must either be
a master or a synchronized slave.
Moreover, please note that this tool is just a demonstration to quickly
test the I/O features of the device (and for me to verify the kernel
part is actually working): for serious use you should call
@i{ioctl} by yourself with proper arguments, and avoid all the parsing
of ASCII and repeated invocation of this program.
This is the general syntax of the command:
@example
wr-dio-cmd <ifname> <cmd> [<arg> ...]
@end example
The arguments have the following meaning
@table @code
@item ifname
The name of the network interface, most likely @code{wr0}
(if you have more than one SPEC card, the other interfaces are
called @code{wr1}, @code{wr2} and so on).
@item cmd
The specific command. Supported commands are listed below.
Each command takes zero or more of arguments. If you pass
a wrong number of arguments you'll get help, and
if one argument is wrong (e.g., not a number) the
error message is meant to be directly helpful.
@end table
@b{Note}: This command, like everything else in this package, numbers
channels from 0 through 5, whereas the back panel of the mezzanine
numbers them 0 through 4. The last channel does not represent a physical channel,
it is a virtual channel to generate interrupts.
The current version of the tool supports the following commands:
@table @code
@item stamp [<channel>] [wait]
@itemx stampm [<channel-mask>]
The commands are used to retrieve timestamps from the card.
If no arguments are passed, the tool reports to @i{stdout} all
timestamps for all channels (they are ordered by channel, not
by time). If one integer argument is passed, it can be a channel
number in the range 0 to 5 (@code{stamp} command) or a mask
in the range 0 to 0x3f (@code{stampm} command). If getting stamps
for an individual channel, you can add the @code{wait} option
to have the tool wait for (and report) new timestamps until killed.
@b{Warning}: use of @code{wait} is dangerous because it has
been implemented against the rules. You must
terminate any waiting process before you unload the driver, or
your PC will explode and will destroy your academic career.
@item pulse <channel> <duration> <when> [<period> <count>]
Channel is an integer in the range 0 to 4. The duration must
be specified as a fraction of a second (decimal number, less than
one second), the @code{when} argument can be the string @code{now},
an absolute time (@code{<seconds>.<fraction>}) or a relative
time (@code{+<seconds>.<fraction}). In the last case, the
current second is added to @code{<seconds>} while the fraction
is used unchanged. The @code{+} form is useful for simple checks with
visual inspection. @code{period}, if specified, requests for
a pulse train, with the specified time period between raising edges;
@code{count} is the number of instances to run (-1 means forever,
0 means ``stop generating pulses'').
@item irq <when> [<period> <count>]
This command only generates interrupts and does not generate any
physical pulse. The duration must be specified as a fraction of a
second (decimal number, less than one second), the @code{when}
argument can be the string @code{now}, an absolute time
(@code{<seconds>.<fraction>}) or a relative time
(@code{+<seconds>.<fraction}). In the last case, the current second
is added to @code{<seconds>} while the fraction is used unchanged.
The @code{+} form is useful for simple checks with visual inspection.
@code{period}, if specified, requests for a pulse train, with the
specified time period between rising edges; @code{count} is the number
of instances to run (-1 means forever, 0 means ``stop generating pulses'').
@item mode <channel> <mode> [<channel> <mode> ...]
@itemx mode <m0><m1><m2><m3><m4>
Configure one or more channels for the specified mode. Each mode
is represented by one character; the latter form above thus
configures all 5 channels by means of a 5-bytes-long string,
each characters specifies a mode according to the next table.
The irq channel can not be configured with this command, it is
automatically configured with the @code{irq} command.
@end table
This is the list of supported modes for channels:
@table @code
@item I i
Input mode, with termination or without termination. Uppercase
forces the termination on (the rationale is you need a stronger
signal to drive the input). Termination is 50 Ohm. Pulses on
an input channel are timestamped.
@item 0 1
Digital output mode, from the GPIO logic core, resp. low and high.
Both modes disable the termination resistor.
@item D d
DIO core output (not the GPIO core). With this mode the channel
is driven by the WR-aware digital I/O, and can thus generate pulses
and so on. Uppercase enables the termination.
A channel managed by the DIO core is normally low and can
pulse high on request (see @code{pulse}
command. The termination resistor doesn't make much sense for
output, but the code is provided for consistency with input modes.
@item P p (Channel 0)
Pulse per second output from the White Rabbit core that can be used
only for the first channel (ch0). This @i{pps} is sharper in its absolute
time than the one that can be
generated by software using DIO pulses. Again, upper case
selects the termination, for symmetry with input modes.
@item C c (Channel 4)
``Clock'' input. This mode (with or without termination) is
used to feed a clock to the White Rabbit core (currently the
WR core supports a 10MHz input on channel 4 (the last one).
For other channel, the mode is just like @t{I} or @t{i} but
without timestamping (and thus without a software interrupt).
@end table
@b{Note}: The first channel (channel 0) has been modified and now support only the
@t{P}/@t{p} as output mode. You will not be able to use @t{D},@t{d},@t{1},@t{0} modes.
@b{Note}: At startup, the DIO channels are configured by default as:
@code{wr-dio-cmd mode p00ic}.
Generation of a pulse train is performed by the FPGA, but the sofware takes care of
the pulse count. For this reason you'll observe that the pulse period cannot be too short,
according to how powerful your computer is and how much you loaded it with other
tasks.
There is no command to flush the timestamp FIFOs, but you can
always ``@code{wr-dio-cmd stamp > /dev/null}'' if needed.
Example uses of the tool follow:
@example
# Pulse channel 4 for 0.1 seconds now
wr-dio-cmd /dev/fmc-dio-1:0 pulse 4 .1 now
# Pulse for 10 microseconds in the middle of the next second
wr-dio-cmd /dev/fmc-dio-1:0 pulse 4 .00001 +1.5
# Pulse for 1ms at 17:00 today
wr-dio-cmd /dev/fmc-dio-1:0 pulse 4 .001 $(date +%s --date 17:00)
# Get timestamps for the output events above
wr-dio-cmd /dev/fmc-dio-1:0 stamp 4
# Make a train of 5 pulses, 0.5ms wide, every ms at next second
wr-dio-cmd /dev/fmc-dio-1:0 pulse 4 0.0005 +1 .001 5
# Configure channel 0 as input with termination, 1 as input, 4 as low
wr-dio-cmd /dev/fmc-dio-1:0 mode Ii--0
# Generate interrupt now
wr-dio-cmd /dev/fmc-dio-1:0 irq now
# Generate 100 interrupts every 10 ms at the next second
wr-dio-cmd /dev/fmc-dio-1:0 irq +1 .01 100
@end example
@c ==========================================================================
@node Timestamping Fast Input Signals
@section Timestamping Fast Input Signals
When timestamping pulses in the @i{simple-DIO} mezzanine board, an
interrupt is generated to notify the driver that a new timestamp is
pending. On recent computers this works reliably up to more than
100kHz, but clearly there is a point where the system locks up,
because it spends all of its time in interrupt handling.
This problem is transient: as soon as you remove the offending cable
the system recovers. However, you need a 10MHz input signal if you
want to run your SPEC device to be a White Rabbit @i{grandmaster}. In
order to support that, the driver disables DIO interrupts when the
time spent in interrupt management exceeds 80% of the total time,
averaged over one thousand interrupt events. Ethernet interrupts
are not affected. The fact is reported by a kernel message, using
the PCI address of the card that triggered the problem.
@example
spec 0000:04:00.0: DIO irq takes > 80% CPU time: disabling
@end example
This choice allows stamping your pulse trains up to a few dozen
kilohertz and still be able to feed higher frequencies without manual
intervention. However, after DIO interrupts are disabled, the only
way to re-enable them is removing and reloading the device driver.
@b{Note}: if you run two SPEC cards, and one is fed with high frequency
pulses, it may happen that interrupts are disabled on both boards.
The safeguard is currently not very refined, as it was implemented in
a hurry.
@c ==========================================================================
@node WR-DIO Pulse per Second
@section WR-DIO Pulse per Second
To better show how to write your own application with the SPEC driver
and the @i{simple-DIO} mezzanine card, this package includes
@file{wr-dio-pps}, which features a very small and readable source
file.
The program is meant as a source code example, more than a real PPS
signal. If you need a real WR-driven pulse-per-second, you should
use the channel0 wich is "hard-wired" to the PTP core and can be configured by
executing: ``@t{wr-dio-cmd mode 0 p}''.
The program just fires a 1ms-long @i{pps} pulse on one of the output
channels. The device name defaults to @i{wr0} but can specify a different one;
the channel number is a mandatory argument.
@b{Note}: This command, like everything else in this package, numbers
channels from 0 through 4, whereas the back panel of the mezzanine
numbers them 1 through 5. My devices have no panel, so I just made
the wrong guess.
@example
# run pps on channel 2 of the default SPEC card
./wr-dio-pps 2
# run pps on channel 0 of the "second" card
./wr-dio-pps wr1 0
@end example
The following two figures show two such @i{pulse-per-second} signals
retrieved from two different @i{simple-DIO} cards, connected by a 10km
roll of fiber, after syncing with @i{White Rabbit}. In some cases, it
may happen that the leading edges differ by almost exactly 8ns; this
happens because in the @i{simple-DIO} all times are quantized by
8ns-long clock ticks. The differences in internal delays (which depend
on the carrier, the mezzanine and the FPGA binary), are not
self-measured and calibrated in this simple design and may appear in
the output after quantization. A more complete experimental setup
would include calibration of the internal delays of the boards, like
the mechanism in place for the @i{fine-delay} mezzanine card (see
@url{http://www.ohwr.org/projects/fmc-delay-1ns-8cha} and
@url{http://www.ohwr.org/projects/fine-delay-sw}).
@sp 1
@center @image{two-pps-whole, 10cm}
@sp 1
@center @image{two-pps-detail, 10cm}
@sp 1
@c ==========================================================================
@node Distributing Output Pulses
@section Distributing Output Pulses
A typical application for @i{White Rabbit} (or any time
synchronization system) is being able to generate output signals at the
same time in different output boards; another typical application is
time stamping input events.
By using the Ethernet interface included in the SPEC,
an application can exchange data with other @i{White
Rabbit} devices; thus, it can easily request output event to
other output peripherals, or collect remote input events.
The tool-set offered by the driver
is made up of the the @code{PRIV_MEZZANINE_CMD} @i{ioctl} command,
amd the usual Posix API for network communication.
The @i{DIO-specific} @i{ioctl} command is the one used by the
@code{wr-dio-cmd} tool described above, while network communication
should be known to most users of this package. In order to ease new
@i{White Rabbit} users, though, this package includes sample code to
implement a simple dual-headed system with concurrent output. The
examples are also meant to show the basic code that uses the provided
@i{ioctl} command, without all the boring parameter parsing that is
required in more generic tools like @code{wr-dio-cmd}. Because of this
simplification of parameter passing, the pulse width is hardwired to 1ms.
The example is made up of two programs: @code{wr-dio-agent} and
@code{wr-dio-ruler} (the former is a dumb actor, while the latter
states the rules). To keep things simple the two programs
assume that the SPEC is connected point-to-point to another SPEC
and both carry the @i{simple-DIO} mezzanine.
Under this simplified assumptions, the @i{ruler} transmits raw Ethernet
frames to the broadcast address, while the @i{agent} receives almost
everything that appears on the cable. This choice allows plugging two SPEC
cards in the same computer and run the example; if the example
used an IP-based protocol (like UDP) it couldn't be used
with two cards on a single PC -- and a fiber through them.
The simplification above, however, most likely
prevents the programs from working within a more complex
network topology. I expect real @i{White Rabbit} users to add proper
network addressing in their applications.
If you have a single SPEC card, you can still use the @i{ruler} by
itself to mirror an input channel to an output channel of the same
card, with a specified delay.
@sp 1
The @i{agent} program silently listens to the network interface and
receives a data structure ready to be passed to @i{ioctl}. Its only
command line argument is the name of the @i{White Rabbit} interface to
use (for most users it is @code{wr0}):
@example
wr-dio-agent wr0
@end example
The @i{ruler} command, on the other hand, waits for timestamps
to appear on the specified input channel;
when notified about a positive-going edge, ot
replicates the edge on one or more outputs. Each output can be
local or remote, and can use a different delay from the input pulse.
If you lack an input signal, you can make an output pulse with
@code{wr-dio-pps} or other means and use it as a trigger. Please note
that the @i{ruler} does not configure the channel mode, so you might
want to use the @code{mode} command of @code{wr-dio-cmd} in advance.
The following command waits for events on channel 0 of the card connected
to @i{wr1}, and replicates the event with a delay of 1ms on channel 3 of
both the local and the remote card; it also replicates with a 2ms
delay to local channel 4. Please note that the delays should be no
more than the interval between input pulses, because the tools
reprograms all output triggers at each input event.
@b{Note}: As usual, channels are numbered 0 through 4.
@example
wr-dio-ruler wr1 IN0 L3+0.001 R3+0.001 L4+0.002
@end example
There is no sample code that generates trains of pulses as a response
to events, nor support for other than 1ms-long output pulses; anyways,
the code is
thoroughly commented in order to serve as a starting point for
more complex lab environments.
As a final remark, please note that all pulse generation is driven by
host hardware, after an hardware interrupt reports the input event,
but the software controls the number of number of pulses that has been
generated.
For this reason, you'll not be able to reliably replicate pulses with
delays smaller than a few hundred microseconds, depending on the
processing power of your computer and the load introduced by other
processes. For remote connections, you must also count the overhead
of network communication as well as transmission delays over
the fiber (a 10km fiber introduces a
delay of 50 microseconds).
The following example shows use of the @i{ruler} and @i{agent} on
two hosts, called @code{spusa} and @code{tornado}. The input events
on @code{spusa} are replicated to one local channel and two remote channels,
with a delay of 1ms. The input events in this case are from a @i{pulse-per-second} signal:
@smallexample
tornado.root# /tmp/wr-dio-agent wr0 &
spusa.root# wr-dio-ruler wr1 IN4 L3+.001 R4+.001 R2+.001
wr-dio-ruler: configured for local channel 3, delay 0.001000000
wr-dio-ruler: configured for remote channel 4, delay 0.001000000
wr-dio-ruler: configured for remote channel 2, delay 0.001000000
[... wait a few seconds ...]
spusa.root# wr-dio-cmd wr1 stamp 3
ch 3, 385.001000000
ch 3, 386.001000000
ch 3, 387.001000000
ch 3, 388.001000000
tornado.root# wr-dio-cmd wr0 stamp 2
ch 2, 385.001000000
ch 2, 386.001000000
ch 2, 387.001000000
ch 2, 388.001000000
tornado.root# wr-dio-cmd wr0 stamp 4
ch 4, 385.001000000
ch 4, 386.001000000
ch 4, 387.001000000
ch 4, 388.001000000
@end smallexample
@c ##########################################################################
@node Bugs and Missing Features
@chapter Bugs and Missing Features
@itemize @bullet
@item Identification of the mezzanine is completely missing; every @i{fmc}
driver at this point takes hold of every device. We are working on this,
and the next version of spec-sw will support identification, with a flag
to run without identification for users whose EEPROM has not been programmed.
@item Both spec and wr-nic should have GPIO support with @i{gpiolib};
there is skeletal support but no real code for actual I/O. This is not
a priority, just a wish list for better Linux integration.
@item The NIC driver should directly support setting the White Rabbit
mode for each card (grandmaster, free-running master or slave). This
will be supported at module load time, not at runtime (for that please
use the UART).
@item DIO support in @i{wr-nic} is missing some of the features listed
in @file{wr-dio.h} (i.e. DAC control)>
@item The @i{wr-nic} functionality should be completely detached from
the specific mezzanine. This is a longer-term desire.
@item Locking in kernel code should be verified with a serious audit
effort. There are no known issues at this point, but some code may
be made safer.
@end itemize
@c ##########################################################################
@node Portability
@chapter Portability
This package should be portable. However I didn't test it on a wide
variety of systems. Currently most of my use is
on a 32-bit x86 host, running version 3.4 of the kernel.
The complete package builds without any warning from version 2.6.37
up to 3.13 (I didn't try later versions, yet). Frame timestamping
changed seriously after 2.6.36, so the @code{wr-nic.ko} driver is not
easily backward portable.
To allow use of the core @i{spec} driver, to drive custom mezzanines,
the @i{Makefile} supports the configuration variable
@code{CONFIG_WR_NIC}, which you may set to @code{n} before compiling:
@smallexample
export CONFIG_WR_NIC=n
@end smallexample
With this in place, the package compiles without any warning on a
32-bit PC from version 2.6.30 onwards.
By using the backport branch of the 2013-05 release you can build
for all kernels back to 2.6.27 and also 2.6.24 (the one we were still
using in production). Later releases have no associated backport branch.
@c ##########################################################################
@bye
@c LocalWords: gnudd titlepage iftex texinfo CERN documentlanguage settitle
@c LocalWords: documentencoding setfilename afourpaper paragraphindent EEPROM
@c LocalWords: setchapternewpage finalout eeprom gateware devmem devfn busid
@c LocalWords: speclib Gennum timestamps stampm ifname timespec timestamp
@c LocalWords: timestamping linux FPGA ohwr http
#! /usr/bin/sed -f
# allow "%" as a comment char, but only at the beginning of the line
s/^%/@c /
#s/[^\\]%.*$//
s/^\\%/%/
#preserve blanks and braces in @example blocks
/^@example/,/^@end example/ s/{/@{/g
/^@example/,/^@end example/ s/}/@}/g
/^@example/,/^@end example/ p
/^@example/,/^@end example/ d
/^@smallexample/,/^@end smallexample/ s/{/@{/g
/^@smallexample/,/^@end smallexample/ s/}/@}/g
/^@smallexample/,/^@end smallexample/ p
/^@smallexample/,/^@end smallexample/ d
# remove leading blanks
s/^[ ]*//
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