This ensures consistent handling of the SR_CONF_SCAN_OPTIONS and
SR_CONF_DEVICE_OPTIONS (with sdi NULL or non-NULL) config keys
and also reduces copy-pasted boilerplate in the drivers a bit.
This function does not handle channel-group specific items, that's
very driver-specific and thus left to the individual drivers.
Also move some generic checks and error messages from the drivers into
the sr_config_list() wrapper.
Be explicit and consistent in the drivers about which dev_clear function
will be called to avoid confusion and inconsistencies.
Drop some open-coded implementations of std_dev_clear().
../src/hardware/appa-55ii/api.c: In function ‘scan’:
../src/hardware/appa-55ii/api.c:47:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/arachnid-labs-re-load-pro/api.c: In function ‘scan’:
../src/hardware/arachnid-labs-re-load-pro/api.c:62:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/atten-pps3xxx/api.c: In function ‘scan’:
../src/hardware/atten-pps3xxx/api.c:81:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/brymen-dmm/api.c: In function ‘scan’:
../src/hardware/brymen-dmm/api.c:89:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/cem-dt-885x/api.c: In function ‘scan’:
../src/hardware/cem-dt-885x/api.c:74:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/conrad-digi-35-cpu/api.c: In function ‘scan’:
../src/hardware/conrad-digi-35-cpu/api.c:45:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/demo/demo.c: In function ‘scan’:
../src/hardware/demo/demo.c:255:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/fluke-dmm/api.c: In function ‘fluke_scan’:
../src/hardware/fluke-dmm/api.c:64:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/gmc-mh-1x-2x/api.c: In function ‘scan_1x_2x_rs232’:
../src/hardware/gmc-mh-1x-2x/api.c:147:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/gmc-mh-1x-2x/api.c: In function ‘scan_2x_bd232’:
../src/hardware/gmc-mh-1x-2x/api.c:234:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/ikalogic-scanaplus/api.c: In function ‘scan’:
../src/hardware/ikalogic-scanaplus/api.c:69:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
../src/hardware/tondaj-sl-814/api.c: In function ‘scan’:
../src/hardware/tondaj-sl-814/api.c:44:22: warning: variable ‘drvc’ set but not used [-Wunused-but-set-variable]
struct drv_context *drvc;
^
Some driver scan() functions only ever return a single device. For those it
is possible to slightly simplify the handling of the device list by
creating it on demand when the function returns.
Some drivers also have the following expression:
devices = g_slist_append(devices, sdi);
...
if (!devices)
...
This check will never evaluate to false so it is dropped as well.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This fixes parts of bug #423.
The list of fixed warnings:
src/output/srzip.c:285:3: warning: Value stored to 'ret' is never read
ret = zip_append(o, logic->data, logic->unitsize, logic->length);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/scpi/scpi.c:610:2: warning: Value stored to 'ret' is never read
ret = SR_OK;
^ ~~~~~
src/scpi/scpi.c:667:2: warning: Value stored to 'ret' is never read
ret = SR_OK;
^ ~~~~~
src/dmm/vc870.c:410:2: warning: Value stored to 'info_local' is never read
info_local = (struct vc870_info *)info;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
src/hardware/conrad-digi-35-cpu/api.c:130:2: warning: Value stored to 'ret' is never read
ret = SR_OK;
^ ~~~~~
src/hardware/fx2lafw/api.c:658:2: warning: Value stored to 'timeout' is never read
timeout = fx2lafw_get_timeout(devc);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
src/hardware/gmc-mh-1x-2x/protocol.c:941:3: warning: Value stored to 'retc' is never read
retc = SR_ERR_ARG;
^ ~~~~~~~~~~
src/hardware/gmc-mh-1x-2x/api.c:168:2: warning: Value stored to 'model' is never read
model = METRAHIT_NONE;
^ ~~~~~~~~~~~~~
src/hardware/ikalogic-scanalogic2/api.c:325:2: warning: Value stored to 'ret' is never read
ret = SR_OK;
^ ~~~~~
src/hardware/openbench-logic-sniffer/api.c:185:3: warning: Value stored to 'devc' is never read
devc = sdi->priv;
^ ~~~~~~~~~
src/hardware/rigol-ds/api.c:813:3: warning: Value stored to 'devc' is never read
devc = sdi->priv;
^ ~~~~~~~~~
src/hardware/scpi-pps/api.c:405:2: warning: Value stored to 'ret' is never read
ret = SR_OK;
^ ~~~~~
src/hardware/yokogawa-dlm/api.c:239:2: warning: Value stored to 'ret' is never read
ret = SR_ERR_NA;
^ ~~~~~~~~~
Since Autoconf places some important feature flags only into the
configuration header, it is necessary to include it globally to
guarantee a consistent build.
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.
All those options are currently applied only to power-supplies
but they could apply as well to electronic loads, except for the
fact that electronic loads channels are called inputs and not
outputs.
Also when you think about an SMU (or any kind of 4-quadrants
power-supply), their channels can both source and sink current,
so they can be considered as input as much as output.
Those SR_CONF_* are thus renamed so that they can be used in all
those situations.
Use g_malloc0() for small allocations and assume they always
succeed. Simplify error handling in a few places accordingly.
Don't always sanity-check parameters for non-public (SR_PRIV)
functions, we require the developers to invoke them correctly.
This allows further error handling simplifications.
Set this new parameter to 0 (no timeout) at every call site. This is
consistent with previous behaviour, so cannot cause any regressions.
Waiting forever for a serial operation is clearly always wrong. Without
specific knowledge of each device and driver however, I can't choose
appropriate timeouts for each call. The maintainers of these drivers
will need to do so, and also add appropriate handling of timeouts.
When this commit is merged, a bug should be entered for each driver
that is touched by it.
Every driver now publishes its device option config keys, i.e. the
list fetched with sr_config_list(SR_CONF_DEVICE_OPTIONS), with a
set of flags indicating which methods are implemented by the driver
for that key.
The config keys are OR'ed with any combination of SR_CONF_GET,
SR_CONF_SET and SR_CONF_LIST. These are defined as the high bits
of the uint32_t config key. Clients can OR config keys with
SR_CONF_MASK to strip out these bits. This mask will be kept up to
date if other bits are added to the capabilities list; clients MUST
therefore use SR_CONF_MASK for this.
Some keys don't have capability bits added, such as the informative
device type keys (SR_CONF_MULTIMETER, SR_CONF_OSCILLOSCOPE, ...) and
SR_CONF_CONTINUOUS.
Scan options do not have capabilities bits.