CAN的Linux内核linux驱动编译进内核是什么

在电子工程世界为您找到如下关于“内核解析”的新闻
内核解析资料下载
uCOS-II内核架构解析uCOS-II内核架构解析uCOS-II内核架构解析uCOS-II内核架构解析uCOS-II内核架构解析uCOS-II内核架构解析...
的使用 52\r\n3.3.1 GNU Binutils工具介绍 52\r\n3.3.2 Binutils工具软件使用 54\r\n3.4 编译器GCC的使用 54\r\n3.4.1  GCC编译器介绍 54\r\n3.4.2 GCC编译选项解析 56\r\n3.5 调试器GDB的使用技巧 60\r\n3.5.1 GDB调试器介绍 60\r\n3.5.2 GDB调试命令 61\r\n3.6...
3.4.1 GCC编译器介绍
3.4.2 GCC编译选项解析
3.5 调试器GDB的使用技巧
3.5.1 GDB调试器介绍
3.5.2 GDB调试命令
3.6 Linux编程库
3.6.1 Linux编程库介绍
3.6.2 Linux系统调用
3.6.3 Linux线程库
第4章 交叉开发环境
直接内存访问
第十六章 块设备驱动程序
块设备操作
其他一些细节
第十七章 网络驱动程序
连接到内核
net_device结构细节
打开和关闭
数据包传输
数据包的接收
中断处理例程
不使用接收中断
链路状态的改变
套接字缓冲区
MAC 地址解析
定制 ioctl...
内核,可以在软件平台上运行嵌入式软件。本章建立了Modelsim的仿真环境,加载同样的ucLinux内核,可以打印出同Skyeye一样的启动信息。在这个过程中,用户可以通过查看波形,从RTL设计工程师的角度解析嵌入式操作系统。
ARM7TDMI-S处理器内核
以ARM7TDMI为核心的单片机
uClinux嵌入式操作系统
Linux 内核解析~~~ ~~~ ~~~~~·...
本书介绍Linux环境下的编程方法,内容包括Linux系统命令、 Shell脚本、编程语言(gawk、Perl)、系统内核、安全体系、X Window等,内容丰富、论述全面,涵盖了Linux系统的方方面面。本书附带光盘包括了RedHat Linux系统的最新版本,及安装方法,还包括本书的大量程序代码,极大地方便了读者,为使用和将要使用Linux系统的技术人员提供了较全面的参考。&nbsp...
◎《Linux环境C程序设计》源文件◎Ubuntu安装光盘的镜像文件(赠送)◎36.5小时Linux专题讲座视频(赠送)
内容全面:涵盖Linux环境C编程的基础知识、高级技术与实践经验
融会贯通:将Linux系统开发技术、C/C++开发技术及软件工程思想结合起来讲解
内容深入:深入介绍GNOME:桌面环境下的图形界面开发,代码达到可复用水平
重点突出:深入解析Linux调用函数功能,不用具备...
为一个很好地语法解析内核程序...
相关命令 38 2.1.4 比较合并文件相关命令 40 2.1.5 网络相关命令 45 2.2 Linux启动过程详解 50 2.2.1 概述 51 2.2.2 内核引导阶段 51 2.2.3 init阶段 52 2.3 Linux系统服务 54 2.3.1 独立运行的服务 55 2.3.2 xinetd设定的服务 56 2.3.3 设定服务命令常用方法 56 2.4 实验内容 57 2.4.1...
内核解析相关帖子
() 实现相应,
我还尝试使用& &dup2&&来重定向,但也不能达到效果
linux如何修改当前输入设备 LCD 能显示你输入的值 还不叫响应吗?
在USB键盘上Ctrl+C无法终止程序 是因为你的内核没有将控制台定向到USB键盘上
键盘只是输入设备,轻易不要重定向,你还是考虑在你的LCD上再开一个终端界面的窗口,键盘在这个窗口下输入吧...
的处理性能和模块化控制方法为控制系统提供了优势,因此,可以在 C28x 内核和 CLA 协处理器之间划分多个控制回路。例如,一个回路可以在 C28x 内核上运行电机控制算法,同时 CLA 协处理器可专注于电机位置解析算法,从而通过旋转变压器计算出电机位。同样,除功率控制功能之外,还存在多种其他用例,包括但不限于多轴电机控制、功率因数校正 (PFC) 加电机控制,甚至还包括电力线通信 (PLC...
CPU的性能吞吐量,而不是单个CPU内核的个体性能。(我们知道架构增强是有难度的)。但是FPGA和GPU加速器的每瓦性能都有了令人信服的改进。
根据微软的运行测试,在执行深度学习算法的时候,CPU-FPGA和CPU-GPU混合计算在内的每瓦性能也不相伯仲。GPU在运行中更热和有类似的每瓦性能表现,但是同时他们也带来了更强的工作能力。
提高了每瓦性能解析了为什么世界上最强大的超级计算机在...
Mesh-stack学习的最好途径是选择好的开源项目,移植或者仿真,针对实物调试最好的学习方式是 抓包 抓包 抓包!
怎么抓包,这个方式有很多,自己做一个连续接收的程序把raw数据打印出来也是最原始的方式了,当然随着学习的深入可以加一级/二级/三级解析,这样一个实用的Sniffer就有了。如果直接使用官方或者第三方成熟的工具也是非常可取的做法。一般学习得是工具先行的套路。这次KW41Z好像是免费...
老白学linux--获取内核版本信息,进行内核兼容
老白学linux--BUG_ON和WARN_ON解析
老白学linux--dumpe2fs
老白学linux--IO调度
老白学linux——by 白丁...
可以的。cc3200嘿流弊。http现成的,json解析找个tiny的就行了。
[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=2115872&ptid=511304][color=#chenjq 发表于
15:56[/color][/url][/size]
这位道友,你可以用...
推荐博文:【TI FAE 经验分享】C2000上电引导模式解析
博文链接:[url]/blog/b/msp430/archive//ti-fae-c2000.aspx[/url]
推荐博文: 对于ARM开发人员的好消息:MSP432现在完全CMSIS兼容了!
博文链接:[url]http...
STM32F769I-DISCO评测(6)硬件资源解析
STM32F769I-DISCO评测(7)M7内核
STM32F769I-DISCO评测(8)Embedded Wizard 正确打开姿势
STM32F769I-DISCO评测(9)使用Embedded Wizard 创建第一个UI应用
@zhongyuan186118
stm32f769i评测之DEMO例程演示...
• 对大容量外部存储的高效访问
• 适合复杂计算的高性能浮点运算能力
Cortex®-M7 内核
STM32F7 系列器件基于高性能的 ARM® Cortex®-M7 32 位 RISC 内核,工作频率高达 216MHz。 Cortex®-M7 内核带有高性能单 / 双精度浮点运算单元 (ARM),支持单 / 双精度...
解析1、MCU
主控MCU型号是STM32F769NIH6,采用BGA216封装,大小和一枚一角钱人民币大小差不多,如图所示。STM32F769NIH6采用ARM Cortex-M7内核,STM32F7 系列器件是首款基于 ARM® Cortex®-M7 32 位 RISC 内核的微控制器。Cortex®-M7 内核带有高性能单 / 双精度浮点运算单元 (ARM...
内核解析视频
内核解析创意
你可能感兴趣的标签
热门资源推荐15007人阅读
Linux驱动(28)
原文地址:
1.Linux usb设备驱动框架
USB是通用串行总线的总称,Linux内核几乎支持所有的usb设备,包括键盘,鼠标,打印机,modem,扫描仪。Linux的usb驱动分为主机驱动与gadget驱动。前者是设备连接到计算机上,通过主机驱动扫描usb设备,控制所连接的设备。而gadget驱动一般用于嵌入式设备,gadget驱动用于控制嵌入式设备。Linux的usb驱动两种类型图如下:
左侧是usb的主机驱动,右侧是gadget驱动。下面着重介绍一下usb的主机驱动:
(1)usb主机控制器-直接与硬件设备交互。
(2)usb core-向usb设备驱动提供API以及usb主机控制器驱动的程序。使用usb core所提供的函数,宏来完成数据处理的功能。
(3)usb设备驱动,即usb接口驱动,一般所说的usb驱动指的是usb接口驱动
2.usb系统的组成部分
usb系统一般由三个部分组成,主机,一个或多个usb hub,以及与之些hub连接的usb设备。
在任何的usb系统中仅有一个主机,主机系统中的usb接口即上图中的主机控制器,主机控制器可由硬件,软件或固件组成。主机主要负责:
a.检测usb设备的连接与拆除
b.管理主机与usb设备之间的控制流
c.管理主机与usb设备之间的数据流
d.收集状态和活动的统计
e.为连接的usb设备提供电源
(2)usb设备
所有的usb设备都是通过地址来存取的,这个地址在连接或枚举时分配。usb设备对usb系统来说是端点的集合,一组端点实现一个接口。设备端点是usb设备中唯一可寻址的部分。它是主机与设备之间通信流的结束点。一系列的相互独立的端点构成了usb逻辑设备。每个端点支持流进设备或者是流出设备。
主机与设备端点上的usb数据传输是通过管道的方式。
所有的usb device都连接在hub端口上。
3. usb传输模式
(1)控制传输模式(Control)
控制传输模式支持双向传输,用来处理从usb主机端口到usb设备端口的数据传输,用于控制指令,设备状态查询以及确认命令。
(2)等时传输方式(lsochronous)
等时传输是一种周期性的连续性的意向传输模式,通常用于对时间有着密切关系的信息的传输,对准确性要求不高,但对时间要求极为敏感的设备,如视频,音频的传输。
(3)中断传输模式(Interrupt)
中断传输模式用于非周期性的,自然发生的,数据量小的传输,数据传输的方向是从设备到主机。如usb键盘和鼠标
(4)批量传输模式(bulk)
批量传输模式是一种单向的,用于大量数据传输的模式,该方式用来传输正确无误的数据。通常打印机,扫描仪,数码相机以这种方式与主机连接
4. usb设备组成
(1)一个usb设备由可以有一个或多个配置
(2)一个配置通常可以有一个或多个接口
(3)一个接口通常可以有一个或多个端点
通常所尽的usb设备驱动是指接口驱动,即一个接口对应一个驱动。
所以Linux usb设备有四大描述符,分别为设备描述符,配置描述符,接口描述符,端点描述符。下面看一个这几个描述符的相关数据结构:
struct usb_device_descriptor
&&&&&&_u8 bL& //此描述符的字节数
&&&&&&_u8&&bDescriptorT //描述符的种类为设备
&&&& &_u16 bcdUSB;& //此设备与描述符兼容的usb设备说明版本号(BCD码)
&&&&&&_u8&& bDeviceC //设备类码
&&&&&&_u8&& bDeviceSubC //设备子类码
&&&&&&_u8&& bDeviceP //协议码
&&&&&&_u8&& bMaxPacketSize0; //端点0的最大包大小
&&&&&&_u16 idV //厂商标志
&&&&&&_u16 &idP //产品标志
&&&&&&_u16 bcdD //设备发行号
&&&&&&_u8&& iM //描述厂商的字串索引
&&&&&&_u8&& iP //描述产品信息的字串索引
&&&&&&_u8& iSerialN //描述设备序列号信息的字串索引
&&&&&&_u8& bNumC//此设备支持的配置数
& }_attribute_ ((packed));
设备类码的典型值如下:
#define USB_CLASS_PER_INTERFACE 0
#define USB_CLAS_AUDIO&1&&& &//声音设备
#define USB_CLASS_COMM 2&& //&调制解调器,网卡,ISDN连接
#define USB_CLASS_HID& 3&&& //HID设备,如鼠标,键盘
#define USB_CLASS_PHYSICAL 5 //物理设备
#define USB_CLASS_STILL_IMAGE 6 //静止图像捕捉设备
#define USB_CLASS_PRINTER 7//打印机
#define USB_CLASS_MASS_STORAGE //8 批量存储设备
#define USB_CLASS_HUB 9&& //USB HUBS
#define USB_CLASS_CSCID&0x0B& //智能卡
#define USB_CLASS_VIDEO 0X0E //视频设备,如网络摄像头
#define USB_CLASS_VENDOR_SPEC 0xFF //厂商自定义的设备
&&struct usb_config_descriptor{
&_u8 bL//此描述符的字节数
_u8 bDescriptorT //配置描述符类型
_u16 wTotalL //此配置信息的总长(包括配置,接口,端点和设备类型及厂商定义的描述符)
_u8 bNumI //此配置所支持的接口数
_u8 bConfigurationV//在setConfiguration()请求中用作参数来选定此配置
_u8 iC //描述此配置的字串描述符索引
_u8 bmA //电源配置特性
_u8 bMr //此配置下的总线电源耗电量
}_attribute_ ((packed));
配置描述符给出了usb设备配置信息,以及此配置下的接口数。每个接口可能的独立操作。
struct usb_interface_descriptor{
_u8 bL//此描述符的字节数
_u8 bDescriptorT//接口描述符类
_u8 bInterfacN//接口号,当前配置所支持的接口数组索引,从0开始
_u8 bNumE//此接口用的端点数量,如果是0,说明此接口只有缺省控制通道
_u8 bAlernateS//可选设备的索引值
_u8 bInterfaceC// 类৬作为将来保留使用如果是0FFH,此接口由厂商说明
_u8 bInterfaceSubC//子类码
_u8 bInterfaceP//协议码
_u8 iI//描述此接口的字串描述符索引
}_attribute_ ((packed));
struct usb_endpoint_descriptor{
_u8 bL//此描述符的字节数
_u8 bDescriptorT//端点描述符类
_u8 bEndpointA此描述符所描述的端点的地址
_u8 bmA//所指定的端点的特性,如果是00=控制传送,01=等时传送,10=批传送,11=中断传送
_u8 wMaxPacketS//当前配置下端点能够发送与接收的最大数据包大小
_u8 bI//轮询数据传送端点的时间间隙
_u8 bRefresh
_u8 bSynchAddress
}_attribute_ ((packed));
以上给出了usb中的设备描述符,配置描述符,接口描述符和端点描述符。
5. usb设备驱动的几个重要的数据结构
usb_driver,usb_device,usb_bus.
* stru ctusb_driver - identifiesU SB interface
driver tou sbcore
* @name: The driver name shou ld beu niqu e amongU SB drivers,
*&&&&& and shou ld normally be the same as the modu le name.
* @probe: Called to see if the driver is willing to manage a particu lar
*&&&&& interface on a device.& If it is, probe retu rns zero andu ses
*&&&&&u sb_set_intfdata() to associate driver-specific data with the
*&&&&& interface.& It may alsou se
u sb_set_interface() to specify the
*&&&&& appropriate altsetting.& Ifu nwilling to manage the interface,
*&&&&& retu rn -ENODEV, if genu ine IO errors occu red, an appropriate
*&&&&& negative errno valu e.
* @disconnect: Called when the interface is no longer accessible,u su ally
*&&&&& becau se its device has been (or is being) disconnected or the
*&&&&& driver modu le is beingu nloaded.
* @u nlocked_ioctl:U sed for drivers that want to talk tou serspace throu
*&&&&& the &u sbfs& filesystem.& This lets devices provide ways to
*&&&&& expose information tou ser space regardless of where they
*&&&&& do (or don't) showu p otherwise in the filesystem.
* @su spend: Called when the device is going to be su spended by the system.
* @resu me: Called when the device is being resu med by the system.
* @reset_resu me: Called when the su spended device has been reset instead
*&&&&& of being resu med.
* @pre_reset: Called byu sb_reset_device() when the device
*&&&&& is abou t to be reset.
* @post_reset: Called byu sb_reset_device() after the device
*&&&&& has been reset
* @id_table:U SB drivers
u se ID table to su pport hotplu gging.
*&&&&& Export this with MODU LE_DEVICE_TABLE(u sb,...).& This mu st be set
*&&&&& or you r driver's probe fu nction will never get called.
* @dynids:u sed internally to hold the list of dynamically added device
*&&&&& ids for this driver.
* @drvwrap: Driver-model core stru ctu re wrapper.
* @no_dynamic_id: if set to 1, theU SB core will not allow dynamic ids to be
*&&&&& added to this driver by preventing the sysfs file from being created.
* @su pports_au tosu spend: if set to 0, theU SB core will not allow
au tosu spend
*&&&&& for interfaces bou nd to this driver.
* @soft_u nbind: if set to 1, theU SB core will not killU RBs and disable
*&&&&& endpoints before calling the driver's disconnect method.
*U SB interface drivers mu st provide a name, probe() and disconnect()
* methods, and an id_table.& Other driver fields are optional.
* The id_table isu sed in hotplu gging.& It holds a set of descriptors,
* and specialized data may be associated with each entry.& That table
* isu sed by both
u ser and kernel mode hotplu gging su pport.
* The probe() and disconnect() methods are called in a context where
* they can sleep, bu t they shou ld avoid abu sing the privilege.& Most
* work to connect to a device shou ld be done when the device is opened,
* andu ndone at the last close.& The disconnect code needs to address
* concu rrency issu es with respect to open() and close() methods, as
* well as forcing all pending I/O requ ests to complete (byu nlinking
* them as necessary, and blockingu ntil the
u nlinks complete).
&&&&&&&& const char *;
&&&&&&&& int (*) (stru
&&&&&&&&&&&&&&&&&&&&&& const stru ct*);
&&&&&&&& void (*) (stru
&&&&&&&& int (*u nlocked_ioctl) (stru ct*,u nsigned int
&&&&&&&&&&&&&&&&&&&&&&&& void *);
&&&&&&&& int (*)
(stru ct *,);
&&&&&&&& int (*)
(stru ct *);
&&&&&&&& int (*reset_resu me)(stru ct*);
&&&&&&&& int (*)(stru
&&&&&&&& int (*post_reset)(stru ct*);
&&&&&&&& const stru ct*;
&&&&&&&& stru
&&&&&&&& stru
&&&&&&&&u nsigned int no_dynamic_id:1;
&&&&&&&&u nsigned int su pports_au tosu spend:1;
&&&&&&&&u nsigned int soft_u nbind:1;
usb_driver中的probe函数扫描连接到主机上的usb设备,并且注册usb接口驱动。
disconnect函数是当usb设备移除时调用。
* Allocated per bu s (tree of devices) we have:
stru ctu sb_bu s {
&&&&&&&& stru ctdevice *controller ;&&&&&/*
host/master side hardware */
&&&&&&&& int bu snu&&&&&&&&&&&&&&&&&&&&/* Bu s nu mber (in order
of reg) */
&&&&&&&& const char *bu s_&&&&&&&&&&/* stable id (PCI slot_name etc) */
&&&&&&&&u 8
u ses_&&&&&&&&&&&&&&&&&&&/* Does the host controlleru se DMA? */
&&&&&&&&u 8
u ses_pio_for_&&&&&&&/*
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * Does the host controlleru se PIO
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * for control transfers?
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& */
&&&&&&&&u 8 otg_&&&&&&&&&&&&&&&&&&&/* 0, or nu mber of
OTG/HNP port */
&&&&&&&&u nsigned is_b_host:1;&&&&&&&&&&
/* tru e du ring some HNP roleswitches */
&&&&&&&&u nsigned b_hnp_enable:1;&&&&&&&
/* OTG: did A-Host enable HNP? */
&&&&&&&&u nsigned
sg_tablesize ;&&&&&&&&&/* 0 or largest nu mber of sg list entries */
&&&&&&&& int devnu m_&&&&&&&&&&&&&&&/* Next open device nu mber in
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * rou nd-robin allocation */
&&&&&&&& stru ctu sb_devmap &&&&&&&/* device address
allocation map */
&&&&&&&& stru ctusb_device * root_hu&&&/*
Root hu b */
&&&&&&&& stru ctu sb_bu s *hs_&&/*
Companion EHCI bu s, if any */
&&&&&&&& stru ctlist_head bu s_&&&&&/* list of bu
&&&&&&&& int bandwidth_&&&&&&&/* on this bu s: how mu ch of the time
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * reserved for periodic (intr/iso)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * requ ests isu sed, on average?
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *U nits: microseconds/frame.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * Limits: Fu ll/low speed reserve 90%,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * while high speed reserves 80%.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& */
&&&&&&&& int bandwidth_int_&&&&&&&&/* nu mber of Interru pt requ ests */
&&&&&&&& int bandwidth_isoc_&&&&&&&/* nu mber of Isoc. requ ests */
#ifdef CONFIG_USB_DEVICE FS
&&&&&&&& stru ctdentry *u sbfs_&&&/*u
sbfs dentry entry for the bu s */
#ifdefined (CONFIG_U SB_MON) ||(CONFIG_U
SB_MON_MODU LE)
&&&&&&&& stru ctmon_bu s *mon_bu
s ;&&&&&&&/* non-nu ll when associated */
&&&&&&&&&&&&&&&&&&&&&&&&&/* non-zero when monitored */
* stru ctusb_device - kernel's representation of aU
* @devnu m: device nu address on aU SB bu s
* @devpath: device ID string foru se in messages (e.g., /port/...)
* @rou te: tree topology hex string foru se with xHCI
* @state: device state: configu red, not attached, etc.
* @speed: device speed: high/fu ll/low (or error)
* @tt: Transaction Tu sed with low/fu ll speed dev, highspeed hu
* @ttport: device port on that tt hu b
* @toggle: one bit for each endpoint, with ([0] = IN, [1] = OU T) endpoints
* @parent: ou r hu b,u nless we're the root
* @bu s: bu s we're part of
* @ep0: endpoint 0 data (defau lt control pipe)
* @dev: generic device interface
* @descriptor:U SB device descriptor
* @config: all of the device's configs
* @actconfig: the active configu ration
* @ep_in: array of IN endpoints
* @ep_ou t: array of OU T endpoints
* @rawdescriptors: raw descriptors for each config
* @bu s_mA: Cu rrent available from the bu s
* @portnu m: parent port nu mber (origin 1)
* @level: nu mber ofU SB hu b ancestors
* @can_su bmit:U RBs may be su bmitted
* @persist_enabled:&U SB_PERSIST enabled for this device
* @have_langid: whether string_langid is valid
* @au thorized: policy has said we canu
*&&&&& (u ser space) policy determines if we au thorize this device to be
*&&&&&u sed or not. By defau lt, wiredU SB devices are au thorized.
*&&&&& WU SB devices are not,u ntil we au thorize them fromu ser space.
*&&&&& FIXME -- complete doc
* @au thenticated: Crypto au thentication passed
* @wu sb: device is WirelessU SB
* @string_langid: langu age ID for strings
* @produ ct: iProdu ct string, if present (static)
* @manu factu rer: iManu factu rer string, if present (static)
* @serial: iSerialNu mber string, if present (static)
* @filelist:u sbfs files that are open to this device
* @u sb_classdev:U SB class device that was created foru sbfs device
*&&&&& access fromu serspace
* @u sbfs_dentry:u sbfs dentry entry for the device
* @maxchild: nu mber of ports if hu b
* @children: child devices -U SB devices that are attached to this hu b
* @qu irks: qu irks of the whole device
* @u rbnu m: nu mber ofU RBs su bmitted for the whole
* @active_du ration: total time device is not su spended
* @connect_time: time device was first connected
* @do_remote_wakeu p:& remote wakeu p shou ld be enabled
* @reset_resu me: needs reset instead of resu me
* @wu sb_dev: if this is a WirelessU SB device, link to the WU SB
*&&&&& specific data for the device.
* @slot_id: Slot ID assigned by xHCI
*U sbcore drivers shou ld not set
u sbdev-&state directly.& Insteadu se
*u sb_set_device_state().
&&&&&&&& int&&&&&&&&&&&& devnu
&&&&&&&& char&&&&&&&&&&& devpath[16];
&&&&&&&&&&&&&&&&&&&& rou
&&&&&&&& enu m&&;
&&&&&&&& enu m&&;
&&&&&&&& stru ct&&
&&&&&&&& int&&&&&&&&&&&&
&&&&&&&&u nsigned int
&&&&&&&& stru ct*;
&&&&&&&& stru ct*;
&&&&&&&& stru ctep0;
&&&&&&&& stru
&&&&&&&& stru
&&&&&&&& stru ct*;
&&&&&&&& stru ct*
&&&&&&&& stru ct*ep_in[16];
&&&&&&&& stru ct*ep_ou t[16];
&&&&&&&& char **
&&&&&&&&u nsigned short bu s_mA;
&&&&&&&&portnu
&&&&&&&&u nsigned can_su bmit:1;
&&&&&&&&u nsigned persist_enabled:1;
&&&&&&&&u nsigned have_langid:1;
&&&&&&&&u nsigned au thorized:1;
&&&&&&&&u nsigned au thenticated:1;
&&&&&&&&u nsigned wu sb:1;
&&&&&&&& int string_
&&&&&&&&/* static strings from the device */
&&&&&&&& char *;
&&&&&&&& char *;
&&&&&&&& char *;
&&&&&&&& stru
#ifdef CONFIG_USB_DEVICE _CLASS
&&&&&&&& stru ct*u
#ifdef CONFIG_USB_DEVICE FS
&&&&&&&& stru ct*u
&&&&&&&& stru ct*children[];
&&&&&&&&u rbnu
&&&&&&&&u nsigned long active_du
&&&&&&&&u nsigned long connect_
&&&&&&&&u nsigned do_remote_wakeu p:1;
&&&&&&&&u nsigned reset_resu me:1;
&&&&&&&& stru ct*;
&&&&&&&& int slot_
#define()(,
static inline stru ct*(stru ct*)
&&&&&&&& retu rn(-&.);
以上三个结构体分别是usb_driver,usb_bus,usb_device设备结构体。
usb_interface结构体:
&&&&&&&&/* array of alternate settings for this interface,
&&&&&&&& * stored in no particular order */
&&&&&&&& struct*;
&&&&&&&& struct*cur_&&&&&
/* the currently
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * active alternate setting */
&&&&&&&& unsigned num_&&&&&&&/* number of alternate settings */
&&&&&&&&/* If there is an interface association descriptor then it will list
&&&&&&&& * the associated interfaces */
&&&&&&&& struct*intf_
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/*
minor number this interface is
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * bound to */
&&&&&&&&&&&&&&&&/*
state of binding */
&&&&&&&& unsigned sysfs_files_created:1;/* the sysfs attributes exist */
&&&&&&&& unsigned ep_devs_created:1;&&&&/* endpoint &devices& exist */
&&&&&&&& unsigned unregistering:1;&&&&&&/* unregistration is in progress */
&&&&&&&& unsigned needs_remote_wakeup:1;/* driver requires remote wakeup */
&&&&&&&& unsigned needs_altsetting0:1;&&/* switch to altsetting 0 is pending */
&&&&&&&& unsigned needs_binding:1;&&&&&&/* needs delayed unbind/rebind */
&&&&&&&& unsigned reset_running:1;
&&&&&&&& unsigned resetting_device:1;&&&/* true: bandwidth alloc after reset */
&&&&&&&&&&&&&&&&&&&&&/*
interface specific device info */
&&&&&&&& struct*;
&&&&&&&&pm_usage_&&&&&&&&&/*
usage counter for autosuspend */
&&&&&&&& structreset_&&&
/* for resets in atomic context */
&struct usb_host_interface *altsetting包含了usb interface的所有可选设置。
&struct usb_host _interface *cur_altsetting是usb interface的当前可选设置。
下面看一个struct usb_host_interface
/* host-side wrapper for one interface setting's parsed descriptors */
stru ctusb_host_interface {
&&&&&&&& stru ctu sb_interface_descriptordesc
&&&&&&&&/* array of desc.bNu mEndpoint endpoints associated with this
&&&&&&&& * interface setting.& these will be in no particu lar order.
&&&&&&&& */
&&&&&&&& stru ctu sb_host_endpoint *endpoint
&&&&&&&& char *string ;&&&&&&&&&&/* iInterface string, if present */
&&&&&&&&u nsigned char *&&
/* Extra descriptors */
其中struct usb_interface_descriptor即是usb接口描述符。
struct usb_host_endpoint代表的是设备端点。
可以在desc中改变接口包含的端点数。
接下来看一下usb_host_endpoint这个结构体:
* stru ctusb_host_endpoint - host-side endpoint descriptor and qu eu
* @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
* @ss_ep_comp: Su perSpeed companion descriptor for this endpoint
* @u rb_list:u rbs qu eu maintained byu
* @hcpriv: foru se by HCD; typically holds hardware dma qu eu e head (QH)
*&&&&& with one or more transfer descriptors (TDs) peru rb
* @ep_dev: ep_device for sysfs info
* @extra: descriptors following this endpoint in the configu ration
* @extralen: how many bytes of &extra& are valid
* @enabled:U RBs may be su bmitted to this endpoint
*U SB requ ests are always qu eu ed to a given endpoint, identified
* descriptor within an active interface in a givenU SB configu ration.
stru ctusb_host_endpoint {
&&&&&&&& stru ctu sb_endpoint_descriptor &&&&&&&&&desc
&&&&&&&& stru ctu sb_ss_ep_comp_descriptor &&&&&& ss_ep_
&&&&&&&& stru ctlist_head &&&&&&&&&&&&&u
&&&&&&&& void&&&&&&&&&&&&&&&&&&&&&&&&&&& *
&&&&&&&& stru ctep_device &&&&&&&&&&&& *ep_&&&&&&&/* For sysfs
&&&&&&&&u nsigned char *&&
/* Extra descriptors */
&&&&&&&& intenabled ;
其中struct usb_endpoint_descriptor是端点描述符。
urb(usb reqeust block):
urb主要用于Linux host与设备进行数据传输.
urb的生命周期:
(1)由usb设备驱动创建
(2)分配到usb设备的指定端点
(3)由Usb设备驱动提交到usb core
(4)由Usb core提交到usb 主机控制器
(5)由Usb主机控制器控制设备进行数据传输
(6)当urb完成的时候,usb主机控制器驱动通知usb 设备驱动
* stru cturb -U SB Requ
* @urb _list: Foru se by cu rrent owner
of the URB .
* @anchor_list: membership in the list of an anchor
* @anchor: to anchorURB s to a common mooring
* @ep: Points to the endpoint's data stru ctu re.& Will eventu ally
*&&&&& replace @pipe.
* @pipe: Holds endpoint nu mber, direction, type, and more.
*&&&&& Create these valu es with the ei
*&&&&&u sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is &ctrl&
*&&&&& (control), &bu lk&, &int& (interru pt), or &iso& (isochronou s).
*&&&&& For exampleu sb_sndbu lkpipe() oru sb_rcvintpipe().& Endpoint
*&&&&& nu mbers range from zero to fifteen.& Note that &in& endpoint two
*&&&&& is a different endpoint (and pipe) from &ou t& endpoint two.
*&&&&& The cu rrent configu ration controls the existence, type, and
*&&&&& maximu m packet size of any given endpoint.
* @stream_id: the endpoint's stream ID for bu lk streams
* @dev: Identifies theU SB device to perform the requ est.
* @statu s: This is read in non-iso completion fu nctions to get the
*&&&&& statu s of the particu lar requ est.& ISO requ ests
onlyu se it
*&&&&& to tell whether theURB was
u detailed statu s for
*&&&&& each frame is in the fields of the iso_frame-desc.
* @transfer_flags: A variety of flags may beu sed to affect howURB
*&&&&& su bmission,u nlinking, or operation are handled.& Different
*&&&&& kinds ofURB canu se different flags.
* @transfer_bu ffer:& This identifies the bu ffer to (or from) which the I/O
*&&&&& requ est will be performedu nlessURB
_NO_TRANSFER_DMA_MAP is set
*&&&&& (however, do not leave garbage in transfer_bu ffer even then).
*&&&&& This bu ffer mu st be su itable for DMA; allocate it with
*&&&&& kmalloc() or equ ivalent.& For transfers to &in& endpoints, contents
*&&&&& of this bu ffer will be modified.& This bu ffer isu sed for the
*&&&&& stage of control transfers.
* @transfer_dma: When transfer_flags inclu desURB
_NO_TRANSFER_DMA_MAP,
*&&&&& the device driver is saying that it provided this DMA address,
*&&&&& which the host controller driver shou ldu se in preference to the
*&&&&& transfer_bu ffer.
* @sg: scatter gather bu ffer list
* @nu m_sgs: nu mber of entries in the sg list
* @transfer_bu ffer_length: How big is transfer_bu ffer.& The transfer may
*&&&&& be brokenu p into chu nks according to the cu rrent maximu
*&&&&& size for the endpoint, which is a fu nction of the configu ration
*&&&&& and is encoded in the pipe.& When the length is zero, neither
*&&&&& transfer_bu ffer nor transfer_dma isu sed.
* @actu al_length: This is read in non-iso completion fu nctions, and
*&&&&& it tells how many bytes (ou t of transfer_bu ffer_length) were
*&&&&& transferred.& It will normally be the same as requ ested,u nless
*&&&&& either an error was reported or a short read was performed.
*&&&&& TheURB _SHORT_NOT_OK transfer flag may beu
sed to make su ch
*&&&&& short reads be reported as errors.
* @setu p_packet: Onlyu sed for control transfers, this points to eight bytes
*&&&&& of setu p data.& Control transfers always start by sending this data
*&&&&& to the device.& Then transfer_bu ffer is read or written, if needed.
* @setu p_dma: DMA pointer for the setu p packet.& The caller mu st notu
*&&&&& setu p_packet mu st point to a valid bu ffer.
* @start_frame: Retu rns the initial frame for isochronou s transfers.
* @nu mber_of_packets: Lists the nu mber of ISO transfer bu ffers.
* @interval: Specifies the polling interval for interru pt or isochronou s
*&&&&& transfers.& Theu nits are frames (milliseconds) for fu ll and low
*&&&&& speed devices, and microframes (1/8 millisecond) for highspeed
*&&&&& and Su perSpeed devices.
* @error_cou nt: Retu rns the nu mber of ISO transfers that reported errors.
* @context: Foru se in completion fu nctions.& This normally points to
*&&&&& requ est-specific driver context.
* @complete: Completion handler. ThisURB is passed as the parameter
*&&&&& completion fu nction.& The completion fu nction may then do what
*&&&&& it likes with theURB , inclu ding resu
bmitting or freeing it.
* @iso_frame_desc:U sed to provide arrays of ISO transfer bu ffers and to
*&&&&& collect the transfer statu s for each bu ffer.
* This stru ctu re identifiesU SB transfer requ ests.&URB
s mu st be allocated by
* callingu sb_alloc_urb () and freed with a call tou
sb_free_urb ().
* Initialization may be doneu sing variou su sb_fill_*_urb
() fu nctions.&URB s
* are su bmittedu sing
u sb_su bmit_urb (), and pending requ ests may be canceled
u sb_u nlink_urb () oru sb_kill_urb ().
* Data Transfer Bu ffers:
* Normally drivers provide I/O bu ffers allocated with kmalloc() or otherwise
* taken from the general page pool.& That is provided by transfer_bu ffer
* (control requ ests alsou se setu p_packet), and host controller drivers
* perform a dma mapping (andu nmapping) for each bu ffer transferred.& Those
* mapping operations can be expensive on some platforms (perhapsu sing a dma
* bou nce bu ffer or talking to an IOMMU ),
* althou gh they're cheap on commodity x86 and ppc hardware.
* Alternatively, drivers may pass theURB _NO_TRANSFER_DMA_MAP transfer
* which tells the host controller driver that no su ch mapping is needed for
* the transfer_bu ffer since
* the device driver is DMA-aware.& For example, a device driver might
* allocate a DMA bu ffer withu sb_alloc_coherent() or callu sb_bu
ffer_map().
* When this transfer flag is provided, host controller drivers will
* attempt tou se the dma address fou nd in the transfer_dma
* field rather than determining a dma address themselves.
* Note that transfer_bu ffer mu st still be set if the controller
* does not su pport DMA (as indicated by bu s.u ses_dma) and when talking
* to root hu b. If you have to trasfer between highmem zone and the device
* on su ch controller, create a bou nce bu ffer or bail ou
t with an error.
* If transfer_bu ffer cannot be set (is in highmem) and the controller is DMA
* capable, assign NU LL to it, so thatu sbmon knows not tou se the valu
* The setu p_packet mu st always be set, so it cannot be located in highmem.
* Initialization:
* AllURB s su bmitted mu st initialize
the dev, pipe, transfer_flags (may be
* zero), and complete fields.& AllURB s mu st also
initialize
* transfer_bu ffer and transfer_bu ffer_length.& They may provide the
*URB _SHORT_NOT_OK transfer flag, indicating that short reads are
that flag is invalid for write requ ests.
* Bu lkURB s may
URB _ZERO_PACKET transfer flag, indicating that bu lk OU T transfers
* shou ld always terminate with a short packet, even if it means adding an
* extra zero length packet.
* ControlURB s mu st provide a valid pointer in the
setu p_packet field.
*U nlike the transfer_bu ffer, the setu p_packet may not be mapped for
* beforehand.
* Interru ptURB s mu st provide an interval,
saying how often (in milliseconds
* or, for highspeed devices, 125 microsecondu nits)
* to poll for transfers.& After theURB has been su
bmitted, the interval
* field reflects how the transfer was actu ally schedu led.
* The polling interval may be more frequ ent than requ ested.
* For example, some controllers have a maximu m interval of 32 milliseconds,
* while others su pport intervals ofu p to 1024 milliseconds.
* Isochronou sURB s also have transfer intervals.&
(Note that for isochronou s
* endpoints, as well as high speed interru pt endpoints, the encoding of
* the transfer interval in the endpoint descriptor is logarithmic.
* Device drivers mu st convert that valu e to linearu nits themselves.)
* Isochronou sURB s normally
u se theURB _ISO_ASAP transfer flag, telling
* the host controller to schedu le the transfer as soon as bandwidth
*u tilization allows, and then set start_frame to reflect the actu al frame
* selected du ring su bmission.& Otherwise drivers mu st specify the start_frame
* and handle the case where the transfer can't begin then.& However, drivers
* won't know how bandwidth is cu rrently allocated, and while they can
* find the cu rrent frameu sing
u sb_get_cu rrent_frame_nu mber () they can't
* know the range for that frame nu mber.& (Ranges for frame cou nter valu
* are HC-specific, and can go from 256 to 65536 frames from &now&.)
* Isochronou sURB s have a different data transfer
model, in part becau se
* the qu ality of service is only &best effort&.& Callers provide specially
* allocatedURB s, with nu mber_of_packets worth of
iso_frame_desc stru ctu res
* at the end.& Each su ch packet is an individu al ISO transfer.& Isochronou
*URB s are normally qu eu ed, su
bmitted by drivers to arrange that
* transfers are at least dou ble bu ffered, and then explicitly resu bmitted
* in completion handlers, so
* that data (su ch as au dio or video) streams at as constant a rate as the
* host controller schedu ler can su pport.
* Completion Callbacks:
* The completion callback is made in_interru pt(), and one of the first
* things that a completion handler shou ld do is check the statu s field.
* The statu s field is provided for allURB s.& It
is u sed to report
*u nlinked
URB s, and statu s for all non-ISO transfers.& It shou ld not
* be examined before theURB is retu rned to the completion
* The context field is normallyu sed to link
URB s back to the relevant
* driver or requ est state.
* When the completion callback is invoked for non-isochronou sURB
* actu al_length field tells how many bytes were transferred.& This field
* isu pdated even when the
URB terminated with an error or wasu nlinked.
* ISO transfer statu s is reported in the statu s and actu al_length fields
* of the iso_frame_desc array, and the nu mber of errors is reported in
* error_cou nt.& Completion callbacks for ISO transfers will normally
* (re)su bmitURB s to ensu re a constant
transfer rate.
* Note that even fields marked &pu blic& shou ld not be tou ched by the
* when theurb is owned by the hcd, that is, since the call to
*u sb_su bmit_urb () till the entry into
the completion rou tine.
&&&&&&&&/* private:
u sb core and host controller only fields in theurb */
&&&&&&&& stru&&&&&&&&&&&&&&/*
reference cou nt of the URB */
&&&&&&&& void *&&&&&&&&&&&&&&&&&&/* private data for host controller */
&&&&&&&&;&&&&&&&&&&&&/* concu rrent su bmissions cou nter */
&&&&&&&&&&&&&&&&&&&&&&&/*
su bmissions will fail */
&&&&&&&& intu&&&&&&&&&&&&&&&&&&
/* u nlink error code */
&&&&&&&&/* pu blic: docu mented fields in theurb
that can beu sed by drivers */
&&&&&&&& stru&&&&&/* list head for u se by the
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * cu rrent owner */
&&&&&&&& stru ctanchor_&&
/* theURB may be anchored */
&&&&&&&& stru ct*
&&&&&&&& stru ct*;&&&&&&&&/* (in) pointer to associated device */
&&&&&&&& stru ct*;&&/* (internal) pointer to endpoint */
&&&&&&&&u nsigned int
;&&&&&&&&&&&&& /* (in) pipe information */
&&&&&&&&u nsigned int
;&&&&&&&& /* (in) stream ID */
&&&&&&&&&&&&&&&&&&&&&&&&&&&&/* (retu rn) non-ISO statu s */
&&&&&&&&u nsigned int transfer_&&&
/* (in) URB _SHORT_NOT_OK | ...*/
&&&&&&&& void *transfer_bu&&&&&&&&&/* (in) associated data bu ffer */
&&&&&&&&transfer_&&&&&&&/*
(in) dma addr for transfer_bu ffer */
&&&&&&&& stru ct*&&&&&&&&
/* (in) scatter gather bu ffer list */
&&&&&&&& int nu m_&&&&&&&&&&&&&&&&&&&/* (in) nu mber of entries in the sg list
&&&&&&&&transfer_bu
ffer_&&&&/* (in) data bu ffer length */
&&&&&&&&actu
al_&&&&&&&&&&&&&/* (retu rn) actu al transfer length */
&&&&&&&&u nsigned char *;&&&/* (in) setu p packet (control only) */
&&&&&&&&;&&&&&&&&&&/* (in) dma addr for setu p_packet */
&&&&&&&& int start_&&&&&&&&&&&&&&&/* (modify) start frame (ISO) */
&&&&&&&& int nu mber_of_&&&&&&&&&/* (in) nu mber of ISO packets */
&&&&&&&&&&&&&&&&&&&&&&&&&&
/* (modify) transfer interval
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& * (INT/ISO) */
&&&&&&&&&&&&&&&&&&&&&&&/* (retu rn) nu mber of ISO errors */
&&&&&&&& void *;&&&&&&&&&&&&&&&&&/*
(in) context for completion */
&&&&&&&&;&&&&&&&/* (in) completion rou tine */
&&&&&&&& stru ctiso_frame_desc[0];
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/* (in) ISO ONLY */
/* ----------------------------------------------------------------------- */
6. Linux usb 驱动的相关操作函数
&int usb_register(struct usb_driver *d);
void usb_deregister(struct usb_driver *d);
Functions used to register and unregister a USB driver from the USB core.
&这两个函数主要用来注册usb driver与解注册usb driver.
struct usb_device *interface_to_usbdev(struct usb_interface *intf);
Retrieves the controlling struct usb_device * out of a struct usb_interface *.
返回一个usb接口返回一个usb_device.
void usb_set_intfdata(struct usb_interface *intf, void *data);
void *usb_get_intfdata(struct usb_interface *intf);
Functions to set and get access to the private data pointer section within the
struct usb_interface.
设置private data和是返回private data.
int usb_register_dev(struct usb_interface *intf, struct usb_class_driver
*class_driver);
void usb_deregister_dev(struct usb_interface *intf, struct usb_class_driver
*class_driver);
Functions used to register and unregister a specific struct usb_interface * structure
with a struct usb_class_driver * structure.
注册usb接口驱动和解注册usb接口驱动,接口驱动也就是设备驱动。
struct urb *usb_alloc_urb(int iso_packets, int mem_flags);
void usb_free_urb(struct urb *urb);
Functions used to create and destroy a struct usb urb *.
分配和释放urb.
void usb_fill_int_urb(struct urb *urb, struct usb_device *dev, unsigned int
pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete,
void *context, int interval);
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev, unsigned int
pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete,
void *context);
void usb_fill_control_urb(struct urb *urb, struct usb_device *dev, unsigned
int pipe, unsigned char *setup_packet, void *transfer_buffer, int
buffer_ length, usb_complete_t complete, void *context);
Functions used to initialize a struct urb before it is submitted to the USB core.
这三个函数是用来初始化urb.
struct urb* urb 要初始化的urb结构体。
struct usb_device *dev urb发送到的设备
unsigned int pipe& usb_sndintpipe和usb_rcvintpipe分别是usb发送端点管道和接收端点管道
void *transfer_buffer 接收或发送数据的缓冲区
int buffer_length 缓冲区的长度
usb_complete_t& urb完成时的回调函数
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data,
int len, int *actual_length, int timeout);
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);
Functions used to send or receive USB data without having to use a struct urb.
这两个函数的usb接收或发送数据没有使用urb结构体。
7. skelton程序
&* USB Skeleton driver - 2.2
&* Copyright (C)
Greg Kroah-Hartman ()
&*&&& This prog you can redistribute it and/or
&*&&& modify it under the terms of the GNU General Public License as
&*&&& published by the Free Software Foundation, version 2.
&* This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
&* but has been rewritten to be easier to read and use.
#include &linux/kernel.h&
#include &linux/errno.h&
#include &linux/init.h&
#include &linux/slab.h&
#include &linux/module.h&
#include &linux/kref.h&
#include &asm/uaccess.h&
#include &linux/usb.h&
#include &linux/mutex.h&
/* Define these values to match your devices */
#define USB_SKEL_VENDOR_ID&&& 0xfff0
#define USB_SKEL_PRODUCT_ID&&& 0xfff0
/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
&&& { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
&&& { }&&& &&& &&& &&& &&& /* Terminating entry */
MODULE_DEVICE_TABLE(usb, skel_table);
/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE&&& 192 //次设备号
/* our private defines. if this grows any larger, use your own .h file */
#define MAX_TRANSFER&&& &&& (PAGE_SIZE - 512)
#define WRITES_IN_FLIGHT&&& 8
/* Structure to hold all of our device specific stuff */
struct usb_skel {
&&&&& size_
&&& struct usb_device&&&&&& *&&& &&& &&& /* the usb device for this device */
&&& struct usb_interface&&& *&&& &&& /* the interface for this device */
&&& struct semaphore&&& limit_&&& &&& /* limiting the number of writes in progress */
&&& unsigned char&&&&&&&&&& *bulk_in_&&& /* the buffer to receive data */
&&& size_t&&& &&& &&& bulk_in_&&& &&& /* the size of the receive buffer */
&&& __u8&&& &&& &&& bulk_in_endpointA&&& /* the address of the bulk in endpoint */
&&& __u8&&& &&& &&& bulk_out_endpointA&&& /* the address of the bulk out endpoint */
&&& struct kref&&& &&&
&&& struct mutex&&& &&& io_&&& &&& /* synchronize I/O with disconnect */
#define to_skel_dev(d) container_of(d, struct usb_skel, kref)
static struct usb_driver skel_
static void skel_delete(struct kref *kref)
&&& struct usb_skel *dev = to_skel_dev(kref);
&&& usb_put_dev(dev-&udev);
&&& kfree(dev-&bulk_in_buffer);
&&& kfree(dev);
static int skel_open(struct inode *inode, struct file *file)
&&& struct usb_skel *
&&& struct usb_interface *
&&& int retval = 0;
&&& subminor = iminor(inode);
&&& interface = usb_find_interface(&skel_driver, subminor);
&&& if (!interface) {
&&& &&& err (&%s - error, can't find device for minor %d&,
&&& &&& &&&& __FUNCTION__, subminor);
&&& &&& retval = -ENODEV;
&&& dev = usb_get_intfdata(interface);
&&& if (!dev) {
&&& &&& retval = -ENODEV;
&&& /* prevent the device from being autosuspended */
&&& retval = usb_autopm_get_interface(interface);
&&& if (retval)
&&& /* increment our usage count for the device */
&&& kref_get(&dev-&kref);
&&& /* save our object in the file's private structure */
&&& file-&private_data =
static int skel_release(struct inode *inode, struct file *file)
&&& struct usb_skel *
&&& dev = (struct usb_skel *)file-&private_
&&& if (dev == NULL)
&&& &&& return -ENODEV;
&&& /* allow the device to be autosuspended */
&&& mutex_lock(&dev-&io_mutex);
&&& if (dev-&interface)
&&& &&& usb_autopm_put_interface(dev-&interface);
&&& mutex_unlock(&dev-&io_mutex);
&&& /* decrement the count on our device */
&&& kref_put(&dev-&kref, skel_delete);
&&& return 0;
static ssize_t skel_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
&&& struct usb_skel *
&&& int bytes_
&&& dev = (struct usb_skel *)file-&private_
&&& mutex_lock(&dev-&io_mutex);
&&& if (!dev-&interface) {&&& &&& /* disconnect() was called */
&&& &&& retval = -ENODEV;
&&& /* do a blocking bulk read to get data from the device */ & //usb_bulk_msg没有使用urb
&&& retval = usb_bulk_msg(dev-&udev,
&&& &&& &&& &&&&& usb_rcvbulkpipe(dev-&udev, dev-&bulk_in_endpointAddr),
&&& &&& &&& &&&&& dev-&bulk_in_buffer,
&&& &&& &&& &&&&& min(dev-&bulk_in_size, count),
&&& &&& &&& &&&&& &bytes_read, 10000);
&&& /* if the read was successful, copy the data to userspace */
&&& if (!retval) {
&&& &&& if (copy_to_user(buffer, dev-&bulk_in_buffer, bytes_read)) //复制到用户空间
&&& &&& &&& retval = -EFAULT;
&&& &&& else
&&& &&& &&& retval = bytes_
&&& mutex_unlock(&dev-&io_mutex);
static void skel_write_bulk_callback(struct urb *urb)
&&& struct usb_skel *
&&& dev = (struct usb_skel *)urb-&
&&& /* sync/async unlink faults aren't errors */
&&& if (urb-&status &&
&&& &&& !(urb-&status == -ENOENT ||
&&& &&&&& urb-&status == -ECONNRESET ||
&&& &&&&& urb-&status == -ESHUTDOWN)) {
&&& &&& err(&%s - nonzero write bulk status received: %d&,
&&& &&& &&& __FUNCTION__, urb-&status);
&&& /* free up our allocated buffer */
&&& usb_buffer_free(urb-&dev, urb-&transfer_buffer_length,
&&& &&& &&& urb-&transfer_buffer, urb-&transfer_dma);
&&& up(&dev-&limit_sem);
//首先创建一个urb和buffer,初始化urb,然后提交urb.
static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
&&& struct usb_skel *
&&& int retval = 0;
&&& struct urb *urb = NULL;
&&& char *buf = NULL;
&&& size_t writesize = min(count, (size_t)MAX_TRANSFER);
&&& dev = (struct usb_skel *)file-&private_
&&& /* verify that we actually have some data to write */
&&& if (count == 0)
&&& /* limit the number of URBs in flight to stop a user from using up all RAM */
&&& if (down_interruptible(&dev-&limit_sem)) {
&&& &&& retval = -ERESTARTSYS;
&&& mutex_lock(&dev-&io_mutex);
&&& if (!dev-&interface) {&&& &&& /* disconnect() was called */
&&& &&& retval = -ENODEV;
&&& /* create a urb, and a buffer for it, and copy the data to the urb */
&&& urb = usb_alloc_urb(0, GFP_KERNEL);
&&& if (!urb) {
&&& &&& retval = -ENOMEM;
&&& buf = usb_buffer_alloc(dev-&udev, writesize, GFP_KERNEL, &urb-&transfer_dma);
&&& if (!buf) {
&&& &&& retval = -ENOMEM;
&&& if (copy_from_user(buf, user_buffer, writesize)) {
&&& &&& retval = -EFAULT;
&&& /* initialize the urb properly */
&&& usb_fill_bulk_urb(urb, dev-&udev,
&&& &&& &&& & usb_sndbulkpipe(dev-&udev, dev-&bulk_out_endpointAddr),
&&& &&& &&& & buf, writesize, skel_write_bulk_callback, dev);
&&& urb-&transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
&&& /* send the data out the bulk port */
&&& retval = usb_submit_urb(urb, GFP_KERNEL);
&&& if (retval) {
&&& &&& err(&%s - failed submitting write urb, error %d&, __FUNCTION__, retval);
&&& /* release our reference to this urb, the USB core will eventually free it entirely */
&&& usb_free_urb(urb);
&&& mutex_unlock(&dev-&io_mutex);
&&& if (urb) {
&&& &&& usb_buffer_free(dev-&udev, writesize, buf, urb-&transfer_dma);
&&& &&& usb_free_urb(urb);
&&& mutex_unlock(&dev-&io_mutex);
&&& up(&dev-&limit_sem);
static const struct file_operations skel_fops = {
&&& .owner =&&& THIS_MODULE,
&&& .read =&&& &&& skel_read,
&&& .write =&&& skel_write,
&&& .open =&&& &&& skel_open,
&&& .release =&&& skel_release,
&* usb class driver info in order to get a minor number from the usb core,
&* and to have the device registered with the driver core
static struct usb_class_driver skel_class = {
&&& .name =&&& &&& &skel%d&,
&&& .fops =&&& &&& &skel_fops,
&&& .minor_base =&&& USB_SKEL_MINOR_BASE,
static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
&&& struct usb_skel *
&&& struct usb_host_interface *iface_ //usb_host_interface包含usb interface的所有设置
&&& struct usb_endpoint_descriptor * //这个结构体是usb端点描述符
&&& size_t buffer_
&&& int retval = -ENOMEM;
&&& /* allocate memory for our device state and initialize it */
&&& dev = kzalloc(sizeof(*dev), GFP_KERNEL);
&&& if (!dev) {
&&& &&& err(&Out of memory&);
&&& kref_init(&dev-&kref);
&&& sema_init(&dev-&limit_sem, WRITES_IN_FLIGHT);
&&& mutex_init(&dev-&io_mutex);
&&& dev-&udev = usb_get_dev(interface_to_usbdev(interface)); //增加使用计数
&&& dev-&interface =
&&& /* set up the endpoint information */
&&& /* use only the first bulk-in and bulk-out endpoints */
&&& iface_desc = interface-&cur_
&&& for (i = 0; i & iface_desc-&desc.bNumE ++i) {
&&& &&& endpoint = &iface_desc-&endpoint[i].
&&& &&& if (!dev-&bulk_in_endpointAddr &&
&&& &&& &&& usb_endpoint_is_bulk_in(endpoint)) {
&&& &&& &&& /* we found a bulk in endpoint */
&&& &&& &&& buffer_size = le16_to_cpu(endpoint-&wMaxPacketSize);
&&& &&& &&& dev-&bulk_in_size = buffer_
&&& &&& &&& dev-&bulk_in_endpointAddr = endpoint-&bEndpointA
&&& &&& &&& dev-&bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
&&& &&& &&& if (!dev-&bulk_in_buffer) {
&&& &&& &&& &&& err(&Could not allocate bulk_in_buffer&);
&&& &&& &&& &&&
&&& &&& &&& }
&&& &&& if (!dev-&bulk_out_endpointAddr &&
&&& &&& &&& usb_endpoint_is_bulk_out(endpoint)) {
&&& &&& &&& /* we found a bulk out endpoint */
&&& &&& &&& dev-&bulk_out_endpointAddr = endpoint-&bEndpointA
&&& if (!(dev-&bulk_in_endpointAddr && dev-&bulk_out_endpointAddr)) {
&&& &&& err(&Could not find both bulk-in and bulk-out endpoints&);
&&& /* save our data pointer in this interface device */
&&& usb_set_intfdata(interface, dev);
&&& /* we can register the device now, as it is ready */
&&& retval = usb_register_dev(interface, &skel_class);& //注册usb设备
&&& if (retval) {
&&& &&& /* something prevented us from registering this driver */
&&& &&& err(&Not able to get a minor for this device.&);
&&& &&& usb_set_intfdata(interface, NULL);
&&& /* let the user know what node this device is now attached to */
&&& info(&USB Skeleton device now attached to USBSkel-%d&, interface-&minor);
&&& return 0;
&&& if (dev)
&&& &&& kref_put(&dev-&kref, skel_delete);
static void skel_disconnect(struct usb_interface *interface)
&&& struct usb_skel *
&&& int minor = interface-&
&&& /* prevent skel_open() from racing skel_disconnect() */
&&& lock_kernel();
&&& dev = usb_get_intfdata(interface);
&&& usb_set_intfdata(interface, NULL);
&&& /* give back our minor */
&&& usb_deregister_dev(interface, &skel_class);
&&& /* prevent more I/O from starting */
&&& mutex_lock(&dev-&io_mutex);
&&& dev-&interface = NULL;
&&& mutex_unlock(&dev-&io_mutex);
&&& unlock_kernel();
&&& /* decrement our usage count */
&&& kref_put(&dev-&kref, skel_delete);
&&& info(&USB Skeleton #%d now disconnected&, minor);
static struct usb_driver skel_driver = {
&&& .name =&&& &&& &skeleton&,
&&& .probe =&&& skel_probe,
&&& .disconnect =&&& skel_disconnect,
&&& .id_table =&&& skel_table,
static int __init usb_skel_init(void)
&&& /* register this driver with the USB subsystem */
&&& result = usb_register(&skel_driver);
&&& if (result)
&&& &&& err(&usb_register failed. Error number %d&, result);
static void __exit usb_skel_exit(void)
{ //向usb子系统注册这个驱动
&&& /* deregister this driver with the USB subsystem */
&&& usb_deregister(&skel_driver);
module_init(usb_skel_init);
module_exit(usb_skel_exit);
MODULE_LICENSE(&GPL&);
skeleton.c 在/driver/usb/ 目录下,它是一个骨架驱动程序。
skeleton首先向usb子系统中注册驱动,然后注册设备。通常所说的usb驱动是指usb接口驱动。即完成一定的功能,数据处理。面 usb driver通过扫描确定usb设备是否在本驱动的设备列表中,即一个usb driver可能对应多个usb设备,它是用来辨别usb设备的。当usb设备移除时,调用disconnect函数。usb driver用于识别usb interface driver.
最后记住,一个接口对应一个设备驱动,主机与设备之间的数据传输是通过端点来实现的。urb是设备与主机之间数据交换的中介。
关于usb 主机驱动就介绍到这里了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2933056次
积分:27779
积分:27779
排名:第165名
原创:315篇
转载:197篇
译文:11篇
评论:404条
(3)(5)(4)(12)(27)(4)(2)(7)(16)(5)(10)(14)(14)(5)(2)(2)(4)(3)(2)(5)(4)(10)(3)(4)(3)(1)(3)(6)(1)(2)(6)(5)(5)(8)(7)(7)(19)(18)(5)(14)(4)(3)(1)(12)(12)(31)(21)(12)(14)(10)(11)(7)(4)(15)(10)(8)(56)(19)}

我要回帖

更多关于 linux驱动编译进内核 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信