A common task during device scan is to add the newly discovered devices to
the instance list of the driver. Currently this is done by each driver on
its own. This patch introduces a new helper function std_scan_complete()
which takes care of this. The function should be called at the end of a
driver's scan() callback before returning the device list.
Doing this with a helper function provides guaranteed consistent behaviour
among drivers and hopefully paves the way to moving more standard
functionality directly into the sigrok core.
Another common task that every driver has to do for each device instance is
to initialize the device's driver field. So this is done in the new helper
function as well.
All drivers that can make use of the new helper are updated.
Some drivers set the device instance list to NULL in their scan() callback.
This means the driver loses all references to any devices contained in that
list and their resources will be leaked. Drivers can't free the devices at
this point either since an application might still use a device on the
list. So the existing devices on the instance list need to remain
unmodified during the scan() callback, even if that means that there will
be duplicates on the instance list. Only an explicit invocation of
sr_dev_clear() by the application is allowed to free the devices on the
instance list and reset the list.
The link-mso19 open-codes the std_dev_clear() function and uses it as its
custom dev_clear() callback. The std_dev_clear() function is automatically
called if no custom dev_clear() callback is specified, so just drop custom
implementation and use the default.
This also fixes a memory leak where the link-mso19 driver did not properly
free its driver state struct in the dev_clear() callback.
sdi is allocated using g_malloc0() which can never fail, in addition to
that sdi is already dereferenced before the check, which makes the check
useless. So remove it.
Uwe Hermann [Thu, 19 May 2016 20:46:24 +0000 (22:46 +0200)]
Fix Ruby bindings build on Mac OS X and FreeBSD.
Using "\s*" on BSD sed doesn't work the same way as on GNU sed, thus
yielding e.g. " 3.0.8" instead of "3.0.8" in a ./configure check, which
later prevents the Ruby bindings from being built.
Fix this by simply using exactly one space in the sed invocation, since
swig seems to always use just one space there anyway.
scpi-pps: Add shadow driver for HPIB supplies (ID? instead of *IDN?)
HP instruments predating the 488.2 and SCPI standards do not
necessarily have a SCPI-compliant command set. The HP6630A series of
supplies is one such example.
While scpi-pps is flexible enough to accomodate almost any command
syntax given the right profile, it still assumes that "*IDN?" is the
correct question to ask the instrument. Since older HP gear instead
responds to "ID?", this assumption is no longer true.
Thus sr_scpi_get_hw_id() is not appropriate for these instruments, and
the shadow driver added here only replaces that function call, while
reusing the rest of the existing logic. The extra noise is necessary
in order to propagate this through the .scan member of the driver.
ftdi-la: Use the standard connection_id field for the device address
Use the standard connection_id field from the struct sr_dev_inst for
storing the device address rather than using the custom address field in
the driver state struct. This makes things more consistent with the
framework.
The sigrok core needs a list of all available drivers. Currently this list
is manually maintained by updating a global list whenever a driver is added
or removed.
Introduce a new special section that contains the list of all drivers. The
SR_REGISTER_DEV_DRIVER() and SR_REGISTER_DEV_DRIVER_LIST() macro is used to
add drivers to this new list. This is done by placing the pointers to the
driver into a special section. Since nothing else is in this section it is
known that it is simply a list of driver pointers and the core can iterate
over it as if it was an array.
The advantage of this approach is that the code necessary to add a driver
to the list is completely contained to the driver source and it is no
longer necessary to maintain a global list. If a driver is built it will
automatically appear in the list, if it is not built in won't. This means
that the list is always correct, whereas the previous approach used ifdefs
in the global driver list file which could get out-of-sync with the actual
condition when the driver was built.
Any sr_dev_driver structs that are no longer used outside the driver module
are marked as static.
Drop unnecessary struct sr_dev_driver forward declarations
Most drivers have a forward declaration to their sr_dev_driver struct at
the beginning of the driver file. This is due to historic reasons and often
no longer required. So remove all the unnecessary forward declarations.
Some drivers still require the forward declaration, but only reference the
driver struct from within the driver scan() callback. Since the driver
struct is passed to the scan callback replace the references to the global
variable with the local parameter. In some cases this requires adding the
parameter to some of the helper functions that are called from the scan()
callback.
Stefan Brüns [Sun, 1 May 2016 03:20:39 +0000 (05:20 +0200)]
scpi: Add support for arbitray/definite length block data retrieval
Binary block data is specified in IEEE 488.2. First character is '#',
followed by a single ascii digit denoting the the number of digits needed
for the length specification. Length is given in bytes.
This allows drivers to replace retrieval of comma separated ASCII values
with binary formats. See bug #791.
Stefan Brüns [Fri, 22 Apr 2016 22:33:45 +0000 (00:33 +0200)]
strutil: add method to get an sr_rational from a string
The method accepts strings with numbers in scientific or normal notation,
e.g. -1.25 or 3.37e-6. The numeric range is limited by the sr_rational
range, i.e +-9.2e18, resolution is ~19 digits.
Diego Asanza [Wed, 4 May 2016 17:28:37 +0000 (19:28 +0200)]
dslogic: Add support for voltage threshold
The DSLogic provides two FPGA images: one for 3.3V and the other for 5V logic.
The DSLogic Pro allows to set an arbitrary voltage threshold via USB command.
This commit adds support for the DSLogic to load the FPGA image according to
an user-selectable voltage threshold.
For the DSLogic Pro, one of two fixed voltage thresholds are set, depending on
the user-selected value.
Tested with DSLogic and DSLogic Pro.
Signed-off-by: Diego Asanza <redacted> Tested-by: Andrew Bradford <redacted>
demo: Handle the case when zero analog or logic channels were requested
The demo device has support for specifying the number of analog and logic
channels it should have. Currently this does not work correctly if one of
them is set to zero. Being able to set the number of channels to zero for
one of the channel types is quite useful for corner case testing though.
Make the following modifications to handle it correctly:
1) If the channel count is zero no channel group for that channel type
should be created since a channel group needs at least one channel.
2) Drop the check if logic_unitsize is less or equal to zero in
prepare_data() since this condition will always be true if the number of
logic channels is zero and it is not possible to create a demo device with
only analog channels.
zip_append_analog() does not free most of the memory it allocates. Address
this by moving all sanity checks that do not rely on anything else at the
beginning of the function before any allocations are done. And then make
sure to properly free all allocated memory on all paths leaving the
function.
srzip: Fix handling of analog channels with index 0
0 is a valid index for a channel. Using it as the value for the terminating
entry of analog_index_map causes zip_append_analog() to falsely assume that
no channel was found when a packet for a channel with index 0 was received.
This prevents the data for the channel to be added to the sigrok session
file.
Instead use -1, which is not a valid channel index, as
the terminating entry value.
Marvin Schmidt [Fri, 13 May 2016 10:27:14 +0000 (12:27 +0200)]
build: Replace AX_CXX_COMPILE_STDCXX_11 with latest AX_CXX_COMPILE_STDCXX
The former appended the necessary switch to enable C++11 to the CXXFLAGS
whereas AX_CXX_COMPILE_STDCXX appends it to CXX which has the benefit
that all C++ sources are compiled using the same C++ standard. Therefore
it is no longer necessary to manually hardcode '-std=c++11' anywhere
like we did in the Ruby bindings linker command and assures that the
compilation of them is done with C++11 support as well.
Marvin Schmidt [Fri, 13 May 2016 15:44:12 +0000 (17:44 +0200)]
build: Fix distribution of Ruby bindings
The bindings file was not listed in EXTRA_DIST and therefore not
distributed. We also need to provide an target to uninstall the Ruby
bindings and add it to UNINSTALL_EXTRA in order to make `make distcheck`
happy.
Now that the signature of std_init() matches that of the driver init()
callback we can remove all wrapper functions around std_init() and use it
directly as the init() callback.
std_init(): Drop check if pass in driver is non-NULL
std_init() checks if the pass in struct sr_dev_driver is non-NULL and
prints a error message and returns an error if it is NULL.
std_init() is exclusively called from driver init() callbacks for which the
core already checks if the struct sr_dev_driver is non-NULL before invoking
the callback. This means the check in std_init() will always evaluate to
false. So drop this check.
This also means that the prefix parameter that was used in the error
message is no longer needed and can be removed from the function signature.
Doing so will make the std_init() function signature identical to the
init() callback signature which will allow to directly use it as such.
Match std_init() parameter order to the driver init() callback
The std_init() callback has the order of the first two paramters opposite
to the init() callback. This is primarily due to historical development.
Since the std_init() function is usually called from a driver's init()
callback aligning the order will allow direct register pass through rather
than having to swap them around. It also allow to eventually use the
std_init() function directly as the init() callback.
The zeroplus-logic-cube driver uses libusb_get_device_list() but neglects
to call the matching libusb_device_list_free() on the error path. This will
leak the memory allocated for the list as well as all the devices.
To address the issue use sr_usb_open() instead of open-coding its
functionality. sr_usb_open() correctly handles freeing the device list.
The issue was discovered using the following coccinelle semantic patch:
// <smpl>
@@
identifier devlist;
expression ctx, ret;
statement S;
@@
(
libusb_get_device_list(ctx, &devlist);
|
ret = libusb_get_device_list(ctx, &devlist);
if (ret < 0) S
)
... when != libusb_free_device_list(devlist, ...)
*return ...;
// </smpl>
The victor-dmm driver uses libusb_get_device_list() but neglects to call
the matching libusb_device_list_free() on the error path of libusb_open().
This will leak the memory allocated for the list as well as all the
devices.
To address the issue use sr_usb_open() instead of open-coding its
functionality. sr_usb_open() correctly handles freeing the device list.
The issue was discovered using the following coccinelle semantic patch:
// <smpl>
@@
identifier devlist;
expression ctx, ret;
statement S;
@@
(
libusb_get_device_list(ctx, &devlist);
|
ret = libusb_get_device_list(ctx, &devlist);
if (ret < 0) S
)
... when != libusb_free_device_list(devlist, ...)
*return ...;
// </smpl>
The testo driver uses libusb_get_device_list() but neglects to call the
matching libusb_device_list_free() on the error path. This will leak the
memory allocated for the list as well as all the devices.
To address the issue use sr_usb_open() instead of open-coding its
functionality. sr_usb_open() correctly handles freeing the device list.
The issue was discovered using the following coccinelle semantic patch:
// <smpl>
@@
identifier devlist;
expression ctx, ret;
statement S;
@@
(
libusb_get_device_list(ctx, &devlist);
|
ret = libusb_get_device_list(ctx, &devlist);
if (ret < 0) S
)
... when != libusb_free_device_list(devlist, ...)
*return ...;
// </smpl>
lascar-el-usb: lascar_scan(): Fix USB device list leak
lascar_scan() calls libusb_get_device_list() but never the matching
libusb_free_device_list(). This will leak the memory allocated for the
device list as well as all the devices. To fix this add the missing
libusb_free_device_list().
While we are at it also make sure to handle errors returned by
libusb_get_device_list().
The issue was discovered using the following coccinelle semantic patch:
// <smpl>
@@
identifier devlist;
expression ctx, ret;
statement S;
@@
(
libusb_get_device_list(ctx, &devlist);
|
ret = libusb_get_device_list(ctx, &devlist);
if (ret < 0) S
)
... when != libusb_free_device_list(devlist, ...)
*return ...;
// </smpl>
Some drivers check in some of their driver callbacks if the driver has been
initialized and return an error if it has not.
For the scan() callback the sigrok core checks if the driver has been
initialized and if not returns an error. So it is not possible that the
scan() callback gets called if the driver is not initialized. Without the
scan() callback succeeding it is not possible to get a reference to a
device which is associated with the driver, so it is not possible that any
of the device specific callbacks is called without the driver first being
initialized either.
In conclusion these checks are not necessary since they never evaluate to
true and can be dropped. If they should ever become necessary they should
be done in the sigrok core so all drivers and all callbacks are equally
handled.
Drop SR_CONF_SET flag from SR_CONF_CONTINUOUS options
SR_CONF_CONTINUOUS is a capability option indicating whether a device
supports continuous capture or not. If the option exists the device
supports continuous capture and otherwise it doesn't. There is no value
associated with it and hence setting the SR_CONF_SET flag is nonsensical.
None of the drivers which set SR_CONF_SET for SR_CONF_CONTINUOUS handle it
in their config_set() callback and return an error if an application tried
to perform a config_set() operation for SR_CONF_CONTINUOUS.
Simply remove the SR_CONF_SET flag from all SR_CONF_CONTINUOUS options.
Introduce standard implementation of the dev_list() callback
Every single hardware driver has the very same implementation of the
dev_list() callback. Put this into a helper function in the standard helper
library and use it throughout the drivers. This reduces boiler-plate code
by quite a bit.
If a driver does not implement a dev_clear() callback the core will
automatically call std_dev_clear(di, NULL). Remove all driver dev_clear()
implementations that are identical to default. This reduces the amount of
boiler-plate code.
std_init() allocates a drv_context struct which needs to be freed by the
driver in its cleanup struct. But the vast majority of drivers does never
does this causing memory leaks.
Instead of addressing the issue by manually adding code to free the struct
to each driver introduce a new helper function std_cleanup() that takes
care of this. In addition to freeing the drv_context struct std_cleanup()
also invokes sr_dev_clear() which takes care of freeing all devices
attached to the driver.
Combining both operations in the same helper function allows to use
std_cleanup() as the cleanup callback for all existing drivers, which
reduces the amount of boiler-plate code quite a bit.
All drivers are updated to use the new helper function.
Devices for the scpi-pps driver do have additional data attached to it that
needs to be freed when the device is freed. While the driver gets it right
for the cleanup() callback it does not for the dev_clear() callback. This
will cause memory leaks when sr_dev_clear() is called for this driver.
To fix this let the dev_clear() free the additional data.