mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
GCS USB: More the opening and closing code into the read
thread to simplify some threading issues on OSX. Should not influence other operating systems.
This commit is contained in:
parent
b84f833287
commit
06fc1ed963
@ -117,7 +117,7 @@ pjrc_rawhid::~pjrc_rawhid()
|
||||
//
|
||||
int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
|
||||
{
|
||||
static IOHIDManagerRef hid_manager=NULL;
|
||||
IOHIDManagerRef hid_manager=NULL;
|
||||
CFMutableDictionaryRef dict;
|
||||
CFNumberRef num;
|
||||
IOReturn ret;
|
||||
@ -439,7 +439,7 @@ static void hid_close(hid_t *hid)
|
||||
IOHIDManagerRef hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL);
|
||||
IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL);
|
||||
IOHIDDeviceUnscheduleFromRunLoop(hid->ref, CFRunLoopGetCurrent( ), kCFRunLoopDefaultMode);
|
||||
IOHIDDeviceUnscheduleFromRunLoop(hid->ref, the_correct_runloop, kCFRunLoopDefaultMode);
|
||||
IOHIDDeviceClose(hid->ref, kIOHIDOptionsTypeNone);
|
||||
IOHIDManagerClose(hid_manager, 0);
|
||||
hid->ref = NULL;
|
||||
@ -463,7 +463,6 @@ static void attach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDevic
|
||||
{
|
||||
struct hid_struct *h;
|
||||
|
||||
printf("attach callback\n");
|
||||
if (IOHIDDeviceOpen(dev, kIOHIDOptionsTypeNone) != kIOReturnSuccess) return;
|
||||
h = (hid_t *)malloc(sizeof(hid_t));
|
||||
if (!h) return;
|
||||
|
@ -138,6 +138,7 @@ RawHIDReadThread::RawHIDReadThread(RawHID *hid)
|
||||
hidno(hid->m_deviceNo),
|
||||
m_running(true)
|
||||
{
|
||||
hid->m_startedMutex->lock();
|
||||
}
|
||||
|
||||
RawHIDReadThread::~RawHIDReadThread()
|
||||
@ -151,6 +152,7 @@ RawHIDReadThread::~RawHIDReadThread()
|
||||
void RawHIDReadThread::run()
|
||||
{
|
||||
qDebug() << "Read thread started";
|
||||
m_running = m_hid->openDevice();
|
||||
while(m_running)
|
||||
{
|
||||
//here we use a temporary buffer so we don't need to lock
|
||||
@ -182,6 +184,7 @@ void RawHIDReadThread::run()
|
||||
m_running=false;
|
||||
}
|
||||
}
|
||||
m_hid->closeDevice();
|
||||
}
|
||||
|
||||
int RawHIDReadThread::getReadData(char *data, int size)
|
||||
@ -301,13 +304,29 @@ RawHID::RawHID(const QString &deviceName)
|
||||
{
|
||||
|
||||
m_mutex = new QMutex(QMutex::Recursive);
|
||||
m_startedMutex = new QMutex();
|
||||
|
||||
// detect if the USB device is unplugged
|
||||
QObject::connect(&dev, SIGNAL(deviceUnplugged(int)), this, SLOT(onDeviceUnplugged(int)));
|
||||
|
||||
// Starting the read thread will lock the m_startexMutex until the
|
||||
// device is opened
|
||||
m_readThread = new RawHIDReadThread(this);
|
||||
m_readThread->start();
|
||||
|
||||
m_startedMutex->lock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RawHID::openDevice This method opens the USB connection
|
||||
* It is uses as a callback from the read thread so that the USB
|
||||
* system code is registered in that thread instead of the calling
|
||||
* thread (usually UI)
|
||||
*/
|
||||
bool RawHID::openDevice() {
|
||||
int opened = dev.open(USB_MAX_DEVICES, USBMonitor::idVendor_OpenPilot, -1, USB_USAGE_PAGE, USB_USAGE);
|
||||
for (int i =0; i< opened; i++) {
|
||||
if (deviceName == dev.getserial(i))
|
||||
if (serialNumber == dev.getserial(i))
|
||||
m_deviceNo = i;
|
||||
else
|
||||
dev.close(i);
|
||||
@ -316,27 +335,31 @@ RawHID::RawHID(const QString &deviceName)
|
||||
//didn't find the device we are trying to open (shouldnt happen)
|
||||
if (opened < 0)
|
||||
{
|
||||
qDebug() << "Error: cannot open device " << deviceName;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
//m_deviceNo = 0;
|
||||
m_readThread = new RawHIDReadThread(this);
|
||||
m_writeThread = new RawHIDWriteThread(this);
|
||||
|
||||
m_readThread->start();
|
||||
m_writeThread->start();
|
||||
|
||||
m_startedMutex->unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RawHID::closeDevice This method closes the USB connection
|
||||
* It is uses as a callback from the read thread so that the USB
|
||||
* system code is unregistered from that thread\
|
||||
*/
|
||||
bool RawHID::closeDevice() {
|
||||
dev.close(m_deviceNo);
|
||||
}
|
||||
|
||||
RawHID::~RawHID()
|
||||
{
|
||||
dev.close(m_deviceNo);
|
||||
|
||||
if (m_readThread)
|
||||
delete m_readThread;
|
||||
|
||||
if (m_writeThread)
|
||||
delete m_writeThread;
|
||||
// If the read thread exists then the device is open
|
||||
if (m_readThread)
|
||||
close();
|
||||
}
|
||||
|
||||
void RawHID::onDeviceUnplugged(int num)
|
||||
@ -345,7 +368,6 @@ void RawHID::onDeviceUnplugged(int num)
|
||||
return;
|
||||
|
||||
// the USB device has been unplugged
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
@ -372,13 +394,6 @@ void RawHID::close()
|
||||
|
||||
m_mutex->lock();
|
||||
|
||||
if (m_readThread)
|
||||
{
|
||||
m_readThread->terminate();
|
||||
delete m_readThread; // calls wait
|
||||
m_readThread = NULL;
|
||||
}
|
||||
|
||||
if (m_writeThread)
|
||||
{
|
||||
m_writeThread->terminate();
|
||||
@ -386,7 +401,13 @@ void RawHID::close()
|
||||
m_writeThread = NULL;
|
||||
}
|
||||
|
||||
dev.close(m_deviceNo);
|
||||
|
||||
if (m_readThread)
|
||||
{
|
||||
m_readThread->terminate();
|
||||
delete m_readThread; // calls wait
|
||||
m_readThread = NULL;
|
||||
}
|
||||
|
||||
m_mutex->unlock();
|
||||
|
||||
|
@ -74,6 +74,12 @@ protected:
|
||||
virtual qint64 bytesAvailable() const;
|
||||
virtual qint64 bytesToWrite() const;
|
||||
|
||||
//! Callback from the read thread to open the device
|
||||
bool openDevice();
|
||||
|
||||
//! Callback from teh read thread to close the device
|
||||
bool closeDevice();
|
||||
|
||||
QString serialNumber;
|
||||
|
||||
int m_deviceNo;
|
||||
@ -83,6 +89,7 @@ protected:
|
||||
RawHIDWriteThread *m_writeThread;
|
||||
|
||||
QMutex *m_mutex;
|
||||
QMutex *m_startedMutex;
|
||||
};
|
||||
|
||||
#endif // RAWHID_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user