ChinaUnix.net 首页 | 博客 | Linux | 论坛 | 人才 | 培训 | 知识库 | 资料 | 读书 | 手册 | 精华 | 下载 | 沙龙 | 搜索
Linux首页 | Linux论坛 | 论坛精华 | 开源新闻 | 技术文章 | 专题专栏 | 新手指南 | 迁移方案 | 产品方案 | 开源项目 | 开源图书 | 软件下载 | 人才招聘 | Linux博客
  搜索

  产品与方案
·中科红旗全面打造现代化邮政体系
·红旗助力“网上审批服务” 推动电子政务
·红旗正版化开创呼和浩特网吧建设新起点
·红旗Linux助信息产业部邮件服务器“快跑”
·中标普华Linux 为电子政务信息化保驾护航
·中标普华Linux助力基金产业
·中标普华Office率先支持UOF标准
·中标普华邮件系统助力西藏政府信息化建设
·红旗Linux助力国库集中支付系统改革
·红旗助中信卫星 掀起GIS通信应用风暴
·红旗软件助力烟草总局 全面建设“数字烟草”
·红旗助力“信访阳光工程”打造畅通信访渠道
·红帽联合FIS发布下一代实时核心银行平台
·红旗助力金盾 打造全无忧出入境信息系统
·红旗Linux全力打造中国邮政总局名址信息库
·爱尔兰证交所从Unix迁移到红帽企业Linux
·一流的意大利银行选择使用红帽企业Linux
·PLUS Finanzservice选择使用红帽企业Linux
·红帽助力TransACT Communications 公司
·法国零售业巨头Lapeyre采用Redhat Linux
·旅游预订网站选择使用红帽企业Linux
·马哈拉施特拉邦政府的红帽解决之道
·美国联邦政府案例
·红帽为慕尼黑展览会提供现代化集群系统
·Yuba郡用开源软件和红帽产品提高了效率
·红帽企业Linux助印度理工建立高性能计算中心
·采用红帽Linux 将系统维护时间缩短了65%
·从UNIX迁移到Linux使Peñoles公司获益非浅
·Hikal公司用红帽企业Linux开展任务关键的ERP项目
·KDE3.5.4新版本发布
·芝加哥商业交易所从Unix向Linux迁移
·南方基金管理有限公司成功案例 Red Hat Linux
·广东北电通讯设备有限公司成功案例
·挪威国家石油公司从UNIX迁移到红帽Linux,成本减半
·中央电视台CCTV动画部案例 Red Hat Linux

  图书

鸟哥的Linux私房菜基础学..


Linux程序设计.第3版


Linux设备驱动开发详解


  下载
·Endian Firewall
·linux kernel(Linux 内核)
·CentOS
·Fedora Core 6
·Scientific Linux
·Slackware 11.0
·Gentoo Linux
·ubuntu-6.10-i386服务器版本
·ubuntu-6.10-amd64服务器版
·ubuntu-6.10-i386桌面版
·ubuntu-6.10-amd64桌面版
·Engarde Linux
您的位置: Linux时代 > 技术文档 > 程序开发 >

Linux环境下如何设置USB驱动程序(4)

日期:2007-09-20 作者:中科红旗 梁国军 来自:linux.chinaunix.net


  bEndpointAddress:这个是特定的USB地址,可以结合USB_DIR_IN和USB_DIR_OUT来使用,以确定该端点的数据是传向设备还是主机。

  bmAttributes:这个是端点的类型,这个值可以结合位掩码USB_ENDPOINT_XFERTYPE_MASK来使用,以确定此端点的类型是USB_ENDPOINT_XFER_ISOC(等时)、USB_ENDPOINT_XFER_BULK(批量)、USB_ENDPOINT_XFER_INT的哪一种。

  wMaxPacketSize:这个是端点一次可以处理的最大字节数,驱动程序可以发送数量大于此值的数据到端点,在实际传输中,数据量如果大于此值会被分割。

  bInterval:这个值只有在端点类型是中断类型时才起作用,它是端点中断请求的间隔时间,以毫秒为单位。

  提交和控制urb:当驱动程序有数据要发送到USB设备时(大多数情况是在驱动程序的写函数中),要分配一个urb来把数据传输给设备:

  /* 创建一个urb,并且给它分配一个缓存*/

  urb = usb_alloc_urb(0, GFP_KERNEL);

  if (!urb) {

  retval = -ENOMEM;

  goto error;

  }

  当urb被成功分配后,还要创建一个DMA缓冲区来以高效的方式发送数据到设备,传递给驱动程序的数据要复制到这块缓冲中去:

  buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);

  if (!buf) {

  retval = -ENOMEM;

  goto error;

  }

  if (copy_from_user(buf, user_buffer, count)) {

  retval = -EFAULT;

  goto error;

  }

  当数据从用户空间正确复制到局部缓冲区后,urb必须在可以被提交给USB核心之前被正确初始化:

  /* 初始化urb */

  usb_fill_bulk_urb(urb, dev->udev,

  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),

  buf, count, skel_write_bulk_callback, dev);

  urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

  然后urb就可以被提交给USB核心以传输到设备了:

  /* 把数据从批量OUT端口发出 */

  retval = usb_submit_urb(urb, GFP_KERNEL);

  if (retval) {

  err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);

  goto error;

  }

  当urb被成功传输到USB设备之后,urb回调函数将被USB核心调用,在我们的例子中,我们初始化urb,使它指向skel_write_bulk_callback函数,以下就是该函数:

  static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)

  {

  struct usb_skel *dev;

  dev = (struct usb_skel *)urb->context;

  if (urb->status &&

  !(urb->status == -ENOENT ||

  urb->status == -ECONNRESET ||

  urb->status == -ESHUTDOWN)) {

  dbg("%s - nonzero write bulk status received: %d",

  __FUNCTION__, urb->status);

  }

  /* 释放已分配的缓冲区 */

  usb_buffer_free(urb->dev, urb->transfer_buffer_length,

  urb->transfer_buffer, urb->transfer_dma);

  }

  有时候USB驱动程序只是要发送或者接收一些简单的数据,驱动程序也可以不用urb来进行数据的传输,这是里涉及到两个简单的接口函数:usb_bulk_msg和usb_control_msg ,在这个USB框架程序里读操作就是这样的一个应用:

  /* 进行阻塞的批量读以从设备获取数据 */

  retval = usb_bulk_msg(dev->udev,

  usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),

  dev->bulk_in_buffer,

  min(dev->bulk_in_size, count),

  &count, HZ*10);

  /*如果读成功,复制到用户空间 */

  if (!retval) {

  if (copy_to_user(buffer, dev->bulk_in_buffer, count))

  retval = -EFAULT;

  else

  retval = count;

  }

  usb_bulk_msg接口函数的定义如下:

  int usb_bulk_msg(struct usb_device *usb_dev,unsigned int pipe,

  void *data,int len,int *actual_length,int timeout);

  其参数为:

  struct usb_device *usb_dev:指向批量消息所发送的目标USB设备指针。

  unsigned int pipe:批量消息所发送目标USB设备的特定端点,此值是调用usb_sndbulkpipe或者usb_rcvbulkpipe来创建的。

  void *data:如果是一个OUT端点,它是指向即将发送到设备的数据的指针。如果是IN端点,它是指向从设备读取的数据应该存放的位置的指针。

  int len:data参数所指缓冲区的大小。

本文被浏览



 相关新闻



 相关评论
关于我们 | 联系方式 | 广告合作 | 诚聘英才 | 网站地图 | 免费注册

Copyright © 2001-2006 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们

京ICP证041476号