title: C++ app to talk to an FPGA over PCI in userland using mmap
body: <p>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.</p>
  
  <p>I'm trying to write a cpp app to talk to a FPGA over a pci bus, in userland. </p>
  
  <p>The code I have written so far, enumerates over the directories in <code>/sys/bus/pci/devices</code> checking the device and vendor files to locate the correct one.</p>
  
  <p>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.</p>
  
  <p>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 <code>/sys/bus/pci/devices/[device_addr]/resource1</code> with <code>O_RDWR</code>, then call <code>mmap</code> like so:</p>
  
  <pre><code>char *map = (char*)mmap(NULL, FPGA_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  </code></pre>
  
  <p>Where <code>fd</code> is the file descriptor from open.</p>
  
  <p>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.</p>
  
  <p>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. </p>
  
  <p>If there are any details i'm missing just ask.</p>
  
  <p>I'm using a 2.6 Linux kernel, based on ubuntu 11.04 (running on a live usb), the hardware is x86 based.</p>
  
  <p>Thanks</p>
  
  <p>UPDATE:
  After even more googling about and trial and error with the code I got it working.</p>
  
  <p>The steps I followed where:</p>
  
  <ul>
  <li>Identify device using <code>/sys/bus/pci/devices/[device]/[vendor|device]</code></li>
  <li>Parse <code>/sys/bus/pci/devices/[device]/resource</code>, for each line the first
  column is the start address and the second is the end address of the
  mapped region. I wanted <code>BAR1</code> so the second line had the values I
  needed.</li>
  <li><code>open("/dev/mem", O_RDWR)</code> to get file descriptor fd</li>
  <li>call <code>mmap</code> 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).</li>
  </ul>