summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndre Hartmann <aha_1980@gmx.de>2018-10-02 11:41:16 +0200
committerAndré Hartmann <aha_1980@gmx.de>2019-05-02 11:15:05 +0000
commita88ecda86028228174a1ec4e53df235ebac33dcc (patch)
tree9a39dfe2e0e85310c0450fef9be15120f9dd7ba1 /src
parent4a7f051247b05e1e298ffabc00e8ce3dc3e216a0 (diff)
Add QCanBusDevice::resetController() for CAN controller reset
Currently missing: * VectorCAN: no information in the documentation found * PassthroughCAN: no documentation [ChangeLog][QCanBus][QCanBusDevice] Added the function QCanBusDevice::resetController() to reset a CAN controller from bus off state, as far as supported by the various plugins. Fixes: QTBUG-54943 Change-Id: Ic098054b012726c0c69970c0ae84f434c2b3964a Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/canbus/peakcan/peakcanbackend.cpp9
-rw-r--r--src/plugins/canbus/peakcan/peakcanbackend.h2
-rw-r--r--src/plugins/canbus/socketcan/socketcanbackend.cpp8
-rw-r--r--src/plugins/canbus/socketcan/socketcanbackend.h1
-rw-r--r--src/plugins/canbus/systeccan/systeccan_symbols_p.h2
-rw-r--r--src/plugins/canbus/systeccan/systeccanbackend.cpp14
-rw-r--r--src/plugins/canbus/systeccan/systeccanbackend.h2
-rw-r--r--src/plugins/canbus/systeccan/systeccanbackend_p.h1
-rw-r--r--src/plugins/canbus/tinycan/tinycanbackend.cpp24
-rw-r--r--src/plugins/canbus/tinycan/tinycanbackend.h2
-rw-r--r--src/plugins/canbus/tinycan/tinycanbackend_p.h1
-rw-r--r--src/serialbus/doc/src/peakcan.qdoc7
-rw-r--r--src/serialbus/doc/src/socketcan.qdoc9
-rw-r--r--src/serialbus/doc/src/systeccan.qdoc7
-rw-r--r--src/serialbus/doc/src/tinycan.qdoc9
-rw-r--r--src/serialbus/qcanbusdevice.cpp36
-rw-r--r--src/serialbus/qcanbusdevice.h6
-rw-r--r--src/serialbus/qcanbusdevice_p.h2
18 files changed, 138 insertions, 4 deletions
diff --git a/src/plugins/canbus/peakcan/peakcanbackend.cpp b/src/plugins/canbus/peakcan/peakcanbackend.cpp
index 2f4097e..30d3b8c 100644
--- a/src/plugins/canbus/peakcan/peakcanbackend.cpp
+++ b/src/plugins/canbus/peakcan/peakcanbackend.cpp
@@ -717,6 +717,9 @@ PeakCanBackend::PeakCanBackend(const QString &name, QObject *parent)
d->setupChannel(name.toLatin1());
d->setupDefaultConfigurations();
+
+ std::function<void()> f = std::bind(&PeakCanBackend::resetController, this);
+ setResetControllerFunction(f);
}
PeakCanBackend::~PeakCanBackend()
@@ -808,4 +811,10 @@ QString PeakCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame)
return QString();
}
+void PeakCanBackend::resetController()
+{
+ close();
+ open();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/canbus/peakcan/peakcanbackend.h b/src/plugins/canbus/peakcan/peakcanbackend.h
index 7f7083e..6a9cda2 100644
--- a/src/plugins/canbus/peakcan/peakcanbackend.h
+++ b/src/plugins/canbus/peakcan/peakcanbackend.h
@@ -72,6 +72,8 @@ public:
static QList<QCanBusDeviceInfo> interfaces();
private:
+ void resetController();
+
PeakCanBackendPrivate * const d_ptr;
};
diff --git a/src/plugins/canbus/socketcan/socketcanbackend.cpp b/src/plugins/canbus/socketcan/socketcanbackend.cpp
index cac1db5..9e99a57 100644
--- a/src/plugins/canbus/socketcan/socketcanbackend.cpp
+++ b/src/plugins/canbus/socketcan/socketcanbackend.cpp
@@ -194,6 +194,9 @@ SocketCanBackend::SocketCanBackend(const QString &name) :
}
resetConfigurations();
+
+ std::function<void()> f = std::bind(&SocketCanBackend::resetController, this);
+ setResetControllerFunction(f);
}
SocketCanBackend::~SocketCanBackend()
@@ -750,4 +753,9 @@ void SocketCanBackend::readSocket()
enqueueReceivedFrames(newFrames);
}
+void SocketCanBackend::resetController()
+{
+ libSocketCan->restart(canSocketName);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/canbus/socketcan/socketcanbackend.h b/src/plugins/canbus/socketcan/socketcanbackend.h
index 1392251..561d4ee 100644
--- a/src/plugins/canbus/socketcan/socketcanbackend.h
+++ b/src/plugins/canbus/socketcan/socketcanbackend.h
@@ -83,6 +83,7 @@ private:
void resetConfigurations();
bool connectSocket();
bool applyConfigurationParameter(int key, const QVariant &value);
+ void resetController();
canfd_frame m_frame;
sockaddr_can m_address;
diff --git a/src/plugins/canbus/systeccan/systeccan_symbols_p.h b/src/plugins/canbus/systeccan/systeccan_symbols_p.h
index 102817c..8a36327 100644
--- a/src/plugins/canbus/systeccan/systeccan_symbols_p.h
+++ b/src/plugins/canbus/systeccan/systeccan_symbols_p.h
@@ -280,6 +280,7 @@ GENERATE_SYMBOL_VARIABLE(UCANRET, UcanDeinitHardware, tUcanHandle)
GENERATE_SYMBOL_VARIABLE(UCANRET, UcanInitCanEx2, tUcanHandle, quint8 /* channel */, tUcanInitCanParam *)
GENERATE_SYMBOL_VARIABLE(UCANRET, UcanDeinitCanEx, tUcanHandle, quint8 /* channel */)
GENERATE_SYMBOL_VARIABLE(UCANRET, UcanReadCanMsgEx, tUcanHandle, quint8 *, tCanMsgStruct *, quint32 *)
+GENERATE_SYMBOL_VARIABLE(UCANRET, UcanResetCan, tUcanHandle)
GENERATE_SYMBOL_VARIABLE(UCANRET, UcanWriteCanMsgEx, tUcanHandle, quint8, tCanMsgStruct *, quint32 *)
inline bool resolveSymbols(QLibrary *systecLibrary)
@@ -300,6 +301,7 @@ inline bool resolveSymbols(QLibrary *systecLibrary)
RESOLVE_SYMBOL(UcanInitCanEx2);
RESOLVE_SYMBOL(UcanDeinitCanEx);
RESOLVE_SYMBOL(UcanReadCanMsgEx);
+ RESOLVE_SYMBOL(UcanResetCan);
RESOLVE_SYMBOL(UcanWriteCanMsgEx);
return true;
diff --git a/src/plugins/canbus/systeccan/systeccanbackend.cpp b/src/plugins/canbus/systeccan/systeccanbackend.cpp
index 3fdd135..54666d0 100644
--- a/src/plugins/canbus/systeccan/systeccanbackend.cpp
+++ b/src/plugins/canbus/systeccan/systeccanbackend.cpp
@@ -454,6 +454,11 @@ bool SystecCanBackendPrivate::verifyBitRate(int bitrate)
return true;
}
+void SystecCanBackendPrivate::resetController()
+{
+ ::UcanResetCan(handle);
+}
+
SystecCanBackend::SystecCanBackend(const QString &name, QObject *parent) :
QCanBusDevice(parent),
d_ptr(new SystecCanBackendPrivate(this))
@@ -462,6 +467,9 @@ SystecCanBackend::SystecCanBackend(const QString &name, QObject *parent) :
d->setupChannel(name);
d->setupDefaultConfigurations();
+
+ std::function<void()> f = std::bind(&SystecCanBackend::resetController, this);
+ setResetControllerFunction(f);
}
SystecCanBackend::~SystecCanBackend()
@@ -553,4 +561,10 @@ QString SystecCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame)
return QString();
}
+void SystecCanBackend::resetController()
+{
+ Q_D(SystecCanBackend);
+ d->resetController();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/canbus/systeccan/systeccanbackend.h b/src/plugins/canbus/systeccan/systeccanbackend.h
index cb62808..68dcfb9 100644
--- a/src/plugins/canbus/systeccan/systeccanbackend.h
+++ b/src/plugins/canbus/systeccan/systeccanbackend.h
@@ -76,6 +76,8 @@ public:
int channelNumber);
private:
+ void resetController();
+
SystecCanBackendPrivate * const d_ptr;
};
diff --git a/src/plugins/canbus/systeccan/systeccanbackend_p.h b/src/plugins/canbus/systeccan/systeccanbackend_p.h
index 28eb7ff..b938c74 100644
--- a/src/plugins/canbus/systeccan/systeccanbackend_p.h
+++ b/src/plugins/canbus/systeccan/systeccanbackend_p.h
@@ -94,6 +94,7 @@ public:
void startWrite();
void readAllReceivedMessages();
bool verifyBitRate(int bitrate);
+ void resetController();
SystecCanBackend * const q_ptr;
diff --git a/src/plugins/canbus/tinycan/tinycanbackend.cpp b/src/plugins/canbus/tinycan/tinycanbackend.cpp
index 882cb47..411b917 100644
--- a/src/plugins/canbus/tinycan/tinycanbackend.cpp
+++ b/src/plugins/canbus/tinycan/tinycanbackend.cpp
@@ -405,8 +405,7 @@ void TinyCanBackendPrivate::startRead()
} else {
if (status.CanStatus == CAN_STATUS_BUS_OFF) {
qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "CAN bus is in off state, trying to reset the bus.");
- if (::CanSetMode(channelIndex, OP_CAN_RESET, CAN_CMD_NONE) < 0)
- q->setError(systemErrorString(ret), QCanBusDevice::CanBusError::ReadError);
+ resetController();
}
}
@@ -468,6 +467,18 @@ void TinyCanBackendPrivate::cleanupDriver()
}
}
+void TinyCanBackendPrivate::resetController()
+{
+ Q_Q(TinyCanBackend);
+ qint32 ret = ::CanSetMode(channelIndex, OP_CAN_RESET, CAN_CMD_NONE);
+ if (Q_UNLIKELY(ret < 0)) {
+ const QString errorString = systemErrorString(ret);
+ qCWarning(QT_CANBUS_PLUGINS_TINYCAN, "Cannot perform hardware reset: %ls",
+ qUtf16Printable(errorString));
+ q->setError(errorString, QCanBusDevice::CanBusError::ConfigurationError);
+ }
+}
+
bool TinyCanBackendPrivate::setBitRate(int bitrate)
{
Q_Q(TinyCanBackend);
@@ -498,6 +509,9 @@ TinyCanBackend::TinyCanBackend(const QString &name, QObject *parent)
d->setupChannel(name);
d->setupDefaultConfigurations();
+
+ std::function<void()> f = std::bind(&TinyCanBackend::resetController, this);
+ setResetControllerFunction(f);
}
TinyCanBackend::~TinyCanBackend()
@@ -591,4 +605,10 @@ QString TinyCanBackend::interpretErrorFrame(const QCanBusFrame &errorFrame)
return QString();
}
+void TinyCanBackend::resetController()
+{
+ Q_D(TinyCanBackend);
+ d->resetController();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/canbus/tinycan/tinycanbackend.h b/src/plugins/canbus/tinycan/tinycanbackend.h
index 5f504ca..428e9bc 100644
--- a/src/plugins/canbus/tinycan/tinycanbackend.h
+++ b/src/plugins/canbus/tinycan/tinycanbackend.h
@@ -72,6 +72,8 @@ public:
static QList<QCanBusDeviceInfo> interfaces();
private:
+ void resetController();
+
TinyCanBackendPrivate * const d_ptr;
};
diff --git a/src/plugins/canbus/tinycan/tinycanbackend_p.h b/src/plugins/canbus/tinycan/tinycanbackend_p.h
index 905175c..25316a2 100644
--- a/src/plugins/canbus/tinycan/tinycanbackend_p.h
+++ b/src/plugins/canbus/tinycan/tinycanbackend_p.h
@@ -75,6 +75,7 @@ public:
void startRead();
void startupDriver();
void cleanupDriver();
+ void resetController();
bool setBitRate(int bitrate);
diff --git a/src/serialbus/doc/src/peakcan.qdoc b/src/serialbus/doc/src/peakcan.qdoc
index a3d848d..e6ce7ee 100644
--- a/src/serialbus/doc/src/peakcan.qdoc
+++ b/src/serialbus/doc/src/peakcan.qdoc
@@ -105,4 +105,11 @@
100000, 125000, 250000, 500000, 800000, 1000000. Note that this configuration
parameter can only be adjusted while the QCanBusDevice is not connected.
\endtable
+
+ PeakCAN supports the following additional functions:
+
+ \list
+ \li QCanBusDevice::resetController()
+ \endlist
+
*/
diff --git a/src/serialbus/doc/src/socketcan.qdoc b/src/serialbus/doc/src/socketcan.qdoc
index 9ae778d..82a00c8 100644
--- a/src/serialbus/doc/src/socketcan.qdoc
+++ b/src/serialbus/doc/src/socketcan.qdoc
@@ -203,4 +203,11 @@
\snippet snippetmain.cpp SocketCan Filter Example
Extended frame format and flexible data-rate are supported in SocketCAN.
- */
+
+ SocketCAN supports the following additional functions:
+
+ \list
+ \li QCanBusDevice::resetController() (needs libsocketcan)
+ \endlist
+
+*/
diff --git a/src/serialbus/doc/src/systeccan.qdoc b/src/serialbus/doc/src/systeccan.qdoc
index af34665..66ce7c7 100644
--- a/src/serialbus/doc/src/systeccan.qdoc
+++ b/src/serialbus/doc/src/systeccan.qdoc
@@ -109,4 +109,11 @@
is disabled by default. If this option is enabled, the therefore received frames
are marked with QCanBusFrame::hasLocalEcho()
\endtable
+
+ SystecCAN supports the following additional functions:
+
+ \list
+ \li QCanBusDevice::resetController()
+ \endlist
+
*/
diff --git a/src/serialbus/doc/src/tinycan.qdoc b/src/serialbus/doc/src/tinycan.qdoc
index 43349dc..8479576 100644
--- a/src/serialbus/doc/src/tinycan.qdoc
+++ b/src/serialbus/doc/src/tinycan.qdoc
@@ -95,4 +95,11 @@
\li Determines the bit rate of the CAN bus connection. The following bit rates
are supported: 10000, 20000, 50000, 100000, 125000, 250000, 500000, 800000, 1000000.
\endtable
- */
+
+ TinyCAN supports the following additional functions:
+
+ \list
+ \li QCanBusDevice::resetController()
+ \endlist
+
+*/
diff --git a/src/serialbus/qcanbusdevice.cpp b/src/serialbus/qcanbusdevice.cpp
index 22f9d20..2bdec02 100644
--- a/src/serialbus/qcanbusdevice.cpp
+++ b/src/serialbus/qcanbusdevice.cpp
@@ -317,6 +317,17 @@ bool QCanBusDevice::hasOutgoingFrames() const
}
/*!
+ * Called from the derived plugin to register a function that performs the
+ * CAN controller hardware reset when \a resetController() is called.
+ */
+void QCanBusDevice::setResetControllerFunction(std::function<void()> &resetter)
+{
+ Q_D(QCanBusDevice);
+
+ d->m_resetControllerFunction = resetter;
+}
+
+/*!
Sets the configuration parameter \a key for the CAN bus connection
to \a value. The potential keys are represented by \l ConfigurationKey.
@@ -442,6 +453,31 @@ qint64 QCanBusDevice::framesToWrite() const
}
/*!
+ \since 5.14
+
+ Performs a CAN controller reset to release the CAN controller from
+ bus off state, if possible.
+
+ \note CAN controller resets disturb the running communication and
+ may take up to one second to complete. Only call this function to
+ recover from bus errors.
+
+ \note This function may not be implemented in all CAN plugins.
+ Please refer to the plugins help pages for more information.
+*/
+void QCanBusDevice::resetController()
+{
+ if (d_func()->m_resetControllerFunction) {
+ d_func()->m_resetControllerFunction();
+ } else {
+ const char error[] = QT_TRANSLATE_NOOP("QCanBusDevice",
+ "This CAN bus plugin does not support hardware controller reset.");
+ qCWarning(QT_CANBUS, error);
+ setError(tr(error), QCanBusDevice::CanBusError::ConfigurationError);
+ }
+}
+
+/*!
\since 5.12
\enum QCanBusDevice::Direction
diff --git a/src/serialbus/qcanbusdevice.h b/src/serialbus/qcanbusdevice.h
index b590510..911f3ac 100644
--- a/src/serialbus/qcanbusdevice.h
+++ b/src/serialbus/qcanbusdevice.h
@@ -41,6 +41,8 @@
#include <QtSerialBus/qcanbusframe.h>
#include <QtSerialBus/qcanbusdeviceinfo.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QCanBusDevicePrivate;
@@ -120,6 +122,8 @@ public:
qint64 framesAvailable() const;
qint64 framesToWrite() const;
+ void resetController();
+
enum Direction {
Input = 1,
Output = 2,
@@ -163,6 +167,8 @@ protected:
virtual bool open() = 0;
virtual void close() = 0;
+ void setResetControllerFunction(std::function<void()> &resetter);
+
static QCanBusDeviceInfo createDeviceInfo(const QString &name,
bool isVirtual = false,
bool isFlexibleDataRateCapable = false);
diff --git a/src/serialbus/qcanbusdevice_p.h b/src/serialbus/qcanbusdevice_p.h
index faeae65..26d3e89 100644
--- a/src/serialbus/qcanbusdevice_p.h
+++ b/src/serialbus/qcanbusdevice_p.h
@@ -74,6 +74,8 @@ public:
bool waitForReceivedEntered = false;
bool waitForWrittenEntered = false;
+
+ std::function<void()> m_resetControllerFunction;
};
QT_END_NAMESPACE