• linux mmap使用例子_wallwindChinaUnix博客


    linux mmap使用例子_wallwind-ChinaUnix博客

    linux mmap使用例子 (2012-04-25 16:18)

    原文地址linux mmap使用例子 作者gududesiling



    =====文件名:abc.c=====
    一。
    linux mmap使用例子
    转自:http://blog.163.com/zhaoxin851055@126/blog/static/8112929820122872212734/

    #include <sys/mman.h> /* for mmap and munmap */
    #include <sys/types.h> /* for open */
    #include <sys/stat.h> /* for open */
    #include <fcntl.h> /* for open */
    #include <unistd.h> /* for lseek and write */
    #include <stdio.h>

    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 <sys/mman.h> /* for mmap and munmap */
    #include <sys/types.h> /* for open */
    #include <sys/stat.h> /* for open */
    #include <fcntl.h> /* for open */
    #include <unistd.h> /* for lseek and write */
    #include <stdio.h>
    #include <string.h> /* 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的函数声明:

    头文件:
    <unistd.h>
    <sys/mman.h>
    原型: 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 <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include<sys/mman.h>
    #include<fcntl.h>
    #include <asm/page.h>


    #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");

    }

  • 相关阅读:
    一步步构建大型网站架构
    程序员技术练级攻略
    再谈“我是怎么招聘程序员的”
    os.path.basename()
    用pymysql实现的注册登录公告练习
    缓冲(cache)和缓存(buffer)
    数据库视图,触发器,事务,存储过程,函数,备份与恢复
    mysql用户管理和pymysql
    mysql重点,表查询操作和多表查询
    数据库的约束语句和表之间的关系
  • 原文地址:https://www.cnblogs.com/lexus/p/2842379.html
Copyright © 2020-2023  润新知