From a027a19448df9075cd99190844ceaacb16d44714 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Thu, 28 Jul 2022 16:57:15 +0800 Subject: [PATCH] Code refactoring 5 --- DSView/pv/sigsession.cpp | 4 +- libsigrok4DSL/backend.c | 2 + libsigrok4DSL/dsdevice.c | 2 + libsigrok4DSL/error.c | 24 ++++-- libsigrok4DSL/hardware/DSL/command.c | 4 + libsigrok4DSL/hardware/DSL/dscope.c | 53 +++++++++---- libsigrok4DSL/hardware/DSL/dsl.c | 77 +++++++++++++++---- libsigrok4DSL/hardware/DSL/dsl.h | 4 +- libsigrok4DSL/hardware/DSL/dslogic.c | 59 ++++++++++----- libsigrok4DSL/hardware/demo/demo.c | 10 +++ libsigrok4DSL/lib_main.c | 75 +++++++++--------- libsigrok4DSL/libsigrok-internal.h | 39 +++++++++- libsigrok4DSL/libsigrok.h | 109 +++++++++++---------------- libsigrok4DSL/output/srzip.c | 3 +- libsigrok4DSL/session.c | 2 +- libsigrok4DSL/session_driver.c | 25 ++++-- libsigrok4DSL/session_file.c | 1 + libsigrok4DSL/version.c | 95 +---------------------- libsigrok4DSL/version.h | 42 +---------- 19 files changed, 326 insertions(+), 304 deletions(-) diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 3102ea5f..d866df82 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -709,7 +709,7 @@ void SigSession::init_signals() clear_all_decoder(); } else{ - dsv_err("%s", "Device loose contact"); + dsv_info("%s", "Device loose contact, and it reconnect success."); } // Detect what data types we will receive @@ -1288,7 +1288,7 @@ void SigSession::hotplug_proc() _wait_reattch_times++; // 500ms - if (_wait_reattch_times == 5) + if (_wait_reattch_times == 70) { dsv_dbg("%s", "Wait the device reattach time out for 500ms"); _hot_detach = true; diff --git a/libsigrok4DSL/backend.c b/libsigrok4DSL/backend.c index 9a03c0ed..46dc8042 100644 --- a/libsigrok4DSL/backend.c +++ b/libsigrok4DSL/backend.c @@ -335,6 +335,8 @@ SR_API int sr_init(struct sr_context **ctx) context->hotplug_user_data = NULL; context->hotplug_tv.tv_sec = 0; context->hotplug_tv.tv_usec = 0; + context->event_callback = NULL; + context->deiveList = NULL; ret = libusb_init(&context->libusb_ctx); if (LIBUSB_SUCCESS != ret) { diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index b29dd9e5..8351e7d6 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -198,6 +198,8 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status, sdi->channels = NULL; sdi->conn = NULL; sdi->priv = NULL; + sdi->handle = (sr_device_handle)sdi; + sdi->dev_type = DEV_TYPE_UNKOWN; return sdi; } diff --git a/libsigrok4DSL/error.c b/libsigrok4DSL/error.c index d7d792d5..df3e60f8 100644 --- a/libsigrok4DSL/error.c +++ b/libsigrok4DSL/error.c @@ -46,17 +46,17 @@ * description of the error, such as "memory allocation error". * The string must NOT be free'd by the caller! * - * @see sr_strerror_name + * @see sr_error_name * * @since 0.2.0 */ -SR_API const char *sr_strerror(int error_code) +SR_API const char *sr_error_str(int error_code) { const char *str; /* * Note: All defined SR_* error macros from libsigrok.h must have - * an entry in this function, as well as in sr_strerror_name(). + * an entry in this function, as well as in sr_error_name(). */ switch (error_code) { @@ -84,6 +84,12 @@ SR_API const char *sr_strerror(int error_code) case SR_ERR_DEV_CLOSED: str = "device closed but should be open"; break; + case SR_ERR_CALL_STATUS: + str = "Function call status error"; + break; + case SR_ERR_HAVE_DONE: + str = "The Function have called"; + break; default: str = "unknown error"; break; @@ -106,17 +112,17 @@ SR_API const char *sr_strerror(int error_code) * @return A const string containing the "name" of the error code as string. * The string must NOT be free'd by the caller! * - * @see sr_strerror + * @see sr_error_str * * @since 0.2.0 */ -SR_API const char *sr_strerror_name(int error_code) +SR_API const char *sr_error_name(int error_code) { const char *str; /* * Note: All defined SR_* error macros from libsigrok.h must have - * an entry in this function, as well as in sr_strerror(). + * an entry in this function, as well as in sr_error_str(). */ switch (error_code) { @@ -144,6 +150,12 @@ SR_API const char *sr_strerror_name(int error_code) case SR_ERR_DEV_CLOSED: str = "SR_ERR_DEV_CLOSED"; break; + case SR_ERR_CALL_STATUS: + str = "SR_ERR_CALL_STATUS"; + break; + case SR_ERR_HAVE_DONE: + str = "SR_ERR_HAVE_DONE"; + break; default: str = "unknown error code"; break; diff --git a/libsigrok4DSL/hardware/DSL/command.c b/libsigrok4DSL/hardware/DSL/command.c index 46cef034..0907c8fe 100644 --- a/libsigrok4DSL/hardware/DSL/command.c +++ b/libsigrok4DSL/hardware/DSL/command.c @@ -28,6 +28,8 @@ SR_PRIV int command_ctl_wr(libusb_device_handle *devhdl, struct ctl_wr_cmd cmd) { int ret; + assert(devhdl); + /* Send the control command. */ ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, CMD_CTL_WR, 0x0000, 0x0000, @@ -46,6 +48,8 @@ SR_PRIV int command_ctl_rd(libusb_device_handle *devhdl, struct ctl_rd_cmd cmd) { int ret; + assert(devhdl); + /* Send the control message. */ ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, CMD_CTL_RD_PRE, 0x0000, 0x0000, diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 92861b44..c6a6d605 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -198,12 +198,18 @@ static GSList *scan(GSList *options) GSList *l, *devices, *conn_devices; struct libusb_device_descriptor des; libusb_device **devlist; + libusb_device *device_handle = NULL; int devcnt, ret, i, j; const char *conn; enum libusb_speed usb_speed; drvc = di->priv; + if (options != NULL) + sr_info("%s", "Scan DSCope device with options."); + else + sr_info("%s", "Scan DSCope device."); + conn = NULL; for (l = options; l; l = l->next) { src = l->data; @@ -213,21 +219,27 @@ static GSList *scan(GSList *options) break; } } - if (conn) + if (conn){ + sr_info("%s", "Find usb device with connect config."); conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn); + } else conn_devices = NULL; /* Find all DSCope compatible devices and upload firmware to them. */ devices = NULL; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); - for (i = 0; devlist[i]; i++) { + + for (i = 0; devlist[i]; i++) + { + device_handle = devlist[i]; + if (conn) { usb = NULL; for (l = conn_devices; l; l = l->next) { usb = l->data; - if (usb->bus == libusb_get_bus_number(devlist[i]) - && usb->address == libusb_get_device_address(devlist[i])) + if (usb->bus == libusb_get_bus_number(device_handle) + && usb->address == libusb_get_device_address(device_handle)) break; } if (!l) @@ -236,13 +248,13 @@ static GSList *scan(GSList *options) continue; } - if ((ret = libusb_get_device_descriptor( devlist[i], &des)) != 0) { + if ((ret = libusb_get_device_descriptor( device_handle, &des)) != 0) { sr_warn("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } - usb_speed = libusb_get_device_speed( devlist[i]); + usb_speed = libusb_get_device_speed(device_handle); if ((usb_speed != LIBUSB_SPEED_HIGH) && (usb_speed != LIBUSB_SPEED_SUPER)) continue; @@ -253,6 +265,7 @@ static GSList *scan(GSList *options) des.idProduct == supported_DSCope[j].pid && usb_speed == supported_DSCope[j].usb_speed) { prof = &supported_DSCope[j]; + break; } } @@ -260,10 +273,13 @@ static GSList *scan(GSList *options) if (!prof) continue; + sr_info("Got a device handle: %p", device_handle); + devcnt = g_slist_length(drvc->instances); devc = DSCope_dev_new(prof); if (!devc) return NULL; + sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, devcnt, SR_ST_INITIALIZING, prof->vendor, prof->model, prof->model_version); if (!sdi) { @@ -272,24 +288,25 @@ 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); - //devices = g_slist_append(devices, sdi); /* Fill in probelist according to this device's profile. */ if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK) return NULL; - if (dsl_check_conf_profile(devlist[i])) { + if (dsl_check_conf_profile(device_handle)) { /* Already has the firmware, so fix the new address. */ - sr_info("Found an DSCope device."); + 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(devlist[i]), - libusb_get_device_address(devlist[i]), NULL); + 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); - } else { + } + else { char *firmware; char *res_path = sr_get_firmware_res_path(); if (!(firmware = g_try_malloc(strlen(res_path)+strlen(prof->firmware)+1))) { @@ -298,7 +315,7 @@ static GSList *scan(GSList *options) } strcpy(firmware, res_path); strcat(firmware, prof->firmware); - if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, + if (ezusb_upload_firmware(device_handle, USB_CONFIGURATION, firmware) == SR_OK) /* Store when this device's FW was updated. */ devc->fw_updated = g_get_monotonic_time(); @@ -307,10 +324,11 @@ static GSList *scan(GSList *options) "device %d.", devcnt); g_free(firmware); sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(devlist[i]), + sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(device_handle), 0xff, NULL); } } + libusb_free_device_list(devlist, 1); g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); @@ -1813,6 +1831,12 @@ static int dev_close(struct sr_dev_inst *sdi) return ret; } +static int dev_destroy(struct sr_dev_inst *sdi) +{ + dsl_destroy_device(sdi); +} + + static int cleanup(void) { int ret; @@ -2077,6 +2101,7 @@ SR_PRIV struct sr_dev_driver DSCope_driver_info = { .config_list = config_list, .dev_open = dev_open, .dev_close = dev_close, + .dev_destroy = dev_destroy, .dev_status_get = dev_status_get, .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = dev_acquisition_stop, diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index e635aaeb..e51e967d 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -28,7 +28,7 @@ #include #undef LOG_PREFIX -#define LOG_PREFIX "DSL Hardware: " +#define LOG_PREFIX "dsl: " extern struct ds_trigger *trigger; @@ -290,6 +290,7 @@ SR_PRIV gboolean dsl_check_conf_profile(libusb_device *dev) static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) { libusb_device **devlist; + libusb_device *dev_handel=NULL; struct sr_usb_dev_inst *usb; struct libusb_device_descriptor des; struct DSL_context *devc; @@ -303,8 +304,13 @@ static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) devc = sdi->priv; usb = sdi->conn; + sr_info("%s", "Try to open device instance."); + + assert(usb->devhdl == NULL); + if (sdi->status == SR_ST_ACTIVE) { /* Device is already in use. */ + sr_info("%s", "Device is actived, can't to open."); return SR_ERR; } @@ -316,42 +322,55 @@ static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) return SR_ERR; } - for (i = 0; i < device_count; i++) { - if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { + 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) + || 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) { + } + 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. */ - if (libusb_get_bus_number(devlist[i]) != usb->bus - || libusb_get_device_address(devlist[i]) != usb->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. */ - continue; + sr_info("%s", "Font a device, but is not the one."); + continue; + } } - if (!(ret = libusb_open(devlist[i], &usb->devhdl))) { + 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(devlist[i]); - } else { + usb->address = libusb_get_device_address(dev_handel); + } + else { sr_err("Failed to open device: %s.", libusb_error_name(ret)); break; @@ -1831,15 +1850,17 @@ SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboo devc = sdi->priv; usb = sdi->conn; - + /* * If the firmware was recently uploaded, no dev_open operation should be called. * Just wait for renumerate -> detach -> attach */ ret = SR_ERR; if (devc->fw_updated > 0) { + sr_info("%s: Firmware upload have done."); return SR_ERR; - } else { + } + else { sr_info("%s: Firmware upload was not needed.", __func__); ret = hw_dev_open(di, sdi); } @@ -1848,6 +1869,8 @@ SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboo sr_err("%s: Unable to open device.", __func__); return SR_ERR; } + + assert(usb->devhdl); ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); if (ret != 0) { @@ -1886,6 +1909,7 @@ SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboo rd_cmd.header.size = 1; hw_info = 0; rd_cmd.data = &hw_info; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) { sr_err("Failed to get hardware infos."); return SR_ERR; @@ -1938,11 +1962,14 @@ SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi) struct sr_usb_dev_inst *usb; usb = sdi->conn; - if (usb->devhdl == NULL) + if (usb->devhdl == NULL){ + sr_info("%s", "dsl_dev_close(),Device handle is null."); return SR_ERR; + } sr_info("%s: Closing device %d on %d.%d interface %d.", sdi->driver->name, sdi->index, usb->bus, usb->address, USB_INTERFACE); + libusb_release_interface(usb->devhdl, USB_INTERFACE); libusb_close(usb->devhdl); usb->devhdl = NULL; @@ -2480,3 +2507,25 @@ SR_PRIV int dsl_start_transfers(const struct sr_dev_inst *sdi) return SR_OK; } + + +SR_PRIV int dsl_destroy_device(const struct sr_dev_inst *sdi) +{ + assert(sdi); + + struct sr_dev_driver *driver; + driver = sdi->driver; + + 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); + } + + sr_dev_inst_free(sdi); +} \ No newline at end of file diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index c601b4cc..bbda34b1 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -175,7 +175,7 @@ struct DSL_profile { enum libusb_speed usb_speed; const char *vendor; - const char *model; + const char *model; //product name const char *model_version; const char *firmware; @@ -1346,4 +1346,6 @@ SR_PRIV unsigned int dsl_get_timeout(const struct sr_dev_inst *sdi); SR_PRIV int dsl_start_transfers(const struct sr_dev_inst *sdi); SR_PRIV int dsl_header_size(const struct DSL_context *devc); +SR_PRIV int dsl_destroy_device(const struct sr_dev_inst *sdi); + #endif diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index c2862ffd..709f323a 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -268,11 +268,17 @@ static GSList *scan(GSList *options) GSList *l, *devices, *conn_devices; struct libusb_device_descriptor des; libusb_device **devlist; + libusb_device *device_handle = NULL; int devcnt, ret, i, j; const char *conn; enum libusb_speed usb_speed; drvc = di->priv; + + if (options != NULL) + sr_info("%s", "Scan DSLogic device with options."); + else + sr_info("%s", "Scan DSLogic device."); conn = NULL; for (l = options; l; l = l->next) { @@ -283,21 +289,27 @@ static GSList *scan(GSList *options) break; } } - if (conn) + if (conn){ + sr_info("%s", "Find usb device with connect config."); conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn); + } else conn_devices = NULL; /* Find all DSLogic compatible devices and upload firmware to them. */ devices = NULL; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); - for (i = 0; devlist[i]; i++) { + + for (i = 0; devlist[i]; i++) + { + device_handle = devlist[i]; + if (conn) { usb = NULL; for (l = conn_devices; l; l = l->next) { usb = l->data; - if (usb->bus == libusb_get_bus_number(devlist[i]) - && usb->address == libusb_get_device_address(devlist[i])) + if (usb->bus == libusb_get_bus_number(device_handle) + && usb->address == libusb_get_device_address(device_handle)) break; } if (!l) @@ -306,60 +318,66 @@ static GSList *scan(GSList *options) continue; } - if ((ret = libusb_get_device_descriptor( devlist[i], &des)) != 0) { + if ((ret = libusb_get_device_descriptor(device_handle, &des)) != 0) { sr_warn("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } - usb_speed = libusb_get_device_speed( devlist[i]); - if ((usb_speed != LIBUSB_SPEED_HIGH) && - (usb_speed != LIBUSB_SPEED_SUPER)) + usb_speed = libusb_get_device_speed(device_handle); + if ((usb_speed != LIBUSB_SPEED_HIGH) && (usb_speed != LIBUSB_SPEED_SUPER)){ continue; + } + /* Check manufactory id and product id, and speed type. */ prof = NULL; for (j = 0; supported_DSLogic[j].vid; j++) { if (des.idVendor == supported_DSLogic[j].vid && des.idProduct == supported_DSLogic[j].pid && usb_speed == supported_DSLogic[j].usb_speed) { prof = &supported_DSLogic[j]; + break; } } /* Skip if the device was not found. */ if (!prof) continue; + + sr_info("Got a 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, - prof->vendor, prof->model, prof->model_version); + 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); - //devices = g_slist_append(devices, sdi); /* Fill in probelist according to this device's profile. */ if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK) return NULL; - if (dsl_check_conf_profile(devlist[i])) { + if (dsl_check_conf_profile(device_handle)) { /* Already has the firmware, so fix the new address. */ - sr_info("Found an DSLogic device."); + 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(devlist[i]), - libusb_get_device_address(devlist[i]), NULL); + 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); - } else { + } + else { char *firmware; char *res_path = sr_get_firmware_res_path(); if (!(firmware = g_try_malloc(strlen(res_path)+strlen(prof->firmware)+1))) { @@ -368,7 +386,7 @@ static GSList *scan(GSList *options) } strcpy(firmware, res_path); strcat(firmware, prof->firmware); - if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, + if (ezusb_upload_firmware(device_handle, USB_CONFIGURATION, firmware) == SR_OK) /* Store when this device's FW was updated. */ devc->fw_updated = g_get_monotonic_time(); @@ -377,10 +395,11 @@ static GSList *scan(GSList *options) "device %d.", devcnt); g_free(firmware); sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(devlist[i]), + sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(device_handle), 0xff, NULL); } } + libusb_free_device_list(devlist, 1); g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); @@ -1175,6 +1194,11 @@ static int dev_close(struct sr_dev_inst *sdi) return ret; } +static int dev_destroy(struct sr_dev_inst *sdi) +{ + dsl_destroy_device(sdi); +} + static int cleanup(void) { int ret; @@ -1416,6 +1440,7 @@ SR_PRIV struct sr_dev_driver DSLogic_driver_info = { .config_list = config_list, .dev_open = dev_open, .dev_close = dev_close, + .dev_destroy = dev_destroy, .dev_status_get = dev_status_get, .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = dev_acquisition_stop, diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index 4e057705..e14764dc 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -144,6 +144,8 @@ static GSList *hw_scan(GSList *options) drvc = di->priv; devices = NULL; + sr_info("%s", "Scan demo device."); + if (!(devc = g_try_malloc(sizeof(struct demo_context)))) { sr_err("Device context malloc failed."); return NULL; @@ -170,6 +172,7 @@ static GSList *hw_scan(GSList *options) } sdi->priv = devc; sdi->driver = di; + sdi->dev_type = DEV_TYPE_DEMO; devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); @@ -236,6 +239,12 @@ static int hw_dev_close(struct sr_dev_inst *sdi) return SR_OK; } +static int dev_destroy(struct sr_dev_inst *sdi) +{ + hw_dev_close(sdi); + sr_dev_inst_free(sdi); +} + static int hw_cleanup(void) { GSList *l; @@ -1113,6 +1122,7 @@ SR_PRIV struct sr_dev_driver demo_driver_info = { .config_list = config_list, .dev_open = hw_dev_open, .dev_close = hw_dev_close, + .dev_destroy = dev_destroy, .dev_status_get = hw_dev_status_get, .dev_acquisition_start = hw_dev_acquisition_start, .dev_acquisition_stop = hw_dev_acquisition_stop, diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index 184cff9e..88a4fc7f 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -30,10 +30,7 @@ struct device_all_info #define SR_DEVICE_MAX_COUNT 100 static char DS_RES_PATH[500] = {0}; -static struct sr_context *var_sr_context = NULL; -static libsigrok_event_callback_t *var_event_callback = NULL; -static struct device_all_info* var_device_array[SR_DEVICE_MAX_COUNT] = {0}; -static int var_cur_device_count = 0; +static struct sr_context *g_sr_ctx = NULL; //----------------------------private function---------------- @@ -56,7 +53,11 @@ SR_API int sr_lib_init() struct sr_dev_driver **drivers = NULL; struct sr_dev_driver **dr = NULL; - ret = sr_init(&var_sr_context); + if (g_sr_ctx != NULL){ + return SR_ERR_HAVE_DONE; + } + + ret = sr_init(&g_sr_ctx); if (ret != SR_OK){ return ret; } @@ -64,7 +65,7 @@ SR_API int sr_lib_init() // Initialise all libsigrok drivers drivers = sr_driver_list(); for (dr = drivers; *dr; dr++) { - if (sr_driver_init(var_sr_context, *dr) != SR_OK) { + if (sr_driver_init(g_sr_ctx, *dr) != SR_OK) { sr_err("Failed to initialize driver '%s'", (*dr)->name); return SR_ERR; } @@ -80,26 +81,34 @@ SR_API int sr_lib_exit() { struct sr_dev_driver **drivers = NULL; struct sr_dev_driver **dr = NULL; - int i = 0; - - // free all device - for (i=0; ideiveList; 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); + } + } + g_safe_free_list(g_sr_ctx->deiveList); + + if (sr_exit(g_sr_ctx) != SR_OK){ + sr_err("%s", "call sr_exit error"); + } + g_sr_ctx = NULL; return SR_OK; } @@ -130,17 +139,11 @@ SR_PRIV char* sr_get_firmware_res_path() */ SR_API void sr_set_event_callback(libsigrok_event_callback_t *cb) { - var_event_callback = cb; -} - -/** - * When device attached or detached, scan all devices to get the new list. - * The current list will be changed - */ -SR_API int sr_device_scan_list() -{ - if (var_sr_context == NULL){ - sr_err("%s", "Must call 'sr_lib_init' first."); - return SR_ERR; + if (g_sr_ctx == NULL) + sr_lib_init(); + + if (g_sr_ctx != NULL){ + g_sr_ctx->event_callback = cb; } } + diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 9d44c671..7670f4b5 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -48,12 +48,45 @@ #undef max #define max(a,b) ((a)>(b)?(a):(b)) +#define g_safe_free(p) if((p)) g_free((p)); ((p)) = NULL; +#define g_safe_free_list(p) if((p)) g_slist_free((p)); ((p)) = NULL; + struct sr_context { - libusb_context *libusb_ctx; + libusb_context* libusb_ctx; libusb_hotplug_callback_handle hotplug_handle; hotplug_event_callback hotplug_callback; - void *hotplug_user_data; - struct timeval hotplug_tv; + void *hotplug_user_data; + struct timeval hotplug_tv; + libsigrok_event_callback_t event_callback; + GList *deiveList; // All device instance, sr_dev_inst* type +}; + +struct sr_session { + /** List of struct sr_dev pointers. */ + GSList *devs; + /** List of struct datafeed_callback pointers. */ + GSList *datafeed_callbacks; + gboolean running; + + unsigned int num_sources; + + /* + * Both "sources" and "pollfds" are of the same size and contain pairs + * of descriptor and callback function. We can not embed the GPollFD + * into the source struct since we want to be able to pass the array + * of all poll descriptors to g_poll(). + */ + struct source *sources; + GPollFD *pollfds; + int source_timeout; + + /* + * These are our synchronization primitives for stopping the session in + * an async fashion. We need to make sure the session is stopped from + * within the session thread itself. + */ + GMutex stop_mutex; + gboolean abort_session; }; struct sr_usb_dev_inst { diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 60f8e616..de793a93 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -66,17 +66,19 @@ extern "C" { /** Status/error codes returned by libsigrok functions. */ enum { SR_OK = 0, /**< No error. */ - SR_ERR = -1, /**< Generic/unspecified error. */ - SR_ERR_MALLOC = -2, /**< Malloc/calloc/realloc error. */ - SR_ERR_ARG = -3, /**< Function argument error. */ - SR_ERR_BUG = -4, /**< Errors hinting at internal bugs. */ - SR_ERR_SAMPLERATE = -5, /**< Incorrect samplerate. */ - SR_ERR_NA = -6, /**< Not applicable. */ - SR_ERR_DEV_CLOSED = -7, /**< Device is closed, but needs to be open. */ + SR_ERR = 1, /**< Generic/unspecified error. */ + SR_ERR_MALLOC = 2, /**< Malloc/calloc/realloc error. */ + SR_ERR_ARG = 3, /**< Function argument error. */ + SR_ERR_BUG = 4, /**< Errors hinting at internal bugs. */ + SR_ERR_SAMPLERATE = 5, /**< Incorrect samplerate. */ + SR_ERR_NA = 6, /**< Not applicable. */ + SR_ERR_DEV_CLOSED = 7, /**< Device is closed, but needs to be open. */ + SR_ERR_CALL_STATUS = 8, /**< Function call status error. */ + SR_ERR_HAVE_DONE = 9, /**< The Function have called.*/ /* * Note: When adding entries here, don't forget to also update the - * sr_strerror() and sr_strerror_name() functions in error.c. + * sr_error_str() and sr_error_name() functions in error.c. */ }; @@ -163,6 +165,14 @@ enum { #define USB_EV_HOTPLUG_ATTACH 1 #define USB_EV_HOTPLUG_DETTACH 2 +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, +}; /** Data types used by sr_config_info(). */ enum { @@ -1067,6 +1077,10 @@ enum sr_config_option_id{ 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. */ @@ -1201,6 +1215,7 @@ struct sr_dev_driver { /* 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, @@ -1211,35 +1226,7 @@ struct sr_dev_driver { /* Dynamic */ void *priv; }; - -struct sr_session { - /** List of struct sr_dev pointers. */ - GSList *devs; - /** List of struct datafeed_callback pointers. */ - GSList *datafeed_callbacks; - gboolean running; - - unsigned int num_sources; - - /* - * Both "sources" and "pollfds" are of the same size and contain pairs - * of descriptor and callback function. We can not embed the GPollFD - * into the source struct since we want to be able to pass the array - * of all poll descriptors to g_poll(). - */ - struct source *sources; - GPollFD *pollfds; - int source_timeout; - - /* - * These are our synchronization primitives for stopping the session in - * an async fashion. We need to make sure the session is stopped from - * within the session thread itself. - */ - GMutex stop_mutex; - gboolean abort_session; -}; - + enum { SIMPLE_TRIGGER = 0, ADV_TRIGGER, @@ -1327,7 +1314,7 @@ SR_API void sr_config_free(struct sr_config *src); /*--------------------session.c----------------*/ typedef void (*sr_datafeed_callback_t)(const struct sr_dev_inst *sdi, - const struct sr_datafeed_packet *packet, void *cb_data); + const struct sr_datafeed_packet *packet, void *cb_data); /* Session setup */ @@ -1376,20 +1363,12 @@ SR_API int sr_parse_voltage(const char *voltstr, uint64_t *p, uint64_t *q); /*--- version.c -------------------------------------------------------------*/ -SR_API int sr_package_version_major_get(void); -SR_API int sr_package_version_minor_get(void); -SR_API int sr_package_version_micro_get(void); -SR_API const char *sr_package_version_string_get(void); - -SR_API int sr_lib_version_current_get(void); -SR_API int sr_lib_version_revision_get(void); -SR_API int sr_lib_version_age_get(void); -SR_API const char *sr_lib_version_string_get(void); +SR_API const char *sr_get_lib_version_string(); /*--- error.c ---------------------------------------------------------------*/ -SR_API const char *sr_strerror(int error_code); -SR_API const char *sr_strerror_name(int error_code); +SR_API const char *sr_error_str(int error_code); +SR_API const char *sr_error_name(int error_code); /*--- trigger.c ------------------------------------------------------------*/ SR_API int ds_trigger_init(void); @@ -1423,21 +1402,20 @@ SR_API void sr_log_level(int level); /*---event define ---------------------------------------------*/ enum libsigrok_event_type { - // A new device attachs, user need calls sr_device_scan_list to update new list, - // And call sr_device_get_list to get new list, the last one is new. - // User can call sr_device_select to swith a new device. + // 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 device detachs, user need calls sr_device_scan_list to update new list, - // And call sr_device_get_list to get new list. - // User can call sr_device_select to swith a new device. + // 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, - // User can call sr_device_get_list to get new list. + // User can call sr_device_get_list to get new list, and update the data view. EV_CURRENT_DEVICE_CHANGED = 2, -}; -typedef unsigned long long sr_device_handle; + // User can call sr_device_get_list to get new list, and update the list view. + EV_DEVICE_LIST_CHANGED = 3, +}; /** * Device base info @@ -1446,8 +1424,7 @@ struct sr_device_info { sr_device_handle _handle; char _name[50]; - char _full_name[260]; - int _is_hardware; + int _dev_type; // enum sr_device_type int _is_current; //is actived }; @@ -1487,18 +1464,18 @@ SR_API int sr_lib_exit(); */ 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, + * the library will no longer manage data, it just forwards data. + */ +SR_API int sr_set_datafeed_callback(sr_datafeed_callback_t cb, void *cb_data); + /** * Set the firmware binary file directory, * User must call it to set the firmware resource directory */ SR_API void sr_set_firmware_resource_dir(const char *dir); -/** - * When device attached or detached, scan all devices to get the new list. - * The current list will be changed - */ -SR_API int sr_device_scan_list(); - /** * Get the device list, the last item is null. * Call free to release buffer. If the list is empty, it returns null. diff --git a/libsigrok4DSL/output/srzip.c b/libsigrok4DSL/output/srzip.c index fe32333d..24d52dd8 100755 --- a/libsigrok4DSL/output/srzip.c +++ b/libsigrok4DSL/output/srzip.c @@ -28,6 +28,7 @@ #include #include #include "../log.h" +#include "../version.h" struct out_context { uint64_t samplerate; @@ -166,7 +167,7 @@ static int create_archive(const struct sr_output *o) meta = g_key_file_new(); g_key_file_set_string(meta, "global", "sigrok version", - sr_package_version_string_get()); + SR_PACKAGE_VERSION_STRING); devgroup = "device 1"; logic_channels = 0; diff --git a/libsigrok4DSL/session.c b/libsigrok4DSL/session.c index 06d29f5c..1db07e78 100644 --- a/libsigrok4DSL/session.c +++ b/libsigrok4DSL/session.c @@ -365,7 +365,7 @@ SR_API int sr_session_start(void) sdi = l->data; if ((ret = sdi->driver->dev_acquisition_start(sdi, sdi)) != SR_OK) { sr_err("%s: could not start an acquisition " - "(%d)", __func__, sr_strerror(ret)); + "(%d)", __func__, sr_error_str(ret)); break; } } diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index 242b123c..670c1620 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -418,19 +418,27 @@ static int dev_open(struct sr_dev_inst *sdi) static int dev_close(struct sr_dev_inst *sdi) { - const struct session_vdev *const vdev = sdi->priv; - g_free(vdev->sessionfile); - g_free(vdev->capturefile); - g_free(vdev->buf); - if (vdev->logic_buf) - g_free(vdev->logic_buf); + struct session_vdev *vdev; - g_free(sdi->priv); - sdi->priv = NULL; + if (sdi && sdi->priv){ + vdev = sdi->priv; + g_safe_free(vdev->sessionfile); + g_safe_free(vdev->capturefile); + g_safe_free(vdev->buf); + g_safe_free(vdev->logic_buf); + g_safe_free(sdi->priv); + } return SR_OK; } +static int dev_destroy(struct sr_dev_inst *sdi) +{ + assert(sdi); + dev_close(sdi); + sr_dev_inst_free(sdi); +} + static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel *ch, const struct sr_channel_group *cg) @@ -1023,6 +1031,7 @@ SR_PRIV struct sr_dev_driver session_driver = { .config_list = config_list, .dev_open = dev_open, .dev_close = dev_close, + .dev_destroy = dev_destroy, .dev_status_get = dev_status_get, .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = NULL, diff --git a/libsigrok4DSL/session_file.c b/libsigrok4DSL/session_file.c index fe8990b9..97ac294a 100644 --- a/libsigrok4DSL/session_file.c +++ b/libsigrok4DSL/session_file.c @@ -154,6 +154,7 @@ SR_API int sr_session_load(const char *filename) } else if (!strcmp(keys[j], "capturefile")) { sdi = sr_dev_inst_new(mode, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL); sdi->driver = &session_driver; + sdi->dev_type = DEV_TYPE_FILELOG; if (devcnt == 0) /* first device, init the driver */ sdi->driver->init(NULL); diff --git a/libsigrok4DSL/version.c b/libsigrok4DSL/version.c index f5fe8d84..9d1b29bc 100644 --- a/libsigrok4DSL/version.c +++ b/libsigrok4DSL/version.c @@ -47,100 +47,7 @@ * @{ */ -/** - * Get the major libsigrok package version number. - * - * @return The major package version number. - * - * @since 0.1.0 - */ -SR_API int sr_package_version_major_get(void) -{ - return SR_PACKAGE_VERSION_MAJOR; -} - -/** - * Get the minor libsigrok package version number. - * - * @return The minor package version number. - * - * @since 0.1.0 - */ -SR_API int sr_package_version_minor_get(void) -{ - return SR_PACKAGE_VERSION_MINOR; -} - -/** - * Get the micro libsigrok package version number. - * - * @return The micro package version number. - * - * @since 0.1.0 - */ -SR_API int sr_package_version_micro_get(void) -{ - return SR_PACKAGE_VERSION_MICRO; -} - -/** - * Get the libsigrok package version number as a string. - * - * @return The package version number string. The returned string is - * static and thus should NOT be free'd by the caller. - * - * @since 0.1.0 - */ -SR_API const char *sr_package_version_string_get(void) -{ - return SR_PACKAGE_VERSION_STRING; -} - -/** - * Get the "current" part of the libsigrok library version number. - * - * @return The "current" library version number. - * - * @since 0.1.0 - */ -SR_API int sr_lib_version_current_get(void) -{ - return SR_LIB_VERSION_CURRENT; -} - -/** - * Get the "revision" part of the libsigrok library version number. - * - * @return The "revision" library version number. - * - * @since 0.1.0 - */ -SR_API int sr_lib_version_revision_get(void) -{ - return SR_LIB_VERSION_REVISION; -} - -/** - * Get the "age" part of the libsigrok library version number. - * - * @return The "age" library version number. - * - * @since 0.1.0 - */ -SR_API int sr_lib_version_age_get(void) -{ - return SR_LIB_VERSION_AGE; -} - -/** - * Get the libsigrok library version number as a string. - * - * @return The library version number string. The returned string is - * static and thus should NOT be free'd by the caller. - * - * @since 0.1.0 - */ -SR_API const char *sr_lib_version_string_get(void) +SR_API const char *sr_get_lib_version_string() { return SR_LIB_VERSION_STRING; } diff --git a/libsigrok4DSL/version.h b/libsigrok4DSL/version.h index 8597d4f8..fa7613fb 100644 --- a/libsigrok4DSL/version.h +++ b/libsigrok4DSL/version.h @@ -20,49 +20,9 @@ #ifndef LIBSIGROK_VERSION_H #define LIBSIGROK_VERSION_H -/** - * @file - * - * Version number definitions and macros. - */ - -/** - * @ingroup grp_versions - * - * @{ - */ - -/* - * Package version macros (can be used for conditional compilation). - */ - -/** The libsigrok package 'major' version number. */ -#define SR_PACKAGE_VERSION_MAJOR 0 - -/** The libsigrok package 'minor' version number. */ -#define SR_PACKAGE_VERSION_MINOR 2 - -/** The libsigrok package 'micro' version number. */ -#define SR_PACKAGE_VERSION_MICRO 0 - -/** The libsigrok package version ("major.minor.micro") as string. */ #define SR_PACKAGE_VERSION_STRING "0.2.0" -/* - * Library/libtool version macros (can be used for conditional compilation). - */ - -/** The libsigrok libtool 'current' version number. */ -#define SR_LIB_VERSION_CURRENT 1 - -/** The libsigrok libtool 'revision' version number. */ -#define SR_LIB_VERSION_REVISION 2 - -/** The libsigrok libtool 'age' version number. */ -#define SR_LIB_VERSION_AGE 0 - -/** The libsigrok libtool version ("current:revision:age") as string. */ -#define SR_LIB_VERSION_STRING "1:2:0" +#define SR_LIB_VERSION_STRING "1.3.0" /** @} */