2015-03-31 30 views
0

我正在使用Raspberry Pi B +,并且我正在尝试mmap /dev/mem的两个不同部分 - 第一个能够从位置0x2020 00040x04字节长)中设置两个引脚的功能,另一个用于从位置0x2021 40000x1C字节长)的Pi上的BCM2835芯片上操作BSC Slave功能。将同一个文件分两次打印

static uint32_t * initMapMem(int fd, uint32_t addr, uint32_t len) 
{ 
    return (uint32_t *) mmap((void*)0x0, len, 
     PROT_READ|PROT_WRITE|PROT_EXEC, 
     MAP_SHARED|MAP_LOCKED, 
     fd, addr); 
} 

int initialise(void) { 
    int fd; 

    fd = open("/dev/mem", O_RDWR | O_SYNC) ; 

    if (fd < 0) 
    { 
     fprintf(stderr, "This program needs root privileges. Try using sudo.\n"); 
     return 1; 
    } 

    pinReg = initMapMem(fd, 0x20200004, 0x4); 
    bscReg = initMapMem(fd, 0x20214000, 0x1C); 

    close(fd); 

    if (bscReg == MAP_FAILED) 
    { 
     fprintf(stderr, "Bad, mmap failed.\n"); 
     return 1; 
    } 
    if (pinReg == MAP_FAILED) 
    { 
     fprintf(stderr, "Bad, mmap failed.\n"); 
     return 1; 
    } 
    return 0; 
} 

initialise()叫出来的main()。用gdb步进程序我发现bscReg的位置正确,但pinReg返回为MAP_FAILED(又名0xFFFFFFFF),其中errno设置为EINVAL。无论哪种方式完成 - pinReg始终认为自己为MAP_FAILED,当mmap编辑第一或第二。

如何将pinReg设置为有效值?

回答

2

第一个mmap()失败,因为您试图映射的偏移量(0x20200004)不是页面对齐的。创建一个至少为8的大小为0x20200000的映射,然后写入它的偏移量为0x4

+0

Aaah。这就是失败的原因。我以为我只是通过映射我需要的东西而变得co being。我最终映射了'0x0',偏移量'0x2020000',长度'0x8',所以我仍然可以使用现有的'initMapMem'方法 - 无论如何工作。谢谢你的收获! (如果我知道RasPi的内存页面大小是否会有所帮助......)我会立即接受它作为网站允许我的答案。 – sctjkc01 2015-03-31 18:24:38

+0

几乎所有架构(包括ARM)的内存页面大小均为4K。 – duskwuff 2015-03-31 18:41:32

+0

值得一提的是'sysconf(_SC_PAGESIZE)'也会为你提供页面大小(尽管在这种情况下不太可能改变)。 – Ulfalizer 2015-03-31 19:12:01