电子说
一开接触设备树,我就不知道设备树与驱动的关系,设备树是在内核3.0以后才有的。不过3.0以前的和3.0以后的驱动其实变化不大。
驱动的开发方法可以分为三种:传统方法,总线方法,设备树方法。这篇文章围绕点亮一颗LED来说明这三种方法。
驱动流程分为5个部分:
1、分配
2、设置
3、注册file_operation
4、入口
5、出口
一、传统方法
传统方法就是简单粗暴方法,就是将IO设置,驱动放在同一个文件(drv.c)。
drv.c:定义引脚信息
drv.c:驱动中的open函数
drv.c:驱动中的close函数
drv.c:file_operations结构体
为上层应用提供open(),write(),read(),close()。
drv.c:入口函数-申请设备号,创建设备节点
其中register_chrdev():申请设备号。
class_create():创建一个设备类。
device_create():创建一个设备节点,路径:/dev/led
drv.c:出口函数-注销设备,注销设备节点
其中unregister_chrdev():通过主设备号,注销设备号
device_destroy():注销设备节点
class_destroy():注销设备类
传统方法:
优点:操作简单
缺点:不易扩展,每次修改需要重新编译驱动
二、总线方法
在kernel 3.0之前都是采用总线的方法实现驱动与设备之间的联系。把驱动跟设备分开。
其主要理解几个结构体:
①跟设备有关的结构体:structplatform_device{};
②跟驱动有关的结构体:structplatform_driver{};
还要理解其中包含的两个结构体:
-> struct device_driver{};
-> structplatform_device_id{};
要记住一句话:在match的时候:优先匹配id_table的name,不匹配。再匹配driver的name
其中
dev.c:进行设备的引脚定义,定义resouce结构体,供驱动获取资源。
dev.c:注册platform_device结构体
dev.c:入口函数-注册设备
其中platform_device_register():在总线上注册一个设备。
dev.c:出口函数-注销设备
其中platform_device_unregister():在总线上注销一个设备。
对于驱动来说,需要稍微修改一下:
drv.c:增加probe函数和remove函数,其中:
probe()函数:充当传统方法的init函数
remove()函数:充当传统方法的exit函数
platform_get_resource():获取设备中资源,比如引脚定义。
drv.c :入口函数和出口函数修改
将传统方法的file_operations{};结构体改为platform_driver{};结构体
其中platform_driver_register():向总线注册一个设备。
platform_driver_unregister():向总线注销一个设备。
platform总线中的match()函数是设备与驱动匹配的函数,我们看看这个函数的实现,就是匹配设备与驱动的名字一不一致。函数如下:
总线方法:
优点:易扩展
缺点:代码冗余多,需要重新编译设
三、设备树方法
在kernel 3.0以及之后的版本,都是采用设备树的方法实现驱动与设备之间的联系。将总线方法的设备改为设备树实现,解决了总线方法中代码冗余多的问题。
设备树方法只需要在总线方法的基础上稍微修改一下。
dts:添加设备节点:
drv: probe修改,其中通过函数of_property_read_s32()获取设备树的资源。
设备树:
优点:易扩展,不需要重新编译(替换设备树),无冗余代码
缺点:稍微复
最多技术干货内容请稳步到“电子发烧友网”公众号,回复资料即可免费获取一份技术资料,在这里每天可以获取最专业、最前沿的电子技术。
全部0条评论
快来发表一下你的评论吧 !