forked from Ivasoft/DSView
Code refactoring 7
This commit is contained in:
@@ -45,7 +45,7 @@ struct xlog_receiver_info
|
||||
int _type; //see enum xlog_receiver_type
|
||||
FILE *_file;
|
||||
xlog_print_func _fn; // print function
|
||||
xlog_receiver _rev; //user callback
|
||||
xlog_receive_callback _rev; //user callback
|
||||
};
|
||||
|
||||
struct xlog_context
|
||||
@@ -139,10 +139,7 @@ static void print_to_user_callback(struct xlog_receiver_info *info, const char *
|
||||
info->_rev(buf, wr);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a log context, the console is default log receiver
|
||||
*/
|
||||
XLOG_API xlog_context* xlog_new()
|
||||
static xlog_context* xlog_new_context(int bConsole)
|
||||
{
|
||||
int i=0;
|
||||
xlog_context *ctx = (xlog_context*)malloc(sizeof(xlog_context));
|
||||
@@ -152,10 +149,14 @@ XLOG_API xlog_context* xlog_new()
|
||||
ctx->_receivers[i]._fn = NULL;
|
||||
ctx->_receivers[i]._file = NULL;
|
||||
}
|
||||
ctx->_receivers[0]._fn = print_to_console;
|
||||
ctx->_receivers[0]._type = RECEIVER_TYPE_CONSOLE;
|
||||
ctx->_count = 0;
|
||||
ctx->_log_level = XLOG_LEVEL_INFO;
|
||||
ctx->_count = 1;
|
||||
|
||||
if (bConsole){
|
||||
ctx->_receivers[0]._fn = print_to_console;
|
||||
ctx->_receivers[0]._type = RECEIVER_TYPE_CONSOLE;
|
||||
ctx->_count = 1;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&ctx->_mutext, NULL);
|
||||
}
|
||||
@@ -163,6 +164,22 @@ XLOG_API xlog_context* xlog_new()
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a log context, the console is default log receiver
|
||||
*/
|
||||
XLOG_API xlog_context* xlog_new()
|
||||
{
|
||||
return xlog_new_context(1);
|
||||
}
|
||||
|
||||
/*
|
||||
create a log context
|
||||
*/
|
||||
XLOG_API xlog_context* xlog_new2(int bConsole)
|
||||
{
|
||||
return xlog_new_context(bConsole);
|
||||
}
|
||||
|
||||
/**
|
||||
* free a log context, return 0 if success.
|
||||
*/
|
||||
@@ -190,7 +207,7 @@ XLOG_API void xlog_free(xlog_context* ctx)
|
||||
/**
|
||||
* append a log data receiver, return 0 if success.
|
||||
*/
|
||||
XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receiver rev, int *out_index)
|
||||
XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receive_callback rev, int *out_index)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -476,7 +493,7 @@ XLOG_API int xlog_warn(xlog_writer *wr, const char *format, ...)
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ctx->_mutext);
|
||||
pthread_mutex_unlock(&ctx->_mutext);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,13 +63,18 @@ typedef struct xlog_writer xlog_writer;
|
||||
/**
|
||||
* define log data receiver type
|
||||
*/
|
||||
typedef void (*xlog_receiver)(const char *data, int length);
|
||||
typedef void (*xlog_receive_callback)(const char *data, int length);
|
||||
|
||||
/*
|
||||
create a log context, the console is default log receiver
|
||||
*/
|
||||
XLOG_API xlog_context* xlog_new();
|
||||
|
||||
/*
|
||||
create a log context
|
||||
*/
|
||||
XLOG_API xlog_context* xlog_new2(int bConsole);
|
||||
|
||||
/**
|
||||
* free a log context, return 0 if success.
|
||||
* and all xlog_writer will be can't to use.
|
||||
@@ -79,7 +84,7 @@ XLOG_API void xlog_free(xlog_context* ctx);
|
||||
/**
|
||||
* append a log data receiver, return 0 if success.
|
||||
*/
|
||||
XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receiver rev, int *out_index);
|
||||
XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receive_callback rev, int *out_index);
|
||||
|
||||
/**
|
||||
* append a log data receiver, return 0 if success.
|
||||
|
||||
@@ -136,10 +136,6 @@ static int sanity_check_all_drivers(void)
|
||||
sr_err("No dev_list in driver %d ('%s').", i, d);
|
||||
errors++;
|
||||
}
|
||||
if (!drivers[i]->dev_clear) {
|
||||
sr_err("No dev_clear in driver %d ('%s').", i, d);
|
||||
errors++;
|
||||
}
|
||||
/* Note: config_get() is optional. */
|
||||
if (!drivers[i]->config_set) {
|
||||
sr_err("No config_set in driver %d ('%s').", i, d);
|
||||
@@ -302,8 +298,6 @@ SR_API int sr_init(struct sr_context **ctx)
|
||||
int ret = SR_ERR;
|
||||
struct sr_context *context;
|
||||
|
||||
sr_log_init(); //try init log
|
||||
|
||||
if (!ctx) {
|
||||
sr_err("%s(): libsigrok context was NULL.", __func__);
|
||||
return SR_ERR;
|
||||
@@ -377,8 +371,6 @@ SR_API int sr_exit(struct sr_context *ctx)
|
||||
|
||||
g_free(ctx);
|
||||
|
||||
sr_log_uninit(); //try uninit log
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <glib.h>
|
||||
#include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */
|
||||
#include "log.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "device: "
|
||||
@@ -189,11 +190,9 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
|
||||
|
||||
sdi->driver = NULL;
|
||||
sdi->mode = mode;
|
||||
sdi->index = index;
|
||||
sdi->name[0] = '\0';
|
||||
sdi->status = status;
|
||||
sdi->inst_type = -1;
|
||||
sdi->vendor = vendor ? g_strdup(vendor) : NULL;
|
||||
sdi->model = model ? g_strdup(model) : NULL;
|
||||
sdi->version = version ? g_strdup(version) : NULL;
|
||||
sdi->channels = NULL;
|
||||
sdi->conn = NULL;
|
||||
@@ -201,6 +200,10 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
|
||||
sdi->handle = (sr_device_handle)sdi;
|
||||
sdi->dev_type = DEV_TYPE_UNKOWN;
|
||||
|
||||
if (model && *model){
|
||||
strncpy(sdi->name, model, sizeof(sdi->name));
|
||||
}
|
||||
|
||||
return sdi;
|
||||
}
|
||||
|
||||
@@ -235,7 +238,6 @@ SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
|
||||
|
||||
g_free(sdi->priv);
|
||||
g_free(sdi->vendor);
|
||||
g_free(sdi->model);
|
||||
g_free(sdi->version);
|
||||
g_free(sdi);
|
||||
}
|
||||
@@ -254,6 +256,8 @@ SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus,
|
||||
udi->bus = bus;
|
||||
udi->address = address;
|
||||
udi->devhdl = hdl;
|
||||
udi->usb_dev = NULL;
|
||||
udi->is_wait_re_connected = 0;
|
||||
|
||||
return udi;
|
||||
}
|
||||
@@ -331,10 +335,7 @@ SR_API const GSList *sr_dev_mode_list(const struct sr_dev_inst *sdi)
|
||||
|
||||
SR_API int sr_dev_clear(const struct sr_dev_driver *driver)
|
||||
{
|
||||
if (driver && driver->dev_clear)
|
||||
return driver->dev_clear();
|
||||
else
|
||||
return SR_OK;
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_API int sr_dev_open(struct sr_dev_inst *sdi)
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "dscope: "
|
||||
|
||||
static int dev_destroy(struct sr_dev_inst *sdi);
|
||||
|
||||
enum {
|
||||
/** Normal */
|
||||
OP_NORMAL = 0,
|
||||
@@ -177,10 +179,6 @@ static struct DSL_context *DSCope_dev_new(const struct DSL_profile *prof)
|
||||
return devc;
|
||||
}
|
||||
|
||||
static int dev_clear(void)
|
||||
{
|
||||
return std_dev_clear(di, NULL);
|
||||
}
|
||||
|
||||
static int init(struct sr_context *sr_ctx)
|
||||
{
|
||||
@@ -202,6 +200,7 @@ static GSList *scan(GSList *options)
|
||||
int devcnt, ret, i, j;
|
||||
const char *conn;
|
||||
enum libusb_speed usb_speed;
|
||||
struct sr_usb_dev_inst *usb_dev_info;
|
||||
|
||||
drvc = di->priv;
|
||||
|
||||
@@ -273,7 +272,11 @@ static GSList *scan(GSList *options)
|
||||
if (!prof)
|
||||
continue;
|
||||
|
||||
sr_info("Got a device handle: %p", device_handle);
|
||||
if (sr_usb_device_is_exists(device_handle)){
|
||||
sr_info("Device is exists, handle: %p", device_handle);
|
||||
continue;;
|
||||
}
|
||||
sr_info("Got a new device handle: %p", device_handle);
|
||||
|
||||
devcnt = g_slist_length(drvc->instances);
|
||||
devc = DSCope_dev_new(prof);
|
||||
@@ -282,29 +285,33 @@ static GSList *scan(GSList *options)
|
||||
|
||||
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, devcnt, SR_ST_INITIALIZING,
|
||||
prof->vendor, prof->model, prof->model_version);
|
||||
|
||||
if (!sdi) {
|
||||
g_free(devc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sdi->priv = devc;
|
||||
sdi->driver = di;
|
||||
sdi->dev_type = DEV_TYPE_HARDWARE;
|
||||
|
||||
drvc->instances = g_slist_append(drvc->instances, sdi);
|
||||
sdi->dev_type = DEV_TYPE_USB;
|
||||
|
||||
/* Fill in probelist according to this device's profile. */
|
||||
if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK)
|
||||
if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK){
|
||||
sr_err("%s", "dsl_setup_probes() error");
|
||||
dev_destroy(sdi);
|
||||
return NULL;
|
||||
}
|
||||
devices = g_slist_append(devices, sdi);
|
||||
|
||||
if (dsl_check_conf_profile(device_handle)) {
|
||||
/* Already has the firmware, so fix the new address. */
|
||||
sr_info("Found a DSCope device, name: \"%s\"", prof->model);
|
||||
sdi->status = SR_ST_INACTIVE;
|
||||
sdi->inst_type = SR_INST_USB;
|
||||
sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),
|
||||
libusb_get_device_address(device_handle), NULL);
|
||||
/* only report device after firmware is ready */
|
||||
devices = g_slist_append(devices, sdi);
|
||||
|
||||
usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),
|
||||
libusb_get_device_address(device_handle), NULL);
|
||||
usb_dev_info->usb_dev = device_handle;
|
||||
sdi->conn = usb_dev_info;
|
||||
sdi->status = SR_ST_INACTIVE;
|
||||
}
|
||||
else {
|
||||
char *firmware;
|
||||
@@ -323,14 +330,18 @@ static GSList *scan(GSList *options)
|
||||
sr_err("Firmware upload failed for "
|
||||
"device %d.", devcnt);
|
||||
g_free(firmware);
|
||||
sdi->inst_type = SR_INST_USB;
|
||||
sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(device_handle),
|
||||
0xff, NULL);
|
||||
|
||||
usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),0xff, NULL);
|
||||
usb_dev_info->usb_dev = device_handle;
|
||||
sdi->conn = usb_dev_info;
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(devlist, 1);
|
||||
g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);
|
||||
|
||||
if (conn_devices){
|
||||
g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
@@ -1833,10 +1844,9 @@ static int dev_close(struct sr_dev_inst *sdi)
|
||||
|
||||
static int dev_destroy(struct sr_dev_inst *sdi)
|
||||
{
|
||||
dsl_destroy_device(sdi);
|
||||
return dsl_destroy_device(sdi);
|
||||
}
|
||||
|
||||
|
||||
static int cleanup(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -1845,12 +1855,10 @@ static int cleanup(void)
|
||||
if (!(drvc = di->priv))
|
||||
return SR_OK;
|
||||
|
||||
ret = dev_clear();
|
||||
|
||||
g_free(drvc);
|
||||
di->priv = NULL;
|
||||
|
||||
return ret;
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
static void remove_sources(struct DSL_context *devc)
|
||||
@@ -2090,12 +2098,12 @@ SR_PRIV struct sr_dev_driver DSCope_driver_info = {
|
||||
.name = "DSCope",
|
||||
.longname = "DSCope (generic driver for DScope oscilloscope)",
|
||||
.api_version = 1,
|
||||
.driver_type = DRIVER_TYPE_HARDWARE,
|
||||
.init = init,
|
||||
.cleanup = cleanup,
|
||||
.scan = scan,
|
||||
.dev_list = dev_list,
|
||||
.dev_mode_list = dev_mode_list,
|
||||
.dev_clear = dev_clear,
|
||||
.config_get = config_get,
|
||||
.config_set = config_set,
|
||||
.config_list = config_list,
|
||||
|
||||
@@ -306,112 +306,82 @@ static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi)
|
||||
|
||||
sr_info("%s", "Try to open device instance.");
|
||||
|
||||
assert(usb->devhdl == NULL);
|
||||
if(usb->devhdl == NULL){
|
||||
sr_err("%s", "hw_dev_open(), usb->devhdl is null.");
|
||||
return SR_ERR;
|
||||
}
|
||||
if (usb->usb_dev == NULL){
|
||||
sr_err("%s", "hw_dev_open(), usb->usb_dev is null.");
|
||||
return SR_ERR;
|
||||
}
|
||||
if (usb->is_wait_re_connected){
|
||||
sr_err("Device is waitting reconnect, handle:%p", usb->usb_dev);
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
if (sdi->status == SR_ST_ACTIVE) {
|
||||
/* Device is already in use. */
|
||||
sr_info("%s", "Device is actived, can't to open.");
|
||||
sr_info("Device is actived, can't to open, handle:%p", usb->usb_dev);
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
skip = 0;
|
||||
device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
|
||||
if (device_count < 0) {
|
||||
sr_err("Failed to get device list: %s.",
|
||||
libusb_error_name(device_count));
|
||||
if (sdi->status == SR_ST_INITIALIZING) {
|
||||
sr_info("%s", "The device instance is still boosting.");
|
||||
}
|
||||
dev_handel = usb->usb_dev;
|
||||
|
||||
sr_info("Open device instance, handle: %p", dev_handel);
|
||||
|
||||
if (libusb_open(dev_handel, &usb->devhdl) != 0){
|
||||
sr_err("Failed to open device: %s, handle:%p",
|
||||
libusb_error_name(ret), dev_handel);
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
for (i = 0; i < device_count; i++)
|
||||
{
|
||||
dev_handel = devlist[i];
|
||||
|
||||
if ((ret = libusb_get_device_descriptor(dev_handel, &des))) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(ret));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (des.idVendor != devc->profile->vid
|
||||
|| des.idProduct != devc->profile->pid){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sdi->status == SR_ST_INITIALIZING) {
|
||||
sr_info("%s", "The device instance is still boosting.");
|
||||
if (skip != sdi->index) {
|
||||
/* Skip devices of this type that aren't the one we want. */
|
||||
sr_info("%s", "Skip devices of this type that aren't the one we want.");
|
||||
skip += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (sdi->status == SR_ST_INACTIVE) {
|
||||
/*
|
||||
* This device is fully enumerated, so we need to find
|
||||
* this device by vendor, product, bus and address.
|
||||
*/
|
||||
sr_info("%s", "The device instance is live, but not use.");
|
||||
if (libusb_get_bus_number(dev_handel) != usb->bus
|
||||
|| libusb_get_device_address(dev_handel) != usb->address){
|
||||
/* This is not the one. */
|
||||
sr_info("%s", "Font a device, but is not the one.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sr_info("Open device instance, handle: %p", dev_handel);
|
||||
|
||||
if (!(ret = libusb_open(dev_handel, &usb->devhdl))) {
|
||||
if (usb->address == 0xff)
|
||||
/*
|
||||
* First time we touch this device after FW
|
||||
* upload, so we don't know the address yet.
|
||||
*/
|
||||
usb->address = libusb_get_device_address(dev_handel);
|
||||
}
|
||||
else {
|
||||
sr_err("Failed to open device: %s.",
|
||||
libusb_error_name(ret));
|
||||
break;
|
||||
}
|
||||
|
||||
rd_cmd.header.dest = DSL_CTL_FW_VERSION;
|
||||
rd_cmd.header.size = 2;
|
||||
rd_cmd.data = rd_cmd_data;
|
||||
if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) {
|
||||
sr_err("Failed to get firmware version.");
|
||||
break;
|
||||
}
|
||||
vi.major = rd_cmd_data[0];
|
||||
vi.minor = rd_cmd_data[1];
|
||||
|
||||
if (usb->address == 0xff){
|
||||
/*
|
||||
* Different versions may have incompatible issue,
|
||||
* Mark for up level process
|
||||
*/
|
||||
if (vi.major != DSL_REQUIRED_VERSION_MAJOR) {
|
||||
sr_err("Expected firmware version %d.%d, "
|
||||
"got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR,
|
||||
vi.major, vi.minor);
|
||||
sdi->status = SR_ST_INCOMPATIBLE;
|
||||
} else {
|
||||
sdi->status = SR_ST_ACTIVE;
|
||||
}
|
||||
* First time we touch this device after FW
|
||||
* upload, so we don't know the address yet.
|
||||
*/
|
||||
usb->address = libusb_get_device_address(dev_handel);
|
||||
}
|
||||
|
||||
sr_info("Opened device %d on %d.%d, "
|
||||
rd_cmd.header.dest = DSL_CTL_FW_VERSION;
|
||||
rd_cmd.header.size = 2;
|
||||
rd_cmd.data = rd_cmd_data;
|
||||
|
||||
if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) {
|
||||
sr_err("Failed to get firmware version.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
vi.major = rd_cmd_data[0];
|
||||
vi.minor = rd_cmd_data[1];
|
||||
|
||||
/*
|
||||
* Different versions may have incompatible issue,
|
||||
* Mark for up level process.
|
||||
*/
|
||||
if (vi.major != DSL_REQUIRED_VERSION_MAJOR) {
|
||||
sr_err("Expected firmware version %d.%d, "
|
||||
"got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR,
|
||||
vi.major, vi.minor);
|
||||
sdi->status = SR_ST_INCOMPATIBLE;
|
||||
}
|
||||
else {
|
||||
sdi->status = SR_ST_ACTIVE;
|
||||
}
|
||||
|
||||
sr_info("Opened device %p on %d.%d, "
|
||||
"interface %d, firmware %d.%d.",
|
||||
sdi->index, usb->bus, usb->address,
|
||||
usb->usb_dev, usb->bus, usb->address,
|
||||
USB_INTERFACE, vi.major, vi.minor);
|
||||
|
||||
break;
|
||||
}
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
if ((sdi->status != SR_ST_ACTIVE) &&
|
||||
(sdi->status != SR_ST_INCOMPATIBLE))
|
||||
(sdi->status != SR_ST_INCOMPATIBLE)){
|
||||
return SR_ERR;
|
||||
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
@@ -1963,7 +1933,7 @@ SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi)
|
||||
|
||||
usb = sdi->conn;
|
||||
if (usb->devhdl == NULL){
|
||||
sr_info("%s", "dsl_dev_close(),Device handle is null.");
|
||||
sr_info("%s", "dsl_dev_close(),libusb_device_handle is null.");
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
@@ -2521,11 +2491,11 @@ SR_PRIV int dsl_destroy_device(const struct sr_dev_inst *sdi)
|
||||
}
|
||||
|
||||
if (sdi->conn) {
|
||||
if (sdi->inst_type == SR_INST_USB)
|
||||
if (sdi->dev_type == DEV_TYPE_USB)
|
||||
sr_usb_dev_inst_free(sdi->conn);
|
||||
else if (sdi->inst_type == SR_INST_SERIAL)
|
||||
else if (sdi->dev_type == DEV_TYPE_SERIAL)
|
||||
sr_serial_dev_inst_free(sdi->conn);
|
||||
}
|
||||
|
||||
sr_dev_inst_free(sdi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "dslogic: "
|
||||
|
||||
static int dev_destroy(struct sr_dev_inst *sdi);
|
||||
|
||||
static const char *maxHeights[] = {
|
||||
"1X",
|
||||
"2X",
|
||||
@@ -247,11 +249,6 @@ static struct DSL_context *DSLogic_dev_new(const struct DSL_profile *prof)
|
||||
return devc;
|
||||
}
|
||||
|
||||
static int dev_clear(void)
|
||||
{
|
||||
return std_dev_clear(di, NULL);
|
||||
}
|
||||
|
||||
static int init(struct sr_context *sr_ctx)
|
||||
{
|
||||
return std_hw_init(sr_ctx, di, LOG_PREFIX);
|
||||
@@ -272,6 +269,7 @@ static GSList *scan(GSList *options)
|
||||
int devcnt, ret, i, j;
|
||||
const char *conn;
|
||||
enum libusb_speed usb_speed;
|
||||
struct sr_usb_dev_inst *usb_dev_info;
|
||||
|
||||
drvc = di->priv;
|
||||
|
||||
@@ -344,14 +342,17 @@ static GSList *scan(GSList *options)
|
||||
if (!prof)
|
||||
continue;
|
||||
|
||||
sr_info("Got a device handle: %p", device_handle);
|
||||
if (sr_usb_device_is_exists(device_handle)){
|
||||
sr_info("Device is exists, handle: %p", device_handle);
|
||||
continue;;
|
||||
}
|
||||
sr_info("Got a new device handle: %p", device_handle);
|
||||
|
||||
devcnt = g_slist_length(drvc->instances);
|
||||
devc = DSLogic_dev_new(prof);
|
||||
if (!devc)
|
||||
return NULL;
|
||||
|
||||
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, devcnt, SR_ST_INITIALIZING,
|
||||
sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, -1, SR_ST_INITIALIZING,
|
||||
prof->vendor, prof->model, prof->model_version);
|
||||
if (!sdi) {
|
||||
g_free(devc);
|
||||
@@ -359,23 +360,26 @@ static GSList *scan(GSList *options)
|
||||
}
|
||||
sdi->priv = devc;
|
||||
sdi->driver = di;
|
||||
sdi->dev_type = DEV_TYPE_HARDWARE;
|
||||
|
||||
drvc->instances = g_slist_append(drvc->instances, sdi);
|
||||
|
||||
sdi->dev_type = DEV_TYPE_USB;
|
||||
|
||||
/* Fill in probelist according to this device's profile. */
|
||||
if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK)
|
||||
if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK){
|
||||
sr_err("%s", "dsl_setup_probes() error");
|
||||
dev_destroy(sdi);
|
||||
return NULL;
|
||||
}
|
||||
devices = g_slist_append(devices, sdi);
|
||||
|
||||
if (dsl_check_conf_profile(device_handle)) {
|
||||
/* Already has the firmware, so fix the new address. */
|
||||
sr_info("Found a DSLogic device,name: \"%s\"", prof->model);
|
||||
sdi->status = SR_ST_INACTIVE;
|
||||
sdi->inst_type = SR_INST_USB;
|
||||
sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),
|
||||
libusb_get_device_address(device_handle), NULL);
|
||||
/* only report device after firmware is ready */
|
||||
devices = g_slist_append(devices, sdi);
|
||||
|
||||
usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),
|
||||
libusb_get_device_address(device_handle), NULL);
|
||||
|
||||
usb_dev_info->usb_dev = device_handle;
|
||||
sdi->conn = usb_dev_info;
|
||||
sdi->status = SR_ST_INACTIVE;
|
||||
}
|
||||
else {
|
||||
char *firmware;
|
||||
@@ -394,14 +398,18 @@ static GSList *scan(GSList *options)
|
||||
sr_err("Firmware upload failed for "
|
||||
"device %d.", devcnt);
|
||||
g_free(firmware);
|
||||
sdi->inst_type = SR_INST_USB;
|
||||
sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(device_handle),
|
||||
0xff, NULL);
|
||||
|
||||
usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),0xff, NULL);
|
||||
usb_dev_info->usb_dev = device_handle;
|
||||
sdi->conn = usb_dev_info;
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(devlist, 1);
|
||||
g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);
|
||||
|
||||
if (conn_devices){
|
||||
g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
@@ -1196,7 +1204,7 @@ static int dev_close(struct sr_dev_inst *sdi)
|
||||
|
||||
static int dev_destroy(struct sr_dev_inst *sdi)
|
||||
{
|
||||
dsl_destroy_device(sdi);
|
||||
return dsl_destroy_device(sdi);
|
||||
}
|
||||
|
||||
static int cleanup(void)
|
||||
@@ -1207,12 +1215,10 @@ static int cleanup(void)
|
||||
if (!(drvc = di->priv))
|
||||
return SR_OK;
|
||||
|
||||
ret = dev_clear();
|
||||
|
||||
g_free(drvc);
|
||||
di->priv = NULL;
|
||||
|
||||
return ret;
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
static void remove_sources(struct DSL_context *devc)
|
||||
@@ -1429,12 +1435,12 @@ SR_PRIV struct sr_dev_driver DSLogic_driver_info = {
|
||||
.name = "DSLogic",
|
||||
.longname = "DSLogic (generic driver for DSLogic LA)",
|
||||
.api_version = 1,
|
||||
.driver_type = DRIVER_TYPE_HARDWARE,
|
||||
.init = init,
|
||||
.cleanup = cleanup,
|
||||
.scan = scan,
|
||||
.dev_list = dev_list,
|
||||
.dev_mode_list = dev_mode_list,
|
||||
.dev_clear = dev_clear,
|
||||
.config_get = config_get,
|
||||
.config_set = config_set,
|
||||
.config_list = config_list,
|
||||
|
||||
@@ -126,6 +126,8 @@ SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn)
|
||||
|
||||
usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
usb->usb_dev = devlist[i];
|
||||
|
||||
devices = g_slist_append(devices, usb);
|
||||
}
|
||||
libusb_free_device_list(devlist, 1);
|
||||
@@ -179,7 +181,9 @@ SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx)
|
||||
libusb_get_device_address(devlist[i]));
|
||||
|
||||
usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
usb->usb_dev = devlist[i];
|
||||
|
||||
devices = g_slist_append(devices, usb);
|
||||
}
|
||||
libusb_free_config_descriptor(confdes);
|
||||
|
||||
@@ -61,13 +61,6 @@ extern struct ds_trigger *trigger;
|
||||
|
||||
static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data);
|
||||
|
||||
static int clear_instances(void)
|
||||
{
|
||||
/* Nothing needed so far. */
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
static int hw_init(struct sr_context *sr_ctx)
|
||||
{
|
||||
return std_hw_init(sr_ctx, di, LOG_PREFIX);
|
||||
@@ -246,29 +239,9 @@ static int dev_destroy(struct sr_dev_inst *sdi)
|
||||
}
|
||||
|
||||
static int hw_cleanup(void)
|
||||
{
|
||||
GSList *l;
|
||||
struct sr_dev_inst *sdi;
|
||||
struct drv_context *drvc;
|
||||
int ret = SR_OK;
|
||||
{
|
||||
|
||||
if (!(drvc = di->priv))
|
||||
return SR_OK;
|
||||
|
||||
/* Properly close and free all devices. */
|
||||
for (l = drvc->instances; l; l = l->next) {
|
||||
if (!(sdi = l->data)) {
|
||||
/* Log error, but continue cleaning up the rest. */
|
||||
sr_err("%s: sdi was NULL, continuing", __func__);
|
||||
ret = SR_ERR_BUG;
|
||||
continue;
|
||||
}
|
||||
sr_dev_inst_free(sdi);
|
||||
}
|
||||
g_slist_free(drvc->instances);
|
||||
drvc->instances = NULL;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int en_ch_num(const struct sr_dev_inst *sdi)
|
||||
@@ -1111,12 +1084,12 @@ SR_PRIV struct sr_dev_driver demo_driver_info = {
|
||||
.name = "virtual-demo",
|
||||
.longname = "Demo driver and pattern generator",
|
||||
.api_version = 1,
|
||||
.driver_type = DRIVER_TYPE_DEMO,
|
||||
.init = hw_init,
|
||||
.cleanup = hw_cleanup,
|
||||
.scan = hw_scan,
|
||||
.dev_list = hw_dev_list,
|
||||
.dev_mode_list = hw_dev_mode_list,
|
||||
.dev_clear = clear_instances,
|
||||
.config_get = config_get,
|
||||
.config_set = config_set,
|
||||
.config_list = config_list,
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
|
||||
#include "libsigrok-internal.h"
|
||||
#include "log.h"
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -34,55 +37,88 @@
|
||||
#define LOG_PREFIX "lib_main: "
|
||||
|
||||
char DS_RES_PATH[500] = {0};
|
||||
static struct sr_context *sr_ctx = NULL;
|
||||
static libsigrok_event_callback_t event_callback = NULL;
|
||||
static GList* all_device_list = NULL; // All device instance, sr_dev_inst* type
|
||||
static GThread *hotplug_thread = NULL;
|
||||
|
||||
static int sr_exit_flag = 0;
|
||||
static int attach_event_flag = 0;
|
||||
static int detach_event_flag = 0;
|
||||
static int wait_redo_attch_flag = 0;
|
||||
static int wait_redo_attch_times = 0;
|
||||
|
||||
struct sr_lib_context
|
||||
{
|
||||
libsigrok_event_callback_t event_callback;
|
||||
struct sr_context *sr_ctx;
|
||||
GList* device_list; // All device instance, sr_dev_inst* type
|
||||
pthread_mutex_t mutext;
|
||||
GThread *hotplug_thread;
|
||||
int lib_exit_flag;
|
||||
int attach_event_flag;
|
||||
int detach_event_flag;
|
||||
int is_waitting_reconnect;
|
||||
int check_reconnect_times;
|
||||
struct libusb_device *attach_device_handle;
|
||||
struct libusb_device *detach_device_handle;
|
||||
struct sr_device_info current_device;
|
||||
};
|
||||
|
||||
static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event);
|
||||
static void usb_hotplug_process_proc();
|
||||
static void destroy_device_instance(struct sr_dev_inst *dev);
|
||||
|
||||
static struct sr_lib_context lib_ctx = {
|
||||
.event_callback = NULL,
|
||||
.sr_ctx = NULL,
|
||||
.device_list = NULL,
|
||||
.hotplug_thread = NULL,
|
||||
.lib_exit_flag = 0,
|
||||
.attach_event_flag = 0,
|
||||
.detach_event_flag = 0,
|
||||
.is_waitting_reconnect = 0,
|
||||
.check_reconnect_times = 0,
|
||||
.attach_device_handle = NULL,
|
||||
.detach_device_handle = NULL,
|
||||
.current_device = {
|
||||
.handle = NULL,
|
||||
.name[0] = '\0',
|
||||
.is_current = 0,
|
||||
.dev_type = DEV_TYPE_UNKOWN,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Must call first
|
||||
*/
|
||||
SR_API int sr_lib_init()
|
||||
{
|
||||
{
|
||||
int ret = 0;
|
||||
struct sr_dev_driver **drivers = NULL;
|
||||
struct sr_dev_driver **dr = NULL;
|
||||
|
||||
if (sr_ctx != NULL){
|
||||
if (lib_ctx.sr_ctx != NULL){
|
||||
return SR_ERR_HAVE_DONE;
|
||||
}
|
||||
|
||||
ret = sr_init(&sr_ctx);
|
||||
sr_log_init(); //try init log
|
||||
|
||||
sr_info("Init %s.", SR_LIB_NAME);
|
||||
|
||||
ret = sr_init(&lib_ctx.sr_ctx);
|
||||
if (ret != SR_OK){
|
||||
return ret;
|
||||
}
|
||||
sr_exit_flag = 0;
|
||||
lib_ctx.lib_exit_flag = 0;
|
||||
|
||||
// Initialise all libsigrok drivers
|
||||
drivers = sr_driver_list();
|
||||
for (dr = drivers; *dr; dr++) {
|
||||
if (sr_driver_init(sr_ctx, *dr) != SR_OK) {
|
||||
if (sr_driver_init(lib_ctx.sr_ctx, *dr) != SR_OK) {
|
||||
sr_err("Failed to initialize driver '%s'", (*dr)->name);
|
||||
return SR_ERR;
|
||||
}
|
||||
}
|
||||
pthread_mutex_init(&lib_ctx.mutext, NULL); //init locker
|
||||
|
||||
sr_ctx->hotplug_tv.tv_sec = 0;
|
||||
sr_ctx->hotplug_tv.tv_usec = 0;
|
||||
lib_ctx.sr_ctx->hotplug_tv.tv_sec = 0;
|
||||
lib_ctx.sr_ctx->hotplug_tv.tv_usec = 0;
|
||||
|
||||
sr_listen_hotplug(sr_ctx, hotplug_event_listen_callback);
|
||||
sr_listen_hotplug(lib_ctx.sr_ctx, hotplug_event_listen_callback);
|
||||
|
||||
/** Start usb hotplug thread */
|
||||
hotplug_thread = g_thread_new("hotplug_proc", usb_hotplug_process_proc, NULL);
|
||||
lib_ctx.hotplug_thread = g_thread_new("hotplug_proc", usb_hotplug_process_proc, NULL);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
@@ -91,47 +127,38 @@ SR_API int sr_lib_init()
|
||||
* Free all resource before program exits
|
||||
*/
|
||||
SR_API int sr_lib_exit()
|
||||
{
|
||||
struct sr_dev_driver **drivers = NULL;
|
||||
struct sr_dev_driver **dr = NULL;
|
||||
struct sr_dev_driver *driver_ins;
|
||||
GSList *l;
|
||||
struct sr_dev_inst *dev;
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (sr_ctx == NULL){
|
||||
if (lib_ctx.sr_ctx == NULL){
|
||||
return SR_ERR_HAVE_DONE;
|
||||
}
|
||||
|
||||
sr_close_hotplug(sr_ctx);
|
||||
sr_info("Uninit %s.", SR_LIB_NAME);
|
||||
|
||||
sr_exit_flag = 1; //all thread to exit
|
||||
sr_close_hotplug(lib_ctx.sr_ctx);
|
||||
|
||||
if (hotplug_thread != NULL){
|
||||
g_thread_join(hotplug_thread);
|
||||
hotplug_thread = NULL;
|
||||
lib_ctx.lib_exit_flag = 1; //all thread to exit
|
||||
|
||||
if (lib_ctx.hotplug_thread != NULL){
|
||||
g_thread_join(lib_ctx.hotplug_thread);
|
||||
lib_ctx.hotplug_thread = NULL;
|
||||
}
|
||||
|
||||
// Release all device
|
||||
for (l = all_device_list; l; l = l->next)
|
||||
{
|
||||
dev = l->data;
|
||||
if (dev && dev->driver)
|
||||
{
|
||||
driver_ins = dev->driver;
|
||||
|
||||
if (driver_ins->dev_destroy)
|
||||
driver_ins->dev_destroy(dev);
|
||||
else if (driver_ins->dev_close)
|
||||
driver_ins->dev_close(dev);
|
||||
}
|
||||
for (l = lib_ctx.device_list; l; l = l->next){
|
||||
destroy_device_instance((struct sr_dev_inst*)l->data);
|
||||
}
|
||||
g_safe_free_list(all_device_list);
|
||||
|
||||
g_safe_free_list(lib_ctx.device_list);
|
||||
|
||||
if (sr_exit(sr_ctx) != SR_OK){
|
||||
pthread_mutex_destroy(&lib_ctx.mutext); //uninit locker
|
||||
|
||||
if (sr_exit(lib_ctx.sr_ctx) != SR_OK){
|
||||
sr_err("%s", "call sr_exit error");
|
||||
}
|
||||
sr_ctx = NULL;
|
||||
lib_ctx.sr_ctx = NULL;
|
||||
|
||||
sr_log_uninit(); //try uninit log
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
@@ -149,87 +176,404 @@ SR_API void sr_set_firmware_resource_dir(const char *dir)
|
||||
DS_RES_PATH[len] = '/';
|
||||
DS_RES_PATH[len + 1] = 0;
|
||||
}
|
||||
|
||||
sr_info("Firmware resource path:%s", DS_RES_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set event callback, event type see enum libsigrok_event_type
|
||||
*/
|
||||
SR_API void sr_set_event_callback(libsigrok_event_callback_t *cb)
|
||||
SR_API void sr_set_event_callback(libsigrok_event_callback_t cb)
|
||||
{
|
||||
event_callback = cb;
|
||||
lib_ctx.event_callback = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the device list, if the field _handle is 0, the list visited to end.
|
||||
* User need call free() to release the buffer. If the list is empty, the out_list is null.
|
||||
*/
|
||||
SR_API int sr_device_get_list(struct sr_device_info** out_list, int *out_count)
|
||||
{
|
||||
int num;
|
||||
struct sr_device_info *array = NULL;
|
||||
struct sr_device_info *p = NULL;
|
||||
GList *l;
|
||||
struct sr_dev_inst *dev;
|
||||
|
||||
if (out_list == NULL){
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
*out_list = NULL;
|
||||
|
||||
pthread_mutex_lock(&lib_ctx.mutext);
|
||||
|
||||
num = g_slist_length(lib_ctx.device_list);
|
||||
if (num == 0){
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
array = (struct sr_device_info*)malloc(sizeof(struct sr_device_info) * (num+1));
|
||||
if (array == NULL){
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
return SR_ERR_MALLOC;
|
||||
}
|
||||
|
||||
p = array;
|
||||
|
||||
for (l=lib_ctx.device_list; l; l = l->next){
|
||||
dev = l->data;
|
||||
p->handle = dev->handle;
|
||||
strncpy(p->name, dev->name, sizeof(dev->name) - 1);
|
||||
p->dev_type = dev->dev_type;
|
||||
p->is_current = (dev->handle == lib_ctx.current_device.handle);
|
||||
p++;
|
||||
}
|
||||
|
||||
p->handle = 0; //is the end
|
||||
p->name[0] = '\0';
|
||||
|
||||
if (out_count){
|
||||
*out_count = num;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
|
||||
*out_list = array;
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
/**-------------------internal function ---------------*/
|
||||
/**
|
||||
* Check whether the USB device is in the device list.
|
||||
*/
|
||||
SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev)
|
||||
{
|
||||
GList *l;
|
||||
struct sr_dev_inst *dev;
|
||||
struct sr_usb_dev_inst *usb_dev_info;
|
||||
int bFind = 0;
|
||||
|
||||
if (usb_dev == NULL){
|
||||
sr_err("%s", "sr_usb_device_is_exists(), @usb_dev is null.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&lib_ctx.mutext);
|
||||
|
||||
for (l = lib_ctx.device_list; l; l = l->next){
|
||||
dev = l->data;
|
||||
usb_dev_info = dev->conn;
|
||||
if (dev->dev_type == DEV_TYPE_USB
|
||||
&& usb_dev_info != NULL
|
||||
&& usb_dev_info->usb_dev == usb_dev){
|
||||
bFind = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
|
||||
return bFind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove one device from the list, and destory it.
|
||||
* User need to call sr_device_get_list() to get the new list.
|
||||
*/
|
||||
SR_API int sr_remove_device(sr_device_handle handle)
|
||||
{
|
||||
GList *l;
|
||||
struct sr_dev_inst *dev;
|
||||
int bFind = 0;
|
||||
|
||||
if (handle == NULL){
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&lib_ctx.mutext);
|
||||
|
||||
for (l = lib_ctx.device_list; l; l = l->next){
|
||||
dev = l->data;
|
||||
if (dev->handle == handle){
|
||||
lib_ctx.device_list = g_slist_remove(lib_ctx.device_list, l->data);
|
||||
destroy_device_instance(dev);
|
||||
bFind = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
|
||||
if (bFind == 0){
|
||||
return SR_ERR_CALL_STATUS;
|
||||
}
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current device info.
|
||||
* If the current device is not exists, the handle filed will be set null.
|
||||
*/
|
||||
SR_API int sr_get_current_device_info(struct sr_device_info *info)
|
||||
{
|
||||
if (info == NULL){
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
|
||||
info->handle = NULL;
|
||||
info->name[0] = '\0';
|
||||
info->is_current = 0;
|
||||
info->dev_type = DEV_TYPE_UNKOWN;
|
||||
|
||||
if (lib_ctx.current_device.handle != NULL){
|
||||
info->handle = lib_ctx.current_device.handle;
|
||||
strncpy(info->name, lib_ctx.current_device.name, sizeof(info->name));
|
||||
info->is_current = 1;
|
||||
info->dev_type = lib_ctx.current_device.dev_type;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
/**-------------------private function ---------------*/
|
||||
|
||||
static int scan_hardware_device()
|
||||
static int update_device_handle(struct libusb_device *old_dev, struct libusb_device *new_dev)
|
||||
{
|
||||
GList *l;
|
||||
struct sr_dev_inst *dev;
|
||||
struct sr_usb_dev_inst *usb_dev_info;
|
||||
int bFind = 0;
|
||||
uint8_t bus;
|
||||
uint8_t address;
|
||||
|
||||
pthread_mutex_lock(&lib_ctx.mutext);
|
||||
|
||||
for (l = lib_ctx.device_list; l; l = l->next){
|
||||
dev = l->data;
|
||||
usb_dev_info = dev->conn;
|
||||
if (dev->dev_type == DEV_TYPE_USB
|
||||
&& usb_dev_info != NULL
|
||||
&& usb_dev_info->usb_dev == old_dev){
|
||||
|
||||
bus = libusb_get_bus_number(new_dev);
|
||||
address = libusb_get_device_address(new_dev);
|
||||
|
||||
if (bus == usb_dev_info->bus && address == usb_dev_info->address){
|
||||
bFind = 1;
|
||||
usb_dev_info->usb_dev = new_dev;
|
||||
}
|
||||
else{
|
||||
sr_err("Try to update the device handle, but the bus and addres is not the same!");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
return bFind;
|
||||
}
|
||||
|
||||
static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event)
|
||||
{
|
||||
if (event == USB_EV_HOTPLUG_ATTACH){
|
||||
sr_info("One device attached.");
|
||||
int bDone = 0;
|
||||
|
||||
if (wait_redo_attch_flag){
|
||||
sr_info("%s", "Device loose contact, but it reconnect success.");
|
||||
if (dev == NULL){
|
||||
sr_err("%s", "hotplug_event_listen_callback(), @dev is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == USB_EV_HOTPLUG_ATTACH){
|
||||
sr_info("One device attached, handle:%p", dev);
|
||||
|
||||
if (lib_ctx.is_waitting_reconnect){
|
||||
if (lib_ctx.attach_device_handle != NULL){
|
||||
sr_err("One attached device haven't processed complete,handle:%p",
|
||||
lib_ctx.attach_device_handle);
|
||||
}
|
||||
|
||||
if (lib_ctx.detach_device_handle == NULL){
|
||||
sr_err("%s", "The detached device handle is null, but the status is waitting for reconnect.");
|
||||
}
|
||||
else{
|
||||
if (update_device_handle(lib_ctx.detach_device_handle, dev)){
|
||||
bDone = 1;
|
||||
sr_info("%s", "One device loose contact, but it reconnect success.");
|
||||
}
|
||||
else{
|
||||
sr_err("Update device handle error! can't find the old.");
|
||||
}
|
||||
lib_ctx.detach_device_handle = NULL;
|
||||
}
|
||||
}
|
||||
wait_redo_attch_flag = 0;
|
||||
attach_event_flag = 1;
|
||||
if (bDone == 0){
|
||||
lib_ctx.attach_event_flag = 1; // Is a new device attched.
|
||||
lib_ctx.attach_device_handle = dev;
|
||||
}
|
||||
lib_ctx.is_waitting_reconnect = 0;
|
||||
}
|
||||
else if (event == USB_EV_HOTPLUG_DETTACH){
|
||||
sr_info("One device detached.");
|
||||
wait_redo_attch_flag = 1; //Begin wait the device reconnect, if timeout, will process the detach event.
|
||||
wait_redo_attch_times = 0;
|
||||
sr_info("One device detached,handle:%p", dev);
|
||||
|
||||
if (lib_ctx.detach_device_handle != NULL){
|
||||
sr_err("One detached device haven't processed complete,handle:%p",
|
||||
lib_ctx.detach_device_handle);
|
||||
}
|
||||
/**
|
||||
* Begin to wait the device reconnect, if timeout, will process the detach event.
|
||||
*/
|
||||
lib_ctx.is_waitting_reconnect = 1;
|
||||
lib_ctx.check_reconnect_times = 0;
|
||||
lib_ctx.detach_device_handle = dev;
|
||||
}
|
||||
else{
|
||||
sr_err("%s", "Unknown usb event");
|
||||
wait_redo_attch_flag = 1;
|
||||
sr_err("%s", "Unknown usb device event");
|
||||
}
|
||||
}
|
||||
|
||||
static void process_attach_event()
|
||||
{
|
||||
struct sr_dev_driver **drivers;
|
||||
GList *dev_list;
|
||||
GSList *l;
|
||||
GList *cur_list;
|
||||
struct sr_dev_driver *dr;
|
||||
int num = 0;
|
||||
|
||||
sr_info("%s", "Process device attch event.");
|
||||
|
||||
if (lib_ctx.attach_device_handle == NULL){
|
||||
sr_err("%s", "The attached device handle is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
drivers = sr_driver_list();
|
||||
|
||||
while (*drivers)
|
||||
{
|
||||
dr = *drivers;
|
||||
|
||||
if (dr->driver_type == DRIVER_TYPE_HARDWARE)
|
||||
{
|
||||
dev_list = dr->scan(NULL);
|
||||
if (dev_list != NULL){
|
||||
sr_info("Get new device list by driver \"%s\"", dr->name);
|
||||
|
||||
pthread_mutex_lock(&lib_ctx.mutext);
|
||||
cur_list = lib_ctx.device_list;
|
||||
|
||||
for (l= dev_list; l; l = l->next){
|
||||
cur_list = g_slist_append(cur_list, l->data);
|
||||
num++;
|
||||
}
|
||||
|
||||
lib_ctx.device_list = cur_list;
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
g_slist_free(dev_list);
|
||||
}
|
||||
}
|
||||
|
||||
drivers++;
|
||||
}
|
||||
|
||||
if (lib_ctx.event_callback != NULL && num > 0){
|
||||
// Tell user one new device attched, and the list is updated.
|
||||
lib_ctx.event_callback(SR_EV_NEW_DEVICE_ATTACH);
|
||||
}
|
||||
|
||||
lib_ctx.attach_device_handle = NULL;
|
||||
}
|
||||
|
||||
static void process_detach_event()
|
||||
{
|
||||
libusb_device *ev_dev;
|
||||
int ev = SR_EV_INACTIVE_DEVICE_DETACH;
|
||||
GList *l;
|
||||
struct sr_dev_inst *dev;
|
||||
struct sr_usb_dev_inst *usb_dev_info;
|
||||
struct sr_dev_driver *driver_ins;
|
||||
|
||||
sr_info("%s", "Process device detach event.");
|
||||
|
||||
ev_dev = lib_ctx.detach_device_handle;
|
||||
if (ev_dev == NULL){
|
||||
sr_err("%s", "The detached device handle is null.");
|
||||
return;
|
||||
}
|
||||
lib_ctx.detach_device_handle = NULL;
|
||||
|
||||
pthread_mutex_lock(&lib_ctx.mutext);
|
||||
|
||||
for (l = lib_ctx.device_list; l; l = l->next){
|
||||
dev = l->data;
|
||||
usb_dev_info = dev->conn;
|
||||
|
||||
if (dev->dev_type == DEV_TYPE_USB
|
||||
&& usb_dev_info != NULL
|
||||
&& usb_dev_info->usb_dev == ev_dev){
|
||||
//Found the device, and remove it.
|
||||
lib_ctx.device_list = g_slist_remove(lib_ctx.device_list, l->data);
|
||||
destroy_device_instance(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&lib_ctx.mutext);
|
||||
|
||||
if (ev_dev == lib_ctx.current_device.handle)
|
||||
ev = SR_EV_CURRENT_DEVICE_DETACH;
|
||||
|
||||
if (lib_ctx.event_callback != NULL){
|
||||
//Tell user one new device detached, and the list is updated.
|
||||
lib_ctx.event_callback(ev);
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_hotplug_process_proc()
|
||||
{
|
||||
sr_info("%s", "Hotplug thread start!");
|
||||
|
||||
while (!sr_exit_flag)
|
||||
while (!lib_ctx.lib_exit_flag)
|
||||
{
|
||||
sr_hotplug_wait_timout(sr_ctx);
|
||||
sr_hotplug_wait_timout(lib_ctx.sr_ctx);
|
||||
|
||||
if (attach_event_flag){
|
||||
if (lib_ctx.attach_event_flag){
|
||||
process_attach_event();
|
||||
attach_event_flag = 0;
|
||||
lib_ctx.attach_event_flag = 0;
|
||||
}
|
||||
if (detach_event_flag){
|
||||
if (lib_ctx.detach_event_flag){
|
||||
process_detach_event();
|
||||
detach_event_flag = 0;
|
||||
lib_ctx.detach_event_flag = 0;
|
||||
}
|
||||
|
||||
_sleep(100);
|
||||
|
||||
if (wait_redo_attch_flag){
|
||||
wait_redo_attch_times++;
|
||||
if (lib_ctx.is_waitting_reconnect){
|
||||
lib_ctx.check_reconnect_times++;
|
||||
|
||||
// 500ms
|
||||
if (wait_redo_attch_times == 5){
|
||||
if (lib_ctx.check_reconnect_times == 5){
|
||||
//Device loose contact,wait for it reconnection timeout.
|
||||
detach_event_flag = 1; // use detach event
|
||||
wait_redo_attch_flag = 0;
|
||||
lib_ctx.detach_event_flag = 1; // use detach event
|
||||
lib_ctx.is_waitting_reconnect = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sr_info("%s", "Hotplug thread end!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void destroy_device_instance(struct sr_dev_inst *dev)
|
||||
{
|
||||
if (dev == NULL || dev->driver == NULL){
|
||||
sr_err("%s", "destroy_device_instance() argument error.");
|
||||
return;
|
||||
}
|
||||
struct sr_dev_driver *driver_ins;
|
||||
driver_ins = dev->driver;
|
||||
|
||||
if (driver_ins->dev_destroy)
|
||||
driver_ins->dev_destroy(dev);
|
||||
else if (driver_ins->dev_close)
|
||||
driver_ins->dev_close(dev);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,89 @@ struct sr_context {
|
||||
struct timeval hotplug_tv;
|
||||
};
|
||||
|
||||
static const struct sr_dev_mode sr_mode_list[] =
|
||||
{
|
||||
{LOGIC,"Logic Analyzer","la"},
|
||||
{ANALOG, "Data Acquisition", "daq"},
|
||||
{DSO, "Oscilloscope", "osc"},
|
||||
};
|
||||
|
||||
enum sr_dev_driver_type
|
||||
{
|
||||
DRIVER_TYPE_DEMO = 0,
|
||||
DRIVER_TYPE_FILE = 1,
|
||||
DRIVER_TYPE_HARDWARE = 2
|
||||
};
|
||||
|
||||
struct sr_dev_driver {
|
||||
/* Driver-specific */
|
||||
char *name;
|
||||
char *longname;
|
||||
int api_version;
|
||||
int driver_type; // enum sr_dev_driver_type
|
||||
int (*init) (struct sr_context *sr_ctx);
|
||||
int (*cleanup) (void);
|
||||
GSList *(*scan) (GSList *options);
|
||||
GSList *(*dev_list) (void);
|
||||
const GSList *(*dev_mode_list) (const struct sr_dev_inst *sdi);
|
||||
|
||||
int (*config_get) (int id, GVariant **data,
|
||||
const struct sr_dev_inst *sdi,
|
||||
const struct sr_channel *ch,
|
||||
const struct sr_channel_group *cg);
|
||||
int (*config_set) (int id, GVariant *data,
|
||||
struct sr_dev_inst *sdi,
|
||||
struct sr_channel *ch,
|
||||
struct sr_channel_group *cg);
|
||||
int (*config_list) (int info_id, GVariant **data,
|
||||
const struct sr_dev_inst *sdi,
|
||||
const struct sr_channel_group *cg);
|
||||
|
||||
/* Device-specific */
|
||||
int (*dev_open) (struct sr_dev_inst *sdi);
|
||||
int (*dev_close) (struct sr_dev_inst *sdi);
|
||||
int (*dev_destroy) (struct sr_dev_inst *sdi);
|
||||
int (*dev_status_get) (const struct sr_dev_inst *sdi,
|
||||
struct sr_status *status, gboolean prg);
|
||||
int (*dev_acquisition_start) (struct sr_dev_inst *sdi,
|
||||
void *cb_data);
|
||||
int (*dev_acquisition_stop) (const struct sr_dev_inst *sdi,
|
||||
void *cb_data);
|
||||
|
||||
/* Dynamic */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct sr_dev_inst {
|
||||
/** Device driver. */
|
||||
struct sr_dev_driver *driver;
|
||||
/**Identity. */
|
||||
sr_device_handle handle;
|
||||
/** device name. */
|
||||
char name[50];
|
||||
/** Device type:(demo,filelog,hardware). The type see enum sr_device_type. */
|
||||
int dev_type;
|
||||
/** Index of device in driver. */
|
||||
int index;
|
||||
/** Device instance status. SR_ST_NOT_FOUND, etc. */
|
||||
int status;
|
||||
/** Device mode. LA/DAQ/OSC, etc. */
|
||||
int mode;
|
||||
/** Device vendor. */
|
||||
char *vendor;
|
||||
|
||||
/** Device version. */
|
||||
char *version;
|
||||
/** List of channels. */
|
||||
GSList *channels;
|
||||
/** List of sr_channel_group structs */
|
||||
GSList *channel_groups;
|
||||
/** Device instance connection data (used?) */
|
||||
void *conn;
|
||||
/** Device instance private data (used?) */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct sr_session {
|
||||
/** List of struct sr_dev pointers. */
|
||||
GSList *devs;
|
||||
@@ -99,6 +182,8 @@ struct sr_usb_dev_inst {
|
||||
uint8_t bus;
|
||||
uint8_t address;
|
||||
struct libusb_device_handle *devhdl;
|
||||
struct libusb_device *usb_dev;
|
||||
int is_wait_re_connected;
|
||||
};
|
||||
|
||||
#define SERIAL_PARITY_NONE 0
|
||||
@@ -193,7 +278,6 @@ SR_PRIV int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb,void *cb_
|
||||
/*--- std.c -----------------------------------------------------------------*/
|
||||
|
||||
typedef int (*dev_close_t)(struct sr_dev_inst *sdi);
|
||||
typedef void (*std_dev_clear_t)(void *priv);
|
||||
|
||||
SR_PRIV int std_hw_init(struct sr_context *sr_ctx, struct sr_dev_driver *di,
|
||||
const char *prefix);
|
||||
@@ -202,8 +286,6 @@ SR_PRIV int std_hw_dev_acquisition_stop_serial(struct sr_dev_inst *sdi,
|
||||
struct sr_serial_dev_inst *serial, const char *prefix);
|
||||
SR_PRIV int std_session_send_df_header(const struct sr_dev_inst *sdi,
|
||||
const char *prefix);
|
||||
SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver,
|
||||
std_dev_clear_t clear_private);
|
||||
|
||||
/*--- trigger.c -------------------------------------------------*/
|
||||
SR_PRIV uint64_t sr_trigger_get_mask0(uint16_t stage);
|
||||
@@ -271,5 +353,9 @@ SR_PRIV int sr_close_hotplug(struct sr_context *ctx);
|
||||
SR_PRIV void sr_hotplug_wait_timout(struct sr_context *ctx);
|
||||
|
||||
/*--- lib_main.c -------------------------------------------------*/
|
||||
/**
|
||||
* Check whether the USB device is in the device list.
|
||||
*/
|
||||
SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -63,6 +63,8 @@ extern "C" {
|
||||
* return codes, but never remove or redefine existing ones.
|
||||
*/
|
||||
|
||||
#define SR_LIB_NAME "libsigrok"
|
||||
|
||||
/** Status/error codes returned by libsigrok functions. */
|
||||
enum {
|
||||
SR_OK = 0, /**< No error. */
|
||||
@@ -160,13 +162,12 @@ enum {
|
||||
#define SR_PRIV
|
||||
#endif
|
||||
|
||||
typedef unsigned long long sr_device_handle;
|
||||
|
||||
enum sr_device_type{
|
||||
DEV_TYPE_UNKOWN = 0,
|
||||
DEV_TYPE_DEMO = 1,
|
||||
DEV_TYPE_FILELOG = 2,
|
||||
DEV_TYPE_HARDWARE = 3,
|
||||
DEV_TYPE_USB = 3,
|
||||
DEV_TYPE_SERIAL = 4,
|
||||
};
|
||||
|
||||
/** Data types used by sr_config_info(). */
|
||||
@@ -334,6 +335,8 @@ enum {
|
||||
};
|
||||
|
||||
struct sr_context; //hidden all field
|
||||
struct sr_dev_inst;
|
||||
struct sr_dev_driver;
|
||||
|
||||
struct sr_datafeed_packet {
|
||||
uint16_t type;
|
||||
@@ -1069,45 +1072,6 @@ enum sr_config_option_id{
|
||||
SR_CONF_DATALOG,
|
||||
};
|
||||
|
||||
struct sr_dev_inst {
|
||||
/** Device driver. */
|
||||
struct sr_dev_driver *driver;
|
||||
/**Identity. */
|
||||
sr_device_handle handle;
|
||||
/** Device type:(demo,filelog,hardware). The type see enum sr_device_type. */
|
||||
int dev_type;
|
||||
/** Index of device in driver. */
|
||||
int index;
|
||||
/** Device instance status. SR_ST_NOT_FOUND, etc. */
|
||||
int status;
|
||||
/** Device instance type. SR_INST_USB, etc. */
|
||||
int inst_type;
|
||||
/** Device mode. LA/DAQ/OSC, etc. */
|
||||
int mode;
|
||||
/** Device vendor. */
|
||||
char *vendor;
|
||||
/** Device model. */
|
||||
char *model;
|
||||
/** Device version. */
|
||||
char *version;
|
||||
/** List of channels. */
|
||||
GSList *channels;
|
||||
/** List of sr_channel_group structs */
|
||||
GSList *channel_groups;
|
||||
/** Device instance connection data (used?) */
|
||||
void *conn;
|
||||
/** Device instance private data (used?) */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/** Types of device instances (sr_dev_inst). */
|
||||
enum {
|
||||
/** Device instance type for USB devices. */
|
||||
SR_INST_USB = 10000,
|
||||
/** Device instance type for serial port devices. */
|
||||
SR_INST_SERIAL,
|
||||
};
|
||||
|
||||
/** Device instance status. */
|
||||
enum {
|
||||
/** The device instance was not found. */
|
||||
@@ -1175,52 +1139,6 @@ struct sr_dev_mode {
|
||||
const char *name;
|
||||
const char *acronym;
|
||||
};
|
||||
|
||||
static const struct sr_dev_mode sr_mode_list[] =
|
||||
{
|
||||
{LOGIC,"Logic Analyzer","la"},
|
||||
{ANALOG, "Data Acquisition", "daq"},
|
||||
{DSO, "Oscilloscope", "osc"},
|
||||
};
|
||||
|
||||
struct sr_dev_driver {
|
||||
/* Driver-specific */
|
||||
char *name;
|
||||
char *longname;
|
||||
int api_version;
|
||||
int (*init) (struct sr_context *sr_ctx);
|
||||
int (*cleanup) (void);
|
||||
GSList *(*scan) (GSList *options);
|
||||
GSList *(*dev_list) (void);
|
||||
const GSList *(*dev_mode_list) (const struct sr_dev_inst *sdi);
|
||||
int (*dev_clear) (void);
|
||||
|
||||
int (*config_get) (int id, GVariant **data,
|
||||
const struct sr_dev_inst *sdi,
|
||||
const struct sr_channel *ch,
|
||||
const struct sr_channel_group *cg);
|
||||
int (*config_set) (int id, GVariant *data,
|
||||
struct sr_dev_inst *sdi,
|
||||
struct sr_channel *ch,
|
||||
struct sr_channel_group *cg);
|
||||
int (*config_list) (int info_id, GVariant **data,
|
||||
const struct sr_dev_inst *sdi,
|
||||
const struct sr_channel_group *cg);
|
||||
|
||||
/* Device-specific */
|
||||
int (*dev_open) (struct sr_dev_inst *sdi);
|
||||
int (*dev_close) (struct sr_dev_inst *sdi);
|
||||
int (*dev_destroy) (struct sr_dev_inst *sdi);
|
||||
int (*dev_status_get) (const struct sr_dev_inst *sdi,
|
||||
struct sr_status *status, gboolean prg);
|
||||
int (*dev_acquisition_start) (struct sr_dev_inst *sdi,
|
||||
void *cb_data);
|
||||
int (*dev_acquisition_stop) (const struct sr_dev_inst *sdi,
|
||||
void *cb_data);
|
||||
|
||||
/* Dynamic */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
enum {
|
||||
SIMPLE_TRIGGER = 0,
|
||||
@@ -1391,43 +1309,48 @@ SR_API void sr_log_level(int level);
|
||||
/*---event define ---------------------------------------------*/
|
||||
enum libsigrok_event_type
|
||||
{
|
||||
// A new device attachs, user need calls sr_device_get_list to get the list,
|
||||
// and call sr_device_select to swith a new device.
|
||||
EV_DEVICE_ATTACH = 0,
|
||||
// A new device attached, user need to call sr_device_get_list to get the list,
|
||||
// the last one is new.
|
||||
// User can call sr_device_select() to switch to the current device.
|
||||
SR_EV_NEW_DEVICE_ATTACH = 0,
|
||||
|
||||
// A device detachs, user need calls sr_device_get_list to get the list,
|
||||
// and call sr_device_select to swith a new device.
|
||||
EV_DEVICE_DETACH = 1,
|
||||
// The current device detached, user need to call sr_device_get_list to get the list,
|
||||
// and call sr_device_select() to switch to the current device.
|
||||
SR_EV_CURRENT_DEVICE_DETACH = 1,
|
||||
|
||||
// User can call sr_device_get_list to get new list, and update the data view.
|
||||
EV_CURRENT_DEVICE_CHANGED = 2,
|
||||
// A inactive device detached.
|
||||
// User can call sr_device_get_list() to get the new list, and update the list view.
|
||||
SR_EV_INACTIVE_DEVICE_DETACH = 2,
|
||||
|
||||
// User can call sr_device_get_list to get new list, and update the list view.
|
||||
EV_DEVICE_LIST_CHANGED = 3,
|
||||
// The current device switch success.
|
||||
// User can call sr_device_get_list() to get new list, and update the data view.
|
||||
SR_EV_CURRENT_DEVICE_CHANGED = 3,
|
||||
};
|
||||
|
||||
typedef unsigned long long sr_device_handle;
|
||||
|
||||
/**
|
||||
* Device base info
|
||||
*/
|
||||
struct sr_device_info
|
||||
{
|
||||
sr_device_handle _handle;
|
||||
char _name[50];
|
||||
int _dev_type; // enum sr_device_type
|
||||
int _is_current; //is actived
|
||||
sr_device_handle handle;
|
||||
char name[50];
|
||||
int dev_type; // enum sr_device_type
|
||||
int is_current; //is actived
|
||||
};
|
||||
|
||||
struct sr_task_progress
|
||||
{
|
||||
int _progress;
|
||||
int _is_end;
|
||||
int progress;
|
||||
int is_end;
|
||||
};
|
||||
|
||||
struct sr_store_extra_data
|
||||
{
|
||||
char _name[50];
|
||||
char *_data;
|
||||
int _data_length;
|
||||
char name[50];
|
||||
char *data;
|
||||
int data_length;
|
||||
};
|
||||
|
||||
|
||||
@@ -1451,7 +1374,7 @@ SR_API int sr_lib_exit();
|
||||
/**
|
||||
* Set event callback, event type see enum libsigrok_event_type
|
||||
*/
|
||||
SR_API void sr_set_event_callback(libsigrok_event_callback_t *cb);
|
||||
SR_API void sr_set_event_callback(libsigrok_event_callback_t cb);
|
||||
|
||||
/**
|
||||
* By default, the library can manage data by itself. If set the callback,
|
||||
@@ -1466,20 +1389,18 @@ SR_API int sr_set_datafeed_callback(sr_datafeed_callback_t cb, void *cb_data);
|
||||
SR_API void sr_set_firmware_resource_dir(const char *dir);
|
||||
|
||||
/**
|
||||
* Get the device list, the last item is null.
|
||||
* User need call free() to release the buffer. If the list is empty, it returns null.
|
||||
* Get the device list, if the field _handle is 0, the list visited to end.
|
||||
* User need call free() to release the buffer. If the list is empty, the out_list is null.
|
||||
*/
|
||||
SR_API struct sr_device_info* sr_device_get_list(int *out_count);
|
||||
SR_API int sr_device_get_list(struct sr_device_info** out_list, int *out_count);
|
||||
|
||||
/**
|
||||
* Active a device, if success, it will trigs the event of EV_CURRENT_DEVICE_CHANGED.
|
||||
* If the old actived device is hardware, maybe user need store the data first.
|
||||
* Active a device, if success, it will trigs the event of SR_EV_CURRENT_DEVICE_CHANGED.
|
||||
*/
|
||||
SR_API int sr_device_select(sr_device_handle handle);
|
||||
|
||||
/**
|
||||
* Active a device, if success, it will trigs the event of EV_CURRENT_DEVICE_CHANGED.
|
||||
* If the old actived device is hardware, maybe user need store the data first.
|
||||
* Active a device, if success, it will trigs the event of SR_EV_CURRENT_DEVICE_CHANGED.
|
||||
* @index is -1, will select the last one.
|
||||
*/
|
||||
SR_API int sr_device_select_by_index(int index);
|
||||
@@ -1490,16 +1411,16 @@ SR_API int sr_device_select_by_index(int index);
|
||||
SR_API int sr_device_from_file(const char *file_path);
|
||||
|
||||
/**
|
||||
* Get current sample count
|
||||
* Remove one device from the list, and destory it.
|
||||
* User need to call sr_device_get_list() to get the new list.
|
||||
*/
|
||||
SR_API uint64_t sr_sample_count();
|
||||
SR_API int sr_remove_device(sr_device_handle handle);
|
||||
|
||||
/**
|
||||
* Store current session data.
|
||||
* @ext_data_array is the extra data.
|
||||
* Get the current device info.
|
||||
* If the current device is not exists, the handle filed will be set null.
|
||||
*/
|
||||
SR_API int sr_store_session_data(struct sr_task_progress *prog, const char *file_path,
|
||||
struct sr_store_extra_data *ext_data_array, int ext_data_count);
|
||||
SR_API int sr_get_current_device_info(struct sr_device_info *info);
|
||||
|
||||
/**
|
||||
* Start collect data
|
||||
|
||||
@@ -1020,12 +1020,12 @@ SR_PRIV struct sr_dev_driver session_driver = {
|
||||
.name = "virtual-session",
|
||||
.longname = "Session-emulating driver",
|
||||
.api_version = 1,
|
||||
.driver_type = DRIVER_TYPE_FILE,
|
||||
.init = init,
|
||||
.cleanup = dev_clear,
|
||||
.scan = NULL,
|
||||
.dev_list = NULL,
|
||||
.dev_mode_list = dev_mode_list,
|
||||
.dev_clear = dev_clear,
|
||||
.config_get = config_get,
|
||||
.config_set = config_set,
|
||||
.config_list = config_list,
|
||||
|
||||
@@ -53,7 +53,6 @@ SR_PRIV int std_hw_init(struct sr_context *sr_ctx, struct sr_dev_driver *di,
|
||||
}
|
||||
|
||||
drvc->sr_ctx = sr_ctx;
|
||||
drvc->instances = NULL;
|
||||
di->priv = drvc;
|
||||
|
||||
return SR_OK;
|
||||
@@ -161,63 +160,4 @@ SR_PRIV int std_hw_dev_acquisition_stop_serial(struct sr_dev_inst *sdi,
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard driver dev_clear() helper.
|
||||
*
|
||||
* This function can be used to implement the dev_clear() driver API
|
||||
* callback. dev_close() is called before every sr_dev_inst is cleared.
|
||||
*
|
||||
* The only limitation is driver-specific device contexts (sdi->priv).
|
||||
* These are freed, but any dynamic allocation within structs stored
|
||||
* there cannot be freed.
|
||||
*
|
||||
* @param driver The driver which will have its instances released.
|
||||
*
|
||||
* @return SR_OK on success.
|
||||
*/
|
||||
SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver,
|
||||
std_dev_clear_t clear_private)
|
||||
{
|
||||
struct sr_dev_inst *sdi;
|
||||
struct drv_context *drvc;
|
||||
struct dev_context *devc;
|
||||
GSList *l;
|
||||
int ret;
|
||||
|
||||
if (!(drvc = driver->priv))
|
||||
/* Driver was never initialized, nothing to do. */
|
||||
return SR_OK;
|
||||
|
||||
ret = SR_OK;
|
||||
for (l = drvc->instances; l; l = l->next) {
|
||||
/* Log errors, but continue cleaning up the rest. */
|
||||
if (!(sdi = l->data)) {
|
||||
ret = SR_ERR_BUG;
|
||||
continue;
|
||||
}
|
||||
if (!(devc = sdi->priv)) {
|
||||
ret = SR_ERR_BUG;
|
||||
continue;
|
||||
}
|
||||
if (driver->dev_close)
|
||||
driver->dev_close(sdi);
|
||||
|
||||
if (sdi->conn) {
|
||||
if (sdi->inst_type == SR_INST_USB)
|
||||
sr_usb_dev_inst_free(sdi->conn);
|
||||
else if (sdi->inst_type == SR_INST_SERIAL)
|
||||
sr_serial_dev_inst_free(sdi->conn);
|
||||
}
|
||||
if (clear_private)
|
||||
clear_private(sdi->priv);
|
||||
sdi = l->data;
|
||||
sr_dev_inst_free(sdi);
|
||||
}
|
||||
|
||||
g_slist_free(drvc->instances);
|
||||
drvc->instances = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
#include <libsigrok.h>
|
||||
#include "../log.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "test_main: "
|
||||
|
||||
int main()
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = sr_lib_init()) != SR_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
sr_info("%s", "start.");
|
||||
|
||||
char c = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = getchar();
|
||||
|
||||
if (c == 'x'){
|
||||
sr_lib_exit();
|
||||
sr_info("%s", "exit.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
68
libsigrok4DSL/tests/test_main.cpp
Normal file
68
libsigrok4DSL/tests/test_main.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
#include <libsigrok.h>
|
||||
#include "../log.h"
|
||||
#include <stdio.h>
|
||||
#include <QDebug>
|
||||
#include <log/xlog.h>
|
||||
#include <QString>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "test_main: "
|
||||
|
||||
int b_exit = 0;
|
||||
|
||||
void print_log(const char *data, int len){
|
||||
if (len > 0){
|
||||
//*(data + len-1) = 0;
|
||||
QString s(data);
|
||||
// qDebug()<<s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ctrl()
|
||||
{
|
||||
char c = 0;
|
||||
|
||||
qDebug()<<"wait command:";
|
||||
int i = 0;
|
||||
|
||||
while (!b_exit)
|
||||
{
|
||||
c = getchar();
|
||||
if (c == 'x'){
|
||||
sr_info("%s", "exit.");
|
||||
break;
|
||||
}
|
||||
qDebug()<<"b";
|
||||
this_thread::sleep_for(chrono::milliseconds(2000));
|
||||
}
|
||||
|
||||
qDebug()<<"exit command waitting";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
xlog_context *log_ctx = xlog_new2(0);
|
||||
|
||||
sr_log_level(XLOG_LEVEL_INFO);
|
||||
sr_log_set_context(log_ctx);
|
||||
|
||||
xlog_add_receiver(log_ctx, print_log, 0);
|
||||
|
||||
sr_lib_init();
|
||||
|
||||
thread t1(ctrl);
|
||||
t1.join();
|
||||
|
||||
sr_lib_exit();
|
||||
qDebug()<<"exit.";
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user