Skip to content

Commit

Permalink
Improved libusb (macOS, linux) backend message processing.
Browse files Browse the repository at this point in the history
* Handle closed command queues to improve firmware update reliability.
* Added device command queues to poll for improved performance.
* Handle all pending device commands with each pass.
  • Loading branch information
mliberty1 committed May 28, 2024
1 parent 0d79ac0 commit 9dee417
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 15 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
This file contains the list of changes made to the Joulescope driver.


## 1.5.3

2024 May 28

* Improved libusb (macOS, linux) backend message processing.
* Handle closed command queues to improve firmware update reliability.
* Added device command queues to poll for improved performance.
* Handle all pending device commands with each pass.


## 1.5.2

2024 May 8
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ else()
endif()

project(JOULESCOPE_DRIVER
VERSION 1.5.2
VERSION 1.5.3
LANGUAGES C)
SET(PROJECT_PREFIX JSDRV)
SET(VERSION_STRING "${PROJECT_VERSION}")
Expand Down
2 changes: 1 addition & 1 deletion include/jsdrv/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
*
* Changes in the patch version indicate bug fixes and improvements.
*/
#define JSDRV_VERSION_PATCH 2
#define JSDRV_VERSION_PATCH 3

/**
* \brief The maximum version string length.
Expand Down
2 changes: 1 addition & 1 deletion node_api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "joulescope_driver",
"version": "1.5.2",
"version": "1.5.3",
"description": "Interface with Joulescopes using node.js and Electron",
"keywords": [
"Joulescope",
Expand Down
2 changes: 1 addition & 1 deletion pyjoulescope_driver/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.


__version__ = "1.5.2"
__version__ = "1.5.3"

__title__ = "pyjoulescope_driver"
__description__ = 'Joulescope™ driver'
Expand Down
52 changes: 41 additions & 11 deletions src/backend/libusb/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ enum device_mark_e {
DEVICE_MARK_NONE = 0,
DEVICE_MARK_FOUND = 1,
DEVICE_MARK_ADDED = 2,
DEVICE_MARK_REMOVED = 3,
};

enum device_mode_e {
Expand Down Expand Up @@ -475,6 +474,7 @@ static bool device_handle_msg(struct dev_s * d, struct jsdrvp_msg_s * msg) {
msg->value = jsdrv_union_i32(rc);
msg_queue_push(d->ll_device.rsp_q, msg);
} else if (0 == strcmp(JSDRV_MSG_CLOSE, msg->topic)) {
JSDRV_LOGI("device_close(%s)", d->ll_device.prefix);
device_close(d);
msg->value = jsdrv_union_i32(0);
msg_queue_push(d->ll_device.rsp_q, msg);
Expand Down Expand Up @@ -506,12 +506,27 @@ static bool device_handle_msg(struct dev_s * d, struct jsdrvp_msg_s * msg) {
static void process_devices(struct backend_s * s) {
struct jsdrv_list_s * item;
struct dev_s * d;
struct jsdrvp_msg_s * msg;
struct jsdrvp_msg_s * msg = NULL;
jsdrv_list_foreach(&s->devices_active, item) {
d = JSDRV_CONTAINER_OF(item, struct dev_s, item);
msg = msg_queue_pop_immediate(d->ll_device.cmd_q);
device_handle_msg(d, msg);
do {
msg = msg_queue_pop_immediate(d->ll_device.cmd_q);
device_handle_msg(d, msg);
} while (NULL != msg);
}
jsdrv_list_foreach(&s->devices_free, item) {
d = JSDRV_CONTAINER_OF(item, struct dev_s, item);
while (1) {
msg = msg_queue_pop_immediate(d->ll_device.cmd_q);
if (NULL == msg) {
break;
}
JSDRV_LOGW("device closed, but message %s", msg->topic);
msg->value = jsdrv_union_i32(JSDRV_ERROR_CLOSED);
msg_queue_push(d->ll_device.rsp_q, msg);
};
}

}

static int32_t device_add(struct backend_s * s, libusb_device * usb_device, struct libusb_device_descriptor * descriptor) {
Expand Down Expand Up @@ -724,27 +739,42 @@ void * backend_thread(void * arg) {

while (!s->do_exit) {
nfds = 0;

// Add primary backend command queue descriptor.
fds[nfds].fd = msg_queue_handle_get(s->backend.cmd_q);
fds[nfds].events = POLLIN;
fds[nfds++].revents = 0;

// Add hotplug command queue descriptor.
fds[nfds].fd = s->hotplug_event->fd_poll;
fds[nfds].events = s->hotplug_event->events;
fds[nfds++].revents = 0;

// Add libusb file descriptors.
const struct libusb_pollfd ** libusb_fds = libusb_get_pollfds(s->ctx);
for (int i = 0; libusb_fds[i]; ++i) {
fds[nfds].fd = libusb_fds[i]->fd;
fds[nfds++].events = libusb_fds[i]->events;
fds[nfds].events = libusb_fds[i]->events;
fds[nfds++].revents = 0;
}
libusb_free_pollfds(libusb_fds);

rc = poll(fds, nfds, 10);
// Add file descriptors for each device command queue.
for (size_t i = 0; i < JSDRV_ARRAY_SIZE(s->devices); ++i) {
fds[nfds].fd = msg_queue_handle_get(s->devices[i].ll_device.cmd_q);
fds[nfds].events = POLLIN;
fds[nfds++].revents = 0;
}

if (nfds > JSDRV_ARRAY_SIZE(fds)) {
JSDRV_LOG_CRITICAL("nfds too large");
}

rc = poll(fds, nfds, 5000);
rc = libusb_handle_events_timeout_completed(s->ctx, &libusb_timeout_tv, NULL);
//if (fds[0].revents) {
while (handle_msg(s, msg_queue_pop_immediate(s->backend.cmd_q))) {
; //
}
//}
while (handle_msg(s, msg_queue_pop_immediate(s->backend.cmd_q))) {
; //
}
process_devices(s);
if (fds[1].revents) {
handle_hotplug(s);
Expand Down
3 changes: 3 additions & 0 deletions src/js220_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,9 @@ static int32_t d_close(struct dev_s * d) {
rv = JSDRV_ERROR_TIMED_OUT;
} else {
rv = m->value.value.i32;
if (JSDRV_ERROR_CLOSED == rv) {
rv = 0;
}
jsdrvp_msg_free(d->context, m);
}
for (uint32_t idx = 0; idx < JSDRV_ARRAY_SIZE(d->ports); ++idx) {
Expand Down

0 comments on commit 9dee417

Please sign in to comment.