作者Eenie (Eenie)
看板C_and_CPP
标题[问题] I2C LINUX mmap R/W一问
时间Fri Aug 25 17:11:15 2017
开发平台(Platform): (Ex: Win10, Linux, ...)
LINUX
问题(Question):
小弟目前希望能於linux上读写soc板子定义好的I2C Memory Mapped Registers,目前已
知I2C的Memory Base Address为:0xdf02e000,因linux无法直接存取physical address
,故小弟利用开启/dev/mem及使用mmap映射/dev/mem至虚拟位址上,但对於R/W的方式并
不是相当熟悉,目前撰写code进行mapping如下
预期的正确结果(Expected Output):
由linux读写I2C register
程式码(Code):(请善用置底文网页, 记得排版)
int main(int argc, char** argv){
unsigned int base, basepage, baseoff, pagesize;
unsigned char* mem;
int fd;
fd = open("/dev/mem",O_RDWR);
if (fd < 0){
printf("device file open error !\n");
return 0;
}
pagesize = getpagesize();
base = 0xDF02E000;
baseoff = base % pagesize;
basepage = base - baseoff;
mem = (unsigned char*) mmap(NULL, 0x20FD1FFF, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, basepage);
if (mem == (void *)-1){
printf("Error while maping memory\n");
return 0;
}
printf("%x\n",(mem+offset));
#if 0
这边是需做读写的部分。
#endif
close(fd);
munmap(mem, 0x20FD1FFF);
return 0;
}
补充说明(Supplement):
问题一:已知mmap是将fd映射於一虚拟位址,当我去printf(mem+offset)时,
每当我printf一次,每次出来的虚拟位址都不同,请问这样为正确行为吗?
问题二:如我想对I2C (0xdf02e000)的Register做读写,例如:
於0xdf02e000的offset 4h写入0x30
於0xdf02e000的offset 0h写入0x63等等,
请问该如何进行读写?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.128.110.82
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1503652278.A.4D9.html
1F:→ Lipraxde: 1.你程式重开mmap拿到不一样的值是正常的 08/25 17:22
2F:→ Lipraxde: 2.指标怎麽写就怎麽写 08/25 17:22
3F:推 johnjohnlin: btw 楼上说的应该是像 ((int32_t*)mem)[0] = 4 这样 08/26 00:20
4F:→ F04E: 你为什麽要在user space做这件事?你是要读取连接在I2C bus 08/29 11:02
5F:→ F04E: 的device的资料,还是要写I2C controller的driver? 08/29 11:03
6F:推 Hoare: 可参考devmem这支程式的source code 09/02 01:09