There was a problem in scpi_serial.c in the scpi_serial_read_data()
function. Incoming data was written at the read position in the buffer,
although it should be written at the count position in the buffer.
This is another attempt at getting the mess that is libusb event
handling on Windows under control. Until libusb makes its HANDLEs
available for polling, we have no choice but to block while waiting
for libusb events. Since we do not want to force drivers to deal
with multi-threading issues, that means we have to block in the
session main loop.
Fortunately, it turns out that our drivers aren't using multiple
event sources, so it is actually possible to block the main loop
without disrupting too much. This also gets rid of the USB thread
on Windows. Thankfully, libusb does not seem to care that we are
now calling libusb_handle_events_timeout_completed() twice per
iteration: first a blocking call (with timeout) in the callback
wrapper, followed by the non-blocking call in the driver-supplied
callback.
Turns out that having one event source per libusb poll FD is
a bad idea. There is only a single callback for all poll FDs,
and libusb expects to be called only once per poll iteration,
no matter how many FDs triggered.
Also, they should all share the same timeout, which should get
reset on events from any polled FD. The new timeout handling made
this problem apparent, as it caused the callback to be invoked
multiple times on timeouts, once for each separate event source.
In order to fix this, change the implementation to allow for an
arbitrary number of poll FDs per event source. This number is
zero for timer FDs, one for normal I/O sources, and one or more
for libusb sources (Unix only).
Also, on Windows, do not get an additional timeout from libusb
in the event loop. This is only appropriate when polling the
libusb FDs directly, which we aren't doing on Windows.
Handle I/O sources and timer ("dummy") sources within the same
polling loop, so that both may be used together. Slightly change
the API to improve consistency: a timeout value of -1 now disables
the timeout, and 0 makes the source always time out immediately.
The "dummy" sources already behaved that way, although it wasn't
documented as such.
Make sure that I/O events are processed preferentially: Skip any
timeout callbacks if an I/O event occurred within the same poll
iteration. This applies to both timer/idle sources and timeouts
of I/O sources.
Do not create dummy GPollFDs for timer/idle sources. Instead,
split the sources array into an I/O section and a timer section,
and create corresponding GPollFDs only for the I/O section. Use
GArray to simplify the handling of the dynamic arrays.
Keep track of when source timeouts are due and properly compare
against accumulated elapsed time between invocations. This prevents
sources with short timeouts from blocking other sources with longer
timeouts indefinitely.
Looking at the g_poll() implementations for various systems, it
appears that on Windows the return value is 0 if the wait was
interrupted, and errno is never set. Also, the MacOS X wrapper
around select() does not clear revents on timeout.
To deal with these issues, check for EINTR only on Unices, and
assume revents to be invalid unless g_poll() returned a positive
value.
If the call to g_poll() in sr_session_iteration() fails, report
the error back to the caller. Do not treat EINTR as error though.
Check for session abort only if a source callback was actually
invoked, or at least once if none of the callbacks are invoked.
Stop checking for abort if the session has already been stopped,
just in case a callback sets abort_session again.
Also change the documentation to match the actual behavior.
In sr_session_iteration(), remove the inverted evaluation of the
block parameter if a USB source is present. This stops the deluge
of USB event callbacks due to the timeout always being zero.
Also, just for cleanliness, initialize the revents member of each
GPollFD instance to zero.
This was superfluous -- there is no need to be able to query the
last MQ(s) sent by the device, since they're already being sent
along with the measurements in analog packets.
Since there is also no way to change the MQ (that is done with the
buttons on the device), there is no need to even list the possible
MQs.
The need to make this a list no longer applies.
SR_T_MQ is thus a type consisting of a tuple with two elements: the first
item is the MQ (type G_VARIANT_TYPE_UINT32), and the second is the MQ
flags value (G_VARIANT_TYPE_UINT64).
After the packet has been passed through the transformation modules,
the transformed data is in packet_in but the following code uses
the packet variable which still points to the original input.
This fixes bug #631.
Make vxi.h the first #include in all affected files and #undef the
_POSIX_C_SOURCE macro in vxi.h.
This avoids various build issues on e.g. FreeBSD or Mac OS X where
setting _POSIX_C_SOURCE leads to the unavailability of certain types
such as u_long (as used in the VXI/RPC code).
This type consists of an array, with each item a two-member tuple,
representing an MQ/MQflags pair: the first item is the MQ (type
G_VARIANT_TYPE_UINT32), and the second is the MQ flags value
(G_VARIANT_TYPE_UINT64).
A GVariant of type SR_T_MQLIST can thus always represent more than
one MQ/MQflag pair.
The tables defined with this struct can now be used for information
on items other than config keys.
Functions to access these tables have been renamed sr_key_info_[name_]get.
These take an extra argument, keytype, which should be set to SR_KEY_CONFIG
to get the config key tables. Other key types will be added.
Move the include flags for files in the source tree from
configure.ac to Makefile.am where they belong. Also use
AM_CPPFLAGS instead of CFLAGS/CXXFLAGS to make sure the
files in the build/source tree are always picked up first.
Also, remove the include/libsigrok sub-directory from the
search path, thereby making the <libsigrok/> prefix mandatory
when building libsigrok itself. This matches the convention
already imposed on users of the library.
- Don't #include <errno.h> in files that don't actually need it.
- Don't use strerror() on error codes from functions that don't set
errno. Replace strerror() with sr_strerror() for libsigrok functions.
Fixes a bug where new acquisition failes due to leftover pipes from
previous acquisitions:
sr: demo: dev_acquisition_start: pipe() failed
Indeed, PulseView had 2024 pipes opened. With this fix, it stabilizes at
33 with sampling thread active.
Signed-off-by: Hubert CHAUMETTE <hchaumette@baylibre.com>
Move the libusb_detach_kernel_driver() call after the code that
sets the usb->devhdl pointer, otherwise it'll be NULL and result
in a segfault.
#0 libusb_kernel_driver_active (dev=0x0, interface_number=0) at libusb/core.c:1711
#1 dev_open (sdi=0x12d99f0) at src/hardware/fx2lafw/api.c:374
[...]
Tested on a device with the default Cypress VID/PID and one with
the Saleae Logic VID/PID, both works fine.
The timerfd descriptor is closed automatically by
g_io_channel_shutdown(). No need to close it manually.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
At high sampling rates and maximum channels we are not able to acquire
samples fast enough, even though frontends still think that samples
arrive on time. This causes visible shifts in frontend plots.
To compensate for the delay introduce the following workaround: check
if we are late (if any clock events have been missed) and resend the
last frame n times (n == number of missed clock events).
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Currently baylibre-acme uses a fake pipe as the input channel required by
libsigrok API and calls sleep() in the data acquisition callback to create
intervals between measurements.
Switch to a more elegant approach: use Linux' timerfd and set a periodic
timer equal to the sampling rate. Then read the data every time the timer
expires.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Opening a file has a cost (security, allocation, syscalls). The
read_sample() function always does an open/read/close sequence.
In order to optimize that, let's open the file at the moment the
acquisition starts, close it when the acquisition stops and make
read_sample() only lseek() to the beginning of the file and read
the value.
Signed-off-by: Daniel Lezcano <daniel.lezcano@free.fr>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This was originally done as an optimization in combination with a list
reversal which has since been removed from the code. Thus, un-reverse
the channels so that the UI lists them in the correct order again.
The Chroma 62000P series comes in various models with different
current and voltage capabilities. These are encoded in the *IDN
string, so just get them from there, rather than needing a profile
for every model.