Reworked driver code, again.

This commit is contained in:
2026-01-03 20:10:30 +01:00
parent 68680db6b4
commit 3a132bb584
22 changed files with 228 additions and 184 deletions

View File

@@ -37,12 +37,6 @@
BCDriver::BCDriver(QObject* parent )
: QObject{ parent }
{
}
BCDriver::DriverState BCDriver::getDriverState() const BCDriver::DriverState BCDriver::getDriverState() const
{ {
return _driverState; return _driverState;
@@ -59,47 +53,16 @@ BCDriver::DriverState BCDriver::getDriverState() const
* aber die Console noch nicht eingeschaltet war. * aber die Console noch nicht eingeschaltet war.
*/ */
void BCDriverDummy::onStartDriver() BCDriver::DriverStateResult BCDriverDummy::loadAndStartDriver()
{ {
_driverState = DriverState::DeviceReady; _driverState = DriverState::DeviceReady;
emit driverStateChanged( DriverState::DeviceReady, "Driver Ready." ); return _driverState;
} }
// __Fix
/*
try
{
// erstmal die Dll Laden: State::sIdle -> State::sLoaded
if( _driverState == DriverState::NotPresent)
_driverState = loadAndInitDriver();
emit stateChanged( _driverState );
}
catch( std::exception& except )
{
//::CanDownDriver();
//::UnloadAndInitDriver();
emit statusHint( except.what() );
}
*/
/// ----------------------------------------------------------------------------------- /// -----------------------------------------------------------------------------------
/// ----------------------------------------------------------------------------------- /// -----------------------------------------------------------------------------------
/**
* @brief BCDriverDummy::BCDriverDummy
* @param parent
*/
BCDriverDummy::BCDriverDummy( QObject* parent )
: BCDriver(parent)
{
}
TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const
{ {

View File

@@ -84,9 +84,9 @@ class BCDriverStatus;
*/ */
class BCDriver : public QObject class BCDriver
{ {
Q_OBJECT Q_GADGET
public: public:
@@ -96,20 +96,22 @@ public:
enum class DriverState enum class DriverState
{ {
NotPresent, NotPresent,
Error,
Loaded, Loaded,
Initialized, Initialized,
Opened, // bis hierher: dll vorhanden, Treiber geladen Opened, // bis hierher: dll vorhanden, Treiber geladen
DeviceReady // hier: devices connectable, wir können arbeiten. DeviceReady, // hier: devices connectable, wir können arbeiten.
Error,
}; };
Q_ENUM(DriverState) Q_ENUM(DriverState)
// Enthält den Treiberzustand oder einen Fehlerstring // Enthält den Treiberzustand oder einen Fehlerstring
using DriverStateResult = std::expected<DriverState,QString>; using DriverStateResult = std::expected<DriverState,QString>;
explicit BCDriver( QObject* parent = nullptr ); explicit BCDriver() = default;
virtual ~BCDriver() = default; virtual ~BCDriver() = default;
virtual BCDriver::DriverStateResult loadAndStartDriver() = 0;
// Gibt den aktuelle Zustand des Treibers zurück. Der DriverState // Gibt den aktuelle Zustand des Treibers zurück. Der DriverState
// muss auf DeviceReady stehen, um Werte lesen & schreiben zu können. // muss auf DeviceReady stehen, um Werte lesen & schreiben zu können.
// Dazu muss das Bionx-System eingeschaltet sein. // Dazu muss das Bionx-System eingeschaltet sein.
@@ -122,14 +124,6 @@ public:
virtual TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const = 0; virtual TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const = 0;
virtual TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0; virtual TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0;
public slots:
virtual void onStartDriver() = 0;
signals:
void driverStateChanged( DriverState state, const QString& message="" ) const;
protected: protected:
DriverState _driverState{DriverState::NotPresent}; DriverState _driverState{DriverState::NotPresent};
@@ -139,18 +133,15 @@ protected:
class BCDriverDummy : public BCDriver class BCDriverDummy : public BCDriver
{ {
Q_OBJECT
public: public:
explicit BCDriverDummy( QObject* parent = nullptr ); BCDriver::DriverStateResult loadAndStartDriver() override;
TransmitResult readRawByte( uint32_t deviceID, uint8_t registerID ) const override; TransmitResult readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override; TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
public slots:
virtual void onStartDriver() override;
}; };
#endif // BCDRIVER_H #endif // BCDRIVER_H

View File

@@ -36,44 +36,56 @@
#include <can_drv.h> #include <can_drv.h>
/**
* @brief Destruktor. Entlädt den CAN-Bus Treiber wieder.
*/
BCDriverTinyCan::~BCDriverTinyCan()
BCDriverTinyCan::BCDriverTinyCan( QObject* parent )
: BCDriver(parent )
{ {
resetDriver();
} }
/**
* @brief BCDriverTinyCan::loadAndStartDriver
* @return
*/
void BCDriverTinyCan::onStartDriver() BCDriver::DriverStateResult BCDriverTinyCan::loadAndStartDriver()
{ {
DriverStateResult result;
if( _driverState < DriverState::Opened) if( _driverState < DriverState::Opened)
loadDriver(); result = loadDriver();
if( _driverState == DriverState::Opened) if( _driverState == DriverState::Opened)
_driverState = connectDriver(); result = setConsoleSlaveMode();
return result;
} }
void BCDriverTinyCan::loadDriver() /**
* @brief BCDriverTinyCan::loadDriver
* @return
*/
BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
{ {
auto callLoadDriver = [&]() -> DriverStateResult
auto callLoadDriver = []() -> DriverStateResult
{ {
if( ::LoadDriver( NULL ) < 0 ) if( ::LoadDriver( NULL ) < 0 )
return std::unexpected(QString("Driver Error: 'LoadDriver'")); return std::unexpected(QString("Driver Error: 'LoadDriver'"));
return DriverState::Loaded; _driverState = DriverState::Loaded;
return _driverState;
}; };
auto callInitDriver = [](DriverState state) -> DriverStateResult auto callInitDriver = [&](DriverState state) -> DriverStateResult
{ {
Q_UNUSED(state) Q_UNUSED(state)
if( ::CanInitDriver( NULL ) < 0 ) if( ::CanInitDriver( NULL ) < 0 )
return std::unexpected(QString("Driver Error: 'InitDriver'")); return std::unexpected(QString("Driver Error: 'InitDriver'"));
return DriverState::Initialized; _driverState = DriverState::Initialized;
return _driverState;
}; };
auto callOpenDevice = [](DriverState state) -> DriverStateResult auto callOpenDevice = [&](DriverState state) -> DriverStateResult
{ {
Q_UNUSED(state) Q_UNUSED(state)
if( ::CanDeviceOpen( 0, NULL ) < 0 ) if( ::CanDeviceOpen( 0, NULL ) < 0 )
@@ -93,27 +105,64 @@ void BCDriverTinyCan::loadDriver()
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE ); ::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" )); return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" ));
} }
return DriverState::Opened; _driverState = DriverState::Opened;
return _driverState;
}; };
// #1. erstmal komplett zurücksetzen
resetDriver();
// #2. Treiber laden, initialisieren und
// mit dem tinyCan Interface verbinden.
auto newDriverState = callLoadDriver() auto newDriverState = callLoadDriver()
.and_then( callInitDriver ) .and_then( callInitDriver )
.and_then( callOpenDevice ); .and_then( callOpenDevice );
_driverState = DriverState::Error; // success:
QString message("Driver Ready.");
if(newDriverState) if(newDriverState)
_driverState = *newDriverState; {
else // return 'DriverState::Opened'
message = newDriverState.error(); return _driverState;
}
// return driver error message,
// _driverState ist irgendwo unter DriverState::Opened
return newDriverState;
emit driverStateChanged( _driverState, message );
} }
// __fix // __fix
BCDriver::DriverState BCDriverTinyCan::connectDriver() BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
{ {
/*
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
if (consoleInSlaveMode)
{
printf("console already in salve mode. good!" _NL _NL);
}
else
{
if (gConsoleSetSlaveMode)
{
int retry = 20;
printf("putting console in salve mode ... ");
do {
setValue(CONSOLE, CONSOLE_STATUS_SLAVE, 1);
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
usleep(200000);
} while(retry-- && !consoleInSlaveMode);
doSleep(500); // give the console some time to settle
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
}
else
{
printf("console not in slave mode" _NL _NL);
}
}
*/
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console); uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
uint8_t slaveFlag = static_cast<uint8_t>(BC::ID::Cons_Status_Slave); uint8_t slaveFlag = static_cast<uint8_t>(BC::ID::Cons_Status_Slave);
@@ -126,7 +175,7 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
qDebug() << "BCDriverTinyCan::BCDriverTinyCan::XXX Driver Init: putting Console in slave mode ... "; qDebug() << "BCDriverTinyCan::BCDriverTinyCan::XXX Driver Init: putting Console in slave mode ... ";
unsigned int retry = cTimeOuts; unsigned int retry = cTimeOuts;
emit driverStateChanged( _driverState, "Driver Init: putting Console in slave mode ... " );
TransmitResult isSlave = 0; TransmitResult isSlave = 0;
do do
{ {
@@ -145,20 +194,15 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
} }
void BCDriverTinyCan::resetDriver()
/* {
try if( _driverState > DriverState::NotPresent )
{
initBCDevice::ID::Console();
}
catch( std::exception& except )
{ {
::CanDownDriver(); ::CanDownDriver();
::UnloadDriver(); ::UnloadDriver();
_driverState = DriverState::NotPresent;
} }
*/ }
/** /**
* @brief BCDriverTinyCan::readRawByte * @brief BCDriverTinyCan::readRawByte
@@ -173,7 +217,7 @@ TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t register
//TransmitResult //TransmitResult
qDebug() << " --- BCDriverTinyCan::readRawByte DriverState: " << getDriverState(); qDebug() << " --- BCDriverTinyCan::readRawByte DriverState: " << getDriverState();
if( getDriverState() != DriverState::DeviceReady) if( _driverState != DriverState::DeviceReady)
return std::unexpected(QString("readRawValue error: driver not loaded." ) ); return std::unexpected(QString("readRawValue error: driver not loaded." ) );
::TCanMsg msg; ::TCanMsg msg;
@@ -238,7 +282,7 @@ retry:
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const
{ {
if( getDriverState() != DriverState::DeviceReady) if( _driverState != DriverState::DeviceReady)
return std::unexpected(QString("writeRawValue error: driver not loaded." ) ); return std::unexpected(QString("writeRawValue error: driver not loaded." ) );
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value; qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;

View File

@@ -37,24 +37,22 @@
class BCDriverTinyCan : public BCDriver class BCDriverTinyCan : public BCDriver
{ {
Q_OBJECT
public: public:
explicit BCDriverTinyCan( QObject* parent=nullptr );
virtual ~BCDriverTinyCan() = default; virtual ~BCDriverTinyCan();
BCDriver::DriverStateResult loadAndStartDriver() override;
TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const override; TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const override;
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override; TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
public slots: private:
void onStartDriver() override; BCDriver::DriverStateResult loadDriver();
BCDriver::DriverStateResult setConsoleSlaveMode();
protected: void resetDriver();
void loadDriver();
DriverState connectDriver();
//const char* CBCDLL_LIN = "libmhstcan.so"; //const char* CBCDLL_LIN = "libmhstcan.so";
//const char* CBCDLL_WIN = "mhstcan.dll"; //const char* CBCDLL_WIN = "mhstcan.dll";

View File

@@ -727,24 +727,30 @@ int xmain(int argc, char **argv)
CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR); CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR);
CanGetDeviceStatus(0, &status); CanGetDeviceStatus(0, &status);
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN) { if (status.DrvStatus >= DRV_STATUS_CAN_OPEN)
if (status.CanStatus == CAN_STATUS_BUS_OFF) { {
if (status.CanStatus == CAN_STATUS_BUS_OFF)
{
printf("CAN Status BusOff" _NL); printf("CAN Status BusOff" _NL);
CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE); CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE);
} }
} else { }
else
{
printf("error: could not open device" _NL); printf("error: could not open device" _NL);
goto error; goto error;
} }
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE); consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
if (consoleInSlaveMode) {
if (consoleInSlaveMode)
{
printf("console already in salve mode. good!" _NL _NL); printf("console already in salve mode. good!" _NL _NL);
} else { }
if (gConsoleSetSlaveMode) { else
{
if (gConsoleSetSlaveMode)
{
int retry = 20; int retry = 20;
printf("putting console in salve mode ... "); printf("putting console in salve mode ... ");
@@ -756,16 +762,21 @@ int xmain(int argc, char **argv)
doSleep(500); // give the console some time to settle doSleep(500); // give the console some time to settle
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed"); printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
} else }
else
{
printf("console not in slave mode" _NL _NL); printf("console not in slave mode" _NL _NL);
} }
}
if (gAssistInitLevel != -1) { if (gAssistInitLevel != -1)
{
printf("setting initial assistance level to %d" _NL, gAssistInitLevel); printf("setting initial assistance level to %d" _NL, gAssistInitLevel);
setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel); setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel);
} }
if (gSetSpeedLimit > 0) { if (gSetSpeedLimit > 0)
{
printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit); printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit);
setSpeedLimit(gSetSpeedLimit); setSpeedLimit(gSetSpeedLimit);
doShutdown = 1; doShutdown = 1;

View File

@@ -143,7 +143,7 @@ void BCMainWindow::initMainWindow()
*/ */
// besser: model::emit dataChanged // besser: model::emit dataChanged
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole}); // also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleConnectionState ); connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView ); connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated ); connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );

View File

@@ -35,37 +35,61 @@
#include <bctransmitter.h> #include <bctransmitter.h>
/**
* @brief Kosntruktion. Aktiviert erstmal den Dummy-Driver.
*/
BCTransmitter::BCTransmitter(QObject *parent) BCTransmitter::BCTransmitter(QObject *parent)
: QObject(parent), _isBusy(false) : QObject(parent), _isBusy(false)
{ {
//_canDriver = new BCDriverTinyCan{this}; //_canDriver = new BCDriverTinyCan{this};
_canDriver = new BCDriverDummy{this}; _canDriver = &_dummyDriver;
// forward driver state
connect( _canDriver, &BCDriver::driverStateChanged, this, &BCTransmitter::driverStateChanged );
} }
/**
* @brief Steuert die Verbindung mit dem 'echten' CAN-Bus Treiber.
* @param connect true: Vesuche den CAN-Bus Treiber zu laden und zu verbinden
* false: Disconnect & Cleanup
*/
void BCTransmitter::onToggleConnectionState( bool connect ) void BCTransmitter::onToggleDriverConnection( bool connect )
{ {
if( connect ) qDebug() << " --- onToggleDriverConnection: " << connect;
{ // FIX! Ende der current op abwarten!
if( _canDriver->getDriverState() != BCDriver::DriverState::DeviceReady ) // weitere operation stoppen
_canDriver->onStartDriver(); _isBusy = true;
// __fix! connect ? connectCanDriver() : disconnectCanDriver();
TransmitResult hwVersion = _canDriver->readRawByte( (uint32_t)BCDevice::ID::Console, (uint8_t)BC::ID::Cons_Rev_Hw);
if(!hwVersion) }
void BCTransmitter::connectCanDriver()
{
// hier gehts nur um den echten Treiber
// Treiber laden und/oder starten:
if( _tinyCanDriver.getDriverState() != BCDriver::DriverState::DeviceReady )
_tinyCanDriver.loadAndStartDriver();
// hat geklappt
if( _tinyCanDriver.getDriverState() == BCDriver::DriverState::DeviceReady )
{ {
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
uint8_t hwRev = static_cast<uint8_t> (BC::ID::Cons_Rev_Hw);
TransmitResult hwVersion = _tinyCanDriver.readRawByte( console, hwRev);
if( hwVersion.has_value() )
qDebug() << " ---- HAIL to the king!";
else
qDebug() << "Console not responding"; qDebug() << "Console not responding";
} }
else
{
}
} void BCTransmitter::disconnectCanDriver()
{
qDebug() << " ---HAIL to the kings: " << hwVersion.value();
}
} }

View File

@@ -60,12 +60,9 @@ public:
explicit BCTransmitter(QObject *parent = nullptr); explicit BCTransmitter(QObject *parent = nullptr);
//TransmitResult readByte( uint32_t deviceID, uint8_t registerID ) const override;
//TransmitResult writeByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
public slots: public slots:
void onToggleConnectionState( bool connect ); void onToggleDriverConnection( bool connect );
void enqueueValue(BCValuePtrConst value ); void enqueueValue(BCValuePtrConst value );
void processValue(); void processValue();
@@ -76,11 +73,11 @@ signals:
private: private:
void connectCanDriver();
void disconnectCanDriver();
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID ); TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID ); TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
//TransmitResult writeByteValue( uint32_t deviceID, uint8_t registerID );
//TransmitResult writeWordValue( uint32_t deviceID, uint8_t registerID );
using BCDataQueue = QQueue<BCValuePtrConst>; using BCDataQueue = QQueue<BCValuePtrConst>;
@@ -88,8 +85,10 @@ private:
QMutex _mutex; QMutex _mutex;
std::atomic<bool> _isBusy{ false }; std::atomic<bool> _isBusy{ false };
// __fix! set two // __fix!
BCDriver* _canDriver{}; BCDriver* _canDriver{};
BCDriverTinyCan _tinyCanDriver{};
BCDriverDummy _dummyDriver{};
}; };

View File

@@ -56,8 +56,6 @@
- -
*/ */
using OptDouble = std::optional<double>; using OptDouble = std::optional<double>;
// Enthält den gelesenen Wert oder einen Fehlerstring // Enthält den gelesenen Wert oder einen Fehlerstring
@@ -65,8 +63,6 @@ using TransmitResult = std::expected<uint32_t,QString>;
// Funktionsobject, um Werte aus der Transmitterschicht zu holden // Funktionsobject, um Werte aus der Transmitterschicht zu holden
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>; //using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>;
class BCValue class BCValue
{ {

BIN
doc/Challenges.docx Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -1,7 +1,9 @@
Challenges Challenges
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
BionxControl
Aufgabe: Aufgabe:
@@ -10,12 +12,9 @@ Ansatz:
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
Aufgabe:
Ansatz:
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
xtree
Aufgabe: Aufgabe:
@@ -23,6 +22,7 @@ Ansatz:
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
znode
Aufgabe: Aufgabe:
@@ -30,6 +30,7 @@ Ansatz:
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
libPigPio
Aufgabe: Aufgabe:
@@ -37,6 +38,23 @@ Ansatz:
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
supportware
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
raDIYo
Aufgabe:
Ansatz:
-------------------------------------------------------------------------------------------------
miniCash.connect
Aufgabe: Aufgabe:

BIN
doc/~$allenges.docx Normal file

Binary file not shown.

BIN
doc/~WRL0643.tmp Normal file

Binary file not shown.