首页 Linux下USB驱动程序简单例程

Linux下USB驱动程序简单例程

举报
开通vip

Linux下USB驱动程序简单例程// 自定义结构体类型 // 用于保存USB设备相关信息 struct usb_skel { struct usb_device * udev; /* usb设备对象 */ struct usb_interface * interface; /* usb设备接口对象 */ struct semaphore limit_sem; /* 写信号量 */ unsigned char * bulk_in_buffer; /* 批量传输方式的接收缓存 */ size_t bulk_in_size; /* 接收...

Linux下USB驱动程序简单例程
// 自定义结构体类型 // 用于保存USB设备相关信息 struct usb_skel { struct usb_device * udev; /* usb设备对象 */ struct usb_interface * interface; /* usb设备接口对象 */ struct semaphore limit_sem; /* 写信号量 */ unsigned char * bulk_in_buffer; /* 批量传输方式的接收缓存 */ size_t bulk_in_size; /* 接收缓存中的有效字节数 */ __u8 bulk_in_endpointAddr; /* 批量输入端口地址 */ __u8 bulk_out_endpointAddr; /* 批量输出端口地址 */ struct kref kref; }dev; // 以production ID和vendor ID组合匹配驱动程序 static struct usb_device_id skel_table [] = { { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, { } /* Terminating entry */ }; Static ssize_t skel_write(struct file * filep, const char * buff, size_t count, lof f_t * offp) { // 数据的发送方式可以选择urb方式和非urb方式 // urb方式将数据填充到一个urb中,然后发送urb给内核,内核再将数据送上USB总线// 非urb方式直接将数据发送给内核,而不填充urb结构 // 创建通讯管道 unsigned int pipe = usb_sndbulkpipe(dev.udevice, dev.bulk_out_endpointAddr); /************************** urb 方式 *********************************/ // 创建一个urb(usb request block) struct urb * usb_alloc_urb(0, // 等时包的数量,如果不是乘载等时包,应该为0 mem_flags); // 填充urb void usb_fill_bulk_urb(urb, dev.udevice, // 目的USB设备指针 pipe, // 与USB设备通讯时使用的管道 buff, // 发送数据缓存 count,// 发送数据的字节数 skel_write_bulk_callback, // 数据发送结束后回调函数指针 void *context); // 由用户定义 // 发送urb,如果成功retval值为0,数据发送结束后可以通过urb->status查询状态retval = usb_submit_urb(urb, GFP_KERNEL); /*************************** 非urb方式 ***************************/ Usinged int bytes_read; retval = usb_bulk_msg(dev->udev, pipe, buff, count, &bytes_read, 10000); } // 设备文件操作结构 static struct file_operations skel_fops = { .owner = THIS_MODULE, .read = skel_read, .write = skel_write, .open = skel_open, .release = skel_release, }; static struct usb_class_driver skel_class = { .name = "skel%d", // 设备驱动程序类名 .fops = &skel_fops, // 设备文件操作结构 .minor_base = USB_SKEL_MINOR_BASE, // 次设备号的基准值 }; skel_probe(usb_interface * interface, struct usb_device_id * device_id) { dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->interface = interface; // 本例程,probe函数查找端口中BULK_IN端点和BULK_OUT端点, // 并将相关信息保存道dev变量中 iface_desc = interface->cur_altsetting; // 获取接口的当前配置 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; // 如果这是一个BULK_IN端点 if ( !dev->bulk_in_endpointAddr && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) = = USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) = = USB_ENDPOINT_XF ER_BULK)) { buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); dev->bulk_in_size = buffer_size; dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!dev->bulk_in_buffer) { err("Could not allocate bulk_in_buffer"); goto error; } } // 如果这是一个BULK_OUT端点 if (!dev->bulk_out_endpointAddr && ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)= =USB_DIR_OUT) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)= = USB_ENDPOINT_X FER_BULK)) { /* we found a bulk out endpoint */ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; } } if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { err("Could not find both bulk-in and bulk-out endpoints"); goto error; } // 注册usb_class_driver结构,其中包含对USB设备的操作 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 等 retval = usb_register_dev(interface, &skel_class); } static struct usb_driver skel_driver = { .name = "skeleton", //驱动程序名 .probe = skel_probe, // 函数指针,设备与skel_table匹配成功后被调用, // 完成一些初始化工作 .disconnect = skel_disconnect, .id_table = skel_table, // usb内核通过设备的production ID和vendor ID的组合 // 或者设备的class、subclass跟protocol的组合来识别设备 // skel_table用于匹配USB内核识别是否将此驱动程序作为已 // 识别设备的驱动程序。 }; static int __init usb_skel_init(void) { int result; /* register this driver with the USB subsystem */ result = usb_register(&skel_driver); if (result) err("usb_register failed. Error number %d", result); return result; } static void __exit usb_skel_exit(void) { /* deregister this driver with the USB subsystem */ usb_deregister(&skel_driver); } module_init (usb_skel_init); module_exit (usb_skel_exit); MODULE_LICENSE("GPL");
本文档为【Linux下USB驱动程序简单例程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_153723
暂无简介~
格式:doc
大小:23KB
软件:Word
页数:0
分类:互联网
上传时间:2019-03-15
浏览量:5