USB驱动开发大全【转】
本文转载自:http://www.360doc.com/content/12/0504/19/8363527_208666082.shtml
编写USB驱动程序步骤:
1所有usb驱动都必须创建主要结构体struct usb_driver
struct usb_driver
->struct module *owner
(有他可正确对该驱动程序引用计数,应为THIS_MODULE)
->const char *name
(驱动名字,运行时可在查看 /sys/bus/usb/drivers/)
->const struct usb_device_id *id_table
(包含该驱动可支持的所有不同类型的驱动设备,没添探测回调函数不会被调用)
->int (*probe)(struct usb_interface *intf,const struct usb_device_id *id)
(usb驱动探测函数,确认后struct usb_interface 应恰当初始化,然后返0,如果出错则返负值)
->void(*disconnect)(struct usb_interface *intf)
(当struct usb_interface 被从系统中移除或驱动正从usb核心中卸载时,usb核心将调用此函数)
代码实例:
static struct usb_driver skel_driver={
.owner = THIS_MODULE,
.name = "skeleton",
.id_table = skel_table,
.probe = skel_probe,
.disconnect = skel_disconnect,
};
↓
2usb_register()注册将struct usb_driver 注册到usb核心,传统是在usb驱动程序模块初始化代码中完成该工作的
static int __init usb_skel_init(void)
{
...
usb_register(&skel_driver);
...
}
↓
3struct usb_device_id usb核心用该表判断哪个设备该使用哪个驱动程序,热插拔脚本使用它来确定当一个特定的设备插入到系统时该自动装载哪个驱动程序。
->__u16 match_flags(确定设备和结构体中下列字段中哪一个相匹配)
->__u16 idVendor(设备的usb制造商id)
->__u16 idProduct(设备的usb产品id)
↓
4USB骨架程序的关键几点如下:
1. USB驱动的注册和注销
Usb驱动程序在注册时会发送一个命令给usb_register,通常在驱动程序的初始化函数里。
当要从系统卸载驱动程序时,需要注销usb子系统。即需要usb_unregister 函数处理。
2 当usb设备插入时,为了使linux-hotplug(Linux中PCI、USB等设备热插拔支持)系统自动装载驱动程序,你需要创建一个MODULE_DEVICE_TABLE。代码如下(这个模块仅支持某一特定设备):
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);
USB_DEVICE宏利用厂商ID和产品ID为我们提供了一个设备的唯一标识。当系统插入一个ID匹配的USB设备到USB总线时,驱动会在USB core中注册。驱动程序中probe 函数也就会被调用。usb_device 结构指针、接口号和接口ID都会被传递到函数中。
3 static void * skel_probe(struct usb_device *dev,unsigned int ifnum, const struct usb_device_id *id)
驱动程序需要确认插入的设备是否可以被接受,如果不接受,或者在初始化的过程中发生任何错误,probe函数返回一个NULL值。否则返回一个含有设备驱动程序状态的指针。通过这个指针,就可以访问所有结构中的回调函数。
4 在骨架驱动程序里,最后一点是我们要注册devfs。我们创建一个缓冲用来保存那些被发送给usb设备的数据和那些从设备上接受的数据,同时USB urb 被初始化,并且我们在devfs子系统中注册设备,允许devfs用户访问我们的设备。注册过程如下:
/* initialize the devfs node for this device and register it */sprintf(name, "skel%d", skel->;minor);
skel->devfs = devfs_register (usb_devfs_handle, name,DEVFS_FL_DEFAULT, USB_MAJOR,USB_SKEL_MINOR_BASE + skel->minor,
S_IFCHR | S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP | S_IROTH, &skel_fops, NULL);
如果devfs_register函数失败,不用担心,devfs子系统会将此情况报告给用户。
当然最后,如果设备从usb总线拔掉,设备指针会调用disconnect 函数。驱动程序就需要清除那些被分配了的所有私有数据、关闭urbs,并且从devfs上注销调自己。
/* remove our devfs node */devfs_unregister(skel->;devfs);
↓
5其他
1 struct usb_host_endpoint(描述usb端点)
→(包含) struct usb_endpoint_descriptor(含真正端点信息,数据格式,是真正驱动关心的字段)
端点描述符:
bEndpointAddress = 81(in)(第8位为1是输入设备)(usb的端点地址,包含端点方向)
bmAttibutes = 03(interrupt)(端点类型,为中断传输)
wMaxPacketSize = 0008(每次传8个字节)(端点每次可处理最大字节长度)
bInterval = 08(8ms)(如端点为中断,该值为轮询间隔)
2 usb端点捆绑为接口,usb接口只处理一种usb逻辑连接,如鼠标键盘等.
一个usb设备可有多接口,usb扬声器:一个usb键盘用于按键,一个usb音频流,则需两个不同的驱动程序。
usb驱动 通常将struct usb_interface 转成 struct usb_device 用函数 interface_to_usbdev转
3 struct usb_interface 描述usb接口
→struct usb_host_interface * altsetting(接口结构体数组,包含所有可能用于该接口的可选设置)
→struct usb_host_endpoint
→unsigned num_altsetting(可选设置的数量)
→struct usb_host_interface * cur_altsetting(接口当前活动设置)
→int minor(usb核心分配给接口的次设备号,成功调用usb_register_dev有效)
4 usb设备非常复杂,由许多不同逻辑单元组成,简单关系如下:
设备通常有一个以上的配置
配置经常有一个以上接口
接口通常有一个以上设置
接口通常有一个以上端点
设备描述-》配置描述-》接口描述-》端点描述
5 usb sysfs设备命名方案
根集线器-集线器端口号:配置。接口
对于usb hub树中层次更高的字树命名方案
根集线器-集线器端口号-集线器端口号:配置。接口
6 linux内核的代码通过一个成为urb(usb请求块)和所有usb设备通信. 用struct urb描述(include/linux/usb.h中定义)
->urb用异步同usb设备特定usb端点发送/接收数据,使用类似网络代码中的struct skbuff
-> urb 被动态创建,随时可被驱动程序或usb核心取消,内部有引用计数,可被多次调用,使他们可在最后一个使用者释放他们时自动地销毁
-> urb使得流处理或其他复杂的重叠的通信成为可能,获得高数据传输速度。
->usb_alloc_urb() 创建urb包 usb_free_urb() 释放urb包
->usb_fill_int_urb()正确初始化将发送到usb设备的中断端点urb
usb_fill_bulk_urb() .. .. .. ... 批量传输端点urb
usb_fill_control_urb() .. .. .. ... 控制端点urb
等时urb在提交给核心时必须手动初始化(很不幸,没函数)
->usb_submit_urb()urb被usb驱动正确创建和初始化后,就可提交到usb核心,发送到usb设备上了,如果调用成功,函数返0,urb控制权转给usb核心
->usb_kill_urb() or usb_unlink_urb()取消已经被提交给核心的urb
USB驱动开发大全【转】的更多相关文章
- HarmonyOS USB DDK助你轻松实现USB驱动开发
HDF(Hardware Driver Foundation)驱动框架是HarmonyOS硬件生态开放的基础,为开发者提供了驱动加载.驱动服务管理和驱动消息机制等驱动能力,让开发者能精准且高效地开发驱 ...
- usb驱动开发1之学习准备
此系列是http://blog.csdn.net/fudan_abc/博文的整理,同时加入了自己的理解.很敬佩fudan_abc的文章,仔细学习和分析受益很多.注:fundan_abc所分析linux ...
- 庖丁解牛:USB 驱动开发技术彻底解密
我们知道如果开发工程师不懂RS232 肯定会让人笑话可以想象面向未来USB 接口无处不在因此掌握USB 的原理固件编程及其驱动开发技术势必成为当务之急USB 即插即用的优点和灵活性运用于各种电子产品现 ...
- 转: 嵌入式linux下usb驱动开发方法--看完少走弯路【转】
转自:http://blog.csdn.net/jimmy_1986/article/details/5838297 嵌入式linux下的usb属于所有驱动中相当复杂的一个子系统,要想将她彻底征服,至 ...
- usb驱动开发24之接口驱动
从第一节我们已经知道,usb_generic_driver在自己的生命线里,以一己之力将设备的各个接口送给了linux的设备模型,让usb总线的match函数,也就是usb_device_match, ...
- usb驱动开发15之设备生命线
总算是进入了HCD的片儿区,既然来到一个片区,怎么都要去拜会一下山头几个大哥吧.,先回忆一些我们怎么到这里的?给你列举一个调用函数过程usb_control_msg->usb_internal_ ...
- usb驱动开发14之设备生命线
直接看代码吧. /*-------------------------------------------------------------------*/ /** * usb_submit_urb ...
- usb驱动开发12之设备生命线
函数usb_control_msg完成一些初始化后调用了usb_internal_control_msg之后就free urb.剩下的活,全部留给usb_internal_control_msg去做了 ...
- usb驱动开发10之usb_device_match
在第五节我们说过会专门分析函数usb_device_match,以体现模型的重要性.同时,我们还是要守信用的. 再贴一遍代码,看代码就要不厌其烦. static int usb_device_matc ...
随机推荐
- 前端开发与SEO
前端开发中通过一些小习惯,可以有利于SEO,本着蚊子再小也是肉的原则,能抓住自然不能忽略. 1.控制首页链接数量,不能过多,也不要太少.更不要为了凑数而添加 2.扁平化层次,力争跳转三次可以到任何页面 ...
- 微软的HLSL Shader Model 6.0 compiler要转向LLVM了,开源的节奏. Apple/Khronos都有各自计划
So, Microsoft is making an opensource HLSL-to-almost-LLVM compiler, and Khronos is making an opensou ...
- 被swoole坑哭的PHP程序员
被swoole坑哭的PHP程序员 2015-09-16 09:57 文帅营 博客园 字号:T | T 首先说一下对swoole的理解:披着PHP外衣的C程序.很多PHPer朋友看到swoole提供的强 ...
- ASP.Net一键自动化更新代码、编译、合并dll、压缩js、css、混淆dll、zip打包、发布到测试环境的bat批处理
不废话,直接代码: D: cd D:\src\testproj\PrecompiledWeb svn revert ../ -R svn update .. rmdir BS /S /Q C:\Win ...
- vert.x学习(六),动态模板与静态文件的结合
这篇学习在动态模板里面引入css,把动态模板与静态文件结合起来使用. 编写DynamicReference.java package com.javafm.vertx.helloworld; impo ...
- supervisorctl error: <class 'socket.error'>
http://stackoverflow.com/questions/18859063/supervisor-socket-error-issue supervisorctl reread error ...
- 《Linux内核分析》期末总结
Linux内核设计期中总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 前八周博客汇总及总结 Linux内核设计第一周——从汇编语言出发理解计算机工作原理 我们学习了汇编语言的基础知识,这一 ...
- 云计算CTO工作的具体内容(挺详细)
职位描述: 工作职责: 1.参与制定公司发展战略.年度经营计划和预算方案. 2.全面管理公司研发和技术支持工作,全面负责技术层面的整体运营,包括软件研发.项目实施.销售支持及技术管理: 3.规划公司的 ...
- [原创]Hadoop默认设置导致NameNode启动失败一例
看到市面上很多书在讲解Hadoop的时候都轻描淡写的提到了HDFS的设置问题.大多采取的是默认设置,最多也就是设置一些副本数量之类. 笔者在工作中遇到了这样一种情况:每次重启系统之后,NameNode ...
- HTML中head里的内容经浏览器解析后全到body里了
HTML中head里的内容经浏览器解析后全到body里了 修改完代码后,用chrome审查元素,head里的内容都到body中去了 http://bbs.csdn.net/topics/3802586 ...