ImageVerifierCode 换一换
格式:DOCX , 页数:40 ,大小:38.65KB ,
资源ID:8249618      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8249618.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(通用USB设备驱动源码分析.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

通用USB设备驱动源码分析.docx

1、通用USB设备驱动源码分析通用USB设备驱动源码分析Author:aaron前段时间写了篇的文章,描述了自己如何为高通的一个usb modem设备写驱动的过程,最近发现实际上可以使用linux自带的一个叫usbserial的模块作为这个modem的驱动并能良好的工作,所以写了这片文章来详细的分析下usbserial模块的源码(2.6.16.3).应该来说,对于那些仅仅是用USB来通信,在上层可看作tty设备,不属于任何USB设备类型,没有什么流控等的普通USB设备来说都可以使用这个驱动来作为设备驱动程序.下面就来对这样一种通用的驱动程序来进行详细的分析.不对之处敬请指正!为了能让usbsera

2、il模块支持我的设备,我必须在命令行上输入如下命令:sudo modprobe usbserial vendor=0x12d1 product=0x1003该命令用特权用户来加载usbserial模块,并把该模块依赖的模块一并加载进系统,同时它还设置了usbserial的两个参数: vendor, product,很显然这两个参数是厂商ID和设备ID,而作用就是用于匹配设备.首先,当然是要知道usbserial模块由哪些文件编译而成,这样才能有目的性的去分析其代码.而要知道其组成当然是去其目录下看Makefile了,它位于内核源码目录下的./drivers/usb/serial/下./driv

3、ers/usb/serial/Makefile:# Makefile for the USB serial device drivers.# Object file lists.obj-$(CONFIG_USB_SERIAL)+= usbserial.o#编译内核时如何编译该模块usbserial-obj-$(CONFIG_USB_SERIAL_CONSOLE)+= console.ousbserial-obj-$(CONFIG_USB_EZUSB)+= ezusb.ousbserial-objs:= usb-serial.o generic.o bus.o $(usbserial-obj-y

4、)#OK,就是usbserial模块的组成了.obj-$(CONFIG_USB_SERIAL_AIRPRIME)+= airprime.oobj-$(CONFIG_USB_SERIAL_ANYDATA)+= anydata.o.我们重点看的是usb-serial.c,generic.c, bus.c在看源码之前我们先说说该模块的原理及整体结构:很简单跟应用层交互的是一个tty设备,也就是说该模块把USB设备映射成一个tty设备(即在/dev/目录下为该USB设备创建一个tty设备文件),然后用于可以用minicom之类的串口工具来打开这个设备,并同设备端的设备通信.对于发送过程: tty设备文

5、件在获取了用户要求发送的数据之后传递到下层usbserial模块的核心层,而该核心层就是将数据打包成USB格式的数据并由USB通信发送到设备端去,对于接收过程: usbserial模块会在该设备打开时就启动一个urb在那等待设备端发数据过来,收到数据后就push到上层tty设备的缓冲中去,而tty设备在收到数据后就会给用户,或直接显示在minicom之类的工具上.usb-serial.c就是usbserial模块的核心,它主要用来接收设备端发来的数据并传送到上层,同时也接收来自上层应用的数据,并组装成urb包发送给设备.generic.c对特定设备单独的操作,相当于是设备自己的驱动程序,由于很

6、多设备具有通用性,所以对于没有特殊要求的设备都可以使用这个驱动来作为自己设备的驱动程序.它有两个参数vendor和product,上面提过了.bus.c每个usb驱动和设备都必须要归入某一条总线上,即都是归属于某条总线的,只有这样系统才能从特定一条总线开始找到每个驱动和设备并为他们匹配.这个文件就是用来模拟一条总线,而usbserial的每个驱动和设备都会注册到这条总线上来.好了,是时候分析usbserial模块了.我们知道当把一个模块加载进系统时会调用这个模块里的一个由module_init()声明的一个初始化函数. usbserial当然也不另外,usb-serial.c:module_i

7、nit(usb_serial_init);module_exit(usb_serial_exit);没错加载时调用的就是:usb_serial_init().usb-serial.c:struct tty_driver *usb_serial_tty_driver;static int _init usb_serial_init(void)int i;int result;/创建一个tty_driver对象,对应的就是tty设备的驱动.usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);if (!usb_serial_tty_

8、driver)return -ENOMEM;/* Initialize our global data */for (i = 0; i owner = THIS_MODULE;usb_serial_tty_driver-driver_name = usbserial;usb_serial_tty_driver-devfs_name = usb/tts/;usb_serial_tty_driver-name =ttyUSB;/tty设备文件名以这个开头,后加0,1,2,3,.usb_serial_tty_driver-major = SERIAL_TTY_MAJOR;/主设备号usb_seria

9、l_tty_driver-minor_start = 0;usb_serial_tty_driver-type = TTY_DRIVER_TYPE_SERIAL;/设备类型usb_serial_tty_driver-subtype = SERIAL_TYPE_NORMAL;usb_serial_tty_driver-flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;usb_serial_tty_driver-init_termios = tty_std_termios;usb_serial_tty_driver-init_termios.c_c

10、flag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;/赋值tty设备的操作集合,即应用层调用open时最终会调到serial_ops-open里面tty_set_operations(usb_serial_tty_driver, &serial_ops);result = tty_register_driver(usb_serial_tty_driver);/注册这个tty驱动if (result) err(%s - tty_register_driver failed, _FUNCTION_);goto exit_reg_driver;/* registe

11、r the USB driver */result = usb_register(&usb_serial_driver);/注册一个usb驱动if (result 0) err(%s - usb_register failed, _FUNCTION_);goto exit_tty;/* register the generic driver, if we should */result = usb_serial_generic_register(debug);/注册generic驱动程序if (result description)driver-description = driver-dri

12、ver.name;/* Add this device to our list of devices */list_add(&driver-driver_list, &usb_serial_driver_list);/加入驱动列表retval = usb_serial_bus_register(driver);/把该驱动注册进usb serial bus下if (retval) err(problem %d when registering driver %s, retval, driver-description);list_del(&driver-driver_list);elseinfo

13、(USB Serial support registered for %s, driver-description);return retval;其中的fixup_generic()函数仅仅是为driver赋上默认的操作函数.Usb-serial.c:#define set_to_generic_if_null(type, function)do if (!type-function) type-function = usb_serial_generic_#function;dbg(Had to override the #function usb serial operation with

14、the generic one.); while (0)static void fixup_generic(struct usb_serial_driver *device)set_to_generic_if_null(device, open);set_to_generic_if_null(device, write);set_to_generic_if_null(device, close);set_to_generic_if_null(device, write_room);set_to_generic_if_null(device, chars_in_buffer);set_to_ge

15、neric_if_null(device, read_bulk_callback);set_to_generic_if_null(device, write_bulk_callback);set_to_generic_if_null(device, shutdown);即通过上面的usb_serial_register()函数后usb_serial_generic_device的函数集为:usb_serial_generic_device.open = usb_serial_generic_open;usb_serial_generic_device.close = usb_serial_ge

16、neric_close.驱动usb_serial_generic_device将是以后操作tty设备的主要函数.我们会在后面分析.bus.c:int usb_serial_bus_register(struct usb_serial_driver *driver)int retval;driver-driver.bus = &usb_serial_bus_type;/注册到该bus下retval = driver_register(&driver-driver);return retval;最后usb_serial_generic_register()函数注册了一个generic_driver驱动.generic.c:static struct usb_driver generic_driver = .name =usbserial_generic,.probe =generic_probe,/匹配函数.disconnect =

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1