应用层读写i2c主设备寄存器(mmap函数)
2015-09-29 12:26
381 查看
一、mmap函数用法
头文件:
#include <sys/mman.h>
函数:void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);
参数start:指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。
参数length:代表将文件中多大的部分映射到内存。
参数prot:映射区域的保护方式。可以为以下几种方式的组合:
PROT_EXEC 映射区域可被执行
PROT_READ 映射区域可被读取
PROT_WRITE 映射区域可被写入
PROT_NONE 映射区域不能存取
参数flags:影响映射区域的各种特性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
MAP_FIXED 如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。
MAP_SHARED对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。
MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。
MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。
MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。
MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换(swap)。
参数fd:要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。
参数offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
返回值:
若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。
二、代码
代码结构同上篇“应用层读写i2c主设备寄存器”,预定义AUDIO_REG_BASE和MAP_SIZE的值决定内存映射的位置和大小
头文件:
#include <sys/mman.h>
函数:void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);
参数start:指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。
参数length:代表将文件中多大的部分映射到内存。
参数prot:映射区域的保护方式。可以为以下几种方式的组合:
PROT_EXEC 映射区域可被执行
PROT_READ 映射区域可被读取
PROT_WRITE 映射区域可被写入
PROT_NONE 映射区域不能存取
参数flags:影响映射区域的各种特性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
MAP_FIXED 如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。
MAP_SHARED对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。
MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。
MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。
MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。
MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换(swap)。
参数fd:要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。
参数offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
返回值:
若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。
二、代码
代码结构同上篇“应用层读写i2c主设备寄存器”,预定义AUDIO_REG_BASE和MAP_SIZE的值决定内存映射的位置和大小
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <linux/types.h> #include <sys/types.h> #include <sys/ioctl.h> #include <errno.h> #include <assert.h> #include <string.h> #define AUDIO_REG_BASE ( 0x01C71000) #define MAP_SIZE 0xFF int strtol_lzh(unsigned char *ps,int flag) { int i=10; int r=0; char *pc = ps; if(NULL==ps ) return -1; while(*pc != '\0') { if((*pc >= 'a' && *pc <= 'f') || (*pc >= 'A' && *pc <= 'F') || (*pc == 'x' || *pc == 'X') ) { i=16; } else if( *pc < '0' || *pc > '9') { return -1; } pc++; } if(flag!=0) i=flag; pc = ps; while(*pc != '\0') { r *= i; if( *pc>='a' && *pc <= 'f') { r += (*pc-'a')+10; } else if( *pc>='A' && *pc <= 'F') { r += (*pc-'A')+10; } else if( *pc>='0' && *pc <= '9') { r += (*pc-'0'); } pc++; } return r; } static int dev_fd; int main(int argc, char **argv) { unsigned char reg_address =0; unsigned int data=0; int tmp; dev_fd = open("/dev/mem", O_RDWR | O_NDELAY); if (dev_fd < 0) { printf("open(/dev/mem) failed."); return 0; } unsigned char *map_base=(unsigned char * )mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, AUDIO_REG_BASE ); if(argc==1) { printf("SYNCEN:%x \n", *(volatile unsigned int *)(map_base+0x00)); //读出00寄存器值 printf("MOSESET:%x \n", *(volatile unsigned int *)(map_base+0x04)); printf("HDW:%x \n", *(volatile unsigned int *)(map_base+0x08)); printf("VDW:%x \n", *(volatile unsigned int *)(map_base+0x0C)); printf("PPLN:%x \n", *(volatile unsigned int *)(map_base+0x10)); printf("LPFR:%x \n", *(volatile unsigned int *)(map_base+0x14)); printf("SPH:%x \n", *(volatile unsigned int *)(map_base+0x18)); printf("LNH:%x \n", *(volatile unsigned int *)(map_base+0x1C)); printf("SLV0:%x \n", *(volatile unsigned int *)(map_base+0x20)); printf("SLV1:%x \n", *(volatile unsigned int *)(map_base+0x24)); printf("LNV:%x \n", *(volatile unsigned int *)(map_base+0x28)); printf("CULH:%x \n", *(volatile unsigned int *)(map_base+0x2C)); printf("CULV:%x \n", *(volatile unsigned int *)(map_base+0x30)); printf("HSIZE:%x \n", *(volatile unsigned int *)(map_base+0x34)); printf("REC656IF:%x \n", *(volatile unsigned int *)(map_base+0x84)); printf("VDINT0:%x \n", *(volatile unsigned int *)(map_base+0x70)); printf("VDINT1:%x \n", *(volatile unsigned int *)(map_base+0x74)); printf("VDINT2:%x \n", *(volatile unsigned int *)(map_base+0x78)); printf("CCDCFG:%x \n", *(volatile unsigned int *)(map_base+0x88)); } else if(argc==2|| argc > 4) { printf("Usage: %s [[-r regAddr] | [-w regAddr byteData]]\n", argv[0]); } else { if( strstr(argv[1],"-w") ) // write a byte only { if(-1 == (tmp=(unsigned short)strtol_lzh(argv[2],16)) ) { printf(" Invalid reg_addr: %s ",argv[2]); close(dev_fd); return -1; } reg_address = (unsigned short)tmp; if(-1 == (tmp=(unsigned int)strtol_lzh(argv[3],16)) ) { printf(" Invalid data: %s ",argv[3]); close(dev_fd); return -1; } data = (unsigned int)tmp; *(volatile unsigned int *)(map_base + reg_address ) = data; printf("mode: write reg_addr: 0x%02x data: %x \n", reg_address, data); } if( strstr(argv[1],"-r") ) // read a byte only { if(-1 == (tmp=(unsigned short)strtol_lzh(argv[2],16)) ) { printf(" Invalid reg_addr: %s ",argv[2]); close(dev_fd); return -1; } reg_address = (unsigned short)tmp; printf("mode: read reg_addr: %3d (%02x) \n", reg_address, *(volatile unsigned int *)(map_base + reg_address )); } } if(dev_fd) close(dev_fd); munmap(map_base,MAP_SIZE); return 0; }
相关文章推荐
- 解决iOS 9 symbolicatecrash卡死
- Linux系统巡检常用命令
- js中null和undefined区别
- LVS配置文件详解及相关技巧介绍
- iOS开发UI篇—简单介绍静态单元格的使用
- Build wxWidgets applications in Ubuntu
- java利用栈实现四则运算
- 服务器设置该考虑哪些关键点
- IOS开发UI篇—UITableview控件使用小结
- 转15个必须知道的chrome开发者技巧GIF
- HTML5几个设计和修改的页面范例分享
- ajax 异步上传带进度条视频并提取缩略图
- os开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- matlab中字符串连接的3种方法
- C++11智能指针之unique_ptr
- c++课程感谢3
- 你应该知道的16个Linux服务器监控命令
- oracle 索引建立小计
- 详解原码、反码、补码——深入理解补码
- 使用JQuery制作浮动窗口