linux mmap实例_linux mmap使用例子

=====文件名:abc.c=====

一。

linux mmap使用例子

转自:http://blog.163.com/zhaoxin851055@126/blog/static/8112929820122872212734/

#include/* for mmap and munmap */

#include/* for open */

#include/* for open */

#include/* for open */

#include/* for lseek and write */

#include

int main(int argc, char **argv)

{

int fd;

char *mapped_mem, * p;

int flength = 1024;

void * start_addr = 0;

fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

flength = lseek(fd, 1, SEEK_END);

write(fd, "\0", 1); /* 在文件最后添加一个空字符,以便下面printf正常工作 */

lseek(fd, 0, SEEK_SET);

mapped_mem = mmap(start_addr, flength, PROT_READ, //允许读

MAP_PRIVATE, //不允许其它进程访问此内存区域

fd, 0);

/* 使用映射区域. */

printf("%s\n", mapped_mem); /* 为了保证这里工作正常,参数传递的文件名最好是一个文本文件 */

close(fd);

munmap(mapped_mem, flength);

return 0;

}

编译运行此程序:

gcc -Wall mmap.c

./a.out text_filename

上面的方法因为用了PROT_READ,所以只能读取文件里的内容,不能修改,如果换成PROT_WRITE就可以修改文件的内容了。又由于 用了MAAP_PRIVATE所以只能此进程使用此内存区域,如果换成MAP_SHARED,则可以被其它进程访

#include/* for mmap and munmap */

#include/* for open */

#include/* for open */

#include/* for open */

#include/* for lseek and write */

#include

#include/* for memcpy */

int main(int argc, char **argv)

{

int fd;

char *mapped_mem, * p;

int flength = 1024;

void * start_addr = 0;

fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

flength = lseek(fd, 1, SEEK_END);

write(fd, "\0", 1); /* 在文件最后添加一个空字符,以便下面printf正常工作 */

lseek(fd, 0, SEEK_SET);

start_addr = 0x80000;

mapped_mem = mmap(start_addr, flength, PROT_READ|PROT_WRITE, //允许写入

MAP_SHARED, //允许其它进程访问此内存区域

fd, 0);

/* 使用映射区域. */

printf("%s\n", mapped_mem); /* 为了保证这里工作正常,参数传递的文件名最好是一个文本文 */

while((p = strstr(mapped_mem, "Hello"))) /* 此处来修改文件 内容 */

{

memcpy(p, "Linux", 5);

p += 5;

}

close(fd);

munmap(mapped_mem, flength);

return 0;

}

/*

Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明:

头文件:

原型: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offsize);

返回值: 成功则返回映射区起始地址, 失败则返回MAP_FAILED(-1).

参数:

addr: 指定映射的起始地址, 通常设为NULL, 由系统指定.

length: 将文件的多大长度映射到内存.

prot: 映射区的保护方式, 可以是:

PROT_EXEC: 映射区可被执行.

PROT_READ: 映射区可被读取.

PROT_WRITE: 映射区可被写入.

PROT_NONE: 映射区不能存取.

flags: 映射区的特性, 可以是:

MAP_SHARED: 对映射区域的写入数据会复制回文件, 且允许其他映射该文件的进程共享.

MAP_PRIVATE: 对映射区域的写入操作会产生一个映射的复制(copy-on-write), 对此区域所做的修改不会写回原文件.

此外还有其他几个flags不很常用, 具体查看linux C函数说明.

fd: 由open返回的文件描述符, 代表要映射的文件.

offset: 以文件开始处的偏移量, 必须是分页大小的整数倍, 通常为0, 表示从文件头开始映射.

下面说一下内存映射的步骤:

用open系统调用打开文件, 并返回描述符fd.

用mmap建立内存映射, 并返回映射首地址指针start.

对映射(文件)进行各种操作, 显示(printf), 修改(sprintf).

用munmap(void *start, size_t lenght)关闭内存映射.

用close系统调用关闭文件fd.*/

二。下面这个代码比较经典,但是我们基于这个修改ppc8280的gpio操作时,没有成功。

/*linux下使用mmap控制GPIO

2008-07-12 7:41

欢迎看看我的另一个小窝,说不定有意外的惊喜哦 ^_^ www.devres.info

如果没有/dev/mem,则执行

mknod /dev/mem c 1 1

编译下面的代码*/

#include

#include

#include

#include

#include

#include

#define GPIO_CTL_BASE 0x56000000

#define rGPBCON 0x10

#define rGPBDAT 0x14

#define rGPBUP 0x18

unsigned int *GPBCON,*GPBDAT,*GPBUP;

void Led_Display(int data)

{

*(volatile unsigned int *)GPBDAT= (~data & 0xf)<<7;//因为是第7-10位,且只有4位,故 左移7

}

int main(int argc, char** argv)

{

int gpio_fd, ip=0, i=0;

unsigned char *gpio_map;

gpio_map = NULL;

GPBCON = NULL;

GPBDAT = NULL;

GPBUP = NULL;

gpio_fd =open("/dev/mem",O_RDWR);

if (gpio_fd == -1)

{

printf("can't open /dev/mem.\n");

return ;

}

gpio_map = (unsigned char *)mmap(0, 0xbc,PROT_READ | PROT_WRITE, MAP_SHARED,gpio_fd, GPIO_CTL_BASE);

GPBCON = (volatile unsigned int *) (gpio_map+rGPBCON);

GPBDAT = (volatile unsigned int *) (gpio_map+rGPBDAT);

GPBUP = (volatile unsigned int *) (gpio_map+rGPBUP);

//初始化io

*(volatile unsigned int *)GPBCON=0x154000;

*(volatile unsigned int *)GPBUP=0x7ff;

for(i=0;i<16;i++)

{

Led_Display(i);

sleep(1);

}

munmap(0, 0xbc);

if (gpio_fd != 0x0)

{

close(gpio_fd);

}

printf("GPIO Control Test end\n");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值