linux下的led驱动(不涉及设备树)

文章介绍了在32位系统中,Linux内核如何通过MMU将有限的物理内存映射到4GB的虚拟内存空间,并详细阐述了ioremap和iounmap函数在获取和释放设备寄存器的虚拟地址中的作用。通过示例展示了如何使用这些函数控制GPIO,以及构建驱动模块和测试应用程序来控制LED灯的亮灭。
摘要由CSDN通过智能技术生成

1.原理

32位机对应2^32(4G)位虚拟内存空间,我们的开发板含有512M物理内存,linux内核启动会初始化MMU(内存管理单元),MMU会将这512M的物理空间映射到这4G的空间上。我们通过向虚拟内存写数据,操作物理内存。

我们想要知道物理内存对应的虚拟内存地址,涉及两个API函数ioremap和iounmap;

ioremap:用于获取物理地址空间对应对应的虚拟地址空间。

函数原型:

__arm_ioremap为真实函数对应原型:

参数1:cookiie物理空间起始地址

参数2:size:映射空间的大小

参数3:mtype:ioremap 的类型,可以选择 MT_DEVICE、MT_DEVICE_NONSHARED、

MT_DEVICE_CACHED 和 MT_DEVICE_WC,ioremap 函数选择 MT_DEVICE。

返回值:void __iomen*:它表示返回值为虚拟空间的viod*类型

用法举例:想找到 I.MX6ULL 的 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 寄存器对应

的虚拟地址。IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的实际起始地址:0X020E0068;i.MX寄存器的大小位4字节

iounmap:用于取消内存映射,再卸载驱动时使用。

函数原型:

参数:要取消映射虚拟空间的首地址。

I/O内存:由外部寄存器或内存映射到虚拟内存空间的内存

得到虚拟内存的地址后,可以直接操作该地址,但linux内核建议使用一组操作函数来使用

1.读:

该组函数用于读取8,16,32位数据,addr是要读取数据的地址,返回值是读取的数据

2.写:

  1. 实际操作led过程

控制GPIO1_IO03的寄存器地址如下:

定义虚拟内存指针并获取映射地址

有虚拟地址后,我们就可以像操作裸机一样通过配置寄存器控制该引脚了,先是使能时钟,将功能复用为GPIO功能,再设置IO属性,最后将该引脚设置为输出功能。

接下来,我们就是搭建驱动模块,和完成file_operetions结构体,在驱动的读函数中将这些功能设置完成,然后构建字符设备驱动。

最后编写测试APP,通过向我们的设备文件/dev/led写0或1来控制led灯亮或熄灭。

驱动源码

测试APP比较简单,就是向我们创建的设备文件/dev/led写入0或1,将它通过file_operations的.write写入到驱动,从而控制led

源码如下

结果:向/dev/led写0,led熄灭

向/dev/led写1点亮led

总结:

系统对内存的地址进行重定义,让重定义后的地址组合成一块连续的内存,它的最大空间就是cpu的最大寻址空间,对于32位机来说,这个空间的范围是4GB,在每个进程创建时,内核会为这个进程分配4G的内存,而我们嵌入式开发需要的是具体某个外设寄存的地址,由单片机的物理内存到虚拟内存的映射是由内核的MMU完成的,我们只需要获取到真实寄存器地址对应的虚拟内存地址,然后往虚拟地址对应的内存写入值,从而也是向寄存器写值,控制外设。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值