26 if(boost::filesystem::is_symlink(_deviceFilePath)) {
27 _deviceFilePath = boost::filesystem::canonical(_deviceFilePath);
29 std::string fileName = _deviceFilePath.filename().string();
30 _deviceKernelBase = (
void*)readUint64HexFromFile(
"/sys/class/uio/" + fileName +
"/maps/map0/addr");
31 _deviceMemSize = readUint64HexFromFile(
"/sys/class/uio/" + fileName +
"/maps/map0/size");
32 _lastInterruptCount = readUint32FromFile(
"/sys/class/uio/" + fileName +
"/event");
35 _deviceFileDescriptor =
::open(_deviceFilePath.c_str(), O_RDWR);
36 if(_deviceFileDescriptor < 0) {
51 void UioAccess::read(uint64_t map, uint64_t address, int32_t* __restrict__ data,
size_t sizeInBytes) {
57 address = address %
reinterpret_cast<uint64_t
>(_deviceKernelBase);
59 if(address + sizeInBytes > _deviceMemSize) {
63 volatile int32_t* rptr =
static_cast<volatile int32_t*
>(_deviceUserBase) + address /
sizeof(int32_t);
64 while(sizeInBytes >=
sizeof(int32_t)) {
65 *(data++) = *(rptr++);
66 sizeInBytes -=
sizeof(int32_t);
70 void UioAccess::write(uint64_t map, uint64_t address, int32_t
const* data,
size_t sizeInBytes) {
76 address = address %
reinterpret_cast<uint64_t
>(_deviceKernelBase);
78 if(address + sizeInBytes > _deviceMemSize) {
82 volatile int32_t* __restrict__ wptr =
static_cast<volatile int32_t*
>(_deviceUserBase) + address /
sizeof(int32_t);
83 while(sizeInBytes >=
sizeof(int32_t)) {
84 *(wptr++) = *(data++);
85 sizeInBytes -=
sizeof(int32_t);
91 uint32_t totalInterruptCount = 0;
93 uint32_t occurredInterruptCount = 0;
96 pfd.fd = _deviceFileDescriptor;
99 int ret = poll(&pfd, 1, timeoutMs);
103 ret =
::read(_deviceFileDescriptor, &totalInterruptCount,
sizeof(totalInterruptCount));
105 if(ret != (ssize_t)
sizeof(totalInterruptCount)) {
110 occurredInterruptCount = subtractUint32OverflowSafe(totalInterruptCount, _lastInterruptCount);
111 _lastInterruptCount = totalInterruptCount;
115 occurredInterruptCount = 0;
120 return occurredInterruptCount;
125 ssize_t ret =
::write(_deviceFileDescriptor, &unmask,
sizeof(unmask));
127 if(ret != (ssize_t)
sizeof(unmask)) {
133 return _deviceFilePath.string();
136 void UioAccess::UioMMap() {
137 _deviceUserBase = mmap(NULL, _deviceMemSize, PROT_READ | PROT_WRITE, MAP_SHARED, _deviceFileDescriptor, 0);
138 if(_deviceUserBase == MAP_FAILED) {
139 ::close(_deviceFileDescriptor);
145 void UioAccess::UioUnmap() {
146 munmap(_deviceUserBase, _deviceMemSize);
149 uint32_t UioAccess::subtractUint32OverflowSafe(uint32_t minuend, uint32_t subtrahend) {
150 if(subtrahend > minuend) {
152 (uint32_t)(
static_cast<uint64_t
>(std::numeric_limits<uint32_t>::max()) -
static_cast<uint64_t
>(subtrahend));
155 return minuend - subtrahend;
159 uint32_t UioAccess::readUint32FromFile(std::string fileName) {
161 std::ifstream inputFile(fileName);
163 if(inputFile.is_open()) {
167 return (uint32_t)value;
170 uint64_t UioAccess::readUint64HexFromFile(std::string fileName) {
172 std::ifstream inputFile(fileName);
174 if(inputFile.is_open()) {
175 inputFile >> std::hex >> value;
void read(uint64_t map, uint64_t address, int32_t *data, size_t sizeInBytes)
Read data from the specified memory offset address.
void open()
Opens UIO device for read and write operations and interrupt handling.
std::string getDeviceFilePath()
Return UIO device file path.
uint32_t waitForInterrupt(int timeoutMs)
Wait for hardware interrupt to occur within specified timeout period.
void write(uint64_t map, uint64_t address, int32_t const *data, size_t sizeInBytes)
Write data to the specified memory offset address.
UioAccess(const std::string &deviceFilePath)
void clearInterrupts()
Clear all pending interrupts.
void close()
Closes UIO device.
Exception thrown when a logic error has occured.
Exception thrown when a runtime error has occured.