| ||
|
| Linux首页 | Linux论坛 | 论坛精华 | 开源新闻 | 技术文章 | 专题专栏 | 新手指南 | 迁移方案 | 产品方案 | 开源项目 | 开源图书 | 软件下载 | 人才招聘 | Linux博客 |
| 您的位置:
Linux时代 > 技术文档 > 程序开发 >
Linux环境下如何设置USB驱动程序(5)
int *actual_length:指向保存实际传输字节数的位置的指针,至于是传输到设备还是从设备接收取决于端点的方向。 int timeout:以Jiffies为单位的等待的超时时间,如果该值为0,该函数一直等待消息的结束。 如果该接口函数调用成功,返回值为0,否则返回一个负的错误值。 usb_control_msg接口函数定义如下: int usb_control_msg(struct usb_device *dev,unsigned int pipe,__u8 request,__u8requesttype,__u16 value,__u16 index,void *data,__u16 size,int timeout) 除了允许驱动程序发送和接收USB控制消息之外,usb_control_msg函数的运作和usb_bulk_msg函数类似,其参数和usb_bulk_msg的参数有几个重要区别: struct usb_device *dev:指向控制消息所发送的目标USB设备的指针。 unsigned int pipe:控制消息所发送的目标USB设备的特定端点,该值是调用usb_sndctrlpipe或usb_rcvctrlpipe来创建的。 __u8 request:控制消息的USB请求值。 __u8 requesttype:控制消息的USB请求类型值。 __u16 value:控制消息的USB消息值。 __u16 index:控制消息的USB消息索引值。 void *data:如果是一个OUT端点,它是指身即将发送到设备的数据的指针。如果是一个IN端点,它是指向从设备读取的数据应该存放的位置的指针。 __u16 size:data参数所指缓冲区的大小。 int timeout:以Jiffies为单位的应该等待的超时时间,如果为0,该函数将一直等待消息结束。 如果该接口函数调用成功,返回传输到设备或者从设备读取的字节数;如果不成功它返回一个负的错误值。 这两个接口函数都不能在一个中断上下文中或者持有自旋锁的情况下调用,同样,该函数也不能被任何其它函数取消,使用时要谨慎。 我们要给未知的USB设备写驱动程序,只需要把这个框架程序稍做修改就可以用了,前面我们已经说过要修改制造商和产品的ID号,把0xfff0这两个值改为未知USB的ID号。 #define USB_SKEL_VENDOR_ID 0xfff0 #define USB_SKEL_PRODUCT_ID 0xfff0 还有就是在探测函数中把需要探测的接口端点类型写好,在这个框架程序中只探测了批量(USB_ENDPOINT_XFER_BULK)IN和OUT端点,可以在此处使用掩码(USB_ENDPOINT_XFERTYPE_MASK)让其探测其它的端点类型,驱动程序会对USB设备的每一个接口进行一次探测,当探测成功后,驱动程序就被绑定到这个接口上。再有就是urb的初始化问题,如果你只写简单的USB驱动,这块不用多加考虑,框架程序里的东西已经够用了,这里我们简单介绍三个初始化urb的辅助函数: usb_fill_int_urb :它的函数原型是这样的: void usb_fill_int_urb(struct urb *urb,struct usb_device *dev, unsigned int pipe,void *transfer_buff, int buffer_length,usb_complete_t complete, void *context,int interval); 这个函数用来正确的初始化即将被发送到USB设备的中断端点的urb。 usb_fill_bulk_urb :它的函数原型是这样的: 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) 这个函数是用来正确的初始化批量urb端点的。 usb_fill_control_urb :它的函数原型是这样的: 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); 这个函数是用来正确初始化控制urb端点的。 还有一个初始化等时urb的,它现在还没有初始化函数,所以它们在被提交到USB核心前,必须在驱动程序中手工地进行初始化,可以参考内核源代码树下的/usr/src/~/drivers/usb/media下的konicawc.c文件。 驱动模块的编译、配置和使用 现在我们的驱动程序已经大体写好了,然后在linux下把它编译成模块就可以把驱动模块插入到内核中运行了,编译的Makefile文件可以这样来写: ifneq ($(KERNELRELEASE),) obj-m := xxx.o else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif clean: rm -rf *.mod.* *.o *.ko .*.ko.* .tmp* .*.mod.o.* .*.o.* 其中xxx是源文件的文件名,在linux下直接执行make就可以生成驱动模块(xxx.ko)了。生成驱动模块后使用insmod xxx.ko就可以插入到内核中运行了,用lsmod可以看到你插入到内核中的模块,也可以从系统中用命令rmmod xxx把模块卸载掉;如果把编译出来的驱动模块拷贝到/lib/modules/~/kernel/drivers/usb/下,然后depmod一下,那么你在插入USB设备的时候,系统就会自动为你加载驱动模块的;当然这个得有hotplug的支持;加载驱动模块成功后就会在/dev/下生成设备文件了,如果用命令cat /proc/bus/usb/devices,我们可以看到驱动程序已经绑定到接口上了: 本文被浏览次
| |||||||||||
| 关于我们 | 联系方式 | 广告合作 | 诚聘英才 | 网站地图 | 免费注册 |
Copyright © 2001-2006 ChinaUnix.net All Rights Reserved 感谢所有关心和支持过ChinaUnix的朋友们 |