动态映射结构体 与 内核提供的读写寄存器接口

之前讲过映射硬件,可以看一下:                    现在用动态的映射

驱动操控硬件(静态、动态控制LED)icon-default.png?t=N3I4https://blog.csdn.net/weixin_54683011/article/details/130366248?spm=1001.2014.3001.5502

动态映射操作LED

1、建立动态映射

首先使用request_mem_region()函数向内核申请需要映射的内存资源。

然后使用ioremap()函数来实现映射,传给它一个物理地址,返回一个虚拟地址。

也就是说,要先申请(不一定申请成功),然后再映射,然后再使用。

2、销毁动态映射

首先使用iounmap()函数解除映射,然后使用release_mem_region()函数释放申请。

也就是说,使用完要解除映射时,先解除映射,然后再释放申请。

原来的:

static int __init chrdev_init(void)
{
.....
.....
.....
if (!request_mem_region(GPJ0CON_PA, 4, "GPJ0CON"))
		return -EINVAL;
	if (!request_mem_region(GPJ0DAT_PA, 4, "GPJ0CON"))
		return -EINVAL;
	
	pGPJ0CON = ioremap(GPJ0CON_PA, 4);
	pGPJ0DAT = ioremap(GPJ0DAT_PA, 4);
	
	*pGPJ0CON = 0x11111111;
	*pGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));		// 亮
....
....
}


static void __exit chrdev_exit(void)
{
	printk(KERN_INFO "chrdev_exit helloworld exit\n");

	*pGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));	
	
	// 解除映射
	iounmap(pGPJ0CON);
	iounmap(pGPJ0DAT);
	release_mem_region(GPJ0CON_PA, 4);
	release_mem_region(GPJ0DAT_PA, 4);


	// 使用新的接口来注销字符设备驱动
	// 第一步真正注销字符设备驱动用cdev_del
	cdev_del(&test_cdev);
	// 第二步去注销申请的主次设备号
	unregister_chrdev_region(mydev, MYCNT);
}

动态映射结构体方式:(最好用这种方式)

	
static int __init chrdev_init(void)
{
...
...
...
    // 2步完成了映射
	if (!request_mem_region(GPJ0_REGBASE, sizeof(gpj0_reg_t), "GPJ0REG"))
		return -EINVAL;
	pGPJ0REG = ioremap(GPJ0_REGBASE, sizeof(gpj0_reg_t));
	// 映射之后用指向结构体的指针来进行操作
	// 指针使用->结构体内元素的方式来操作各个寄存器
	pGPJ0REG->gpj0con = 0x11111111;
	pGPJ0REG->gpj0dat = ((0 << 3) | (0 << 4) | (0 << 5)); // 亮

	return 0;
}

static void __exit chrdev_exit(void)
{
	printk(KERN_INFO "chrdev_exit helloworld exit\n");

	//	*pGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));
	pGPJ0REG->gpj0dat = ((1 << 3) | (1 << 4) | (1 << 5));

	// 解除映射
	/*                原来的
		iounmap(pGPJ0CON);
		iounmap(pGPJ0DAT);
		release_mem_region(GPJ0CON_PA, 4);
		release_mem_region(GPJ0DAT_PA, 4);

	*/               动态映射方式
	iounmap(pGPJ0REG);
	release_mem_region(GPJ0_REGBASE, sizeof(gpj0_reg_t));

	// 在module_exit宏调用的函数中去注销字符设备驱动
	unregister_chrdev(mymajor, MYNAME);
}

内核提供的读写寄存器接口

为了增加可移植性,内核提供的寄存器读写接口:

(1)writel和readl
(2)iowrite32和ioread32

(1)和(2)没有什么本质上的差异

writel:

功能:writel() 函数往内存映射的 I/O 空间上写入32位(4字节)数据。

参数:
data:要写入的一个字节的数据.
addr:32位I/O 地址。

readl

功能:readl() 函数从内存映射的 I/O 空间读取32位(4字节)数据。

参数
addr :I/O 地址。
返回值 : 从 I/O 空间读取的数值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值