完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
上一篇帖子主要讲了怎么在内核驱动中调用gpiolib.c中的函数来实现对GPIO的控制,今天这篇这篇帖子我们用第三种方法,直接映射物理地址道内存空间,然后自己来写我们的GPIO控制,这个的要求可能更高,需要大家了解GPIO的控制方式。这个主要是要学会看数据手册,根据手册里的东西来控制,在坛子里已经有大神写出了这种控制方式,小狂只是在他的基础上完善罢了,这种方式跟硬件息息相关,所以小狂觉得还是有必要在这里讲一下。 这里先普及一下一个小小的知识点,有很多小伙伴问过小狂,为什么玩嵌入式一旦上了系统就不能直接使用寄存器的物理地址了呢,就不能像单片机一定对寄存器直接操作了呢。在这简单的说两句,其实现在单片机做的跟嵌入式芯片越来越像了,据说STM32H7的主频都可以达到400MHZ啦,这几乎就是ARM9的速度了,但是有个东西跨越不了,就是MMU,内存管理单元,单片机是没有MMU的,什么是MMU简单点说就是对内存的管理,可以让你的程序不必过分的考虑内存的开销,再说白点,就是可以让你的多个程序能在虚拟内存空间中公用物理内存互不干扰,假如有1G内存,进程A可以独享,进程B也可以独享,而不互相干扰。这就可以解释我们最初的内容了,一旦嵌入式系统启动起来后,准确的说是MMU启动起来后,物理地址就交由MMU来控制,用户如果这个时候使用物理地址就会破坏MMU的进程,这是很危险的事情。但是没有关系,我们操作不了物理地址,但是linux底层提供了可以把物理地址映射到内存中的函数,我们可以调用相应的函数把物理地址映射到内存空间中,供我们使用,哈哈,今天,小狂就带着大家来实现这个简单的功能。 同样,开始之前我们先介绍几个函数。 request_mem_region(S1D_PHYSICAL_REG_ADDR,S1D_PHYSICAL_REG_SIZE,"EpsonFB_RG") 这个函数是检查是否物理地址为S1D_PHYSICAL_REG_ADDR之后连续的S1D_PHYSICAL_REG_SIZE字节大小空间可以被安全占用,EpsonFB_RG为你为这次申请内存起的名字。 release_mem_region (S1D_PHYSICAL_REG_ADDR,S1D_PHYSICAL_REG_SIZE) 有申请就有释放,当我们不用的时候就应该把我们申请的空间释放掉 void * ioremap(unsigned long phys_addr,unsigned long size, unsigned long flags) ioremap函数的主要作用是检查传入地址的合法性,建立也表,完成物理地址到虚拟地址的转换,返回的是虚拟地址。 在内核中编程,我们就应该使用内核中的编程方式,在我们拿到映射后的地址后,不能像玩单片机的时候那样直接控制,应该使用对应的IO接口函数 #define readl(addr) (*(volatile unsignedint *) __io_virt(addr)) 上边的函数,读取相应的虚拟地址中的寄存器的数值 #define writel(b,addr) (*(volatile unsignedint *) __io_virt(addr) = (b)) 这个函数用来写寄存器的数值。我们这次大概就需要这些函数,既然是直接操作寄存器,那我们就要看手册了,我们要实现相应的IO的输出功能,看手册中怎么说 英文的,懒得翻译了直接上图,说的大概意思就是我们要使用输出功能就要设置OE寄存器,然后如果想要输出就要实质DATAOUT寄存器了解了这些,我们就来编程吧,这次我们编程采用多文件的方式,驱动在一个.c文件中,寄存器的定义,内存的获取,在另外一个文件中。 先定义寄存器的基地址,定义寄存器结构体看图。 这些寄存器的获得都来自手册,稍微截图说明一下 一定不要定义错啊,定义错了,就悲催了,因为这个偏移量并不是连续的,所以里边定义了很多保留量。定义玩寄存器地址后,我们就要申请内存了, 哎,被stm32的库毒害的太深,写着写着就一堆stm32库的味道,这里我们申请的是整个GPIO寄存器的地址,所以我们只要给定相应的GPIO主地址就行啦。 使能GPIO的函数 设置输出的函数 其实这么写是不对的,应该先读出相应寄存器的值,然后把要控制的位清零,其次才是写值,这样写,会破坏原来的寄存器的内容的,但是懒得改了就这样,让后,他们加入到驱动模块中。 在初始化模块中申请申请内存,并使能我们的GPIO1_25。 然后在write实现函数中实现我们的控制,是不是很简单,有了这种方式,你可以无缝对接单片机的io控制方式啦。 在这里,由于我们实现多个.c,这里的makefile会有些不一样 主要的区别就在红色的框内,obj-m是最终生成库的名字,最好另起名字不要跟你的任何一个.C文件的名字雷同,gpioset-objs是你的.c文件转换成的.o文件,这里,少了这样写没有问题,多了的话,建议,用Makefile的转换函数定义一个变量来写。 完事之后直接编译,没有神马不一样, 然后下载到板子上,具体的操作跟上一篇帖子说的内容完全一样了,如果你按照我的方式写了,你会发现,你把心跳灯给停了,就是因为上边的控制没有读寄存器直接写了,就会影响其他的功能,再次强调不建议这么写。 总结 花了三天的时间终于把三种控制方法给写完了,玩的开心就好,哈哈,大家中意哪一种就用哪一只种,嘿嘿,小狂花了这么多口舌,其实就像说明一个问题,一种问题的实现方法可能会有很多种,大家不要被教科书,或者某个教程固定了思维,玩就要玩出特色,当然可能会很累啊,哈哈。谢谢大家的支持,下一篇串口控制。支持小狂的,希望一如既往的支持哦,哈哈。
|
|
相关推荐
3 个讨论
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
【米尔-紫光MYB-J7A100T国产FPGA开发板试用】米尔-紫光PG2L100H国产FPGA开发板开箱评测
1046 浏览 0 评论
【米尔-紫光PG2L100H国产FPGA开发板试用】官方LED例程测试体验
5452 浏览 0 评论
【米尔-紫光PG2L100H国产FPGA开发板试用】上电测试报告
5101 浏览 0 评论
【米尔-紫光PG2L100H国产FPGA开发板试用】开箱评测!米尔电子PG2L100H开发板深度体验报告
1021 浏览 0 评论
【米尔-Xilinx XC7A100T FPGA开发板试用】+04.SFP之Aurora测试(zmj)
840 浏览 0 评论
【米尔-瑞米派兼容树莓派扩展模块-试用体验】基于ROS系统的三麦轮小车自主导航
3662浏览 2评论
【米尔NXP i.MX 93开发板试用评测】5、安装Debian和排除启动故障
740浏览 2评论
【米尔NXP i.MX 93开发板试用评测】2、异构通信环境搭建和源码编译
882浏览 2评论
【米尔-瑞米派兼容树莓派扩展模块-试用体验】Free RTOS应用开发环境部署
1467浏览 1评论
【米尔-芯驰D9开发板- 国产平台试用】- 03- 外设接口测试-U盘、485总线
6824浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 15:17 , Processed in 0.519055 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号