导航:首页 > 编程系统 > linux驱动层次

linux驱动层次

发布时间:2025-01-12 10:48:12

㈠ 如何学习嵌入式linux驱动

学习嵌入式Linux驱动,首先我们需要的是去了解整个嵌入式开发的整个流程分为四个层次:底层硬件设计、嵌入式驱动开发、内核开发、应用层开发。其中底层硬件设计必须要有一定的硬件功底,我建议你若不是科班出身(数电、模电、高频学的比较好)的人不要去考虑。内核开发需要你有很好的软件功底(C语言、C++学的很好,有过一定的项目经验最好),这个事嵌入式驱动开发的人以后可以考虑发展的方向,不建议一开始就学。如果你是面临着急需找工作的人并且你有一定的商业头脑、创新思维,我认为学习应用层开发是最好不过的选择,但是你别忘了因为简单容易学所以学的人比较多。如果你把前面三个选择都否定了,而且你C语言学的还可以,有学过C51或者STM32这些简单的东西,你不妨看下去。如果你觉得这些对你没用或者不感兴趣,请就此打住不要再往下看不要再浪费你的时间了。亲,去做你该做的事吧!
一、入门者:了解嵌入式
了解嵌入式开发我觉得最好的东西还是《嵌入式系统设计师教程》,这本书写的很烂,无非是用来应付考试的。但是我认为对我们了解嵌入式开发需要学习些什么东西还是有一点用处的,可以在网上浏览一下,你就可以知道嵌入式大概要学的东西,不建议精读。另外如果想大致了解一下嵌入式开发的四个层次,可以看下韦东山韦老师的《作为一个新人,怎样学习嵌入式Linux》http://blog.sina.com.cn/s/blog_13955cfdb0102v3it.html

二、初学者:学习使用Linux
我这里的初学者者指的是已经回了解了嵌入式,有欲望想往深处学习的码农们。这个时候我们已经找到了感觉了。嵌入式操作系统有Vxworks、WINCE、uCLinux、Embedded Linux等操作,但是我们一般选择Linux。原因有二:Linux代码开源,可供学习免费使用。Linux学习的资料非常多,很容易找到小伙伴。学习嵌入式Linux驱动,就必须先学习使用Linux。但是我们对于Linux的使用其实不必学的太多,多了反而会在这浪费的时间。像大家都说可以的《鸟哥的linux私房菜》我不建议大家读,我认为像《Linux就该这么学》这样范范而谈的书籍反而更适合我们初学者。我们对Linux的定位是:基本命令会用,不懂再查。
http://www.linuxprobe.com/chapter-00.html如果觉的适合自己可以去看下

二、菜鸟们:加强C语言,看得懂电路图
我相信到这一阶段你已经深深的爱上了Linux,当然你也可能恨死她了,恨她为什么有那么多命令,恨她为什么不去想Windows那么傻瓜式啊,点点就可以了,但是你别忘了其实Windows也有DOS命令行,只是你没有用过而已吧。我对没有去Linux命令界面敲过几行命令的人视为不会使用操作系统的人,你觉得啦?
既然你爱上她了(不爱请不要再往下看),那请问你为了一个爱你的人做件可能对你难的事,你愿意吗?愿意的话,我们就要去加强自己的C语言基础,我觉得书看的多,视频看的多,还不如看懂一本书,把一本书的程序题好好敲敲,你觉得啦?所以我还是推荐最好的入门的C语言书籍《C程序设计》谭浩强前辈写的。对于看得懂电路图我认为最好的是去下一个画电路板的软件随便找几个电路图画画,慢慢就会了,当然你也可以跳过,我相信如果你真的爱上这一行了以后的学习工作中会逼出来的。

三、码农们:选择一块合适的开发板,然后看书、看数据手册、敲代码、看视频
嵌入式Linux驱动开发是一个敲代码的过程,所以称之为码农。对于嵌入式Linux驱动开发来说是一个偏软件的工作,而码农们就是一个看书、看资料、看视频学习理论知识,然后自己实现的反反复复的过程。只有你不断Debug不断解决不断充实理论知识,才可能往更高层次走。对于书籍我推荐韦东山韦老师的《嵌入式Linux驱动开发完全手册》,当然我觉得成为中国化的S3C2440数据手册更好些(至于为什么学ARM9的S3C2440可以往下看),当然这本书也有他的不好之处:太过于实践,理论知识不全。我觉得配合杜春雷老师的《ARM体系结构与编程》看会非常好,有比较详细的对ARM的介绍。另外既然我们学习S3C2440的话,《S3C2440数据手册》我们是非看不可。另外老外写的《设备驱动开发》也就是所谓的LDD,还有就是宋宝华老师的《Linux设备驱动开发详解》,挺不错的。视频的话我力顶《嵌入式Linux驱动开发完全手册》的作者韦东山韦老师的视频,可以去百问网http://www.100ask.org/ 自行查看。开发板的话我觉得可以自行选择,最好选择S3c2440或者S3c2410的芯片,因为ARM9的资料最多,随便上网搜就是一大把。
四、大神们:研究Linux
毛德操/ 胡希明写的《Linux内核源代码情景分析》、 赵炯《Linux内核完全注释》、《unix环境高级编程》还有更多的可以去看一看瞧一瞧了,我相信你学到这里就可以自找出路了,我也目前在前面阶段,以后把这些学习完再做补充了。

我相信能够学习嵌入式Linux驱动的人都能够知道有好的学习资料学习能够事半功倍的,本人也是学习驱动的菜鸟,历经了学习的沧桑,今天在这里分享一下自己学习嵌入式Linux驱动过程中自认为好的资料,不好请勿喷。有兴趣的可以转载分享给你的朋友。以后有时间我会整理我在学习过程中的东西,加我关注以后一起学习叫流。

㈡ linux主机侧与设备侧USB驱动

USB采用树形拓扑结构,主机侧和设备侧的USB控制器分别称为主机控制器((Host Controller)和USB设备控制器(UDC),每条总线上只有一个主机控制器,负责协调主机和设备间的通信,而设备不能主动向主机发送任何消息。

在Linux系统中,USB驱动可以从两个角度去观察,一个角度是主机侧,一个角度是设备侧。从上图主机侧去看,在Linux驱动中,处于USB驱动最底层的是USB主机控制器硬件,在其上运行的是USB主机控制器驱动,在主机控制器上的为USB核心层,再上层为USB设备驱动层(插入主机上的U盘、鼠标、USB转串口等设备驱动)。因此,在主机侧的层次结构中,要实现的USB驱动包括两类:USB主机控制器驱动和USB设备驱动,前者控制插入其中的USB设备,后者控制USB设备如何与主机通信。Linux内核中的USB核心负责USB驱动管理和协议处理的主要工作。主机控制器驱动和设备驱动之间的USB核心非常重要,其功能包括:通过定义一些数据结构、宏和功能函数,向上为设备驱动提供编程接口,向下为USB主机控制器驱动提供编程接口;维护整个系统的USB设备信息;完成设备热插拔控制、总线数据传输控制等。

㈢ Linux网络设备驱动的具体结构

Linux网络设备驱动程序的体系结构从上到下可以划分为4层,依次为网络协议接口层、网络设备接口层、提供实际功能的设备驱动功能层以及网络设备与媒介层,这4层的作用如下所示:
1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是ARP,还是IP,都通过dev_queue_xmit() 函数发送数据,并通过netif rx ()函数接收数据。这一层的存在使得上层协议独立于具体的设备。
2)网络设备接口层向协议接口层提供统一的用于描述具体网络设备属性和操作的结构体net device,该结构体是设备驱动功能层中各函数的容器。实际上,网络设备接口层从宏观上规划了具体操作硬件的设备驱动功能层的结构。
3)设备驱动功能层的各函数是网络设备接口层net_device数据结构的具体成员,是驱使网络设备硬件完成相应动作的程序,它通过hard_start_ xmit ()函数启动发送操作,并通过网络设备上的中断触发接收操作。
4)网络设备与媒介层是完成数据包发送和接收的物理实体,包括网络适配器和具体的传输媒介,网络适配器被设备驱动功能层中的函数在物理上驱动。对于Linux系统而言,网络设备和媒介都可以是虚拟的。

㈣ linux中的底层,应用层,驱动之间的关系

内核--系统的底层,最核心的东西,操作系统运转的基础
驱动--应用程序与内核之间的接口,沟通应用软件与操作系统的桥梁
应用层--所有的应用程序的统称,实现某一个或几个专有的功能

㈤ Linux系统中USB驱动程序的工作流程详解

1.USB主机

在Linux驱动中,USB驱动处于最底层的是USB主机控制器硬件,在其之上运行的是USB主机控制器驱动,主机控制器之上为USB核心层,再上层为USB设备驱动层(插入主机上的U盘、鼠标、USB转串口等设备驱动)。

因此,在主机侧的层次结构中,要实现的USB驱动包括两类:USB主机控制器驱动和USB设备驱动,前者控制插入其中的USB设备,后者控制USB设备如何与主机通信。Linux内核USB核心负责USB驱动管理和协议处理的主要工作。主机控制器驱动和设备驱动之间的USB核心非常重要,其功能包括:通过定义一些数据结构、宏和功能函数,向上为设备驱动提供编程接口,向下为USB主机控制器驱动提供编程接口;通过全局变量维护整个系统的USB设备信息;完成设备热插拔控制、总线数据传输控制等。

2.USB设备

Linux内核中USB设备侧驱动程序分为3个层次:UDC驱动程序、Gadget API和Gadget驱动程序。UDC驱动程序直接访问硬件,控制USB设备和主机间的底层通信,向上层提供与硬件相关操作的回调函数。当前Gadget API是UDC驱动程序回调函数的简单包装。Gadget驱动程序具体控制USB设备功能的实现,使设备表现出网络连接、打印机或USB Mass Storage等特性,它使用Gadget API控制UDC实现上述功能。Gadget API把下层的UDC驱动程序和上层的Gadget驱动程序隔离开,使得在Linux系统中编写USB设备侧驱动程序时能够把功能的实现和底层通信分离。

3.层次

在USB设备组织结构中,从上到下分为设备(device)、配置(config)、接口(interface)和端点(endpoint)四个层次。USB设备程序绑定到接口上。

对于这四个层次的简单描述如下:

(1)设备通常具有一个或多个的配置

(2)配置经常具有一个或多个的接口

(3)接口没有或具有一个以上的端点

4.端点

USB通信最基本的形式是通过端点(USB端点分中断(Interrupt)、批量(Bulk)、等时(ISO)、控制(Control)四种,每种用途不同),USB端点只能往一个方向传送数据,从主机到设备或者从设备到主机,端点可以看作是单向的管道(pipe)。驱动程序把驱动程序对象注册到USB子系统中,稍后再使用制造商和设备标识来判断是否已经安装了硬件。USB核心使用一个列表(是一个包含制造商ID和设备号ID的一个结构体)来判断对于一个设备该使用哪一个驱动程序,热插拨脚本使用它来确定当一个特定的设备插入到系统时该自动执行哪一个驱动程序的Probe。

5. 数据结构

(1)USB设备:对应数据结构struct usb_device

(2)配置:struct usb_host_config (任一时刻,只能有一个配置生效)

(3)USB接口:struct usb_interface (USB 核心将其传递给USB设备驱动,并由USB设备驱动负责后续的控制。一个USB接口代表一个基本功能,每个USB驱动控制一个接口。所以一个物理上的硬件设备可能需要 一个以上的驱动程序。)

(4)端点: struct usb_host_endpoint ,它所包含的真实端点信息在另一个结构中:struct usb_endpoint_descriptor(端点描述符,包含所有的USB特定数据)。

6. USB端点分类

USB 通讯的最基本形式是通过一个称为端点的东西。一个USB端点只能向一个方向传输数据(从主机到设备(称为输出端点)或者从设备到主机(称为输入端点))。端点可被看作一个单向的管道。

USB 端点有 4 种不同类型, 分别具有不同的数据传送方式:

(1)控制CONTROL

控制端点被用来控制对USB设备的不同部分访问. 通常用作配置设备、获取设备信息、发送命令到设备或获取设备状态报告。这些端点通常较小。每个 USB 设备都有一个控制端点称为端点 0, 被 USB 核心用来在插入时配置设备。USB协议保证总有足够的带宽留给控制端点传送数据到设备.

(2)中断INTERRUPT

每当 USB 主机向设备请求数据时,中断端点以固定的速率传送小量的数据。此为USB 键盘和鼠标的主要的数据传送方法。它还用以传送数据到USB设备来控制设备。通常不用来传送大量数据。USB协议保证总有足够的带宽留给中断端点传送数据到设备.

(3)批量BULK

批量端点用以传送大量数据。这些端点通常比中断端点大得多. 它们普遍用于不能有任何数据丢失的情况。USB 协议不保证传输在特定时间范围内完成。如果总线上没有足够的空间来发送整个BULK包,它被分为多个包进行传输。这些端点普遍用于打印机、USB Mass Storage和USB网络设备上。

(4)等时ISOCHRONOUS

等时端点也批量传送大量数据, 但是这个数据不被保证能送达。这些端点用在可以处理数据丢失的设备中,并且更多依赖于保持持续的数据流。如音频和视频设备等等。

控制和批量端点用于异步数据传送,而中断和等时端点是周期性的。这意味着这些端点被设置来在固定的时间连续传送数据,USB 核心为它们保留了相应的带宽。

7. endpoint

C/C++ Code复制内容到剪贴板structusb_host_endpoint{structusb_endpoint_descriptordesc;//端点描述符structlist_hearb_list;//此端点的URB对列,由USB核心维护void*hcpriv;structep_device*ep_dev;/*Forsysfsinfo*/unsignedchar*extra;/*Extradescriptors*/intextralen;intenabled;};

当调用USB设备驱动调用usb_submit_urb提交urb请求时,将调用int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)把此urb增加到urb_list的尾巴上。(hcd: Host Controller Driver,对应数据结构struct usb_hcd )

8. urb

所有USB通讯均为请求--响应模式,USB设备不会主动向Host发送数据。写数据:USB设备驱动发送urb请求给USB设备,USB设备不需要回数据。读数据:USB设备驱动发送urb请求给USB设备,USB设备需要回数据。

USB 设备驱动通过urb和所有的 USB 设备通讯。urb用 struct urb 结构描述(include/linux/usb.h )。

urb 以一种异步的方式同一个特定USB设备的特定端点发送或接受数据。一个 USB 设备驱动可根据驱动的需要,分配多个 urb 给一个端点或重用单个 urb 给多个不同的端点。设备中的每个端点都处理一个 urb 队列, 所以多个 urb 可在队列清空之前被发送到相同的端点。

一个 urb 的典型生命循环如下:

(1)被创建;

(2)被分配给一个特定 USB 设备的特定端点;

(3)被提交给 USB 核心;

(4)被 USB 核心提交给特定设备的特定 USB 主机控制器驱动;

(5)被 USB 主机控制器驱动处理, 并传送到设备;

(6)以上操作完成后,USB主机控制器驱动通知 USB 设备驱动。

urb 也可被提交它的驱动在任何时间取消;如果设备被移除,urb 可以被USB核心取消。urb 被动态创建并包含一个内部引用计数,使它们可以在最后一个用户释放它们时被自动释放。

8.1 提交 urb

一旦 urb 被正确地创建并初始化, 它就可以提交给 USB 核心以发送出到 USB 设备. 这通过调用函数sb_submit_urb 实现.

int usb_submit_urb(struct urb *urb, gfp_t mem_flags);

参数:

struct urb *urb :指向被提交的 urb 的指针

gfp_t mem_flags :使用传递给 kmalloc 调用同样的参数, 用来告诉 USB 核心如何及时分配内存缓冲

因为函数 usb_submit_urb 可被在任何时候被调用(包括从一个中断上下文), mem_flags 变量必须正确设置. 根据 usb_submit_urb 被调用的时间,只有 3 个有效值可用:

GFP_ATOMIC

只要满足以下条件,就应当使用此值:

1) 调用者处于一个 urb 结束处理例程,中断处理例程,底半部,tasklet或者一个定时器回调函数.

2) 调用者持有自旋锁或者读写锁. 注意如果正持有一个信号量, 这个值不必要.

3) current-state 不是 TASK_RUNNING. 除非驱动已自己改变 current 状态,否则状态应该一直是TASK_RUNNING .

GFP_NOIO

驱动处于块 I/O 处理过程中. 它还应当用在所有的存储类型的错误处理过程中.

GFP_KERNEL

所有不属于之前提到的其他情况

在 urb 被成功提交给 USB 核心之后, 直到结束处理例程函数被调用前,都不能访问 urb 结构的任何成员

8.2 urb结束处理例程

如果 usb_submit_urb 被成功调用, 并把对 urb 的控制权传递给 USB 核心, 函数返回 0; 否则返回一个负的错误代码. 如果函数调用成功, 当 urb 被结束的时候结束处理例程会被调用一次.当这个函数被调用时, USB 核心就完成了这个urb, 并将它的控制权返回给设备驱动.

只有3 种结束urb并调用结束处理例程的情况:

(1)urb 被成功发送给设备, 且设备返回正确的确认.如果这样, urb 中的status变量被设置为 0.

(2)发生错误, 错误值记录在 urb 结构中的 status 变量.

(3)urb 从 USB 核心unlink. 这发生在要么当驱动通过调用 usb_unlink_urb 或者 usb_kill_urb告知 USB 核心取消一个已提交的 urb,或者在一个 urb 已经被提交给它时设备从系统中去除.

9. 探测和断开

在 struct usb_driver 结构中, 有 2 个 USB 核心在适当的时候调用的函数:

(1)当设备插入时, 如果 USB 核心认为这个驱动可以处理(USB核心使用一个列表(是一个包含制造商ID和设备号ID的一个结构体)来判断对于一个设备该使用哪一个驱动程序),则调用探测(probe)函数,探测函数检查传递给它的设备信息, 并判断驱动是否真正合适这个设备.

(2)由于某些原因,设备被移除或驱动不再控制设备时,调用断开(disconnect)函数,做适当清理.

探测和断开回调函数都在USB集线器内核线程上下文中被调用, 因此它们休眠是合法的. 为了缩短 USB 探测时间,大部分工作尽可能在设备打开时完成.这是因为 USB 核心是在一个线程中处理 USB 设备的添加和移除, 因此任何慢设备驱动都可能使 USB 设备探测时间变长。

9.1探测函数分析

在探测回调函数中, USB设备驱动应当初始化它可能用来管理 USB 设备的所有本地结构并保存所有需要的设备信息到本地结构, 因为在此时做这些通常更容易.为了和设备通讯,USB 驱动通常要探测设备的端点地址和缓冲大小.

PS:Linux USB驱动相关细节知识补充

1. 在usb_fill_bulk_urb,usb_fill_int_urb,usb_fill_control_urb都需要指定回调函数,当此URB请求完成时,usb core回调用此函数。

注意:urb 回调函数是在中断上下文运行, 因此它不应做任何内存分配, 持有任何信号量, 或任何可导致进程休眠的事情. 如果从回调中提交 urb 并需要分配新内存块, 需使用 GFP_ATOMIC 标志来告知 USB 核心不要休眠.

2. urb封装函数:

(1)int usb_bulk_msg(struct usb_device *usb_dev,unsigned int pipe,void*data, int len, int*actual_length,int timeout)

功能:创建批量 urb 并发送到指定的设备, 接着在返回之前等待完成.

参数:

struct usb_device *usb_dev :目标 USB 设备指针

unsigned int pipe :目标 USB 设备的特定端点. 必须使用特定的宏创建.

void *data :如果是 OUT 端点, 指向要发送到设备的数据的指针. 如果是 IN 端点, 这是从设备读取的数据的缓冲区指针.

int len : data 参数指向的缓冲的长度

int *actual_length :指向函数放置真实字节数的指针,根据端点方向,这些字节要么是被发送到设备的,要么是从设备中读取的.

int timeout :时钟嘀哒数, 应等待的时间. 如果为 0, 函数永远等待操作完成.

返回值:成功返回0,actual_length 参数包含被传送或从设备中读取的字节数.否则返回负的错误值.

(2)int usb_control_msg(struct usb_device*dev, unsigned int pipe, __u8 request,__u8 requesttype, __u16 value, __u16 index,void *data, __u16 size,int timeout)

功能:创建控制 urb 并发送到指定的设备, 接着在返回之前等待完成.

参数:

struct usb_device *usb_dev :目标 USB 设备指针

unsigned int pipe :目标 USB 设备的特定端点. 必须使用特定的宏创建.

__u8 request :控制消息的 USB 请求值.

__u8 requesttype :控制消息的 USB 请求类型.

__u16 value :控制消息的 USB 消息值.

__u16 index :控制消息的 USB 消息索引值.

void *data :如果是 OUT 端点, 指向要发送到设备的数据的指针. 如果是 IN 端点, 这是从设备读取的数据的缓冲区指针.

__u16 size : data 参数指向的缓冲的长度

int timeout :时钟嘀哒数, 应等待的时间. 如果为 0, 函数永远等待操作完成.

返回值:成功返回被传送到或从设备读取的字节数.否则返回负的错误值.

(3)int usb_interrupt_msg(struct usb_device*usb_dev, unsigned int pipe,void *data,int len, int *actual_length,int timeout)

功能:创建中断 urb 并发送到指定的设备, 接着在返回之前等待完成.其实就是usb_bulk_msg的包装,所有参数和usb_bulk_msg一样使用

阅读全文

与linux驱动层次相关的资料

热点内容
找不到镜像文件和网络有关系吗 浏览:493
如何找到使用软件的app 浏览:73
wordcount降序 浏览:699
用模版批量建立excel表格文件 浏览:929
mif文件波形生成器 浏览:334
cf文件程序损坏修复器就行 浏览:469
华为qq下载的apk文件在哪里 浏览:660
常用的逻辑数据模型各有什么优缺点 浏览:698
2do安卓教程 浏览:313
全民突击208版本一挑战视频 浏览:441
格兰达编程工资待遇怎么样 浏览:68
iphone5s手机输入法 浏览:556
摄像头文件储存在哪里 浏览:301
sql查看数据库文件 浏览:39
邮政app上英文名怎么填 浏览:72
linuxgd库安装 浏览:990
我想买药哪个网站比较好啊 浏览:266
超大数据运算用什么语言 浏览:241
属性里文件路径也可以看见吗 浏览:321
java怎样截取字符串 浏览:195

友情链接