From b48160286b530779789d866f10b4653c64ba4b2f Mon Sep 17 00:00:00 2001 From: Yasser Yassine Date: Sat, 11 Oct 2025 20:33:22 +0000 Subject: [PATCH] Device: Add reconnect() --- communication/driver.cpp | 6 +- device/device.cpp | 36 ++++++++++++ include/icsneo/communication/communication.h | 1 + include/icsneo/communication/driver.h | 5 ++ include/icsneo/device/device.h | 1 + include/icsneo/device/founddevice.h | 3 +- .../device/tree/radepsilon/radepsilon.h | 6 +- .../device/tree/radepsilonxl/radepsilonxl.h | 1 + .../device/tree/radgigastar/radgigastar.h | 39 +++++++++---- .../device/tree/radgigastar2/radgigastar2.h | 55 +++++++------------ include/icsneo/device/versionreport.h | 5 ++ include/icsneo/platform/dxx.h | 1 + include/icsneo/platform/posix/cdcacm.h | 1 + include/icsneo/platform/posix/firmio.h | 2 + include/icsneo/platform/posix/pcap.h | 2 + include/icsneo/platform/servd.h | 2 + include/icsneo/platform/tcp.h | 3 +- include/icsneo/platform/windows/cdcacm.h | 1 + include/icsneo/platform/windows/pcap.h | 2 + 19 files changed, 118 insertions(+), 54 deletions(-) diff --git a/communication/driver.cpp b/communication/driver.cpp index 5c56638..c71d29b 100644 --- a/communication/driver.cpp +++ b/communication/driver.cpp @@ -71,8 +71,12 @@ bool Driver::write(const std::vector& bytes) { if(writeBlocks) { if(writeQueueFull()) { - while(writeQueueAlmostFull()) // Wait until we have some decent amount of space + while(writeQueueAlmostFull() && !isDisconnected() && !isClosing()) // Wait until we have some decent amount of space std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + if(isDisconnected() || isClosing()) { + return false; + } } } else { if(writeQueueFull()) { diff --git a/device/device.cpp b/device/device.cpp index 498e13f..260cac0 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -229,8 +229,12 @@ std::vector Device::getChipVersions(bool refreshComponents) { result[i] = (uint8_t)((dotVersion & 0x000000FFul) >> 0); return result; }; + for(const auto& chipInfo : getChipInfo()) { for(const auto& component : compVersions) { + if(!component.valid) { + continue; + } if(component.identifier == (uint32_t)chipInfo.id) { chipVersions.emplace_back(); auto& version = chipVersions.back(); @@ -407,6 +411,38 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) { return true; } +bool Device::reconnect(std::chrono::milliseconds timeout, std::chrono::milliseconds interval) { + if(isOnline()) { + goOffline(); + } + bool readsArePaused = com->readsArePaused(); + if(!com->close()) { + return false; + } + + std::vector foundDevices; + auto findAll = com->driver->getFinder(); + auto start = std::chrono::system_clock::now(); + while((std::chrono::system_clock::now() - start) < timeout) { + foundDevices.clear(); + findAll(foundDevices); + for(auto& fd : foundDevices) { + if(!memcmp(fd.serial, data.serial, 6)) { + com->driver = fd.makeDriver(report, getWritableNeoDevice()); + if(readsArePaused) { + // Pause reads again + com->pauseReads(); + } + return com->open(); + } + } + std::this_thread::sleep_for(interval); + } + + return false; +} + + APIEvent::Type Device::attemptToBeginCommunication() { versions.clear(); diff --git a/include/icsneo/communication/communication.h b/include/icsneo/communication/communication.h index bde7a2e..0f52973 100644 --- a/include/icsneo/communication/communication.h +++ b/include/icsneo/communication/communication.h @@ -42,6 +42,7 @@ public: bool close(); bool isOpen(); bool isDisconnected(); + virtual void spawnThreads(); virtual void joinThreads(); void modeChangeIncoming() { driver->modeChangeIncoming(); } diff --git a/include/icsneo/communication/driver.h b/include/icsneo/communication/driver.h index 515b0c9..8fcebc3 100644 --- a/include/icsneo/communication/driver.h +++ b/include/icsneo/communication/driver.h @@ -12,9 +12,12 @@ #include "icsneo/api/eventmanager.h" #include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h" #include "icsneo/communication/ringbuffer.h" +#include "icsneo/device/founddevice.h" namespace icsneo { +typedef std::function&)> driver_finder_t; + #define ICSNEO_DRIVER_RINGBUFFER_SIZE (512 * 1024) class Driver { public: @@ -25,6 +28,7 @@ public: virtual void modeChangeIncoming() {} virtual void awaitModeChangeComplete() {} virtual bool close() = 0; + virtual driver_finder_t getFinder() = 0; inline bool isDisconnected() const { return disconnected; }; inline bool isClosing() const { return closing; } @@ -37,6 +41,7 @@ public: bool readAvailable() { return readBuffer.size() > 0; } RingBuffer& getReadBuffer() { return readBuffer; } + virtual bool enableCommunication(bool /* enable */, bool& sendMsg) { sendMsg = true; return true; } device_eventhandler_t report; diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index c9c7a80..21e0446 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -229,6 +229,7 @@ public: virtual bool goOffline(); virtual bool enableLogData(); virtual bool disableLogData(); + virtual bool reconnect(std::chrono::milliseconds timeout, std::chrono::milliseconds interval = std::chrono::milliseconds(100)); enum class PreloadReturn : uint8_t { diff --git a/include/icsneo/device/founddevice.h b/include/icsneo/device/founddevice.h index 0f05eb6..0b86b5d 100644 --- a/include/icsneo/device/founddevice.h +++ b/include/icsneo/device/founddevice.h @@ -1,11 +1,12 @@ #ifndef __FOUNDDEVICE_H_ #define __FOUNDDEVICE_H_ -#include "icsneo/communication/driver.h" #include "icsneo/device/neodevice.h" +#include "icsneo/api/eventmanager.h" namespace icsneo { +class Driver; typedef std::function< std::unique_ptr(device_eventhandler_t err, neodevice_t& forDevice) > driver_factory_t; class FoundDevice { diff --git a/include/icsneo/device/tree/radepsilon/radepsilon.h b/include/icsneo/device/tree/radepsilon/radepsilon.h index 0b4903f..868b0db 100644 --- a/include/icsneo/device/tree/radepsilon/radepsilon.h +++ b/include/icsneo/device/tree/radepsilon/radepsilon.h @@ -25,10 +25,6 @@ public: return supportedNetworks; } - bool supportsComponentVersions() const override { return true; } - - bool getEthPhyRegControlSupported() const override { return true; } - ProductID getProductID() const override { return ProductID::RADEpsilon; } @@ -46,7 +42,9 @@ public: .add(ChipID::RADEpsilon_MCHIP, BootloaderCommunication::RED) .add(); } + bool supportsComponentVersions() const override { return true; } + bool getEthPhyRegControlSupported() const override { return true; } protected: RADEpsilon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { initialize(makeDriver); diff --git a/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h b/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h index 62d0843..948ce6b 100644 --- a/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h +++ b/include/icsneo/device/tree/radepsilonxl/radepsilonxl.h @@ -28,6 +28,7 @@ public: bool supportsComponentVersions() const override { return true; } bool getEthPhyRegControlSupported() const override { return true; } + ProductID getProductID() const override { return ProductID::RADEpsilon; } diff --git a/include/icsneo/device/tree/radgigastar/radgigastar.h b/include/icsneo/device/tree/radgigastar/radgigastar.h index eca9196..39c656d 100644 --- a/include/icsneo/device/tree/radgigastar/radgigastar.h +++ b/include/icsneo/device/tree/radgigastar/radgigastar.h @@ -30,7 +30,7 @@ public: const std::vector& getChipInfo() const override { static std::vector chips = { - {ChipID::RADGigastar_ZYNQ, true, "ZCHIP", "RADGigastar2_T1S_LIN_SW_bin", 1, FirmwareType::Zip}, + {ChipID::RADGigastar_ZYNQ, true, "ZCHIP", "RADGigastar_SW_bin", 1, FirmwareType::Zip}, {ChipID::RADGigastar_FFG_ZYNQ, false, "ZCHIP", "RADGigastar_FFG_SW_bin", 1, FirmwareType::Zip}, {ChipID::RADGigastar_USBZ_ZYNQ, true, "USB ZCHIP", "RADGigastar_USBz_SW_bin", 2, FirmwareType::Zip}, {ChipID::RADGigastar_USBZ_Z7010_ZYNQ, false, "USB ZCHIP", "RADGigastar_USBz_Z7010_SW_bin", 2, FirmwareType::Zip}, @@ -41,24 +41,39 @@ public: BootloaderPipeline getBootloader() override { if(supportsComponentVersions()) { + // main: 16.1, usb: 14.0 auto chipVersions = getChipVersions(); auto mainVersion = std::find_if(chipVersions.begin(), chipVersions.end(), [](const auto& ver) { return ver.name == "ZCHIP"; }); + auto usbVersion = std::find_if(chipVersions.begin(), chipVersions.end(), [](const auto& ver) { return ver.name == "USB ZCHIP"; }); + + bool useNewBootloader = false; if(mainVersion != chipVersions.end()) { - static constexpr uint8_t NewBootloaderMajor = 0; - static constexpr uint8_t NewBootloaderMinor = 0; - + static constexpr uint8_t NewBootloaderMajor = 16; + static constexpr uint8_t NewBootloaderMinor = 1; if( mainVersion->major > NewBootloaderMajor || - (mainVersion->major == NewBootloaderMajor && mainVersion->minor > NewBootloaderMinor) + (mainVersion->major == NewBootloaderMajor && mainVersion->minor >= NewBootloaderMinor) ) { - BootloaderPipeline pipeline; - for(const auto& version : chipVersions) { - pipeline.add(version.id, BootloaderCommunication::RADMultiChip); - } - pipeline.add(); - pipeline.add(std::chrono::milliseconds(3000)); - return pipeline; + useNewBootloader = true; } + } else if(usbVersion != chipVersions.end()) { + static constexpr uint8_t NewBootloaderMajorUSB = 14; + static constexpr uint8_t NewBootloaderMinorUSB= 0; + if( + usbVersion->major > NewBootloaderMajorUSB || + (usbVersion->major == NewBootloaderMajorUSB && usbVersion->minor >= NewBootloaderMinorUSB) + ) { + useNewBootloader = true; + } + } + if(useNewBootloader) { + BootloaderPipeline pipeline; + for(const auto& version : chipVersions) { + pipeline.add(version.id, BootloaderCommunication::RADMultiChip); + } + pipeline.add(); + pipeline.add(std::chrono::milliseconds(3000)); + return pipeline; } } // If we've reached this point, then we use the legacy flashing diff --git a/include/icsneo/device/tree/radgigastar2/radgigastar2.h b/include/icsneo/device/tree/radgigastar2/radgigastar2.h index bfe7f26..79d74f9 100644 --- a/include/icsneo/device/tree/radgigastar2/radgigastar2.h +++ b/include/icsneo/device/tree/radgigastar2/radgigastar2.h @@ -15,9 +15,9 @@ namespace icsneo class RADGigastar2 : public Device { public: enum class FirmwareVariant { - T1Sx6_CANx1_LINx16, - T1Sx8_CANx4_LINx6, - Invalid + T1Sx6_CANx1_LINx16 = 0, + T1Sx8_CANx4_LINx6 = 1, + Invalid = 2 }; // Serial numbers start with GT @@ -100,6 +100,8 @@ public: FirmwareVariant getCurrentVariant() { if(supportsComponentVersions()) { + refreshComponentVersions(); + const auto& components = getComponentVersions(); for(const auto& component : components) { if(!component.valid) { @@ -107,7 +109,10 @@ public: } if(component.identifier == static_cast(ChipID::RADGigastar2_ZYNQ)) { - auto res = static_cast(std::clamp(component.componentInfo, 0, 2)); + if(component.componentInfo > 2) { + return FirmwareVariant::Invalid; + } + auto res = static_cast(component.componentInfo); if(variantToFlash == FirmwareVariant::Invalid) { variantToFlash = res; // Set the variantToFlash if it hasn't been set yet, we always flash the same firmware variant as the current if it is unspecified } @@ -140,41 +145,21 @@ public: } BootloaderPipeline getBootloader() override { - if(supportsComponentVersions()) { - auto chipVersions = getChipVersions(); - auto mainVersion = std::find_if(chipVersions.begin(), chipVersions.end(), [](const auto& ver) { return ver.name == "ZCHIP"; }); - if(mainVersion != chipVersions.end()) { - static constexpr uint8_t NewBootloaderMajor = 0; - static constexpr uint8_t NewBootloaderMinor = 0; - - if( - mainVersion->major > NewBootloaderMajor || - (mainVersion->major == NewBootloaderMajor && mainVersion->minor > NewBootloaderMinor) - ) { - BootloaderPipeline pipeline; - for(const auto& version : chipVersions) { - pipeline.add(version.id, BootloaderCommunication::RADMultiChip); - } - pipeline.add(); - pipeline.add(std::chrono::milliseconds(3000)); - return pipeline; - } - } + auto chipVersions = getChipVersions(); + BootloaderPipeline pipeline; + for(const auto& version : chipVersions) { + pipeline.add(version.id, BootloaderCommunication::RADMultiChip); } - // If we've reached this point, then we use the legacy flashing - if(com->driver->isEthernet()) { - return BootloaderPipeline() - .add(ChipID::RADGigastar2_ZYNQ, BootloaderCommunication::RAD) - .add() - .add(std::chrono::milliseconds(3000)); - } - return BootloaderPipeline() - .add(ChipID::RADGigastar_USBZ_ZYNQ, BootloaderCommunication::RAD) - .add() - .add(std::chrono::milliseconds(3000)); + pipeline.add(); + pipeline.add(std::chrono::milliseconds(3000)); + return pipeline; } std::vector getChipVersions(bool refreshComponents = true) override { + if(variantToFlash == FirmwareVariant::Invalid) { + getCurrentVariant(); + } + if(refreshComponents) { refreshComponentVersions(); } diff --git a/include/icsneo/device/versionreport.h b/include/icsneo/device/versionreport.h index c8d1fa6..608fb99 100644 --- a/include/icsneo/device/versionreport.h +++ b/include/icsneo/device/versionreport.h @@ -4,6 +4,7 @@ #ifdef __cplusplus #include "icsneo/device/chipid.h" +#include "icsneo/device/deviceversion.h" #include #include @@ -17,6 +18,10 @@ struct VersionReport { uint8_t minor; uint8_t maintenance; uint8_t build; + + icsneo::DeviceAppVersion makeAppVersion() const { + return {major, minor}; + } }; } diff --git a/include/icsneo/platform/dxx.h b/include/icsneo/platform/dxx.h index 781b4eb..d0a7922 100644 --- a/include/icsneo/platform/dxx.h +++ b/include/icsneo/platform/dxx.h @@ -21,6 +21,7 @@ public: bool isOpen() override; bool close() override; + driver_finder_t getFinder() override { return DXX::Find; } private: void read(); diff --git a/include/icsneo/platform/posix/cdcacm.h b/include/icsneo/platform/posix/cdcacm.h index 9d978ca..769ec92 100644 --- a/include/icsneo/platform/posix/cdcacm.h +++ b/include/icsneo/platform/posix/cdcacm.h @@ -32,6 +32,7 @@ public: bool open() override; bool isOpen() override; bool close() override; + driver_finder_t getFinder() override { return CDCACM::Find; } void modeChangeIncoming() override; void awaitModeChangeComplete() override; diff --git a/include/icsneo/platform/posix/firmio.h b/include/icsneo/platform/posix/firmio.h index cf2cdb2..82e8522 100644 --- a/include/icsneo/platform/posix/firmio.h +++ b/include/icsneo/platform/posix/firmio.h @@ -24,6 +24,8 @@ public: bool open() override; bool isOpen() override; bool close() override; + driver_finder_t getFinder() override { return FirmIO::Find; } + private: std::thread readThread, writeThread; diff --git a/include/icsneo/platform/posix/pcap.h b/include/icsneo/platform/posix/pcap.h index 223df13..064f518 100644 --- a/include/icsneo/platform/posix/pcap.h +++ b/include/icsneo/platform/posix/pcap.h @@ -24,6 +24,8 @@ public: bool isOpen() override; bool close() override; bool isEthernet() const override { return true; } + driver_finder_t getFinder() override { return PCAP::Find; } + private: char errbuf[PCAP_ERRBUF_SIZE] = { 0 }; neodevice_t& device; diff --git a/include/icsneo/platform/servd.h b/include/icsneo/platform/servd.h index 410b8d4..3a80b38 100644 --- a/include/icsneo/platform/servd.h +++ b/include/icsneo/platform/servd.h @@ -25,6 +25,8 @@ public: bool close() override; bool faa(const std::string& key, int32_t inc, int32_t& orig); bool enableCommunication(bool enable, bool& sendMsg) override; + driver_finder_t getFinder() override { return Servd::Find; } + private: void alive(); void read(Address&& address); diff --git a/include/icsneo/platform/tcp.h b/include/icsneo/platform/tcp.h index 7d4f1af..7687fd3 100644 --- a/include/icsneo/platform/tcp.h +++ b/include/icsneo/platform/tcp.h @@ -6,7 +6,6 @@ #include #include "icsneo/communication/driver.h" -#include "icsneo/device/founddevice.h" namespace icsneo { @@ -25,6 +24,8 @@ public: bool isOpen() override; bool close() override; bool isEthernet() const override { return true; } + driver_finder_t getFinder() override { return TCP::Find; } + private: #ifdef _WIN32 typedef size_t SocketFileDescriptor; diff --git a/include/icsneo/platform/windows/cdcacm.h b/include/icsneo/platform/windows/cdcacm.h index a975795..79fa3e7 100644 --- a/include/icsneo/platform/windows/cdcacm.h +++ b/include/icsneo/platform/windows/cdcacm.h @@ -21,6 +21,7 @@ public: bool open() override; bool isOpen() override; bool close() override; + driver_finder_t getFinder() override { return CDCACM::Find; } private: void read(); diff --git a/include/icsneo/platform/windows/pcap.h b/include/icsneo/platform/windows/pcap.h index a672ddf..044be66 100644 --- a/include/icsneo/platform/windows/pcap.h +++ b/include/icsneo/platform/windows/pcap.h @@ -24,6 +24,8 @@ public: bool isOpen() override; bool close() override; bool isEthernet() const override { return true; } + driver_finder_t getFinder() override { return PCAP::Find; } + private: const PCAPDLL& pcap; char errbuf[PCAP_ERRBUF_SIZE] = { 0 };