2014-09-04 163 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