Skip to content

Instantly share code, notes, and snippets.

@zonque
Created August 6, 2019 09:55
Show Gist options
  • Save zonque/b93a82b03b825622f4ff6742b2d09df4 to your computer and use it in GitHub Desktop.
Save zonque/b93a82b03b825622f4ff6742b2d09df4 to your computer and use it in GitHub Desktop.
Iterator over UIO devices
// License: MIT
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/user.h>
#include <assert.h>
#include <string>
#include <fstream>
#include <iostream>
typedef struct {
struct fir_filter_t {
uint32_t coeffs[256];
} fir_filter[96];
} fpga_map_t;
class UIODevice {
int fd;
public:
UIODevice(int f) : fd(f) {}
~UIODevice() {
close(fd);
}
void *map(int index, int size) {
if (fd < 0)
return nullptr;
return mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, index * 4096);
}
static UIODevice *findByName(std::string wanted) {
DIR *d;
struct dirent *de;
std::string uioBase = "/sys/class/uio";
d = opendir(uioBase.c_str());
if (d == nullptr)
return nullptr;
while ((de = readdir(d))) {
if (de->d_name[0] == '.')
continue;
std::string name = std::string(de->d_name);
std::ifstream t(uioBase + "/" + name + "/name");
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
str.erase(str.find_last_not_of("\n") + 1);
if (str == wanted) {
std::string fname = std::string("/dev/") + name;
int fd = open(fname.c_str(), O_RDWR);
if (fd >= 0) {
closedir(d);
return new UIODevice(fd);
}
}
}
closedir(d);
return nullptr;
}
};
int main(void) {
UIODevice *uio = UIODevice::findByName("AXI_TO_BRAM");
assert(uio != nullptr);
fpga_map_t *map = (fpga_map_t *) uio->map(0, sizeof(fpga_map_t));
assert(map != nullptr);
map->fir_filter[10].coeffs[100] = 0xfeedface;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment