《2022年编写USB驱动程序步骤 .pdf》由会员分享,可在线阅读,更多相关《2022年编写USB驱动程序步骤 .pdf(5页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、编写 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,co
2、nst 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_
3、table, .probe = skel_probe, .disconnect = skel_disconnect, ; 2usb_register()注册将 struct usb_driver 注册到 usb 核心,传统是在usb 驱动程序模块初始化代码中完成该工作的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 5 页 - - - - - - - - - static int _init usb_skel_init(void) . usb_register(&skel
4、_driver); . 3struct usb_device_id usb核心用该表判断哪个设备该使用哪个驱动程序,热插拔脚本使用它来确定当一个特定的设备插入到系统时该自动装载哪个驱动程序。 -_u16 match_flags(确定设备和结构体中下列字段中哪一个相匹配) -_u16 idVendor(设备的 usb 制造商 id ) -_u16 idProduct(设备的 usb 产品 id )4USB骨架程序的关键几点如下: 1. USB 驱动的注册和注销 Usb 驱动程序在注册时会发送一个命令给usb_register,通常在驱动程序的初始化函数里。当要从系统卸载驱动程序时,需要注销usb
5、 子系统。即需要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)
6、; USB_DEVICE宏利用厂商 ID 和产品 ID 为我们提供了一个设备的唯一标识。当系统插入一个ID 匹配的 USB设备到 USB总线时,驱动会在USB core 中注册。驱动程序中probe 函数也就会被调用。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 5 页 - - - - - - - - - usb_device 结构指针、接口号和接口ID 都会被传递到函数中。 3 static void * skel_probe(struct usb_device *d
7、ev,unsigned int ifnum, const struct usb_device_id *id) 驱动程序需要确认插入的设备是否可以被接受,如果不接受,或者在初始化的过程中发生任何错误,probe 函数返回一个NULL值。否则返回一个含有设备驱动程序状态的指针。通过这个指针,就可以访问所有结构中的回调函数。 4 在骨架驱动程序里, 最后一点是我们要注册devfs 。我们创建一个缓冲用来保存那些被发送给usb设备的数据和那些从设备上接受的数据,同时USB urb 被初始化,并且我们在devfs 子系统中注册设备,允许 devfs 用户访问我们的设备。注册过程如下: /* initia
8、lize 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函数
9、失败,不用担心,devfs 子系统会将此情况报告给用户。当然最后,如果设备从usb 总线拔掉,设备指针会调用disconnect 函数。驱动程序就需要清除那些被分配了的所有私有数据、关闭urbs ,并且从 devfs 上注销调自己。 /* remove our devfs node */devfs_unregister(skel-;devfs); 5 其他 1 struct usb_host_endpoint(描述 usb 端点 ) (包含) struct usb_endpoint_descriptor(含真正端点信息,数据格式,是真正驱动关心的字段) 端点描述符:名师资料总结 - - -精品
10、资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 5 页 - - - - - - - - - bEndpointAddress = 81(in)(第 8 位为 1 是输入设备 ) (usb 的端点地址,包含端点方向) bmAttibutes = 03(interrupt)(端点类型,为中断传输) wMaxPacketSize = 0008(每次传 8 个字节)(端点每次可处理最大字节长度) bInterval = 08(8ms )(如端点为中断,该值为轮询间隔) 2 usb端点捆绑为接口, usb 接
11、口只处理一种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_endpointunsigned num_a lt
12、setting(可选设置的数量 ) struct usb_host_interface * cur_altsetting(接口当前活动设置) int minor( usb 核心分配给接口的次设备号,成功调用usb_register_dev有效) 4 usb设备非常复杂,由许多不同逻辑单元组成,简单关系如下:设备通常有一个以上的配置配置经常有一个以上接口接口通常有一个以上设置接口通常有一个以上端点设备描述 - 配置描述 - 接口描述 - 端点描述 5 usb sysfs设备命名方案根集线器 - 集线器端口号:配置。接口对于 usb hub 树中层次更高的字树命名方案名师资料总结 - - -精品资
13、料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 5 页 - - - - - - - - - 根集线器 - 集线器端口号 - 集线器端口号:配置。接口 6 linux内核的代码通过一个成为urb (usb 请求块)和所有usb 设备通信 . 用 struct urb描述(include/linux/usb.h中定义) -urb用异步同 usb 设备特定 usb 端点发送 / 接收数据,使用类似网络代码中的struct skbuff - urb 被动态创建,随时可被驱动程序或usb 核心取消,内部有引用计
14、数,可被多次调用,使他们可在最后一个使用者释放他们时自动地销毁 - 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 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 5 页 - - - - - - - - -