2014-09-04 156 views
1

我想学习使用mmap读取和写入一些寄存器。我有以下代码。使用mmap读取/写入寄存器

#define MY_BASE_ADDRESS 0xC0000000 //Base Address for the PCIe 
#define LED_ADDRESS  0x00010000 //Offset for LEDS 0x00010000 
#define MAPPED_FILE_SIZE (50 * sizeof(int)) //Guess 
#define PAGE_SIZE (sysconf(_SC_PAGESIZE)); 

void *mapped_region, *mapped_LED_base; 

off_t dev_base = ( MY_BASE_ADDRESS | LED_ADDRESS); 
unsigned long readback = 0; 

首先我打开在/ dev/MEM

//The O_SYNC option prevents Linux from caching the contents of /dev/mem 
memoryFileDescriptor = open("/dev/mem", O_RDWR | O_SYNC); 
    if (memoryFileDescriptor == -1) 
     { 
     printf("Can't open /dev/mem. %d\n", memoryFileDescriptor); 
     exit(0); 
     } 

// Map one page of memory into user space such that the device is in that page, but 
//it may not 
// be at the start of the page. 
mapped_region = mmap(NULL, 
        MAPPED_FILE_SIZE, //How to know size? 
        PROT_READ | PROT_WRITE, 
        MAP_SHARED, //File may not be updated until msync or munmap is 
                      // called. 
        memoryFileDescriptor, 
        dev_base); //How to know the offset? 

// get the address of the device in user space which will be an offset from the base 
// that was mapped as memory is mapped at the start of a page 
mapped_LED_base = mapped_region + dev_base; 

然后我会写地址:

*((volatile unsigned long *) (mapped_LED_base)) = 0xFFFFF; 

和阅读

readback = *((volatile unsigned long *) (mapped_LED_base)); 

我有麻烦知道什么是MAP_SIZE及其偏移量?文件不那么清楚。当前的代码给出了分段错误错误。

我使用Linux和C++

回答

0

大小为您的硬件寄存器的大小,所以目前你说你有50×32位寄存器。在实践中,这个数字四舍五入为体系结构的页面大小,通常为4KB。

如果你只有一个寄存器是无符号long,那么你应该将它设置为sizeof(unsigned long) - 即使系统“增长”到4KB,你也不应该映射超过实际需要的映射。

+0

是dev_base,偏移量是否正确?这意味着mmap将开始的地址? – user1876942 2014-09-04 08:04:24

+0

映射开始的文件中的地址,是的。你真的检查过你从mmap中得到的指针是不是-1(意思是错误)? – 2014-09-04 08:07:06

+0

是的,mmap不返回-1。因此,我打开dev/mem并在地址dev_base处开始我的映射,长度为50 * ints。该地址是正确的,不知道它为什么崩溃。 – user1876942 2014-09-04 08:10:02