9 _uioAccess = std::make_shared<UioAccess>(
"/dev/" + deviceName);
17 std::string address, std::map<std::string, std::string> parameters) {
21 return boost::shared_ptr<DeviceBackend>(
new UioBackend(address, parameters[
"map"]));
38 if(_interruptWaitingThread.joinable()) {
39 _stopInterruptLoop =
true;
40 _interruptWaitingThread.join();
53 void UioBackend::read(uint64_t bar, uint64_t address, int32_t* data,
size_t sizeInBytes) {
57 _uioAccess->read(bar, address, data, sizeInBytes);
60 void UioBackend::write(uint64_t bar, uint64_t address, int32_t
const* data,
size_t sizeInBytes) {
64 _uioAccess->write(bar, address, data, sizeInBytes);
69 std::promise<void> subscriptionDonePromise;
71 if(interruptNumber != 0) {
72 setException(
"UIO: Backend only uses interrupt number 0");
73 subscriptionDonePromise.set_value();
74 return subscriptionDonePromise.get_future();
76 if(_interruptWaitingThread.joinable()) {
77 subscriptionDonePromise.set_value();
78 return subscriptionDonePromise.get_future();
81 _stopInterruptLoop =
false;
83 auto subscriptionDoneFuture = subscriptionDonePromise.get_future();
84 _interruptWaitingThread = std::thread(&UioBackend::waitForInterruptLoop,
this, std::move(subscriptionDonePromise));
85 return subscriptionDoneFuture;
89 std::string result = std::string(
"UIO backend: Device path = " + _uioAccess->getDeviceFilePath());
91 result +=
" (device closed)";
97 void UioBackend::waitForInterruptLoop(std::promise<void> subscriptionDonePromise) {
107 auto promiseFulfiller = cppext::finally([&]() { subscriptionDonePromise.set_value(); });
110 _uioAccess->clearInterrupts();
113 if(_uioAccess->waitForInterrupt(0) > 0) {
114 _uioAccess->clearInterrupts();
122 while(!_stopInterruptLoop) {
124 auto numberOfInterrupts = _uioAccess->waitForInterrupt(100);
126 if(numberOfInterrupts > 0) {
127 _uioAccess->clearInterrupts();
134 if(numberOfInterrupts > 1) {
135 std::cout <<
"UioBackend: Lost " << (numberOfInterrupts - 1) <<
" interrupts. " << std::endl;
137 std::cout <<
"dispatching interrupt " << std::endl;
bool isFunctional() const noexcept final
Return whether a device is working as intended, usually this means it is opened and does not have any...
void setOpenedAndClearException() noexcept
Backends should call this function at the end of a (successful) open() call.
void setException(const std::string &message) noexcept final
Set the backend into an exception state.
void checkActiveException() final
Function to be called by backends when needing to check for an active exception.
bool isOpen() override
Return whether a device has been opened or not.
std::atomic< bool > _opened
flag if backend is opened
Base class for address-based device backends (e.g.
void close() final
Deactivates all asynchronous accessors and calls closeImpl().
static boost::shared_ptr< DeviceBackend > createInstance(std::string address, std::map< std::string, std::string > parameters)
void write(uint64_t bar, uint64_t address, int32_t const *data, size_t sizeInBytes) override
Write function to be implemented by backends.
void open() override
Open the device.
void closeImpl() override
All backends derrived from NumericAddressedBackend must implement closeImpl() instead of close.
void read(uint64_t bar, uint64_t address, int32_t *data, size_t sizeInBytes) override
Read function to be implemented by backends.
std::future< void > activateSubscription(uint32_t interruptNumber, boost::shared_ptr< async::DomainImpl< std::nullptr_t > > asyncDomain) override
Activate/create the subscription for a given interrupt (for instance by starting the according interr...
UioBackend(std::string deviceName, std::string mapFileName)
std::string readDeviceInfo() override
Return a device information string containing hardware details like the firmware version number or th...
boost::shared_ptr< async::DomainImpl< std::nullptr_t > > _asyncDomain
bool barIndexValid(uint64_t bar) override
Function to be implemented by the backends.
Exception thrown when a logic error has occured.
Exception thrown when a runtime error has occured.
const char * what() const noexcept override
Return the message describing what exactly went wrong.