Lately I've seen a couple of posts that ask for a PCI based prototype boards which has drivers available. Well actually, almost any post which asks about PCI based prototype boards asks for drivers as well. I'm writing this post in the hope that someone will find it useful.
Firstly, I'd like to point out that at least in Linux it isn't that hard to write a driver since a lot of information is publicly available [1]. But it isn't really necessary to write a kernel module since it is very easy to communicate with a PCI card from Linux if you know what to do. The program included below show how to map a PCI card into a programs address space and write some values to it.
While this is probably not suitable for a final product it will do nicely for experimentation during development. You can even do DMA in this kind of program if you make sure to boot linux with a command line like mem=120M to fool Linux into thinking you have less memory than you really have which allows you to use the rest for DMA without fear of overwriting important data. I'm sorry to say that you cannot do IRQ:s in this way though, for that you will need a true driver.
[1]/Andreas
/* Simple test program which will map a PCI card into userspace and * manipulate it. */ #include #include #include #include #include #include
#include int main(int argc,char **argv) { int fd; volatile long *foo; long verify[2048]; int i; int idx,val; int count; long long writecount; int verifications;
/* This is where we first open the memory and then mmap * a PCI card at address 0xfa240000 into the programs address * space. A real program should probably scan /proc/bus/pci/devices * to find out where the PCI card has been configured but I was lazy * when I wrote this test program... */ fd = open("/dev/mem",O_RDWR); foo = mmap(0,262144,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0xfa240000);
printf("Opened PCI card\n");
printf("Resetting PHY\n"); foo[0x1002] = 0x00000000; sleep(1); printf("Removed reset\n"); foo[0x1002] = 0x80000000;
sleep(5);
printf("Writing packet\n"); foo[0] = 0xffffffff; foo[1] = 0xffff0001; foo[2] = 0x01234567; foo[3] = 0x08004500; foo[4] = 0x00200001; foo[5] = 0x00000511; foo[6] = 0x10000a00; foo[7] = 0x00050a00; foo[8] = 0x00010020; foo[9] = 0x00ff0010; foo[10] = 0x0000abcd; foo[11] = 0xef001122; foo[0x1000] = 0; foo[0x1001] = 60; printf("Sending packet\n"); foo[0x1002] = 0x80000001; }