如何在linux中的pci-e卡上从用户空间读取条形码0中的数据?

时间:2014-09-22 17:24:40

标签: linux driver pci

在Windows上有一个名为pcitree的程序,它允许您在不编写设备驱动程序的情况下设置和读取内存。是否有一个替代pcitree的Linux,可以让我读取我的pcie卡0块的内存?

一个简单的用例是我使用驱动程序代码在我的pci-e卡的第0块的第一个内存地址上写一个32位整数。然后我使用pcitree替代方法读取块0的第一个内存地址的值并查看我的整数。

谢谢

3 个答案:

答案 0 :(得分:3)

我在网上发现了一些符合我要求的代码github.com/billfarrow/pcimem。 据我所知,这个链接提供了通过系统调用将内核内存映射到用户内存的代码" mmap"

这主要是从程序的自述文件和mmap的手册页中窃取的。 mmap需要

  • 起始地址
  • 一个大小
  • 内存保护标志
  • 链接到pci卡的bar0的文件描述符。
  • 和一个偏移量

mmap返回一个用户空间指针,指向由起始地址和大小参数定义的内存。

此代码显示了mmaps用法的示例。

//The file handle can be found by typing lscpi -v
//and looking for your device.
fd = open("/sys/devices/pci0001\:00/0001\:00\:07.0/resource0", O_RDWR | O_SYNC);
//mmap returns a userspace address
//0, 4096 tells it to pull one page 
ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
printf("PCI BAR0 0x0000 = 0x%4x\n", *((unsigned short *) ptr);

答案 1 :(得分:0)

我使用上面描述的PCI BAR0寄存器的方式但是得到了分段故障。我使用gdb从我的代码调试错误,如下所示,它显示mmap()的返回值是(void *)0xffffffffffffffff

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define PRINT_ERROR \
        do { \
                fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
                __LINE__, __FILE__, errno, strerror(errno)); exit(1); \
        } while(0)

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main(int argc, char **argv) {

    int fd;
    void *ptr;
    //The file handle can be found by typing lscpi -v
    //and looking for your device.
    fd = open("/sys/bus/pci/devices/0000\:00\:05.0/resource0", O_RDWR | O_SYNC);
    //mmap returns a userspace address
    //0, 4096 tells it to pull one page
    ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    printf("PCI BAR0 0x0000 = 0x%4x\n", *((unsigned short *) ptr));

    if(munmap(ptr, 4096) == -1) PRINT_ERROR;
    close(fd);
    return 0;
}

答案 2 :(得分:0)

在内核中具有/ dev / mem功能的系统上,可以使用以下命令读取设备的栏:

sudo dd if=/dev/mem skip=13701120 count=1 bs=256 | hexdump

查看dd手册页。在上面的示例中,13701120 * 256是将读取256个字节的起始物理地址。