关于/dev/mem学习

/dev/mem,通过mmap可以将物理地址映射到用户空间的虚拟地址上,在用户空间完成对设备寄存器的操作,/dev/mem是物理内存的全映像,可以用来访问物理内存,一般用法是open("/dev/mem",O_RDWR|O_SYNC),接着就可以用mmap来访问物理内存以及外设的IO资源,这就是实现用户空间驱动的一种方法。

关于mmap原理
映射就是建立一种一一对应关系,在这里主要是指硬盘上文件的位置与进程逻辑地址空间 中一块大小相同的区域之间的一一对应
这种对应关系纯属是逻辑上的概念,物理上是不存在的,原因是进程的逻辑地址空间本身就是不存在的。在内存映射的过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上被放入了内存,具体到代码,就是建立并初始化了相关的数据结构(struct address_space),这个过程由系统调用mmap()实现,所以建立内存映射的效率很高。

int pli_init()
{
	if(pliFd > 0)
		return 1;
	pliFd = open(MEM_PATH,O_RDWR|O_SYNC);
	if(pliFd < 0)
	{
		printf("pli_init failed!\r\n");
		return -1;
	}

	baseIOVirAddress = mmap((void *)NULL, REGS_RANG_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, pliFd,INTER_REGS_BASE);
	if(baseIOVirAddress == MAP_FAILED) {
		printf("Unable to mmap \r\n");
		return -1;
	}
	printf("pli_init success Base 0x%x!\r\n",INTER_REGS_BASE);
	return pliFd;
}
int* pli_getIOAddress( int addr)
{
	volatile void* targetIOVirAddress = NULL;
	if(baseIOVirAddress == NULL)
		return NULL;
	targetIOVirAddress = baseIOVirAddress + addr;
	return (int*)targetIOVirAddress;
}
/*
* 设置GPIOX 接口复用功能
* port: 0~9  A~J GPIO类型
* portPin: 0~15  GPIOX对应引脚
* mode: 0x00: 普通IO口功能 0xXX 复用功能  其他: 普通IO口功能
*/
int setMPPMode(unsigned char port,unsigned int portPin,unsigned char mode)
{
	volatile unsigned int *baseRegAddr = NULL;
	unsigned char pin = portPin;
	if(pin < 8)
	{
		pin *= 4;
		baseRegAddr =(volatile unsigned int *) pli_getIOAddress(SYS_REG_BASE_ADDR+0x70+port*8);
	}
	else
	{
		pin = (pin-8)*4;
		baseRegAddr = (volatile unsigned int *)pli_getIOAddress(SYS_REG_BASE_ADDR+0x70+port*8+4);
	}
	*baseRegAddr &= ~(0xf << (pin));  //先设置为通用IO模式
	*baseRegAddr |= (mode << (pin));  //这个决定复用还是通用
//设置IO模式
	//printf("port %d portPin %d setMPPMode  0x%x = 0x%x\r\n",port,portPin,(SYS_REG_BASE_ADDR+0x70+port*8),*baseRegAddr);



	return 1;
}

在这里插入图片描述

/*
*	设置通用GPIO的方向
* port: 0~9  A~J GPIO类型
* portPin: 0~15  GPIOX对应引脚
* isOut : 1 is output,0 is input
********/
int setGPIODir(unsigned char port,unsigned int GPIOPin,unsigned char isOut)
{
	volatile unsigned int *baseRegAddr = NULL;
	if(isOut > 0)
		isOut = 1;
	else
		isOut = 0;
	baseRegAddr = pli_getIOAddress(GPIO_BASE_ADDR+0x40*port);//DIR
	//printf("Before 0x%x\r\n",(*baseRegAddr));
	//对应位置零后,再置为想要的
	*baseRegAddr = ((*baseRegAddr) & (~(1 << GPIOPin))) | (isOut << GPIOPin);//setDIR
	//printf("port %d portPin %d setMPPMode  0x%x = 0x%x\r\n",port,GPIOPin,(GPIO_BASE_ADDR+0x40*port),*baseRegAddr);
	//printf("port %d portPin %d setMPPMode  0x%x = 0x%x\r\n",port,GPIOPin,(GPIO_BASE_ADDR+0x40*port+0x20),*baseRegAddr);
	return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只很笨很懒的肥猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值