您的位置首页>企业动态>

想要驾驭Linux驱动开发,必须深刻理解Linux总线设备驱动框架

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解想要驾驭Linux驱动开发,必须深刻理解Linux总线设备驱动框架问题。Linux驱动程序的

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解想要驾驭Linux驱动开发,必须深刻理解Linux总线设备驱动框架问题。

Linux驱动程序的开发和应用程序的开发有很大的区别,这就导致了编写Linux设备驱动程序和编写应用程序的本质区别。

1.用户模式和内核模式。

Linux操作系统分为用户模式和内核模式。内核模式完成与硬件的交互,如读写内存、从硬盘读取数据到内存等。驱动程序与底部的硬件交互,因此它在内核模式下工作。用户模式可以理解为上层应用,可以是Java应用、Qt应用、Python应用等等。Linux操作系统之所以分为两种状态,是因为即使用户模式下的应用出现异常,也不会导致操作系统崩溃,而这一切都归功于内核模式对操作系统的强大保护能力。

另一方面,Linux操作系统之所以分为两种状态,是为了给应用程序提供统一的计算机硬件抽象。在用户模式下工作的应用程序可以完全忽略底层硬件操作,这些操作由内核模式程序完成。这些内核程序大多是设备驱动程序。应用程序可以在不知道硬件工作原理的情况下很好地操作硬件设备,同时不会使硬件设备进入非法状态。值得注意的是,用户模式和内核模式可以相互转换。每当应用程序执行系统调用或被硬件中断挂起时,Linux操作系统就会从用户模式切换到内核模式。当系统调用完成或中断处理完成时,操作系统将从内核模式返回到用户模式,继续执行应用程序。

二是模块机制。

模块是可以在运行时添加到内核中的代码,这是Linux的一个很好的特性。这个特性可以让内核轻松扩展或收缩。扩展内核可以增加内核的功能,而收缩内核可以减小内核的大小。Linux内核支持多种模块,其中驱动程序是最重要的一个。每个模块由编译后的目标代码组成。使用insmod命令将模块添加到正在运行的内核中,使用rmmod命令从内核中删除一个未使用的模块。当内核启动时加载一个模块叫做静态加载,当内核已经运行时加载叫做动态加载。模块可以扩展内核期望的任何功能,但它们通常用于实现设备驱动程序。模块最基本的框架代码如下:

三.公共汽车、设备和司机。

要想控制Linux驱动开发,必须对Linux总线设备驱动框架有深刻的理解。之所以形成这个框架,主要是为了代码的可重用性,因为驱动和设备之间是一对多的关系。就像主设备号和辅助设备号一样,主设备号代表驱动程序,辅助设备号代表特定设备。另外,为了提高驱动的可移植性,Linux剥离了驱动使用的资源(如GPIO和中断等)。)到设备进行管理。也就是说,设备包含它自己的设备属性,并且还包括它用来连接到SOC的资源。而驾驶员则专注于操作的过程和方法。总线的功能是在软件层面管理设备和驱动程序。为了让系统知道它的存在,设备需要向总线注册。同样,为了让系统知道它的存在,驱动程序也需要向总线注册自己。并且设备和总线在初始化时必须知道它是什么样的总线。因此,为了实现操作的一致性,Linux发明了一种叫做Platform bus的虚拟总线。多个设备和驱动程序注册在同一总线上,那么设备如何找到最适合自己的驱动程序,或者驱动程序如何找到支持的设备?这也是公交的责任,公交就像媒人一样,负责匹配设备和司机。设备会向公交车司机提出自己的条件(最简单最准确的就是指定对方的名字),司机也会告知公交车它能支持的设备的条件(通常是车型ID等)。但最简单的也可以是设备的名称)。设备注册后,总线会遍历注册在上面的驱动程序,找到最适合设备的驱动程序,然后填入设备的结构成员中;注册驱动时,总线会遍历其上注册的设备,找到支持的设备(可能有多个设备,驱动与设备的关系为1:N),将设备填入驱动的支持列表中。我们称之为公交匹配的撮合行为。拉完线后,设备和驱动之间的交互可以忽略。

Linux驱动程序的开发和应用程序的开发有很大的区别,这就导致了编写Linux设备驱动程序和编写应用程序的本质区别。

1.用户模式和内核模式。

Linux操作系统分为用户模式和内核模式。内核模式完成与硬件的交互,如读写内存、从硬盘读取数据到内存等。驱动程序与底部的硬件交互,因此它在内核模式下工作。用户模式可以理解为上层应用,可以是Java应用、Qt应用、Python应用等等。Linux操作系统之所以分为两种状态,是因为即使用户模式下的应用出现异常,也不会导致操作系统崩溃,而这一切都归功于内核模式对操作系统的强大保护能力。

另一方面,Linux操作系统之所以分为两种状态,是为了给应用程序提供统一的计算机硬件抽象。在用户模式下工作的应用程序可以完全忽略底层硬件操作,这些操作由内核模式程序完成。

。而这些内核态程序大部分是设备驱动程序。应用程序可以在不了解硬件工作原理的情况下,很好地操作硬件设备,同时不会使硬件设备进入非法状态。值得注意的是,用户态和内核态是可以互相转换的。每当应用程序执行系统调用或者被硬件中断挂起时,Linux操作系统都会从用户态切换到内核态;当系统调用完成或者中断处理完成后,操作系统会从内核态返回到用户态,继续执行应用程序。

二、模块机制

模块是可以在运行时加入内核的代码,这是Linux一个很好地特性,这个特性可以使内核很容易得扩大或缩小,扩大内核可以增加内核的功能,缩小内核可以减少内核的大小。Linux内核支持多种模块,驱动程序就是其中最重要的一种,每一个模块由编译好的目标代码组成,使用insmod命令将模块加入正在运行的内核,使用rmmod命令将一个未使用的模块从内核删除。模块在在内核启动时装载称为静态装载,在内核已经运行时装载称为动态装载。模块可以扩充内核所期望的任何功能,但通常用于实现设备驱动程序。一个模块的最基本框架代码如下:

三、总线,设备,驱动

想要驾驭Linux驱动开发,必须深刻理解Linux总线设备驱动框架。之所以会形成这样的框架,主要是为了代码的可重用性,因为驱动和设备的关系是一对多的。正如主设备号和次设备号之分,主设备号表示驱动程序,次设备号表示具体的设备。另外是为了提高驱动的可移植性,Linux把驱动要用到的资源(如GPIO和中断等)剥离给设备去管理。即在设备里面包含其自己的设备属性,还包括了其连接到SOC所用到的资源。而驱动重点关注操作的流程和方法。总线的作用则是在软件层面对设备和驱动进行管理。设备要让系统感知自己的存在,设备需要向总线注册自己;同样地,驱动要让系统感知自己的存在,也需要向总线注册自己。设备和总线在初始化时必须要明确自己是哪种总线的。因此,为了达到操作一致性,Linux发明了一种虚拟的总线,称为Platform总线。多个设备和多个驱动都注册到同一个总线上,那设备怎么找到最适合自己的驱动呢,或者说驱动怎么找到其所支持的设备呢?这个也是由总线负责,总线就像是一个红娘,负责在设备和驱动中牵线。设备会向总线提出自己对驱动的条件(最简单的也是最精确的就是指定对方的名字了),而驱动也会向总线告知自己能够支持的设备的条件(一般是型号ID等,最简单的也可以是设备的名字)。那设备在注册的时候,总线就会遍历注册在它上面的驱动,找到最适合这个设备的驱动,然后填入设备的结构成员中;驱动注册的时候,总线也会遍历注册在其之上的设备,找到其支持的设备(可以是多个,驱动和设备的关系是1:N),并将设备填入驱动的支持列表中。我们称总线这个牵线的行为是match。牵好线之后,设备和驱动之间的交互红娘可不管了。

.dfma { position: relative; width: 1000px; margin: 0 auto; } .dfma a::after { position: absolute; left: 0; bottom: 0; width: 30px; line-height: 1.4; text-align: center; background-color: rgba(0, 0, 0, .5); color: #fff; font-size: 12px; content:"广告"; } .dfma img { display: block; }
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。