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 ...
随机推荐
- javascript循环和数组的基础练习
九九乘法表 <script> //外层循环行数 for(var i=0; i<=9; i++){ //内曾循环控制每一行的列数 for(var j=0;j<=i; j++){ ...
- iOS Crash日志
Understanding Crash Reports on iPhone OS https://developer.apple.com/videos/wwdc/2010/?id=317 http:/ ...
- logoff remote desktop sessions via command line tools
This trick I learned from my one of ex-college. In Windows servers, only two remote desktop session ...
- TID大会学习心得之敏捷软件架构-微服务
敏捷微服务构建 王威: TW咨询师.架构转型教练.敏捷技术教练 敏捷的目标 敏捷的目标是提升效率?降低成本?减员增效? 敏捷:关注价值.快速反馈.快速响应.其的目标是提升响应力,响应力的提升不一定会提 ...
- 【leedcode】add-two-numbers
You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...
- LeetCode Design Hit Counter
原题链接在这里:https://leetcode.com/problems/design-hit-counter/. 题目: Design a hit counter which counts the ...
- Python开发【前端】:DOM
DOM(文档对象模型(Document Object Model)) 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口.在网页 ...
- k8s入门系列之guestbook快速部署
k8s集群以及一些扩展插件已经安装完毕,本篇文章介绍一下如何在k8s集群上快速部署guestbook应用. •实验环境为集群:master(1)+node(4),详细内容参考<k8s入门系列之集 ...
- Win8电脑蓝屏并提示dpc_watchdog_violation
用尽系统自带的工具均无法恢复,F8能进系统.后来使用如下方法解决了 这种错误情况的发生可能是由于 iastor.sys 驱动没有完全兼容 Windows 8系统所造成的. 微软正在研究一种可行方案,来 ...
- 使用WKWebView遇到的坑
苹果从iOS8开始推出了WKWebView,大有替换UIWebView的意思(尽管Xcode中还没给UIWebView标记过期版本),所以决定将项目进行适配,iOS8及以上版本,改用WKWebView ...