应用层读写i2c主设备寄存器(mmap函数)

一、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 <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;  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值