fix: usb hotplug registor error on archlinux

This commit is contained in:
dreamsourcelabTAI 2022-02-14 14:07:00 +08:00
parent 012bcf78e6
commit f18df5288c
10 changed files with 119 additions and 46 deletions

View File

@ -74,6 +74,7 @@ bool AppControl::Init()
m_error = "DSView run ERROR: libsigrok init failed.";
return false;
}
_session->set_sr_context(sr_ctx);
QString resdir = GetResourceDir();
sr_set_firmware_resource_dir(resdir.toUtf8().data());

View File

@ -41,6 +41,7 @@
#include <QStandardPaths>
#include <QScreen>
#include <QTimer>
#include <libusb.h>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <QGuiApplication>

View File

@ -69,7 +69,6 @@ SigSession* SigSession::_session = NULL;
SigSession::SigSession(DeviceManager *device_manager)
{
_hotplug_handle = 0;
_dev_inst = NULL;
_device_manager = device_manager;
// TODO: This should not be necessary
@ -110,6 +109,8 @@ SigSession::SigSession(DeviceManager *device_manager)
_group_data = new data::Group();
_group_cnt = 0;
_sr_ctx = NULL;
_feed_timer.Stop();
_feed_timer.SetCallback(std::bind(&SigSession::feed_timeout, this));
}
@ -1205,44 +1206,40 @@ void SigSession::data_feed_in_proc(const struct sr_dev_inst *sdi,
/*
* hotplug function
*/
int SigSession::hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data) {
void SigSession::hotplug_callback(void *ctx, void *dev, int event, void *user_data) {
(void)ctx;
(void)dev;
(void)user_data;
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
if (1 == event) {
_session->_hot_attach = true;
qDebug("DreamSourceLab Hardware Attached!\n");
}else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
qDebug("receive event:DreamSourceLab Hardware attached!");
}else if (2 == event) {
_session->_hot_detach = true;
qDebug("DreamSourceLab Hardware Detached!\n");
qDebug("receive event:DreamSourceLab Hardware detached!");
}else{
qDebug("Unhandled event %d\n", event);
}
return 0;
}
void SigSession::hotplug_proc()
{
struct timeval tv;
{
if (!_dev_inst)
return;
tv.tv_sec = tv.tv_usec = 0;
return;
try {
while(_session && !_bHotplugStop) {
libusb_handle_events_timeout(NULL, &tv);
sr_hotplug_wait_timout(_sr_ctx);
if (_hot_attach) {
qDebug("DreamSourceLab hardware attached!");
qDebug("process event:DreamSourceLab hardware attached!");
_callback->device_attach();
_hot_attach = false;
}
if (_hot_detach) {
qDebug("DreamSourceLab hardware detached!");
qDebug("process event:DreamSourceLab hardware detached!");
_callback->device_detach();
_hot_detach = false;
}
@ -1256,25 +1253,14 @@ void SigSession::hotplug_proc()
void SigSession::register_hotplug_callback()
{
int ret;
ret = libusb_hotplug_register_callback(NULL,
(libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
(libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
0x2A0E,
LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY,
hotplug_callback,
NULL,
&_hotplug_handle);
if (LIBUSB_SUCCESS != ret){
qDebug() << "Error creating a hotplug callback,code:"<<ret;
if (sr_listen_hotplug(_sr_ctx, hotplug_callback, NULL) != 0){
qDebug() << "Error creating a hotplug callback,code:";
}
}
void SigSession::deregister_hotplug_callback()
{
libusb_hotplug_deregister_callback(NULL, _hotplug_handle);
sr_close_hotplug(_sr_ctx);
}
void SigSession::start_hotplug_work()
@ -1784,11 +1770,7 @@ void SigSession::set_stop_scale(float scale)
stop_hotplug_work();
if (_hotplug_handle)
{
deregister_hotplug_callback();
_hotplug_handle = 0;
}
deregister_hotplug_callback();
}
//append a decode task, and try create a thread

View File

@ -27,8 +27,7 @@
#include <string>
#include <vector>
#include <stdint.h>
#include <QString>
#include <libusb.h>
#include <QString>
#include <thread>
#include <QDateTime>
@ -258,6 +257,10 @@ public:
_callback->decode_done();
}
inline void set_sr_context(struct sr_context *ctx){
_sr_ctx = ctx;
}
private:
inline void data_updated(){
_callback->data_updated();
@ -321,8 +324,7 @@ private:
// thread for hotplug
void hotplug_proc();
static LIBUSB_CALL int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data);
static void hotplug_callback(void *ctx, void *dev, int event, void *user_data);
public:
void reload();
@ -373,9 +375,7 @@ private:
data::Analog *_analog_data;
data::Group *_group_data;
int _group_cnt;
libusb_hotplug_callback_handle _hotplug_handle;
bool _hot_attach;
bool _hot_detach;
@ -409,6 +409,7 @@ private:
bool _dso_feed;
float _stop_scale;
bool _bClose;
struct sr_context *_sr_ctx;
ISessionCallback *_callback;

View File

@ -28,6 +28,7 @@
#include <QLabel>
#include <QAbstractItemView>
#include <math.h>
#include <libusb.h>
#include "../devicemanager.h"
#include "../device/devinst.h"

View File

@ -30,9 +30,10 @@ Requirements
Building and installing
-----------------------
Step1: Get the DSView source code
Step1: Get the DSView source code, and switch to right branch, the newest branch is dev-tai
$ git clone git://github.com/DreamSourceLab/DSView
Step2: Installing the requirements:

View File

@ -355,6 +355,13 @@ SR_API int sr_init(struct sr_context **ctx)
goto done;
}
context->libusb_ctx = NULL;
context->hotplug_handle = 0;
context->hotplug_callback = NULL;
context->hotplug_user_data = NULL;
context->hotplug_tv.tv_sec = 0;
context->hotplug_tv.tv_usec = 0;
#ifdef HAVE_LIBUSB_1_0
ret = libusb_init(&context->libusb_ctx);
if (LIBUSB_SUCCESS != ret) {
@ -401,4 +408,73 @@ SR_API int sr_exit(struct sr_context *ctx)
return SR_OK;
}
LIBUSB_CALL int sr_hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data){
if (user_data == NULL){
sr_err("%s(): libsigrok usb event callback, userdata is NULL.", __func__);
return 0;
}
struct sr_context *user_ctx = (struct sr_context*)user_data;
if (user_ctx->hotplug_callback != NULL){
user_ctx->hotplug_callback(ctx, dev, (int)event, user_ctx->hotplug_user_data);
}
return 0;
}
SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback callback, void *userdata)
{
int ret;
if (!ctx) {
sr_err("%s(): libsigrok context was NULL.", __func__);
return SR_ERR;
}
if (callback == NULL){
sr_err("%s(): callback was NULL.", __func__);
return SR_ERR;
}
ctx->hotplug_callback = callback;
ctx->hotplug_user_data = userdata;
ret = libusb_hotplug_register_callback(ctx->libusb_ctx,
(libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
(libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
0x2A0E,
LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY,
(libusb_hotplug_callback_fn)sr_hotplug_callback,
ctx,
&ctx->hotplug_handle);
if (LIBUSB_SUCCESS != ret){
return -1;
}
return 0;
}
SR_API int sr_close_hotplug(struct sr_context *ctx)
{
if (!ctx) {
sr_err("%s(): libsigrok context was NULL.", __func__);
return SR_ERR;
}
libusb_hotplug_deregister_callback(ctx->libusb_ctx, ctx->hotplug_handle);
return 0;
}
SR_API void sr_hotplug_wait_timout(struct sr_context *ctx)
{
if (!ctx) {
sr_err("%s(): libsigrok context was NULL.", __func__);
return SR_ERR;
}
libusb_handle_events_timeout(ctx->libusb_ctx, &ctx->hotplug_tv);
}
/** @} */

View File

@ -49,6 +49,10 @@ extern char DS_RES_PATH[500];
struct sr_context {
#ifdef HAVE_LIBUSB_1_0
libusb_context *libusb_ctx;
libusb_hotplug_callback_handle hotplug_handle;
hotplug_event_callback hotplug_callback;
void *hotplug_user_data;
struct timeval hotplug_tv;
#endif
};

View File

@ -339,7 +339,7 @@ enum {
SR_PKT_DATA_ERROR,
};
struct sr_context;
struct sr_context; //hidden all field
struct sr_datafeed_packet {
uint16_t type;

View File

@ -28,8 +28,14 @@
/*--- backend.c -------------------------------------------------------------*/
//@event, 1:attach, 2:left
typedef void (*hotplug_event_callback)(void *context,void *device, int event, void *userdata);
SR_API int sr_init(struct sr_context **ctx);
SR_API int sr_exit(struct sr_context *ctx);
SR_API int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback callback, void *userdata);
SR_API int sr_close_hotplug(struct sr_context *ctx);
SR_API void sr_hotplug_wait_timout(struct sr_context *ctx);
/*--- log.c -----------------------------------------------------------------*/