2014-09-04 2 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 битных регистров. На практике это число округляется до размера страницы архитектуры, обычно 4 КБ.

Если у вас есть только один длинный регистратор без знака, то вы должны установить его на sizeof(unsigned long) - вам не следует отображать больше, чем вам нужно, даже если система «растет» до 4 КБ.

+0

Действительно ли dev_base, смещение правильно? Это означает адрес, где начнется mmap? – user1876942

+0

Адрес в файле, где начинается ваше сопоставление, да. Вы действительно отметили, что ваш указатель, который вы возвращаете из mmap, не равен -1 (что означает ошибку)? –

+0

Да, mmap не возвращает -1. Итак, я открываю dev/mem и начинаю свое сопоставление по адресу dev_base для длины 50 * ints. Этот адрес правильный, не знаю, почему он сбой. – user1876942

Смежные вопросы