mmap应用--进程间通信&设备操作&共享内存

一、两个程序映射同一个文件到自己的地址空间, 进程A先运行, 每隔两秒读取映射区域, 看是否发生变化. 进程B后运行, 它修改映射区域, 然后推出, 此时进程A能够观察到存储映射区的变化。

#include <sys/mman.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <error.h> 
 
#define BUF_SIZE 100 

int main(int argc, char **argv)  
{  
 int fd, nread, i;  
 struct stat sb;  
 char *mapped, buf[BUF_SIZE];  
 
 for (i = 0; i < BUF_SIZE; i++) {   
        buf[i] = '#';  
    }   
 
 /* 打开文件 */ 
 if ((fd = open("hello.txt", O_RDWR)) < 0) {   
        perror("open");  
    }   
 
 /* 获取文件的属性 */ 
 if ((fstat(fd, &sb)) == -1) {   
        perror("fstat");  
    }   
 
 /* 将文件映射至进程的地址空间 */ 
 if ((mapped = (char *)mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == (void *)-1) 
 {   
    perror("mmap");  
 }   
 
 /* 文件已在内存, 关闭文件也可以操纵内存 */ 
    close(fd);  
 
 /* 每隔两秒查看存储映射区是否被修改 */ 
 while (1) {   
        printf("%s\n", mapped);  
        sleep(2);  
    }   
 
 return 0;  
}  
~                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
~                       
```  //进程B
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <error.h> 
 
#define BUF_SIZE 100 
 
int main(int argc, char **argv)  
{  
 int fd, nread, i;  
 struct stat sb;  
 char *mapped, buf[BUF_SIZE];  
 
 for (i = 0; i < BUF_SIZE; i++) {   
        buf[i] = '#';  
    }   
 
 /* 打开文件 */ 
 if ((fd = open("hello.txt", O_RDWR)) < 0) {   
        perror("open");  
    }   
 
 /* 获取文件的属性 */ 
 if ((fstat(fd, &sb)) == -1) {   
        perror("fstat");  
    }   
 
 /* 私有文件映射将无法修改文件 */ 
 if ((mapped = (char *)mmap(NULL, sb.st_size, PROT_READ |   
                    PROT_WRITE, MAP_SHARED, fd, 0)) == (void *)-1) {   
        perror("mmap");  
    }   
 
 /* 映射完后, 关闭文件也可以操纵内存 */ 
    close(fd);  
 
 /* 修改一个字符 */ 
    mapped[20] = '6';
    mapped[19] = '6';

    if ((msync((void *)mapped, sb.st_size, MS_SYNC)) == -1) {   
        perror("msync");  
    }   
 
     /* 释放存储映射区 */ 
    if ((munmap((void *)mapped, sb.st_size)) == -1) {   
        perror("munmap");  
    }   


 return 0;  
}  
二、mmap设备操作
2.1 HPS_FPGA AMBA-AXI bridge 总线空间映射 
在ARM和FPGA集成的SOC中,有一种AXI总线,其有4种总线桥。其中一种桥HPS-FPGA low weight bridge,这个实现了HPS(CPU)到FPGA的数据操作。
首先, fd = open("dev/mem",O_RDWR); 这里dev/mem是一个HPS的所有物理地址空间,包括:内存地址、IO地址、映射总线地址如(PCI)。
其次, mmap(NULL,HPS_FPGA_SPAN,,,fd,HPS_FPGA_START); 其中:HPS_FPGA_SPAN大小0x20000,HPS_FPGA_START:0XFF200000
2.2、部分内存设备映射
首先, fd = open("dev/mem",O_RDWR);
其次,mmap(NULL,DDR_SIZE,,,fd,DDR_START); 这里的思想是,把部分DDR物理内存映射到虚拟空间,实现应用层操作物理内存。
2.3、映射后操作
mmap本质是提升访问文件的性能。使用mmap映射后,应用层直接以操作地址的方式读写设备,不需要像read/write再陷入内核层(应用层和内核层的交互消耗时间)。
posted @ 2022-02-11 20:26  行者行者行者  阅读(138)  评论(0)    收藏  举报