session.c: Remove all remaining sources on sr_session_stop
Some sources may not be necessarily associated with a device. The best example
is the anykey pollfd from sigrok-cli. sr_session_stop only removes sources
associated with hardware devices via dev_acquisition_stop. Sources such as
anykey are not removed, and thus session->num_sources will not get to 0. As a
result, we may get into situations where the event loop enters an infinite
state.
To prevent this, all we have to do is remove any active sources that are still
present after dev_acquisition_stop has been called for all devices.
device.c: Fix memory leak in sr_serial_dev_inst_free
sr_serial_dev_inst_free() freed all members of sr_serial_dev_inst, but did not
free the struct itself, as expected from a free_*() function. This inadvertently
caused a memory leak in every place sr_serial_dev_inst is used.
serial-dmm does not check if a sample limit is actually in place before deciding
to stop acquisition. Since the sample limit is set at 0 by default, operating
in continuous mode will cause acquisition to stop before even sending the first
sample.
Check to make sure we actually are in a sample-limited mode before stopping for
this reason.
Uwe Hermann [Sat, 22 Dec 2012 00:33:03 +0000 (01:33 +0100)]
configure.ac: Improve check for libusb-1.0.
PKG_CHECK_MODULES() checks for libusb-1.0 via pkg-config already, no
need to use a "manual" additional check via AC_CHECK_LIB() just to set
HAVE_LIBUSB_1_0 in config.h.
This helps with cross-compiling setups, among other things.
Joel Holdsworth [Thu, 13 Dec 2012 21:07:53 +0000 (21:07 +0000)]
Pass sr_datafeed_packets and payloads with const pointers
This patch marks packet structures and their payloads as const.
This indicates to packet receivers that modifications to these are
not allowed. In general all pointers should be marked const unless
modification of the referenced data is explicitly allowed.
Hardware scanning creates an ftdi_context before attempting to locate devices
based on PID/VID. If no devices are detected, execution jumps to cleanup. The
context is freed with free(), instead of ftdi_free().
We cannot assume that the libftdi context is stored in a contiguous memory
region, and thus cannot use a simple free. Case in point, this situation is
identified by valgrind as a "definitely lost" memory leak.
Use ftdi_free() instead of a simple free() in hw_scan(). Valgrind no longer
complains about a memory leak in this area.
clear_instances() does not need any modification, as it correctly uses
ftdi_free().
It solved that issue, but inadvertently introduced a new bug:
"Device came back" would be printed even if no firmware upload was performed.
This is counterintuitive, as the device is only reset when a firmware upload is
performed.
There are three cases:
i) Firmware upload was successful
ii) Firmware upload failed
iii) Firmware upload was NOT needed
Each case warrants a separate message from the driver. Print the
following messages depending on the outcome:
i) "Device came back"
ii) "Device failed to renumerate"
iii) "Firmware upload was not needed."
Uwe Hermann [Sun, 16 Dec 2012 20:28:26 +0000 (21:28 +0100)]
serial-dmm: Eliminate unneeded "subdriver" field.
Just use the 'int dmm' + wrapper method that is used for all other
functions which need this information. There is no real need to
special-case the hw_dev_acquisition_start() API call here.
linsigrok.h: Document meaning of SR_UNIT_CONCENTRATION
Having concentration as a unit is vague, as it can be expressed in
many ways. In the context of sigrok, concentration means a normalized
number from 0 to 1.
libsigrok.h: Don't store subdriver in sr_dev_driver
Not all drivers use subdrivers. The only reason the subdriver field was
introduced was to accomodate the model of serial-dmm.
The sr_dev_driver struct is available to the frontend. Exposing the subdriver
field creates the problem of exposing knowledge of libsigrok's internal driver
layout, even though the drivers are designed to be a flat list to the frontend.
Store the subdriver in the dev_context struct of serial-dmm.
The global *di alias was used to keep track of the driver context.
It caused issues with trying to use several subdrivers at once, so
its use was obsoleted.
The correct context is preserved through different mechanisms, either
the *sdi pointer, or wrappers which pass the correct context.
Wrappers for hw_init, hw_cleanup, clear_instances, and hw_scan are needed for
each subdriver due to the nature of serial-dmm. These wrappers are implemented
as macros, in order to reduce the number of lines of code.
For each of those functions, we have a separate wrapper list, then we connect
them together in a first-class driver using a DRV macro, and yet another list
(the DRV list).
Instead of declaring those wrappers in separate lists, include them in the DRV
macro. This approach reduces the number of macro lists from five to just one.
From the perspective of adding a new subdriver, this also greatly reduces the
number of places needed to hook in a new device.
Uwe Hermann [Tue, 11 Dec 2012 16:06:04 +0000 (17:06 +0100)]
serial-dmm: Simplify code a bit.
Store/use the receive_data() function and a pointer to the driver struct
in the dmms[] array. Use a ".subdriver" entry in the driver struct.
Use a macro to simplify hw_init() wrappers.
di was initialized as NULL. If no device covered by this driver
is used, di remains NULL. This causes a segmentation fault when
calling clear_instances().
Peter Stuge [Sat, 3 Nov 2012 07:27:48 +0000 (08:27 +0100)]
backend.c: Fix memory leak in sr_init() error path
Commit 785b9ff290cbdb86e7d0b0280c33b43faf9c0518 added libusb init into
sr_init() which can generate an error. In this case, the already
allocated struct sr_context would have leaked.
During scan the serial port is opened with SERIAL_RDONLY | SERIAL_NONBLOCK,
which works fine, but when acquisition starts, it is opened only with
SERIAL_RDONLY. On Linux, if cdc_acm can make a claim to the USB to serial
converter, opening the port will fail.
Uwe Hermann [Sun, 11 Nov 2012 22:54:49 +0000 (23:54 +0100)]
sr_init(): Add driver sanity checks.
After sr_init() has successfully run, we can be sure that all drivers
define all the API calls, so we don't have to do these checks later
in the individual API functions / wrappers.
If there are one or more drivers with missing API functions (or driver
name / longname, and so on), sr_init() will fail. This helps catch this
kind of developer error early on.
demo: Do not use a separate thread for generating data
We already have an event-based mechanism in place. Using a thread just
adds unneeded complexity, especially for a driver designed not for
performance, but for providing a testbed to frontends.
Generate the data in the event handler, not in a separate thread.
When the parser found a space, it treated it as an invalid digit
and discarded the whole packet. This behavior was incorrect on
2000 count devices, where the first digit can be sent as a space
rather than a '0'.