1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Now able (hopefully) to unplug USB device from PC whilst the GCS is still connected to it via USB .. in WINDOWS ONLY.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2913 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
pip 2011-02-28 00:34:31 +00:00 committed by pip
parent 011abe3117
commit a2cf1c4673
4 changed files with 195 additions and 107 deletions

View File

@ -45,6 +45,7 @@ static const int WRITE_SIZE = 64;
// *********************************************************************************
/** /**
* Thread to desynchronize reading from the device * Thread to desynchronize reading from the device
@ -85,6 +86,8 @@ protected:
}; };
// *********************************************************************************
/** /**
* This class is nearly the same than RawHIDReadThread but for writing * This class is nearly the same than RawHIDReadThread but for writing
*/ */
@ -126,7 +129,7 @@ protected:
bool m_running; bool m_running;
}; };
// *********************************************************************************
RawHIDReadThread::RawHIDReadThread(RawHID *hid) RawHIDReadThread::RawHIDReadThread(RawHID *hid)
: m_hid(hid), : m_hid(hid),
@ -206,6 +209,8 @@ RawHIDWriteThread::RawHIDWriteThread(RawHID *hid)
{ {
} }
// *********************************************************************************
RawHIDWriteThread::~RawHIDWriteThread() RawHIDWriteThread::~RawHIDWriteThread()
{ {
m_running = false; m_running = false;
@ -283,20 +288,28 @@ qint64 RawHIDWriteThread::getBytesToWrite()
return m_writeBuffer.size(); return m_writeBuffer.size();
} }
// *********************************************************************************
RawHID::RawHID(const QString &deviceName) RawHID::RawHID(const QString &deviceName)
:QIODevice(), :QIODevice(),
serialNumber(deviceName), serialNumber(deviceName),
m_deviceNo(-1), m_deviceNo(-1),
m_readThread(NULL), m_readThread(NULL),
m_writeThread(NULL) m_writeThread(NULL),
m_mutex(NULL)
{ {
//find the device the user want to open and close the other m_mutex = new QMutex(QMutex::Recursive);
// detect if the USB device is unplugged
QObject::connect(&dev, SIGNAL(deviceUnplugged(int)), this, SLOT(onDeviceUnplugged(int)));
//find the device the user want to open and close the other
int opened = dev.open(USB_MAX_DEVICES, USB_VID, USB_PID, USB_USAGE_PAGE, USB_USAGE); int opened = dev.open(USB_MAX_DEVICES, USB_VID, USB_PID, USB_USAGE_PAGE, USB_USAGE);
//for each devices found, get serial number and close //for each devices found, get serial number and close
for (int i=0; i<opened; i++) for (int i = 0; i < opened; i++)
{ {
if(deviceName == dev.getserial(i)) if (deviceName == dev.getserial(i))
m_deviceNo = i; m_deviceNo = i;
else else
dev.close(i); dev.close(i);
@ -318,46 +331,72 @@ RawHID::RawHID(const QString &deviceName)
RawHID::~RawHID() RawHID::~RawHID()
{ {
if(m_readThread) dev.close(m_deviceNo);
if (m_readThread)
delete m_readThread; delete m_readThread;
if(m_writeThread) if (m_writeThread)
delete m_writeThread; delete m_writeThread;
} }
void RawHID::onDeviceUnplugged(int num)
{
if (num != m_deviceNo)
return;
// the USB device has been unplugged
close();
}
bool RawHID::open(OpenMode mode) bool RawHID::open(OpenMode mode)
{ {
if(m_deviceNo < 0) QMutexLocker locker(m_mutex);
if (m_deviceNo < 0)
return false; return false;
QIODevice::open(mode); QIODevice::open(mode);
if(!m_readThread) if (!m_readThread)
m_readThread = new RawHIDReadThread(this); m_readThread = new RawHIDReadThread(this);
if(!m_writeThread) if (!m_writeThread)
m_writeThread = new RawHIDWriteThread(this); m_writeThread = new RawHIDWriteThread(this);
if (m_readThread) m_readThread->start(); // Pip
if (m_writeThread) m_writeThread->start(); // Pip
return true; return true;
} }
void RawHID::close() void RawHID::close()
{ {
emit aboutToClose(); emit aboutToClose();
if(m_readThread) {
m_readThread->terminate();
delete m_readThread; // calls wait
m_readThread = NULL;
}
if(m_writeThread) { m_mutex->lock();
m_writeThread->terminate();
delete m_writeThread; if (m_readThread)
m_writeThread = NULL; {
} m_readThread->terminate();
delete m_readThread; // calls wait
m_readThread = NULL;
}
if (m_writeThread)
{
m_writeThread->terminate();
delete m_writeThread;
m_writeThread = NULL;
}
dev.close(m_deviceNo);
m_mutex->unlock();
emit closed();
dev.close(m_deviceNo);
QIODevice::close(); QIODevice::close();
} }
@ -368,21 +407,42 @@ bool RawHID::isSequential() const
qint64 RawHID::bytesAvailable() const qint64 RawHID::bytesAvailable() const
{ {
return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable(); QMutexLocker locker(m_mutex);
if (!m_readThread)
return -1;
return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable();
} }
qint64 RawHID::bytesToWrite() const qint64 RawHID::bytesToWrite() const
{ {
QMutexLocker locker(m_mutex);
if (!m_writeThread)
return -1;
return m_writeThread->getBytesToWrite() + QIODevice::bytesToWrite(); return m_writeThread->getBytesToWrite() + QIODevice::bytesToWrite();
} }
qint64 RawHID::readData(char *data, qint64 maxSize) qint64 RawHID::readData(char *data, qint64 maxSize)
{ {
return m_readThread->getReadData(data, maxSize); QMutexLocker locker(m_mutex);
if (!m_readThread || !data)
return -1;
return m_readThread->getReadData(data, maxSize);
} }
qint64 RawHID::writeData(const char *data, qint64 maxSize) qint64 RawHID::writeData(const char *data, qint64 maxSize)
{ {
return m_writeThread->pushDataToWrite(data, maxSize); QMutexLocker locker(m_mutex);
if (!m_writeThread || !data)
return -1;
return m_writeThread->pushDataToWrite(data, maxSize);
} }
// *********************************************************************************

View File

@ -1,77 +1,87 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file rawhid.h * @file rawhid.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup RawHIDPlugin Raw HID Plugin * @addtogroup RawHIDPlugin Raw HID Plugin
* @{ * @{
* @brief Impliments a HID USB connection to the flight hardware as a QIODevice * @brief Impliments a HID USB connection to the flight hardware as a QIODevice
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef RAWHID_H #ifndef RAWHID_H
#define RAWHID_H #define RAWHID_H
#include "rawhid_global.h" #include "rawhid_global.h"
#include <QThread> #include <QThread>
#include <QIODevice> #include <QIODevice>
#include <QMutex> #include <QMutex>
#include <QByteArray> #include <QByteArray>
#include "pjrc_rawhid.h" #include "pjrc_rawhid.h"
//helper classes //helper classes
class RawHIDReadThread; class RawHIDReadThread;
class RawHIDWriteThread; class RawHIDWriteThread;
/** /**
* The actual IO device that will be used to communicate * The actual IO device that will be used to communicate
* with the board. * with the board.
*/ */
class RAWHID_EXPORT RawHID : public QIODevice class RAWHID_EXPORT RawHID : public QIODevice
{ {
friend class RawHIDReadThread; Q_OBJECT
friend class RawHIDWriteThread;
friend class RawHIDReadThread;
public: friend class RawHIDWriteThread;
RawHID();
RawHID(const QString &deviceName); public:
virtual ~RawHID(); RawHID();
RawHID(const QString &deviceName);
virtual bool open(OpenMode mode); virtual ~RawHID();
virtual void close();
virtual bool isSequential() const; virtual bool open(OpenMode mode);
virtual void close();
protected: virtual bool isSequential() const;
virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize); signals:
virtual qint64 bytesAvailable() const; void closed();
virtual qint64 bytesToWrite() const;
public slots:
QString serialNumber; void onDeviceUnplugged(int num);
int m_deviceNo; protected:
pjrc_rawhid dev; virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize);
RawHIDReadThread *m_readThread; virtual qint64 bytesAvailable() const;
RawHIDWriteThread *m_writeThread; virtual qint64 bytesToWrite() const;
};
QString serialNumber;
#endif // RAWHID_H
int m_deviceNo;
pjrc_rawhid dev;
RawHIDReadThread *m_readThread;
RawHIDWriteThread *m_writeThread;
QMutex *m_mutex;
};
#endif // RAWHID_H

View File

@ -171,6 +171,17 @@ void RawHIDConnection::onRawHidDestroyed(QObject *obj) // Pip
RawHidHandle = NULL; RawHidHandle = NULL;
} }
void RawHIDConnection::onRawHidClosed()
{
if (RawHidHandle)
{
// delete RawHidHandle;
// RawHidHandle = NULL;
emit deviceClosed(this);
}
}
QIODevice *RawHIDConnection::openDevice(const QString &deviceName) QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
{ {
//added by andrew //added by andrew
@ -181,7 +192,11 @@ QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
//return new RawHID(deviceName); //return new RawHID(deviceName);
RawHidHandle = new RawHID(deviceName); RawHidHandle = new RawHID(deviceName);
connect(RawHidHandle, SLOT(destroyed(QObject *)), this, SLOT(onRawHidDestroyed(QObject *))); // Pip if (RawHidHandle)
{
connect(RawHidHandle, SIGNAL(closed()), this, SLOT(onRawHidClosed()), Qt::QueuedConnection);
connect(RawHidHandle, SIGNAL(destroyed(QObject *)), this, SLOT(onRawHidDestroyed(QObject *)), Qt::QueuedConnection);
}
return RawHidHandle; return RawHidHandle;
} }
@ -197,7 +212,7 @@ void RawHIDConnection::closeDevice(const QString &deviceName)
delete RawHidHandle; delete RawHidHandle;
RawHidHandle = NULL; RawHidHandle = NULL;
emit deviceClosed(this); // Pip emit deviceClosed(this);
} }
//end added by andrew //end added by andrew
} }

View File

@ -94,6 +94,9 @@ public:
signals: signals:
void deviceClosed(QObject *obj); // Pip void deviceClosed(QObject *obj); // Pip
public slots:
void onRawHidClosed();
protected slots: protected slots:
void onEnumerationChanged(); void onEnumerationChanged();