POSIX: STM32: Check re-enumeration by inode
This is much more stable than waiting for a set amount of time We still timeout at 5s, if we see that being hit it can be increasedpull/35/head
parent
b7c7d4349a
commit
6d22b1e001
|
|
@ -6,7 +6,9 @@
|
|||
#include "icsneo/communication/driver.h"
|
||||
#include "icsneo/device/neodevice.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/platform/optional.h"
|
||||
#include <chrono>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace icsneo {
|
||||
|
|
@ -37,6 +39,7 @@ public:
|
|||
private:
|
||||
neodevice_t& device;
|
||||
int fd = -1;
|
||||
optional<ino_t> disallowedInode;
|
||||
std::atomic<bool> modeChanging{false};
|
||||
std::thread modeChangeThread;
|
||||
std::mutex modeChangeMutex;
|
||||
|
|
|
|||
|
|
@ -35,10 +35,28 @@ bool STM32::open() {
|
|||
// Some devices can take a while to boot
|
||||
for(int i = 0; i != 50; ++i) {
|
||||
fd = ::open(ttyPath.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if(fd != -1)
|
||||
break;
|
||||
|
||||
if(fd != -1) {
|
||||
// Opened successfully, check if it's the same inode as the disallowed one
|
||||
// The inode is disallowed if we're expecting the device to re-enumerate (modeChanging)
|
||||
if(disallowedInode.has_value()) {
|
||||
struct stat fileStat = {};
|
||||
if(fstat(fd, &fileStat) >= 0) {
|
||||
if(fileStat.st_ino != *disallowedInode)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// This is still the old device, wait and try again
|
||||
::close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
disallowedInode.reset();
|
||||
if(!isOpen()) {
|
||||
//std::cout << "Open of " << ttyPath.c_str() << " failed with " << strerror(errno) << ' ';
|
||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||
|
|
@ -110,6 +128,15 @@ bool STM32::close() {
|
|||
closing = false;
|
||||
disconnected = false;
|
||||
|
||||
if(modeChanging) {
|
||||
// We're expecting this inode to go away after we close the device
|
||||
// In order to block waiting for this to happen, we first need to
|
||||
// get the inode.
|
||||
struct stat fileStat = {};
|
||||
if(fstat(fd, &fileStat) >= 0)
|
||||
disallowedInode = fileStat.st_ino;
|
||||
}
|
||||
|
||||
int ret = ::close(fd);
|
||||
fd = -1;
|
||||
|
||||
|
|
@ -120,7 +147,6 @@ bool STM32::close() {
|
|||
|
||||
if(modeChanging) {
|
||||
modeChanging = false;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||
return open(); // Reopen the reenumerated device
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue