您的位置:首页 > 运维架构 > Linux

Linux学习之Led驱动程序理解

2016-01-03 20:59 501 查看
最近就是在学习驱动模块怎么编写,为什么要这样写,下面就写一下led驱动程序每一段代码的理解。


前面的头文件就不说了,看这个static unsigned long gpio1_base_addr;这里就是定义一个静态变量,用来通过地址的改变,来改变各种寄存器,因为地址可以直接累加的,所以通过改变地址来改变后面所要用到的寄存器,像下面三个,那些加在基地址后面的不是随便就写得,要通过查询那个寄存器的表而得来的,都是通过使寄存器实现不同的功能,通过改变他们的相位,设置他们的引脚来控制灯的开关。


而下面定义的也都是通过查表找到自己需要什么功能的寄存器,从而对寄存器的相应位进行设置,达到自己的要求。





这里面的open ,write,iotcl函数,当调用时会和后面说到的核心结构体有关系,当应用函数打开某个设备时,设备驱动程序的file_operations结构中的相应的open成员就会被调用;其它相应的write,ioctl等函数读写、控制设备时,驱动的程序中的相应的read,write,ioctl函数会被调用。也就是说,我觉得编写一个驱动模块代码就是实现那个核心驱动模块结构体中的功能,也就是完成各种函数。

而上面的各种函数中,就是通过改变GPIO的数据寄存器来改变引脚的输出电平,open就会设置引脚为低电平的时候输出为0,led就会被依次点亮,高电平就会熄灭led,ioctl函数也就是通过改变来实现的,原理相同。

这个就是驱动中核心的结构体代码:



.open = leds_open, //用来初始化LED所用的GPIO引脚

.write
= leds_write,

.unlocked_ioctl = leds_ioctl,//用来根据用户传入的参数设置用户传入的参数设置GPIO的输出电平从而改变灯的状态

下面就是执行编译模块以及卸载模块的代码





gpio1_base_addr = ioremap(0x4804c000, 0x1000); //

这一行代码就是上面所说的通过基地址的改变找到所使用的寄存器, 将物理地址映射为虚拟地址。



上面就是驱动程序的初始化函数和卸载的函数,当我们在生成了什么什么.ko的模块文件的时候,然后执行insmod就会调用这个函数,

最后的应该就是描述所写的驱动程序的一些信息,自己定义就好了。

好啦,差不多就是这样了,通过对led驱动模块程序的深入理解,所以决定要开始自己写了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: