2
0
forked from Ivasoft/DSView

Code refactoring 7

This commit is contained in:
dreamsourcelabTAI
2022-08-08 15:59:50 +08:00
parent 8aa16cae18
commit 9c935ad683
16 changed files with 800 additions and 499 deletions

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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,

View File

@@ -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);
}
}

View File

@@ -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,

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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;
}

View 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;
}