First off i'm new to Linux programming so apologies if this makes no sense or I'm barking up the wrong tree, point me in the correct direction.
I'm trying to write a cpp app to talk to a FPGA over a pci bus, in userland.
The code I have written so far, enumerates over the directories in /sys/bus/pci/devices
checking the device and vendor files to locate the correct one.
Once I've found the device I know that the mapped regions I need to write to are somehow represented by resource[n] files, but i'm not sure how to use them to read/write some values.
From the code written for another OS I know I want to talk to BAR1 of the PCI device, the way i've (tried to) do this is with mmap (is this the right way to go about it?). First I get a filehandle to /sys/bus/pci/devices/[device_addr]/resource1
with O_RDWR
, then call mmap
like so:
char *map = (char*)mmap(NULL, FPGA_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
Where fd
is the file descriptor from open.
Am I going about this the correct way or are the better functions/calls to use? I realise I could write a kernel module to do this, but I'd rather not have to get into kernel module programming just yet.
If it helps I can pastebin the code for a short while, but i'm not really after a critique of the code, just some pointers on the best method to do it.
If there are any details i'm missing just ask.
I'm using a 2.6 Linux kernel, based on ubuntu 11.04 (running on a live usb), the hardware is x86 based.
Thanks
UPDATE: After even more googling about and trial and error with the code I got it working.
The steps I followed where:
- Identify device using
/sys/bus/pci/devices/[device]/[vendor|device]
- Parse
/sys/bus/pci/devices/[device]/resource
, for each line the first column is the start address and the second is the end address of the mapped region. I wantedBAR1
so the second line had the values I needed. open("/dev/mem", O_RDWR)
to get file descriptor fd- call
mmap
as above, but pass in the start address as the offset (last argument) and use the start and end address to get the mapped regions size (second argument).
That's a perfectly acceptable mmap call and should work correctly.
来源:https://stackoverflow.com/questions/6874945/c-app-to-talk-to-an-fpga-over-pci-in-userland-using-mmap